diff options
3 files changed, 91 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2ae040a69583..308d441fb871 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -69,6 +69,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OF import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; import static android.app.Flags.lifetimeExtensionRefactor; +import static android.app.NotificationManager.zenModeFromInterruptionFilter; import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED; import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED; import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT; @@ -5311,18 +5312,41 @@ public class NotificationManagerService extends SystemService { @Override public void requestInterruptionFilterFromListener(INotificationListener token, int interruptionFilter) throws RemoteException { - final int callingUid = Binder.getCallingUid(); - final boolean isSystemOrSystemUi = isCallerSystemOrSystemUi(); - final long identity = Binder.clearCallingIdentity(); - try { + if (android.app.Flags.modesApi()) { + final int callingUid = Binder.getCallingUid(); + ManagedServiceInfo info; synchronized (mNotificationLock) { - final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token); - mZenModeHelper.requestFromListener(info.component, interruptionFilter, - callingUid, isSystemOrSystemUi); - updateInterruptionFilterLocked(); + info = mListeners.checkServiceTokenLocked(token); + } + + final int zenMode = zenModeFromInterruptionFilter(interruptionFilter, -1); + if (zenMode == -1) return; + if (!canManageGlobalZenPolicy(info.component.getPackageName(), callingUid)) { + mZenModeHelper.applyGlobalZenModeAsImplicitZenRule( + info.component.getPackageName(), callingUid, zenMode); + } else { + int origin = computeZenOrigin(/* fromUser= */ false); + Binder.withCleanCallingIdentity(() -> { + mZenModeHelper.setManualZenMode(zenMode, /* conditionId= */ null, origin, + "listener:" + info.component.flattenToShortString(), + /* caller= */ info.component.getPackageName(), + callingUid); + }); + } + } else { + final int callingUid = Binder.getCallingUid(); + final boolean isSystemOrSystemUi = isCallerSystemOrSystemUi(); + final long identity = Binder.clearCallingIdentity(); + try { + synchronized (mNotificationLock) { + final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token); + mZenModeHelper.requestFromListener(info.component, interruptionFilter, + callingUid, isSystemOrSystemUi); + updateInterruptionFilterLocked(); + } + } finally { + Binder.restoreCallingIdentity(identity); } - } finally { - Binder.restoreCallingIdentity(identity); } } @@ -5358,10 +5382,10 @@ public class NotificationManagerService extends SystemService { @Override public void setZenMode(int mode, Uri conditionId, String reason, boolean fromUser) { enforceSystemOrSystemUI("INotificationManager.setZenMode"); - final int callingUid = Binder.getCallingUid(); - final long identity = Binder.clearCallingIdentity(); enforceUserOriginOnlyFromSystem(fromUser, "setZenMode"); + final int callingUid = Binder.getCallingUid(); + final long identity = Binder.clearCallingIdentity(); try { mZenModeHelper.setManualZenMode(mode, conditionId, computeZenOrigin(fromUser), reason, /* caller= */ null, callingUid); @@ -5554,7 +5578,7 @@ public class NotificationManagerService extends SystemService { @Override public void setInterruptionFilter(String pkg, int filter, boolean fromUser) { enforcePolicyAccess(pkg, "setInterruptionFilter"); - final int zen = NotificationManager.zenModeFromInterruptionFilter(filter, -1); + final int zen = zenModeFromInterruptionFilter(filter, -1); if (zen == -1) throw new IllegalArgumentException("Invalid filter: " + filter); final int callingUid = Binder.getCallingUid(); enforceUserOriginOnlyFromSystem(fromUser, "setInterruptionFilter"); diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index bc4781a68dd4..153af13b61b4 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -359,6 +359,7 @@ public class ZenModeHelper { return NotificationManager.zenModeToInterruptionFilter(mZenMode); } + // TODO: b/310620812 - Remove when MODES_API is inlined (no more callers). public void requestFromListener(ComponentName name, int filter, int callingUid, boolean fromSystemOrSystemUi) { final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 723ac15fb50f..9c2cba8ecf96 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -224,6 +224,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.permission.PermissionManager; +import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.rule.DeniedDevices; @@ -13978,6 +13979,58 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) + public void requestInterruptionFilterFromListener_fromApp_doesNotSetGlobalZen() + throws Exception { + mService.setCallerIsNormalPackage(); + mService.mZenModeHelper = mock(ZenModeHelper.class); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(info); + info.component = new ComponentName("pkg", "cls"); + + mBinderService.requestInterruptionFilterFromListener(mock(INotificationListener.class), + INTERRUPTION_FILTER_PRIORITY); + + verify(mService.mZenModeHelper).applyGlobalZenModeAsImplicitZenRule(eq("pkg"), eq(mUid), + eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS)); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_MODES_API) + public void requestInterruptionFilterFromListener_fromSystem_setsGlobalZen() + throws Exception { + mService.isSystemUid = true; + mService.mZenModeHelper = mock(ZenModeHelper.class); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(info); + info.component = new ComponentName("pkg", "cls"); + + mBinderService.requestInterruptionFilterFromListener(mock(INotificationListener.class), + INTERRUPTION_FILTER_PRIORITY); + + verify(mService.mZenModeHelper).setManualZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), + eq(null), eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), + eq("pkg"), eq(mUid)); + } + + @Test + @DisableFlags(android.app.Flags.FLAG_MODES_API) + public void requestInterruptionFilterFromListener_flagOff_callsRequestFromListener() + throws Exception { + mService.setCallerIsNormalPackage(); + mService.mZenModeHelper = mock(ZenModeHelper.class); + ManagedServices.ManagedServiceInfo info = mock(ManagedServices.ManagedServiceInfo.class); + when(mListeners.checkServiceTokenLocked(any())).thenReturn(info); + info.component = new ComponentName("pkg", "cls"); + + mBinderService.requestInterruptionFilterFromListener(mock(INotificationListener.class), + INTERRUPTION_FILTER_PRIORITY); + + verify(mService.mZenModeHelper).requestFromListener(eq(info.component), + eq(INTERRUPTION_FILTER_PRIORITY), eq(mUid), /* fromSystemOrSystemUi= */ eq(false)); + } + + @Test + @EnableFlags(android.app.Flags.FLAG_MODES_API) @EnableCompatChanges(NotificationManagerService.MANAGE_GLOBAL_ZEN_VIA_IMPLICIT_RULES) public void updateAutomaticZenRule_implicitRuleWithoutCPS_disallowedFromApp() throws Exception { setUpRealZenTest(); |