summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Sandler <dsandler@android.com>2012-11-13 20:49:47 -0800
committerThe Android Automerger <android-build@android.com>2012-11-19 16:06:13 -0800
commitcc2e849fa992ebcf99c63837e96a6c8950d2cebf (patch)
treea01d98ff6fa72a012929436b7d5ed91314a23d0e
parent9a7debe5857ffc7c71cfc4082b1b6d72a5cf81cd (diff)
downloadbase-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-xcore/res/res/values/config.xml21
-rw-r--r--core/res/res/values/symbols.xml2
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java59
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);
+ }
}
}