Loading core/res/res/values/config.xml +2 −1 Original line number Diff line number Diff line Loading @@ -1917,7 +1917,8 @@ <string name="config_defaultNetworkRecommendationProviderPackage" translatable="false"></string> <!-- The package name of the default search selector app. Must be granted the POST_NOTIFICATIONS permission. permission, and notifications from this app must be given the notification flag FLAG_NO_DISMISS if the notification requests FLAG_ONGOING_EVENT. --> <string name="config_defaultSearchSelectorPackageName" translatable="false"></string> Loading services/core/java/com/android/server/notification/NotificationManagerService.java +9 −1 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ public class NotificationManagerService extends SystemService { private NotificationRecordLogger mNotificationRecordLogger; private InstanceIdSequence mNotificationInstanceIdSequence; private Set<String> mMsgPkgsAllowedAsConvos = new HashSet(); private String mDefaultSearchSelectorPkg; // Broadcast intent receiver for notification permissions review-related intents private ReviewNotificationPermissionsReceiver mReviewNotificationPermissionsReceiver; Loading Loading @@ -2435,6 +2436,8 @@ public class NotificationManagerService extends SystemService { mMsgPkgsAllowedAsConvos = Set.of(getStringArrayResource( com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos)); mDefaultSearchSelectorPkg = getContext().getString(getContext().getResources() .getIdentifier("config_defaultSearchSelectorPackageName", "string", "android")); mFlagResolver = flagResolver; Loading Loading @@ -6934,7 +6937,12 @@ public class NotificationManagerService extends SystemService { */ private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) { return notification.isMediaNotification() || isEnterpriseExempted(ai) || isCallNotification(ai.packageName, ai.uid, notification); || isCallNotification(ai.packageName, ai.uid, notification) || isDefaultSearchSelectorPackage(ai.packageName); } private boolean isDefaultSearchSelectorPackage(String pkg) { return Objects.equals(mDefaultSearchSelectorPkg, pkg); } private boolean isEnterpriseExempted(ApplicationInfo ai) { Loading services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +33 −1 Original line number Diff line number Diff line Loading @@ -358,7 +358,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private static final int NOTIFICATION_LOCATION_UNKNOWN = 0; private static final String VALID_CONVO_SHORTCUT_ID = "shortcut"; private static final String SEARCH_SELECTOR_PKG = "searchSelector"; @Mock private NotificationListeners mListeners; @Mock Loading Loading @@ -549,6 +549,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // apps allowed as convos mService.setStringArrayResourceValue(PKG_O); TestableResources tr = mContext.getOrCreateTestableResources(); tr.addOverride(com.android.internal.R.string.config_defaultSearchSelectorPackageName, SEARCH_SELECTOR_PKG); mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper())); mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient, mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, Loading Loading @@ -10635,6 +10639,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixSystemNotification_defaultSearchSelectior_withOnGoingFlag_nondismissible() throws Exception { final ApplicationInfo ai = new ApplicationInfo(); ai.packageName = SEARCH_SELECTOR_PKG; ai.uid = mUid; ai.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(ai); when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, ai.uid, ai.packageName)).thenReturn(AppOpsManager.MODE_IGNORED); // Given: a notification from an app on the system partition has the flag // FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixCallNotification_withOnGoingFlag_shouldNotBeNonDismissible() throws Exception { Loading Loading
core/res/res/values/config.xml +2 −1 Original line number Diff line number Diff line Loading @@ -1917,7 +1917,8 @@ <string name="config_defaultNetworkRecommendationProviderPackage" translatable="false"></string> <!-- The package name of the default search selector app. Must be granted the POST_NOTIFICATIONS permission. permission, and notifications from this app must be given the notification flag FLAG_NO_DISMISS if the notification requests FLAG_ONGOING_EVENT. --> <string name="config_defaultSearchSelectorPackageName" translatable="false"></string> Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +9 −1 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ public class NotificationManagerService extends SystemService { private NotificationRecordLogger mNotificationRecordLogger; private InstanceIdSequence mNotificationInstanceIdSequence; private Set<String> mMsgPkgsAllowedAsConvos = new HashSet(); private String mDefaultSearchSelectorPkg; // Broadcast intent receiver for notification permissions review-related intents private ReviewNotificationPermissionsReceiver mReviewNotificationPermissionsReceiver; Loading Loading @@ -2435,6 +2436,8 @@ public class NotificationManagerService extends SystemService { mMsgPkgsAllowedAsConvos = Set.of(getStringArrayResource( com.android.internal.R.array.config_notificationMsgPkgsAllowedAsConvos)); mDefaultSearchSelectorPkg = getContext().getString(getContext().getResources() .getIdentifier("config_defaultSearchSelectorPackageName", "string", "android")); mFlagResolver = flagResolver; Loading Loading @@ -6934,7 +6937,12 @@ public class NotificationManagerService extends SystemService { */ private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) { return notification.isMediaNotification() || isEnterpriseExempted(ai) || isCallNotification(ai.packageName, ai.uid, notification); || isCallNotification(ai.packageName, ai.uid, notification) || isDefaultSearchSelectorPackage(ai.packageName); } private boolean isDefaultSearchSelectorPackage(String pkg) { return Objects.equals(mDefaultSearchSelectorPkg, pkg); } private boolean isEnterpriseExempted(ApplicationInfo ai) { Loading
services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +33 −1 Original line number Diff line number Diff line Loading @@ -358,7 +358,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { private static final int NOTIFICATION_LOCATION_UNKNOWN = 0; private static final String VALID_CONVO_SHORTCUT_ID = "shortcut"; private static final String SEARCH_SELECTOR_PKG = "searchSelector"; @Mock private NotificationListeners mListeners; @Mock Loading Loading @@ -549,6 +549,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // apps allowed as convos mService.setStringArrayResourceValue(PKG_O); TestableResources tr = mContext.getOrCreateTestableResources(); tr.addOverride(com.android.internal.R.string.config_defaultSearchSelectorPackageName, SEARCH_SELECTOR_PKG); mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper())); mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient, mockLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr, Loading Loading @@ -10635,6 +10639,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixSystemNotification_defaultSearchSelectior_withOnGoingFlag_nondismissible() throws Exception { final ApplicationInfo ai = new ApplicationInfo(); ai.packageName = SEARCH_SELECTOR_PKG; ai.uid = mUid; ai.flags |= ApplicationInfo.FLAG_SYSTEM; when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())) .thenReturn(ai); when(mAppOpsManager.checkOpNoThrow( AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, ai.uid, ai.packageName)).thenReturn(AppOpsManager.MODE_IGNORED); // Given: a notification from an app on the system partition has the flag // FLAG_ONGOING_EVENT set // feature flag: ALLOW_DISMISS_ONGOING is on mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true); Notification n = new Notification.Builder(mContext, "test") .setOngoing(true) .build(); // When: fix the notification with NotificationManagerService mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true); // Then: the notification's flag FLAG_NO_DISMISS should be set assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS); } @Test public void fixCallNotification_withOnGoingFlag_shouldNotBeNonDismissible() throws Exception { Loading