Loading services/core/java/com/android/server/notification/NotificationManagerService.java +26 −3 Original line number Diff line number Diff line Loading @@ -6248,6 +6248,7 @@ public class NotificationManagerService extends SystemService { int callingUid = Binder.getCallingUid(); @ZenModeConfig.ConfigOrigin int origin = computeZenOrigin(fromUser); boolean isSystemCaller = isCallerSystemOrSystemUiOrShell(); boolean shouldApplyAsImplicitRule = android.app.Flags.modesApi() && !canManageGlobalZenPolicy(pkg, callingUid); Loading Loading @@ -6284,11 +6285,33 @@ public class NotificationManagerService extends SystemService { policy.priorityCallSenders, policy.priorityMessageSenders, policy.suppressedVisualEffects, currPolicy.priorityConversationSenders); } int newVisualEffects = calculateSuppressedVisualEffects( policy, currPolicy, applicationInfo.targetSdkVersion); if (android.app.Flags.modesUi()) { // 1. Callers should not modify STATE_CHANNELS_BYPASSING_DND, which is // internally calculated and only indicates whether channels that want to bypass // DND _exist_. // 2. Only system callers should modify STATE_PRIORITY_CHANNELS_BLOCKED because // it is @hide. // 3. If the policy has been modified by the targetSdkVersion checks above then // it has lost its state flags and that's fine (STATE_PRIORITY_CHANNELS_BLOCKED // didn't exist until V). int newState = Policy.STATE_UNSET; if (isSystemCaller && policy.state != Policy.STATE_UNSET) { newState = Policy.policyState( currPolicy.hasPriorityChannels(), policy.allowPriorityChannels()); } policy = new Policy(policy.priorityCategories, policy.priorityCallSenders, policy.priorityMessageSenders, newVisualEffects, newState, policy.priorityConversationSenders); } else { policy = new Policy(policy.priorityCategories, policy.priorityCallSenders, policy.priorityMessageSenders, newVisualEffects, policy.priorityConversationSenders); } if (shouldApplyAsImplicitRule) { mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, callingUid, policy); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +54 −1 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.app.NotificationManager.Policy; import android.app.PendingIntent; import android.app.Person; import android.app.RemoteInput; Loading Loading @@ -655,7 +656,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())) .thenReturn(INVALID_TASK_ID); mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class)); when(mUm.getProfileIds(eq(mUserId), eq(false))).thenReturn(new int[] { mUserId }); when(mUm.getProfileIds(eq(mUserId), anyBoolean())).thenReturn(new int[]{mUserId}); when(mUmInternal.getProfileIds(eq(mUserId), anyBoolean())).thenReturn(new int[]{mUserId}); when(mAmi.getCurrentUserId()).thenReturn(mUserId); when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(true); Loading Loading @@ -15971,6 +15973,57 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(updatedRule.getValue().isEnabled()).isFalse(); } @Test @EnableFlags({android.app.Flags.FLAG_MODES_API, android.app.Flags.FLAG_MODES_UI}) public void setNotificationPolicy_fromSystemApp_appliesPriorityChannelsAllowed() throws Exception { setUpRealZenTest(); // Start with hasPriorityChannels=true, allowPriorityChannels=true ("default"). mService.mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0, 0, Policy.policyState(true, true), 0), ZenModeConfig.ORIGIN_SYSTEM, Process.SYSTEM_UID); // The caller will supply states with "wrong" hasPriorityChannels. int stateBlockingPriorityChannels = Policy.policyState(false, false); mBinderService.setNotificationPolicy(mPkg, new Policy(1, 0, 0, 0, stateBlockingPriorityChannels, 0), false); // hasPriorityChannels is untouched and allowPriorityChannels was updated. assertThat(mBinderService.getNotificationPolicy(mPkg).priorityCategories).isEqualTo(1); assertThat(mBinderService.getNotificationPolicy(mPkg).state).isEqualTo( Policy.policyState(true, false)); // Same but setting allowPriorityChannels to true. int stateAllowingPriorityChannels = Policy.policyState(false, true); mBinderService.setNotificationPolicy(mPkg, new Policy(2, 0, 0, 0, stateAllowingPriorityChannels, 0), false); assertThat(mBinderService.getNotificationPolicy(mPkg).priorityCategories).isEqualTo(2); assertThat(mBinderService.getNotificationPolicy(mPkg).state).isEqualTo( Policy.policyState(true, true)); } @Test @EnableFlags({android.app.Flags.FLAG_MODES_API, android.app.Flags.FLAG_MODES_UI}) @DisableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void setNotificationPolicy_fromRegularAppThatCanModifyPolicy_ignoresState() throws Exception { setUpRealZenTest(); // Start with hasPriorityChannels=true, allowPriorityChannels=true ("default"). mService.mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0, 0, Policy.policyState(true, true), 0), ZenModeConfig.ORIGIN_SYSTEM, Process.SYSTEM_UID); mService.setCallerIsNormalPackage(); mBinderService.setNotificationPolicy(mPkg, new Policy(1, 0, 0, 0, Policy.policyState(false, false), 0), false); // Policy was updated but the attempt to change state was ignored (it's a @hide API). assertThat(mBinderService.getNotificationPolicy(mPkg).priorityCategories).isEqualTo(1); assertThat(mBinderService.getNotificationPolicy(mPkg).state).isEqualTo( Policy.policyState(true, true)); } /** Prepares for a zen-related test that uses the real {@link ZenModeHelper}. */ private void setUpRealZenTest() throws Exception { when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt())) Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +26 −3 Original line number Diff line number Diff line Loading @@ -6248,6 +6248,7 @@ public class NotificationManagerService extends SystemService { int callingUid = Binder.getCallingUid(); @ZenModeConfig.ConfigOrigin int origin = computeZenOrigin(fromUser); boolean isSystemCaller = isCallerSystemOrSystemUiOrShell(); boolean shouldApplyAsImplicitRule = android.app.Flags.modesApi() && !canManageGlobalZenPolicy(pkg, callingUid); Loading Loading @@ -6284,11 +6285,33 @@ public class NotificationManagerService extends SystemService { policy.priorityCallSenders, policy.priorityMessageSenders, policy.suppressedVisualEffects, currPolicy.priorityConversationSenders); } int newVisualEffects = calculateSuppressedVisualEffects( policy, currPolicy, applicationInfo.targetSdkVersion); if (android.app.Flags.modesUi()) { // 1. Callers should not modify STATE_CHANNELS_BYPASSING_DND, which is // internally calculated and only indicates whether channels that want to bypass // DND _exist_. // 2. Only system callers should modify STATE_PRIORITY_CHANNELS_BLOCKED because // it is @hide. // 3. If the policy has been modified by the targetSdkVersion checks above then // it has lost its state flags and that's fine (STATE_PRIORITY_CHANNELS_BLOCKED // didn't exist until V). int newState = Policy.STATE_UNSET; if (isSystemCaller && policy.state != Policy.STATE_UNSET) { newState = Policy.policyState( currPolicy.hasPriorityChannels(), policy.allowPriorityChannels()); } policy = new Policy(policy.priorityCategories, policy.priorityCallSenders, policy.priorityMessageSenders, newVisualEffects, newState, policy.priorityConversationSenders); } else { policy = new Policy(policy.priorityCategories, policy.priorityCallSenders, policy.priorityMessageSenders, newVisualEffects, policy.priorityConversationSenders); } if (shouldApplyAsImplicitRule) { mZenModeHelper.applyGlobalPolicyAsImplicitZenRule(pkg, callingUid, policy); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +54 −1 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; import android.app.NotificationManager; import android.app.NotificationManager.Policy; import android.app.PendingIntent; import android.app.Person; import android.app.RemoteInput; Loading Loading @@ -655,7 +656,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())) .thenReturn(INVALID_TASK_ID); mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class)); when(mUm.getProfileIds(eq(mUserId), eq(false))).thenReturn(new int[] { mUserId }); when(mUm.getProfileIds(eq(mUserId), anyBoolean())).thenReturn(new int[]{mUserId}); when(mUmInternal.getProfileIds(eq(mUserId), anyBoolean())).thenReturn(new int[]{mUserId}); when(mAmi.getCurrentUserId()).thenReturn(mUserId); when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(true); Loading Loading @@ -15971,6 +15973,57 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertThat(updatedRule.getValue().isEnabled()).isFalse(); } @Test @EnableFlags({android.app.Flags.FLAG_MODES_API, android.app.Flags.FLAG_MODES_UI}) public void setNotificationPolicy_fromSystemApp_appliesPriorityChannelsAllowed() throws Exception { setUpRealZenTest(); // Start with hasPriorityChannels=true, allowPriorityChannels=true ("default"). mService.mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0, 0, Policy.policyState(true, true), 0), ZenModeConfig.ORIGIN_SYSTEM, Process.SYSTEM_UID); // The caller will supply states with "wrong" hasPriorityChannels. int stateBlockingPriorityChannels = Policy.policyState(false, false); mBinderService.setNotificationPolicy(mPkg, new Policy(1, 0, 0, 0, stateBlockingPriorityChannels, 0), false); // hasPriorityChannels is untouched and allowPriorityChannels was updated. assertThat(mBinderService.getNotificationPolicy(mPkg).priorityCategories).isEqualTo(1); assertThat(mBinderService.getNotificationPolicy(mPkg).state).isEqualTo( Policy.policyState(true, false)); // Same but setting allowPriorityChannels to true. int stateAllowingPriorityChannels = Policy.policyState(false, true); mBinderService.setNotificationPolicy(mPkg, new Policy(2, 0, 0, 0, stateAllowingPriorityChannels, 0), false); assertThat(mBinderService.getNotificationPolicy(mPkg).priorityCategories).isEqualTo(2); assertThat(mBinderService.getNotificationPolicy(mPkg).state).isEqualTo( Policy.policyState(true, true)); } @Test @EnableFlags({android.app.Flags.FLAG_MODES_API, android.app.Flags.FLAG_MODES_UI}) @DisableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void setNotificationPolicy_fromRegularAppThatCanModifyPolicy_ignoresState() throws Exception { setUpRealZenTest(); // Start with hasPriorityChannels=true, allowPriorityChannels=true ("default"). mService.mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0, 0, Policy.policyState(true, true), 0), ZenModeConfig.ORIGIN_SYSTEM, Process.SYSTEM_UID); mService.setCallerIsNormalPackage(); mBinderService.setNotificationPolicy(mPkg, new Policy(1, 0, 0, 0, Policy.policyState(false, false), 0), false); // Policy was updated but the attempt to change state was ignored (it's a @hide API). assertThat(mBinderService.getNotificationPolicy(mPkg).priorityCategories).isEqualTo(1); assertThat(mBinderService.getNotificationPolicy(mPkg).state).isEqualTo( Policy.policyState(true, true)); } /** Prepares for a zen-related test that uses the real {@link ZenModeHelper}. */ private void setUpRealZenTest() throws Exception { when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt()))