Loading services/core/java/com/android/server/notification/NotificationManagerInternal.java +19 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.notification; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.service.notification.DeviceEffectsApplier; import java.util.Set; Loading Loading @@ -54,4 +55,22 @@ public interface NotificationManagerInternal { void cleanupHistoryFiles(); void removeBitmaps(); /** * Sets the {@link DeviceEffectsApplier} that will be used to apply the different * {@link android.service.notification.ZenDeviceEffects} that are relevant for the platform * when {@link android.service.notification.ZenModeConfig.ZenRule} instances are activated and * deactivated. * * <p>This method is optional and needs only be called if the platform supports non-standard * effects (i.e. any that are not <em>public APIs</em> in * {@link android.service.notification.ZenDeviceEffects}, or if they must be applied in a * non-standard fashion. If not used, a {@link DefaultDeviceEffectsApplier} will be invoked, * which should be sufficient for most devices. * * <p>If this method is called, it <em>must</em> be during system startup and <em>before</em> * the {@link com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START} boot phase. * Otherwise an {@link IllegalStateException} will be thrown. */ void setDeviceEffectsApplier(DeviceEffectsApplier applier); } services/core/java/com/android/server/notification/NotificationManagerService.java +13 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ import android.provider.Settings.Secure; import android.service.notification.Adjustment; import android.service.notification.Condition; import android.service.notification.ConversationChannelWrapper; import android.service.notification.DeviceEffectsApplier; import android.service.notification.IConditionProvider; import android.service.notification.INotificationListener; import android.service.notification.IStatusBarNotificationHolder; Loading Loading @@ -6964,6 +6965,18 @@ public class NotificationManagerService extends SystemService { } } } @Override public void setDeviceEffectsApplier(DeviceEffectsApplier applier) { if (!android.app.Flags.modesApi()) { return; } if (mZenModeHelper == null) { throw new IllegalStateException("ZenModeHelper is not yet ready!"); } // This can also throw IllegalStateException if called too late. mZenModeHelper.setDeviceEffectsApplier(applier); } }; private static boolean isBigPictureWithBitmapOrIcon(Notification n) { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +48 −5 Original line number Diff line number Diff line Loading @@ -219,6 +219,7 @@ import android.provider.MediaStore; import android.provider.Settings; import android.service.notification.Adjustment; import android.service.notification.ConversationChannelWrapper; import android.service.notification.DeviceEffectsApplier; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationRankingUpdate; Loading Loading @@ -635,6 +636,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } private void initNMS() throws Exception { initNMS(SystemService.PHASE_BOOT_COMPLETED); } private void initNMS(int upToBootPhase) throws Exception { mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, mNotificationInstanceIdSequence); Loading Loading @@ -662,13 +667,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class), mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager, mPowerManager, mPostNotificationTrackerFactory); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); if (upToBootPhase >= SystemService.PHASE_SYSTEM_SERVICES_READY) { mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); } Mockito.reset(mHistoryManager); verify(mHistoryManager, never()).onBootPhaseAppsCanStart(); if (upToBootPhase >= SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START, mMainLooper); verify(mHistoryManager).onBootPhaseAppsCanStart(); } // TODO b/291907312: remove feature flag if (Flags.refactorAttentionHelper()) { Loading Loading @@ -914,7 +927,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestNotificationChannel.setAllowBubbles(channelEnabled); } private void setUpPrefsForHistory(int uid, boolean globalEnabled) { private void setUpPrefsForHistory(int uid, boolean globalEnabled) throws Exception { initNMS(SystemService.PHASE_ACTIVITY_MANAGER_READY); // Sets NOTIFICATION_HISTORY_ENABLED setting for calling process uid Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, globalEnabled ? 1 : 0, uid); Loading Loading @@ -10090,7 +10105,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test public void testHandleOnPackageRemoved_ClearsHistory() throws RemoteException { public void testHandleOnPackageRemoved_ClearsHistory() throws Exception { // Enables Notification History setting setUpPrefsForHistory(mUid, true /* =enabled */); Loading Loading @@ -13208,6 +13223,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mSnoozeHelper).clearData(anyInt()); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void setDeviceEffectsApplier_succeeds() throws Exception { initNMS(SystemService.PHASE_SYSTEM_SERVICES_READY); mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class)); // No exception! } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void setDeviceEffectsApplier_tooLate_throws() throws Exception { initNMS(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); assertThrows(IllegalStateException.class, () -> mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class))); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void setDeviceEffectsApplier_calledTwice_throws() throws Exception { initNMS(SystemService.PHASE_SYSTEM_SERVICES_READY); mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class)); assertThrows(IllegalStateException.class, () -> mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class))); } @Test @EnableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void setNotificationPolicy_mappedToImplicitRule() throws RemoteException { Loading
services/core/java/com/android/server/notification/NotificationManagerInternal.java +19 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.notification; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.service.notification.DeviceEffectsApplier; import java.util.Set; Loading Loading @@ -54,4 +55,22 @@ public interface NotificationManagerInternal { void cleanupHistoryFiles(); void removeBitmaps(); /** * Sets the {@link DeviceEffectsApplier} that will be used to apply the different * {@link android.service.notification.ZenDeviceEffects} that are relevant for the platform * when {@link android.service.notification.ZenModeConfig.ZenRule} instances are activated and * deactivated. * * <p>This method is optional and needs only be called if the platform supports non-standard * effects (i.e. any that are not <em>public APIs</em> in * {@link android.service.notification.ZenDeviceEffects}, or if they must be applied in a * non-standard fashion. If not used, a {@link DefaultDeviceEffectsApplier} will be invoked, * which should be sufficient for most devices. * * <p>If this method is called, it <em>must</em> be during system startup and <em>before</em> * the {@link com.android.server.SystemService#PHASE_THIRD_PARTY_APPS_CAN_START} boot phase. * Otherwise an {@link IllegalStateException} will be thrown. */ void setDeviceEffectsApplier(DeviceEffectsApplier applier); }
services/core/java/com/android/server/notification/NotificationManagerService.java +13 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ import android.provider.Settings.Secure; import android.service.notification.Adjustment; import android.service.notification.Condition; import android.service.notification.ConversationChannelWrapper; import android.service.notification.DeviceEffectsApplier; import android.service.notification.IConditionProvider; import android.service.notification.INotificationListener; import android.service.notification.IStatusBarNotificationHolder; Loading Loading @@ -6964,6 +6965,18 @@ public class NotificationManagerService extends SystemService { } } } @Override public void setDeviceEffectsApplier(DeviceEffectsApplier applier) { if (!android.app.Flags.modesApi()) { return; } if (mZenModeHelper == null) { throw new IllegalStateException("ZenModeHelper is not yet ready!"); } // This can also throw IllegalStateException if called too late. mZenModeHelper.setDeviceEffectsApplier(applier); } }; private static boolean isBigPictureWithBitmapOrIcon(Notification n) { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +48 −5 Original line number Diff line number Diff line Loading @@ -219,6 +219,7 @@ import android.provider.MediaStore; import android.provider.Settings; import android.service.notification.Adjustment; import android.service.notification.ConversationChannelWrapper; import android.service.notification.DeviceEffectsApplier; import android.service.notification.NotificationListenerFilter; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationRankingUpdate; Loading Loading @@ -635,6 +636,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } private void initNMS() throws Exception { initNMS(SystemService.PHASE_BOOT_COMPLETED); } private void initNMS(int upToBootPhase) throws Exception { mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, mNotificationInstanceIdSequence); Loading Loading @@ -662,13 +667,21 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class), mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager, mPowerManager, mPostNotificationTrackerFactory); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); if (upToBootPhase >= SystemService.PHASE_SYSTEM_SERVICES_READY) { mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); } Mockito.reset(mHistoryManager); verify(mHistoryManager, never()).onBootPhaseAppsCanStart(); if (upToBootPhase >= SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) { mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START, mMainLooper); verify(mHistoryManager).onBootPhaseAppsCanStart(); } // TODO b/291907312: remove feature flag if (Flags.refactorAttentionHelper()) { Loading Loading @@ -914,7 +927,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mTestNotificationChannel.setAllowBubbles(channelEnabled); } private void setUpPrefsForHistory(int uid, boolean globalEnabled) { private void setUpPrefsForHistory(int uid, boolean globalEnabled) throws Exception { initNMS(SystemService.PHASE_ACTIVITY_MANAGER_READY); // Sets NOTIFICATION_HISTORY_ENABLED setting for calling process uid Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.NOTIFICATION_HISTORY_ENABLED, globalEnabled ? 1 : 0, uid); Loading Loading @@ -10090,7 +10105,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test public void testHandleOnPackageRemoved_ClearsHistory() throws RemoteException { public void testHandleOnPackageRemoved_ClearsHistory() throws Exception { // Enables Notification History setting setUpPrefsForHistory(mUid, true /* =enabled */); Loading Loading @@ -13208,6 +13223,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mSnoozeHelper).clearData(anyInt()); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void setDeviceEffectsApplier_succeeds() throws Exception { initNMS(SystemService.PHASE_SYSTEM_SERVICES_READY); mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class)); // No exception! } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void setDeviceEffectsApplier_tooLate_throws() throws Exception { initNMS(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); assertThrows(IllegalStateException.class, () -> mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class))); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) public void setDeviceEffectsApplier_calledTwice_throws() throws Exception { initNMS(SystemService.PHASE_SYSTEM_SERVICES_READY); mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class)); assertThrows(IllegalStateException.class, () -> mInternalService.setDeviceEffectsApplier(mock(DeviceEffectsApplier.class))); } @Test @EnableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void setNotificationPolicy_mappedToImplicitRule() throws RemoteException {