Loading services/core/java/com/android/server/notification/NotificationManagerService.java +51 −19 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; Loading Loading @@ -259,6 +260,8 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.compat.IPlatformCompat; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.InstanceId; Loading Loading @@ -559,6 +562,7 @@ public class NotificationManagerService extends SystemService { ArrayList<String> mLights = new ArrayList<>(); private AppOpsManager mAppOps; private IAppOpsService mAppOpsService; private UsageStatsManagerInternal mAppUsageStats; private DevicePolicyManagerInternal mDpm; private StatsManager mStatsManager; Loading Loading @@ -1667,6 +1671,18 @@ public class NotificationManagerService extends SystemService { } }; @VisibleForTesting final IAppOpsCallback mAppOpsCallback = new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName) { if (mEnableAppSettingMigration) { int opValue = mAppOps.checkOpNoThrow( AppOpsManager.OP_POST_NOTIFICATION, uid, packageName); boolean blocked = op != MODE_ALLOWED; sendAppBlockStateChangedBroadcast(packageName, uid, blocked); } } }; private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading @@ -2176,7 +2192,8 @@ public class NotificationManagerService extends SystemService { ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am, ActivityTaskManagerInternal atm, UsageStatsManagerInternal appUsageStats, DevicePolicyManagerInternal dpm, IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, UserManager userManager, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, IAppOpsService iAppOps, UserManager userManager, NotificationHistoryManager historyManager, StatsManager statsManager, TelephonyManager telephonyManager, ActivityManagerInternal ami, MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper) { Loading @@ -2196,6 +2213,13 @@ public class NotificationManagerService extends SystemService { mPackageManager = packageManager; mPackageManagerClient = packageManagerClient; mAppOps = appOps; mAppOpsService = iAppOps; try { mAppOpsService.startWatchingMode( AppOpsManager.OP_POST_NOTIFICATION, null, mAppOpsCallback); } catch (RemoteException e) { Slog.e(TAG, "Could not register OP_POST_NOTIFICATION listener"); } mAppUsageStats = appUsageStats; mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mCompanionManager = companionManager; Loading Loading @@ -2484,7 +2508,8 @@ public class NotificationManagerService extends SystemService { LocalServices.getService(DevicePolicyManagerInternal.class), UriGrantsManager.getService(), LocalServices.getService(UriGrantsManagerInternal.class), (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE), getContext().getSystemService(AppOpsManager.class), IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE)), getContext().getSystemService(UserManager.class), new NotificationHistoryManager(getContext(), handler), mStatsManager = (StatsManager) getContext().getSystemService( Loading Loading @@ -2722,6 +2747,19 @@ public class NotificationManagerService extends SystemService { }); } private void sendAppBlockStateChangedBroadcast(String pkg, int uid, boolean blocked) { try { getContext().sendBroadcastAsUser( new Intent(ACTION_APP_BLOCK_STATE_CHANGED) .putExtra(NotificationManager.EXTRA_BLOCKED_STATE, blocked) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .setPackage(pkg), UserHandle.of(UserHandle.getUserId(uid)), null); } catch (SecurityException e) { Slog.w(TAG, "Can't notify app about app block change", e); } } @Override public void onUserStopping(@NonNull TargetUser user) { mHandler.post(() -> { Loading Loading @@ -3429,7 +3467,8 @@ public class NotificationManagerService extends SystemService { if (wasEnabled == enabled) { return; } mPermissionHelper.setNotificationPermission(pkg, uid, enabled, true); mPermissionHelper.setNotificationPermission( pkg, UserHandle.getUserId(uid), enabled, true); } else { synchronized (mNotificationLock) { boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid) Loading @@ -3441,6 +3480,12 @@ public class NotificationManagerService extends SystemService { } mPreferencesHelper.setEnabled(pkg, uid, enabled); // TODO (b/194833441): this is being ignored by app ops now that the permission // exists mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, enabled ? MODE_ALLOWED : AppOpsManager.MODE_IGNORED); sendAppBlockStateChangedBroadcast(pkg, uid, !enabled); } mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES) .setType(MetricsEvent.TYPE_ACTION) Loading @@ -3452,19 +3497,6 @@ public class NotificationManagerService extends SystemService { UserHandle.getUserId(uid), REASON_PACKAGE_BANNED, null); } mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); try { getContext().sendBroadcastAsUser( new Intent(ACTION_APP_BLOCK_STATE_CHANGED) .putExtra(NotificationManager.EXTRA_BLOCKED_STATE, !enabled) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .setPackage(pkg), UserHandle.of(UserHandle.getUserId(uid)), null); } catch (SecurityException e) { Slog.w(TAG, "Can't notify app about app block change", e); } handleSavePolicyFile(); } Loading Loading @@ -4198,7 +4230,7 @@ public class NotificationManagerService extends SystemService { // noteOp will check to make sure the callingPkg matches the uid if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { == MODE_ALLOWED) { synchronized (mNotificationLock) { tmp = new StatusBarNotification[mNotificationList.size()]; final int N = mNotificationList.size(); Loading Loading @@ -4314,7 +4346,7 @@ public class NotificationManagerService extends SystemService { // noteOp will check to make sure the callingPkg matches the uid if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { == MODE_ALLOWED) { synchronized (mArchive) { tmp = mArchive.getArray(count, includeSnoozed); } Loading @@ -4340,7 +4372,7 @@ public class NotificationManagerService extends SystemService { // noteOp will check to make sure the callingPkg matches the uid if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { == MODE_ALLOWED) { IntArray currentUserIds = mUserProfiles.getCurrentProfileIds(); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryReadHistory"); try { Loading services/core/java/com/android/server/notification/PermissionHelper.java +2 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.permission.PermissionManager.PERMISSION_GRANTED; import android.Manifest; import android.annotation.UserIdInt; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.ParceledListSlice; Loading Loading @@ -133,7 +134,7 @@ public final class PermissionHelper { * can prevent the user from seeing the in app permission dialog. Must not be called * with a lock held. */ public void setNotificationPermission(String packageName, int userId, boolean grant, public void setNotificationPermission(String packageName, @UserIdInt int userId, boolean grant, boolean userSet) { assertFlag(); try { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +17 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.Notification.FLAG_AUTO_CANCEL; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; Loading Loading @@ -182,6 +184,7 @@ import android.widget.RemoteViews; import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; import com.android.internal.app.IAppOpsService; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; Loading Loading @@ -314,6 +317,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock AppOpsManager mAppOpsManager; @Mock IAppOpsService mAppOpsService; @Mock private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; @Mock Loading Loading @@ -449,7 +454,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm, mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal, mAppOpsManager, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); Loading Loading @@ -2127,6 +2133,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testUpdateAppNotifyCreatorBlock() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); // should not trigger a broadcast when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_IGNORED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); // should trigger a broadcast mBinderService.setNotificationsEnabledForPackage(PKG, 0, true); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); Loading @@ -2149,6 +2160,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testUpdateAppNotifyCreatorUnblock() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); // should not trigger a broadcast when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); // should trigger a broadcast mBinderService.setNotificationsEnabledForPackage(PKG, 0, true); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +44 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.notification; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.content.pm.PackageManager.FEATURE_WATCH; Loading @@ -28,10 +31,13 @@ import static com.android.server.notification.NotificationManagerService.ACTION_ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; Loading @@ -42,6 +48,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -54,6 +61,7 @@ import android.app.INotificationManager; import android.app.IUriGrantsManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.StatsManager; import android.app.admin.DevicePolicyManagerInternal; import android.app.usage.UsageStatsManagerInternal; Loading Loading @@ -95,6 +103,7 @@ import android.util.AtomicFile; import androidx.test.InstrumentationRegistry; import com.android.internal.app.IAppOpsService; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; import com.android.server.DeviceIdleInternal; Loading Loading @@ -349,8 +358,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm, mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal, mAppOpsManager, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper); mAppOpsManager, mock(IAppOpsService.class), mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); Loading Loading @@ -568,7 +577,39 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, false); verify(mPermissionHelper, never()).setNotificationPermission( verify(mPermissionHelper).setNotificationPermission( mContext.getPackageName(), UserHandle.getUserId(mUid), false, true); verify(mAppOpsManager, never()).setMode(anyInt(), anyInt(), anyString(), anyInt()); } @Test public void testUpdateAppNotifyCreatorBlock() throws Exception { when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_IGNORED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, captor.getValue().getAction()); assertEquals(PKG, captor.getValue().getPackage()); assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); } @Test public void testUpdateAppNotifyCreatorUnblock() throws Exception { when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, captor.getValue().getAction()); assertEquals(PKG, captor.getValue().getPackage()); assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); } } services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import android.util.Pair; import androidx.test.InstrumentationRegistry; import com.android.internal.app.IAppOpsService; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; import com.android.server.LocalServices; Loading Loading @@ -160,7 +161,8 @@ public class RoleObserverTest extends UiServiceTestCase { mock(UsageStatsManagerInternal.class), mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class), mock(UriGrantsManagerInternal.class), mock(AppOpsManager.class), mUm, mock(NotificationHistoryManager.class), mock(AppOpsManager.class), mock(IAppOpsService.class), mUm, mock(NotificationHistoryManager.class), mock(StatsManager.class), mock(TelephonyManager.class), mock(ActivityManagerInternal.class), mock(MultiRateLimiter.class), mock(PermissionHelper.class)); Loading Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +51 −19 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.Notification.FLAG_AUTOGROUP_SUMMARY; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; Loading Loading @@ -259,6 +260,8 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.compat.IPlatformCompat; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.InstanceId; Loading Loading @@ -559,6 +562,7 @@ public class NotificationManagerService extends SystemService { ArrayList<String> mLights = new ArrayList<>(); private AppOpsManager mAppOps; private IAppOpsService mAppOpsService; private UsageStatsManagerInternal mAppUsageStats; private DevicePolicyManagerInternal mDpm; private StatsManager mStatsManager; Loading Loading @@ -1667,6 +1671,18 @@ public class NotificationManagerService extends SystemService { } }; @VisibleForTesting final IAppOpsCallback mAppOpsCallback = new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName) { if (mEnableAppSettingMigration) { int opValue = mAppOps.checkOpNoThrow( AppOpsManager.OP_POST_NOTIFICATION, uid, packageName); boolean blocked = op != MODE_ALLOWED; sendAppBlockStateChangedBroadcast(packageName, uid, blocked); } } }; private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading Loading @@ -2176,7 +2192,8 @@ public class NotificationManagerService extends SystemService { ActivityManager activityManager, GroupHelper groupHelper, IActivityManager am, ActivityTaskManagerInternal atm, UsageStatsManagerInternal appUsageStats, DevicePolicyManagerInternal dpm, IUriGrantsManager ugm, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, UserManager userManager, UriGrantsManagerInternal ugmInternal, AppOpsManager appOps, IAppOpsService iAppOps, UserManager userManager, NotificationHistoryManager historyManager, StatsManager statsManager, TelephonyManager telephonyManager, ActivityManagerInternal ami, MultiRateLimiter toastRateLimiter, PermissionHelper permissionHelper) { Loading @@ -2196,6 +2213,13 @@ public class NotificationManagerService extends SystemService { mPackageManager = packageManager; mPackageManagerClient = packageManagerClient; mAppOps = appOps; mAppOpsService = iAppOps; try { mAppOpsService.startWatchingMode( AppOpsManager.OP_POST_NOTIFICATION, null, mAppOpsCallback); } catch (RemoteException e) { Slog.e(TAG, "Could not register OP_POST_NOTIFICATION listener"); } mAppUsageStats = appUsageStats; mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mCompanionManager = companionManager; Loading Loading @@ -2484,7 +2508,8 @@ public class NotificationManagerService extends SystemService { LocalServices.getService(DevicePolicyManagerInternal.class), UriGrantsManager.getService(), LocalServices.getService(UriGrantsManagerInternal.class), (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE), getContext().getSystemService(AppOpsManager.class), IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE)), getContext().getSystemService(UserManager.class), new NotificationHistoryManager(getContext(), handler), mStatsManager = (StatsManager) getContext().getSystemService( Loading Loading @@ -2722,6 +2747,19 @@ public class NotificationManagerService extends SystemService { }); } private void sendAppBlockStateChangedBroadcast(String pkg, int uid, boolean blocked) { try { getContext().sendBroadcastAsUser( new Intent(ACTION_APP_BLOCK_STATE_CHANGED) .putExtra(NotificationManager.EXTRA_BLOCKED_STATE, blocked) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .setPackage(pkg), UserHandle.of(UserHandle.getUserId(uid)), null); } catch (SecurityException e) { Slog.w(TAG, "Can't notify app about app block change", e); } } @Override public void onUserStopping(@NonNull TargetUser user) { mHandler.post(() -> { Loading Loading @@ -3429,7 +3467,8 @@ public class NotificationManagerService extends SystemService { if (wasEnabled == enabled) { return; } mPermissionHelper.setNotificationPermission(pkg, uid, enabled, true); mPermissionHelper.setNotificationPermission( pkg, UserHandle.getUserId(uid), enabled, true); } else { synchronized (mNotificationLock) { boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid) Loading @@ -3441,6 +3480,12 @@ public class NotificationManagerService extends SystemService { } mPreferencesHelper.setEnabled(pkg, uid, enabled); // TODO (b/194833441): this is being ignored by app ops now that the permission // exists mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, enabled ? MODE_ALLOWED : AppOpsManager.MODE_IGNORED); sendAppBlockStateChangedBroadcast(pkg, uid, !enabled); } mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES) .setType(MetricsEvent.TYPE_ACTION) Loading @@ -3452,19 +3497,6 @@ public class NotificationManagerService extends SystemService { UserHandle.getUserId(uid), REASON_PACKAGE_BANNED, null); } mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); try { getContext().sendBroadcastAsUser( new Intent(ACTION_APP_BLOCK_STATE_CHANGED) .putExtra(NotificationManager.EXTRA_BLOCKED_STATE, !enabled) .addFlags(Intent.FLAG_RECEIVER_FOREGROUND) .setPackage(pkg), UserHandle.of(UserHandle.getUserId(uid)), null); } catch (SecurityException e) { Slog.w(TAG, "Can't notify app about app block change", e); } handleSavePolicyFile(); } Loading Loading @@ -4198,7 +4230,7 @@ public class NotificationManagerService extends SystemService { // noteOp will check to make sure the callingPkg matches the uid if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { == MODE_ALLOWED) { synchronized (mNotificationLock) { tmp = new StatusBarNotification[mNotificationList.size()]; final int N = mNotificationList.size(); Loading Loading @@ -4314,7 +4346,7 @@ public class NotificationManagerService extends SystemService { // noteOp will check to make sure the callingPkg matches the uid if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { == MODE_ALLOWED) { synchronized (mArchive) { tmp = mArchive.getArray(count, includeSnoozed); } Loading @@ -4340,7 +4372,7 @@ public class NotificationManagerService extends SystemService { // noteOp will check to make sure the callingPkg matches the uid if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_NOTIFICATIONS, uid, callingPkg, callingAttributionTag, null) == AppOpsManager.MODE_ALLOWED) { == MODE_ALLOWED) { IntArray currentUserIds = mUserProfiles.getCurrentProfileIds(); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "notifHistoryReadHistory"); try { Loading
services/core/java/com/android/server/notification/PermissionHelper.java +2 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.permission.PermissionManager.PERMISSION_GRANTED; import android.Manifest; import android.annotation.UserIdInt; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.ParceledListSlice; Loading Loading @@ -133,7 +134,7 @@ public final class PermissionHelper { * can prevent the user from seeing the in app permission dialog. Must not be called * with a lock held. */ public void setNotificationPermission(String packageName, int userId, boolean grant, public void setNotificationPermission(String packageName, @UserIdInt int userId, boolean grant, boolean userSet) { assertFlag(); try { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +17 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.server.notification; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.Notification.FLAG_AUTO_CANCEL; import static android.app.Notification.FLAG_BUBBLE; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; Loading Loading @@ -182,6 +184,7 @@ import android.widget.RemoteViews; import androidx.annotation.Nullable; import androidx.test.InstrumentationRegistry; import com.android.internal.app.IAppOpsService; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; Loading Loading @@ -314,6 +317,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock AppOpsManager mAppOpsManager; @Mock IAppOpsService mAppOpsService; @Mock private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; @Mock Loading Loading @@ -449,7 +454,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm, mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal, mAppOpsManager, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAppOpsManager, mAppOpsService, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); Loading Loading @@ -2127,6 +2133,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testUpdateAppNotifyCreatorBlock() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); // should not trigger a broadcast when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_IGNORED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); // should trigger a broadcast mBinderService.setNotificationsEnabledForPackage(PKG, 0, true); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); Loading @@ -2149,6 +2160,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { public void testUpdateAppNotifyCreatorUnblock() throws Exception { mService.setPreferencesHelper(mPreferencesHelper); // should not trigger a broadcast when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); // should trigger a broadcast mBinderService.setNotificationsEnabledForPackage(PKG, 0, true); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +44 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.notification; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_IGNORED; import static android.app.NotificationManager.EXTRA_BLOCKED_STATE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.content.pm.PackageManager.FEATURE_WATCH; Loading @@ -28,10 +31,13 @@ import static com.android.server.notification.NotificationManagerService.ACTION_ import static com.google.common.truth.Truth.assertThat; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.fail; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; Loading @@ -42,6 +48,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -54,6 +61,7 @@ import android.app.INotificationManager; import android.app.IUriGrantsManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.StatsManager; import android.app.admin.DevicePolicyManagerInternal; import android.app.usage.UsageStatsManagerInternal; Loading Loading @@ -95,6 +103,7 @@ import android.util.AtomicFile; import androidx.test.InstrumentationRegistry; import com.android.internal.app.IAppOpsService; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; import com.android.server.DeviceIdleInternal; Loading Loading @@ -349,8 +358,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm, mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal, mAppOpsManager, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper); mAppOpsManager, mock(IAppOpsService.class), mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class), mAmi, mToastRateLimiter, mPermissionHelper); // Return first true for RoleObserver main-thread check when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false); mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper); Loading Loading @@ -568,7 +577,39 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(mUid)).thenReturn(true); mBinderService.setNotificationsEnabledForPackage(mContext.getPackageName(), mUid, false); verify(mPermissionHelper, never()).setNotificationPermission( verify(mPermissionHelper).setNotificationPermission( mContext.getPackageName(), UserHandle.getUserId(mUid), false, true); verify(mAppOpsManager, never()).setMode(anyInt(), anyInt(), anyString(), anyInt()); } @Test public void testUpdateAppNotifyCreatorBlock() throws Exception { when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_IGNORED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, captor.getValue().getAction()); assertEquals(PKG, captor.getValue().getPackage()); assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); } @Test public void testUpdateAppNotifyCreatorUnblock() throws Exception { when(mAppOpsManager.checkOpNoThrow(anyInt(), eq(mUid), eq(PKG))).thenReturn(MODE_ALLOWED); mService.mAppOpsCallback.opChanged(0, mUid, PKG); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null)); assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED, captor.getValue().getAction()); assertEquals(PKG, captor.getValue().getPackage()); assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true)); } }
services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import android.util.Pair; import androidx.test.InstrumentationRegistry; import com.android.internal.app.IAppOpsService; import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.InstanceIdSequenceFake; import com.android.server.LocalServices; Loading Loading @@ -160,7 +161,8 @@ public class RoleObserverTest extends UiServiceTestCase { mock(UsageStatsManagerInternal.class), mock(DevicePolicyManagerInternal.class), mock(IUriGrantsManager.class), mock(UriGrantsManagerInternal.class), mock(AppOpsManager.class), mUm, mock(NotificationHistoryManager.class), mock(AppOpsManager.class), mock(IAppOpsService.class), mUm, mock(NotificationHistoryManager.class), mock(StatsManager.class), mock(TelephonyManager.class), mock(ActivityManagerInternal.class), mock(MultiRateLimiter.class), mock(PermissionHelper.class)); Loading