Change notifications service to listen to generic pofile availability intents
Bug: 299068704
Test: atest SystemUITests:NotificationLockscreenUserManagerTest
Test: atest NotificationManagerServiceTest
Change-Id: I01cdf42c12f1f042289a917e2b6b1123fcad8932
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index f32f1c2..710e59d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -21,6 +21,7 @@
import static android.os.UserHandle.USER_NULL;
import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS;
+import static android.os.Flags.allowPrivateProfile;
import static com.android.systemui.DejankUtils.whitelistIpcs;
@@ -79,6 +80,7 @@
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
+import java.util.Objects;
import javax.inject.Inject;
@@ -177,57 +179,50 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- switch (action) {
- case Intent.ACTION_USER_REMOVED:
- int removedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
- if (removedUserId != -1) {
- for (UserChangedListener listener : mListeners) {
- listener.onUserRemoved(removedUserId);
- }
+ if (Objects.equals(action, Intent.ACTION_USER_REMOVED)) {
+ int removedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ if (removedUserId != -1) {
+ for (UserChangedListener listener : mListeners) {
+ listener.onUserRemoved(removedUserId);
}
- updateCurrentProfilesCache();
- break;
- case Intent.ACTION_USER_ADDED:
- updateCurrentProfilesCache();
- if (mFeatureFlags.isEnabled(Flags.NOTIF_LS_BACKGROUND_THREAD)) {
- final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
- mBackgroundHandler.post(() -> {
- initValuesForUser(userId);
- });
+ }
+ updateCurrentProfilesCache();
+ } else if (Objects.equals(action, Intent.ACTION_USER_ADDED)){
+ updateCurrentProfilesCache();
+ if (mFeatureFlags.isEnabled(Flags.NOTIF_LS_BACKGROUND_THREAD)) {
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
+ mBackgroundHandler.post(() -> {
+ initValuesForUser(userId);
+ });
+ }
+ } else if (profileAvailabilityActions(action)) {
+ updateCurrentProfilesCache();
+ } else if (Objects.equals(action, Intent.ACTION_USER_UNLOCKED)) {
+ // Start the overview connection to the launcher service
+ // Connect if user hasn't connected yet
+ if (mOverviewProxyServiceLazy.get().getProxy() == null) {
+ mOverviewProxyServiceLazy.get().startConnectionToCurrentUser();
+ }
+ } else if (Objects.equals(action, NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION)) {
+ final IntentSender intentSender = intent.getParcelableExtra(
+ Intent.EXTRA_INTENT);
+ final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
+ if (intentSender != null) {
+ try {
+ ActivityOptions options = ActivityOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ mContext.startIntentSender(intentSender, null, 0, 0, 0,
+ options.toBundle());
+ } catch (IntentSender.SendIntentException e) {
+ /* ignore */
}
- break;
- case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
- case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
- updateCurrentProfilesCache();
- break;
- case Intent.ACTION_USER_UNLOCKED:
- // Start the overview connection to the launcher service
- // Connect if user hasn't connected yet
- if (mOverviewProxyServiceLazy.get().getProxy() == null) {
- mOverviewProxyServiceLazy.get().startConnectionToCurrentUser();
- }
- break;
- case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION:
- final IntentSender intentSender = intent.getParcelableExtra(
- Intent.EXTRA_INTENT);
- final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
- if (intentSender != null) {
- try {
- ActivityOptions options = ActivityOptions.makeBasic();
- options.setPendingIntentBackgroundActivityStartMode(
- ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
- mContext.startIntentSender(intentSender, null, 0, 0, 0,
- options.toBundle());
- } catch (IntentSender.SendIntentException e) {
- /* ignore */
- }
- }
- if (notificationKey != null) {
- final NotificationVisibility nv = mVisibilityProviderLazy.get()
- .obtain(notificationKey, true);
- mClickNotifier.onNotificationClick(notificationKey, nv);
- }
- break;
+ }
+ if (notificationKey != null) {
+ final NotificationVisibility nv = mVisibilityProviderLazy.get()
+ .obtain(notificationKey, true);
+ mClickNotifier.onNotificationClick(notificationKey, nv);
+ }
}
}
};
@@ -403,6 +398,10 @@
filter.addAction(Intent.ACTION_USER_UNLOCKED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ if (allowPrivateProfile()){
+ filter.addAction(Intent.ACTION_PROFILE_AVAILABLE);
+ filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE);
+ }
mBroadcastDispatcher.registerReceiver(mBaseBroadcastReceiver, filter,
null /* executor */, UserHandle.ALL);
@@ -814,6 +813,14 @@
}
}
+ private boolean profileAvailabilityActions(String action){
+ return allowPrivateProfile()?
+ Objects.equals(action,Intent.ACTION_PROFILE_AVAILABLE)||
+ Objects.equals(action,Intent.ACTION_PROFILE_UNAVAILABLE):
+ Objects.equals(action,Intent.ACTION_MANAGED_PROFILE_AVAILABLE)||
+ Objects.equals(action,Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ }
+
@Override
public void dump(PrintWriter pw, String[] args) {
pw.println("NotificationLockscreenUserManager state:");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index a5f5fc7..43adc69 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -22,14 +22,18 @@
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE;
import static android.os.UserHandle.USER_ALL;
import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS;
import static android.provider.Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -99,6 +103,7 @@
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
+ private static final int TEST_PROFILE_USERHANDLE = 12;
@Mock
private NotificationPresenter mPresenter;
@Mock
@@ -701,6 +706,60 @@
assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(newUserId));
}
+ @Test
+ public void testProfileAvailabilityIntent() {
+ mSetFlagsRule.enableFlags(FLAG_ALLOW_PRIVATE_PROFILE);
+ mLockscreenUserManager.mCurrentProfiles.clear();
+ assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size());
+ mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class));
+ simulateProfileAvailabilityActions(Intent.ACTION_PROFILE_AVAILABLE);
+ assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size());
+ }
+
+ @Test
+ public void testProfileUnAvailabilityIntent() {
+ mSetFlagsRule.enableFlags(FLAG_ALLOW_PRIVATE_PROFILE);
+ mLockscreenUserManager.mCurrentProfiles.clear();
+ assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size());
+ mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class));
+ simulateProfileAvailabilityActions(Intent.ACTION_PROFILE_UNAVAILABLE);
+ assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size());
+ }
+
+ @Test
+ public void testManagedProfileAvailabilityIntent() {
+ mSetFlagsRule.disableFlags(FLAG_ALLOW_PRIVATE_PROFILE);
+ mLockscreenUserManager.mCurrentProfiles.clear();
+ mLockscreenUserManager.mCurrentManagedProfiles.clear();
+ assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size());
+ assertEquals(0, mLockscreenUserManager.mCurrentManagedProfiles.size());
+ mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class));
+ simulateProfileAvailabilityActions(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+ assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size());
+ assertEquals(1, mLockscreenUserManager.mCurrentManagedProfiles.size());
+ }
+
+ @Test
+ public void testManagedProfileUnAvailabilityIntent() {
+ mSetFlagsRule.disableFlags(FLAG_ALLOW_PRIVATE_PROFILE);
+ mLockscreenUserManager.mCurrentProfiles.clear();
+ mLockscreenUserManager.mCurrentManagedProfiles.clear();
+ assertEquals(0, mLockscreenUserManager.mCurrentProfiles.size());
+ assertEquals(0, mLockscreenUserManager.mCurrentManagedProfiles.size());
+ mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class));
+ simulateProfileAvailabilityActions(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ assertEquals(2, mLockscreenUserManager.mCurrentProfiles.size());
+ assertEquals(1, mLockscreenUserManager.mCurrentManagedProfiles.size());
+ }
+
+ private void simulateProfileAvailabilityActions(String intentAction) {
+ BroadcastReceiver broadcastReceiver =
+ mLockscreenUserManager.getBaseBroadcastReceiverForTest();
+ final Intent intent = new Intent(intentAction);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, TEST_PROFILE_USERHANDLE);
+ broadcastReceiver.onReceive(mContext, intent);
+ }
+
private class TestNotificationLockscreenUserManager
extends NotificationLockscreenUserManagerImpl {
public TestNotificationLockscreenUserManager(Context context) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 837b761..0b6f1b3 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -71,6 +71,7 @@
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
+import static android.os.Flags.allowPrivateProfile;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.PowerWhitelistManager.REASON_NOTIFICATION_SERVICE;
@@ -1931,7 +1932,8 @@
cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle,
REASON_USER_STOPPED);
}
- } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) {
+ } else if (
+ isProfileUnavailable(action)) {
int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
if (userHandle >= 0 && !mDpm.isKeepProfilesRunningEnabled()) {
cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle,
@@ -1982,6 +1984,12 @@
}
}
}
+
+ private boolean isProfileUnavailable(String action) {
+ return allowPrivateProfile() ?
+ action.equals(Intent.ACTION_PROFILE_UNAVAILABLE) :
+ action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ }
};
private final class SettingsObserver extends ContentObserver {
@@ -2552,6 +2560,9 @@
filter.addAction(Intent.ACTION_USER_REMOVED);
filter.addAction(Intent.ACTION_USER_UNLOCKED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ if (allowPrivateProfile()){
+ filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE);
+ }
getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter, null, null);
IntentFilter pkgFilter = new IntentFilter();
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 3d4b4a6..a568a3c 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -71,6 +71,7 @@
import static android.os.UserManager.USER_TYPE_FULL_SECONDARY;
import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
+import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -207,6 +208,7 @@
import android.os.UserManager;
import android.os.WorkSource;
import android.permission.PermissionManager;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.provider.Settings;
@@ -318,6 +320,7 @@
private static final int UID_HEADLESS = 1_000_000;
private static final int TOAST_DURATION = 2_000;
private static final int SECONDARY_DISPLAY_ID = 42;
+ private static final int TEST_PROFILE_USERHANDLE = 12;
private final int mUid = Binder.getCallingUid();
private final @UserIdInt int mUserId = UserHandle.getUserId(mUid);
@@ -445,7 +448,7 @@
TestableNotificationManagerService.StrongAuthTrackerFake mStrongAuthTracker;
TestableFlagResolver mTestFlagResolver = new TestableFlagResolver();
-
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
1 << 30);
@Mock
@@ -826,6 +829,12 @@
mPackageIntentReceiver.onReceive(getContext(), intent);
}
+ private void simulateProfileAvailabilityActions(String intentAction) {
+ final Intent intent = new Intent(intentAction);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, TEST_PROFILE_USERHANDLE);
+ mUserSwitchIntentReceiver.onReceive(mContext, intent);
+ }
+
private ArrayMap<Boolean, ArrayList<ComponentName>> generateResetComponentValues() {
ArrayMap<Boolean, ArrayList<ComponentName>> changed = new ArrayMap<>();
changed.put(true, new ArrayList<>());
@@ -12683,6 +12692,23 @@
verify(service, times(1)).setDNDMigrationDone(user.id);
}
+ @Test
+ public void testProfileUnavailableIntent() throws RemoteException {
+ mSetFlagsRule.enableFlags(FLAG_ALLOW_PRIVATE_PROFILE);
+ simulateProfileAvailabilityActions(Intent.ACTION_PROFILE_UNAVAILABLE);
+ verify(mWorkerHandler).post(any(Runnable.class));
+ verify(mSnoozeHelper).clearData(anyInt());
+ }
+
+
+ @Test
+ public void testManagedProfileUnavailableIntent() throws RemoteException {
+ mSetFlagsRule.disableFlags(FLAG_ALLOW_PRIVATE_PROFILE);
+ simulateProfileAvailabilityActions(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ verify(mWorkerHandler).post(any(Runnable.class));
+ verify(mSnoozeHelper).clearData(anyInt());
+ }
+
private NotificationRecord createAndPostNotification(Notification.Builder nb, String testName)
throws RemoteException {
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, testName, mUid, 0,