diff options
Diffstat (limited to 'services/java/com/android/server/NotificationManagerService.java')
-rw-r--r-- | services/java/com/android/server/NotificationManagerService.java | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index f3a38f0..70d37bf 100644 --- a/services/java/com/android/server/NotificationManagerService.java +++ b/services/java/com/android/server/NotificationManagerService.java @@ -101,6 +101,7 @@ public class NotificationManagerService extends INotificationManager.Stub private static final int SHORT_DELAY = 2000; // 2 seconds private static final long[] DEFAULT_VIBRATE_PATTERN = {0, 250, 250, 250}; + private static final int VIBRATE_PATTERN_MAXLEN = 8 * 2 + 1; // up to eight bumps private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_NOTIFICATION; private static final boolean SCORE_ONGOING_HIGHER = false; @@ -125,6 +126,9 @@ public class NotificationManagerService extends INotificationManager.Stub private int mDefaultNotificationLedOn; private int mDefaultNotificationLedOff; + private long[] mDefaultVibrationPattern; + private long[] mFallbackVibrationPattern; + private boolean mSystemReady; private int mDisabledNotifications; @@ -596,6 +600,19 @@ public class NotificationManagerService extends INotificationManager.Stub } } + static long[] getLongArray(Resources r, int resid, int maxlen, long[] def) { + int[] ar = r.getIntArray(resid); + if (ar == null) { + return def; + } + final int len = ar.length > maxlen ? maxlen : ar.length; + long[] out = new long[len]; + for (int i=0; i<len; i++) { + out[i] = ar[i]; + } + return out; + } + NotificationManagerService(Context context, StatusBarManagerService statusBar, LightsService lights) { @@ -622,6 +639,16 @@ public class NotificationManagerService extends INotificationManager.Stub mDefaultNotificationLedOff = resources.getInteger( com.android.internal.R.integer.config_defaultNotificationLedOff); + mDefaultVibrationPattern = getLongArray(resources, + com.android.internal.R.array.config_defaultNotificationVibePattern, + VIBRATE_PATTERN_MAXLEN, + DEFAULT_VIBRATE_PATTERN); + + mFallbackVibrationPattern = getLongArray(resources, + com.android.internal.R.array.config_notificationFallbackVibePattern, + VIBRATE_PATTERN_MAXLEN, + DEFAULT_VIBRATE_PATTERN); + // Don't start allowing notifications until the setup wizard has run once. // After that, including subsequent boots, init with notifications turned on. // This works on the first boot because the setup wizard will toggle this @@ -1086,24 +1113,40 @@ public class NotificationManagerService extends INotificationManager.Stub } // vibrate + // Does the notification want to specify its own vibration? + final boolean hasCustomVibrate = notification.vibrate != null; + // new in 4.2: if there was supposed to be a sound and we're in vibrate mode, - // we always vibrate, even if no vibration was specified + // and no other vibration is specified, we apply the default vibration anyway final boolean convertSoundToVibration = - notification.vibrate == null + !hasCustomVibrate && (useDefaultSound || notification.sound != null) && (audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE); + // The DEFAULT_VIBRATE flag trumps any custom vibration. final boolean useDefaultVibrate = - (notification.defaults & Notification.DEFAULT_VIBRATE) != 0 - || convertSoundToVibration; + (notification.defaults & Notification.DEFAULT_VIBRATE) != 0; - if ((useDefaultVibrate || notification.vibrate != null) + if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate) && !(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) { mVibrateNotification = r; - mVibrator.vibrate(useDefaultVibrate ? DEFAULT_VIBRATE_PATTERN - : notification.vibrate, - ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1); + if (useDefaultVibrate || convertSoundToVibration) { + // Escalate privileges so we can use the vibrator even if the notifying app + // does not have the VIBRATE permission. + long identity = Binder.clearCallingIdentity(); + try { + mVibrator.vibrate(convertSoundToVibration ? mFallbackVibrationPattern + : mDefaultVibrationPattern, + ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1); + } finally { + Binder.restoreCallingIdentity(identity); + } + } else if (notification.vibrate.length > 1) { + // If you want your own vibration pattern, you need the VIBRATE permission + mVibrator.vibrate(notification.vibrate, + ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0: -1); + } } } |