Add vibration code to Ringer
When there's a new incoming call, vibrate (according to preferences
and volume settings) the device as well as ringing it.
Bug: 13365911
Change-Id: Id67999a173d36aa4d8472a52ac4ab95eaaea0fb0
diff --git a/src/com/android/telecomm/Ringer.java b/src/com/android/telecomm/Ringer.java
index bb32cc3..fdc9349 100644
--- a/src/com/android/telecomm/Ringer.java
+++ b/src/com/android/telecomm/Ringer.java
@@ -18,6 +18,9 @@
import android.content.Context;
import android.media.AudioManager;
+import android.os.SystemVibrator;
+import android.os.Vibrator;
+import android.provider.Settings;
import android.telecomm.CallState;
import com.google.common.collect.Lists;
@@ -28,6 +31,15 @@
* Controls the ringtone player.
*/
final class Ringer extends CallsManagerListenerBase {
+ private static final long[] VIBRATION_PATTERN = new long[] {
+ 0, // No delay before starting
+ 1000, // How long to vibrate
+ 1000, // How long to wait before vibrating again
+ };
+
+ /** Indicate that we want the pattern to repeat at the step which turns on vibration. */
+ private static final int VIBRATION_PATTERN_REPEAT = 1;
+
private final AsyncRingtonePlayer mRingtonePlayer = new AsyncRingtonePlayer();
/**
@@ -38,8 +50,19 @@
private final CallAudioManager mCallAudioManager;
+ private final Vibrator mVibrator;
+
+ /**
+ * Used to track the status of {@link #mVibrator} in the case of simultaneous incoming calls.
+ */
+ private boolean mIsVibrating = false;
+
Ringer(CallAudioManager callAudioManager) {
mCallAudioManager = callAudioManager;
+
+ // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this
+ // vibrator object will be isolated from others.
+ mVibrator = new SystemVibrator(TelecommApp.getInstance());
}
@Override
@@ -111,6 +134,12 @@
} else {
Log.v(this, "startRinging, skipping because volume is 0");
}
+
+ if (shouldVibrate(TelecommApp.getInstance()) && !mIsVibrating) {
+ mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
+ AudioManager.STREAM_RING);
+ mIsVibrating = true;
+ }
}
private void stopRinging() {
@@ -119,5 +148,28 @@
// Even though stop is asynchronous it's ok to update the audio manager. Things like audio
// focus are voluntary so releasing focus too early is not detrimental.
mCallAudioManager.setIsRinging(false);
+
+ if (mIsVibrating) {
+ mVibrator.cancel();
+ mIsVibrating = false;
+ }
+ }
+
+ private boolean shouldVibrate(Context context) {
+ AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+ int ringerMode = audioManager.getRingerMode();
+ if (getVibrateWhenRinging(context)) {
+ return ringerMode != AudioManager.RINGER_MODE_SILENT;
+ } else {
+ return ringerMode == AudioManager.RINGER_MODE_VIBRATE;
+ }
+ }
+
+ private boolean getVibrateWhenRinging(Context context) {
+ if (!mVibrator.hasVibrator()) {
+ return false;
+ }
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
}
}