Loading core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -745,6 +745,10 @@ <!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION --> <!-- If this is true, notification effects will be played by the notification server. When false, car notification effects will be handled elsewhere. --> <bool name="config_enableServerNotificationEffectsForAutomotive">false</bool> <!-- If this is true, the screen will come on when you unplug usb/power/whatever. --> <bool name="config_unplugTurnsOnScreen">false</bool> Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1910,6 +1910,7 @@ <java-symbol type="array" name="config_testLocationProviders" /> <java-symbol type="array" name="config_defaultNotificationVibePattern" /> <java-symbol type="array" name="config_notificationFallbackVibePattern" /> <java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" /> <java-symbol type="bool" name="config_useAttentionLight" /> <java-symbol type="bool" name="config_adaptive_sleep_available" /> <java-symbol type="bool" name="config_animateScreenLights" /> Loading services/core/java/com/android/server/notification/NotificationManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -455,6 +455,7 @@ public class NotificationManagerService extends SystemService { private int mAutoGroupAtCount; private boolean mIsTelevision; private boolean mIsAutomotive; private boolean mNotificationEffectsEnabledForAutomotive; private MetricsLogger mMetricsLogger; private TriPredicate<String, Integer, String> mAllowedManagedServicePackages; Loading Loading @@ -1686,6 +1687,8 @@ public class NotificationManagerService extends SystemService { mIsAutomotive = mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0); mNotificationEffectsEnabledForAutomotive = resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive); mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); Loading Loading @@ -5560,6 +5563,9 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting @GuardedBy("mNotificationLock") void buzzBeepBlinkLocked(NotificationRecord record) { if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) { return; } boolean buzz = false; boolean beep = false; boolean blink = false; Loading services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +38 −13 Original line number Diff line number Diff line Loading @@ -48,8 +48,8 @@ import android.app.Notification; import android.app.Notification.Builder; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Color; import android.media.AudioAttributes; import android.media.AudioManager; Loading @@ -63,6 +63,7 @@ import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContext; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; Loading @@ -70,6 +71,7 @@ import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; import com.android.internal.util.IntPair; import com.android.server.UiServiceTestCase; import com.android.server.lights.Light; Loading @@ -86,6 +88,7 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class BuzzBeepBlinkTest extends UiServiceTestCase { private TestableContext mContext = spy(getContext()); @Mock AudioManager mAudioManager; @Mock Vibrator mVibrator; @Mock android.media.IRingtonePlayer mRingtonePlayer; Loading @@ -96,6 +99,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { NotificationUsageStats mUsageStats; @Mock IAccessibilityManager mAccessibilityService; @Mock Resources mResources; private NotificationManagerService mService; private String mPkg = "com.android.server.notification"; Loading Loading @@ -145,7 +150,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt()); assertTrue(accessibilityManager.isEnabled()); mService = spy(new NotificationManagerService(getContext())); mService = spy(new NotificationManagerService(mContext)); mService.setAudioManager(mAudioManager); mService.setVibrator(mVibrator); mService.setSystemReady(true); Loading Loading @@ -275,7 +280,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { boolean isLeanback) { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); final Builder builder = new Builder(getContext()) final Builder builder = new Builder(mContext) .setContentTitle("foo") .setSmallIcon(android.R.drawable.sym_def_app_icon) .setPriority(Notification.PRIORITY_HIGH) Loading Loading @@ -321,15 +326,14 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { n.flags |= Notification.FLAG_INSISTENT; } Context context = spy(getContext()); PackageManager packageManager = spy(context.getPackageManager()); when(context.getPackageManager()).thenReturn(packageManager); PackageManager packageManager = spy(mContext.getPackageManager()); when(mContext.getPackageManager()).thenReturn(packageManager); when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) .thenReturn(isLeanback); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid, n, mUser, null, System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(context, sbn, channel); NotificationRecord r = new NotificationRecord(mContext, sbn, channel); mService.addNotification(r); return r; } Loading Loading @@ -455,7 +459,25 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test public void testNoBeepForImportanceDefaultInAutomotive() throws Exception { public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) .thenReturn(false); mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); mService.buzzBeepBlinkLocked(r); verifyNeverBeep(); assertFalse(r.isInterruptive()); } @Test public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) .thenReturn(true); mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); Loading @@ -468,7 +490,10 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test public void testBeepForImportanceHighInAutomotive() throws Exception { public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) .thenReturn(true); mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); Loading Loading @@ -1015,12 +1040,12 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { public void testEmptyUriSoundTreatedAsNoSound() throws Exception { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); channel.setSound(Uri.EMPTY, null); final Notification n = new Builder(getContext(), "test") final Notification n = new Builder(mContext, "test") .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, mPid, n, mUser, null, System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); NotificationRecord r = new NotificationRecord(mContext, sbn, channel); mService.addNotification(r); mService.buzzBeepBlinkLocked(r); Loading Loading @@ -1069,13 +1094,13 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { @Test public void testCrossUserSoundMuted() throws Exception { final Notification n = new Builder(getContext(), "test") final Notification n = new Builder(mContext, "test") .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); int userId = mUser.getIdentifier() + 1; StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(getContext(), sbn, NotificationRecord r = new NotificationRecord(mContext, sbn, new NotificationChannel("test", "test", IMPORTANCE_HIGH)); mService.buzzBeepBlinkLocked(r); Loading Loading
core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -745,6 +745,10 @@ <!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION --> <!-- If this is true, notification effects will be played by the notification server. When false, car notification effects will be handled elsewhere. --> <bool name="config_enableServerNotificationEffectsForAutomotive">false</bool> <!-- If this is true, the screen will come on when you unplug usb/power/whatever. --> <bool name="config_unplugTurnsOnScreen">false</bool> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1910,6 +1910,7 @@ <java-symbol type="array" name="config_testLocationProviders" /> <java-symbol type="array" name="config_defaultNotificationVibePattern" /> <java-symbol type="array" name="config_notificationFallbackVibePattern" /> <java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" /> <java-symbol type="bool" name="config_useAttentionLight" /> <java-symbol type="bool" name="config_adaptive_sleep_available" /> <java-symbol type="bool" name="config_animateScreenLights" /> Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -455,6 +455,7 @@ public class NotificationManagerService extends SystemService { private int mAutoGroupAtCount; private boolean mIsTelevision; private boolean mIsAutomotive; private boolean mNotificationEffectsEnabledForAutomotive; private MetricsLogger mMetricsLogger; private TriPredicate<String, Integer, String> mAllowedManagedServicePackages; Loading Loading @@ -1686,6 +1687,8 @@ public class NotificationManagerService extends SystemService { mIsAutomotive = mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0); mNotificationEffectsEnabledForAutomotive = resources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive); mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); Loading Loading @@ -5560,6 +5563,9 @@ public class NotificationManagerService extends SystemService { @VisibleForTesting @GuardedBy("mNotificationLock") void buzzBeepBlinkLocked(NotificationRecord record) { if (mIsAutomotive && !mNotificationEffectsEnabledForAutomotive) { return; } boolean buzz = false; boolean beep = false; boolean blink = false; Loading
services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +38 −13 Original line number Diff line number Diff line Loading @@ -48,8 +48,8 @@ import android.app.Notification; import android.app.Notification.Builder; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Color; import android.media.AudioAttributes; import android.media.AudioManager; Loading @@ -63,6 +63,7 @@ import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.test.suitebuilder.annotation.SmallTest; import android.testing.TestableContext; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.IAccessibilityManager; Loading @@ -70,6 +71,7 @@ import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; import com.android.internal.util.IntPair; import com.android.server.UiServiceTestCase; import com.android.server.lights.Light; Loading @@ -86,6 +88,7 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidJUnit4.class) public class BuzzBeepBlinkTest extends UiServiceTestCase { private TestableContext mContext = spy(getContext()); @Mock AudioManager mAudioManager; @Mock Vibrator mVibrator; @Mock android.media.IRingtonePlayer mRingtonePlayer; Loading @@ -96,6 +99,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { NotificationUsageStats mUsageStats; @Mock IAccessibilityManager mAccessibilityService; @Mock Resources mResources; private NotificationManagerService mService; private String mPkg = "com.android.server.notification"; Loading Loading @@ -145,7 +150,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt()); assertTrue(accessibilityManager.isEnabled()); mService = spy(new NotificationManagerService(getContext())); mService = spy(new NotificationManagerService(mContext)); mService.setAudioManager(mAudioManager); mService.setVibrator(mVibrator); mService.setSystemReady(true); Loading Loading @@ -275,7 +280,7 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { boolean isLeanback) { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); final Builder builder = new Builder(getContext()) final Builder builder = new Builder(mContext) .setContentTitle("foo") .setSmallIcon(android.R.drawable.sym_def_app_icon) .setPriority(Notification.PRIORITY_HIGH) Loading Loading @@ -321,15 +326,14 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { n.flags |= Notification.FLAG_INSISTENT; } Context context = spy(getContext()); PackageManager packageManager = spy(context.getPackageManager()); when(context.getPackageManager()).thenReturn(packageManager); PackageManager packageManager = spy(mContext.getPackageManager()); when(mContext.getPackageManager()).thenReturn(packageManager); when(packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) .thenReturn(isLeanback); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid, n, mUser, null, System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(context, sbn, channel); NotificationRecord r = new NotificationRecord(mContext, sbn, channel); mService.addNotification(r); return r; } Loading Loading @@ -455,7 +459,25 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test public void testNoBeepForImportanceDefaultInAutomotive() throws Exception { public void testNoBeepForAutomotiveIfEffectsDisabled() throws Exception { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) .thenReturn(false); mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); mService.buzzBeepBlinkLocked(r); verifyNeverBeep(); assertFalse(r.isInterruptive()); } @Test public void testNoBeepForImportanceDefaultInAutomotiveIfEffectsEnabled() throws Exception { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) .thenReturn(true); mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); Loading @@ -468,7 +490,10 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { } @Test public void testBeepForImportanceHighInAutomotive() throws Exception { public void testBeepForImportanceHighInAutomotiveIfEffectsEnabled() throws Exception { when(mContext.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.config_enableServerNotificationEffectsForAutomotive)) .thenReturn(true); mService.setIsAutomotive(true); NotificationRecord r = getBeepyNotification(); Loading Loading @@ -1015,12 +1040,12 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { public void testEmptyUriSoundTreatedAsNoSound() throws Exception { NotificationChannel channel = new NotificationChannel("test", "test", IMPORTANCE_HIGH); channel.setSound(Uri.EMPTY, null); final Notification n = new Builder(getContext(), "test") final Notification n = new Builder(mContext, "test") .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, mPid, n, mUser, null, System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(getContext(), sbn, channel); NotificationRecord r = new NotificationRecord(mContext, sbn, channel); mService.addNotification(r); mService.buzzBeepBlinkLocked(r); Loading Loading @@ -1069,13 +1094,13 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { @Test public void testCrossUserSoundMuted() throws Exception { final Notification n = new Builder(getContext(), "test") final Notification n = new Builder(mContext, "test") .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); int userId = mUser.getIdentifier() + 1; StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid, mPid, n, UserHandle.of(userId), null, System.currentTimeMillis()); NotificationRecord r = new NotificationRecord(getContext(), sbn, NotificationRecord r = new NotificationRecord(mContext, sbn, new NotificationChannel("test", "test", IMPORTANCE_HIGH)); mService.buzzBeepBlinkLocked(r); Loading