diff options
author | Daniel Sandler <dsandler@android.com> | 2012-11-13 20:49:47 -0800 |
---|---|---|
committer | The Android Automerger <android-build@android.com> | 2012-11-19 16:06:13 -0800 |
commit | cc2e849fa992ebcf99c63837e96a6c8950d2cebf (patch) | |
tree | a01d98ff6fa72a012929436b7d5ed91314a23d0e | |
parent | 9a7debe5857ffc7c71cfc4082b1b6d72a5cf81cd (diff) | |
download | base-cc2e849fa992ebcf99c63837e96a6c8950d2cebf.tar.gz |
Notification vibration improvements: [DO NOT MERGE]
- When notifications vibrate as a fallback (that is,
because they want to play a sound but the device is in
vibrate mode), this no longer requires the VIBRATE
permission.
- As a bonus, if your notifications use DEFAULT_VIBRATE,
you don't need the VIBRATE permission either.
- If you specify a custom vibration pattern, you'll still
need the VIBRATE permission for that.
- Notifications vibrating in fallback mode use same
vibration pattern but can be changed easily in future.
- The DEFAULT_VIBRATE and fallback vibrate patterns are now
specified in config.xml.
Bug: 7531442
Change-Id: I7a2d8413d1becc53b9d31f0d1abbc2acc3f650c6
-rwxr-xr-x | core/res/res/values/config.xml | 21 | ||||
-rw-r--r-- | core/res/res/values/symbols.xml | 2 | ||||
-rwxr-xr-x | services/java/com/android/server/NotificationManagerService.java | 59 |
3 files changed, 74 insertions, 8 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 3b7d73a44cbc..f91df99ab6d1 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1000,4 +1000,25 @@ provisioning on some carriers, working around a bug (7305641) where if the preferred is used we don't try the others. --> <bool name="config_dontPreferApn">false</bool> + + <!-- Vibrator pattern to be used as the default for notifications + that specify DEFAULT_VIBRATE. + --> + <integer-array name="config_defaultNotificationVibePattern"> + <item>0</item> + <item>250</item> + <item>250</item> + <item>250</item> + </integer-array> + + <!-- Vibrator pattern to be used as the default for notifications + that do not specify vibration but vibrate anyway because the device + is in vibrate mode. + --> + <integer-array name="config_notificationFallbackVibePattern"> + <item>0</item> + <item>250</item> + <item>250</item> + <item>250</item> + </integer-array> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 68a028975681..68587321b207 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1525,6 +1525,8 @@ <java-symbol type="array" name="radioAttributes" /> <java-symbol type="array" name="config_oemUsbModeOverride" /> <java-symbol type="array" name="config_locationProviderPackageNames" /> + <java-symbol type="array" name="config_defaultNotificationVibePattern" /> + <java-symbol type="array" name="config_notificationFallbackVibePattern" /> <java-symbol type="bool" name="config_animateScreenLights" /> <java-symbol type="bool" name="config_automatic_brightness_available" /> <java-symbol type="bool" name="config_sf_limitedAlpha" /> diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java index f3a38f0c7cdb..70d37bfc8285 100755 --- 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); + } } } |