Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3e73936 authored by Olivier Nshimiye's avatar Olivier Nshimiye
Browse files

Change notifications service to listen to generic pofile availability intents

Bug: 299068704

Test: atest SystemUITests:NotificationLockscreenUserManagerTest
Test: atest NotificationManagerServiceTest
Change-Id: I01cdf42c12f1f042289a917e2b6b1123fcad8932
parent bf54cbc7
Loading
Loading
Loading
Loading
+56 −49
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_
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.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.Objects;

import javax.inject.Inject;

@@ -177,8 +179,7 @@ public class NotificationLockscreenUserManagerImpl implements
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case Intent.ACTION_USER_REMOVED:
            if (Objects.equals(action, Intent.ACTION_USER_REMOVED)) {
                int removedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                if (removedUserId != -1) {
                    for (UserChangedListener listener : mListeners) {
@@ -186,8 +187,7 @@ public class NotificationLockscreenUserManagerImpl implements
                    }
                }
                updateCurrentProfilesCache();
                    break;
                case Intent.ACTION_USER_ADDED:
            } 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);
@@ -195,19 +195,15 @@ public class NotificationLockscreenUserManagerImpl implements
                        initValuesForUser(userId);
                    });
                }
                    break;
                case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
                case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
            } else if (profileAvailabilityActions(action)) {
                updateCurrentProfilesCache();
                    break;
                case Intent.ACTION_USER_UNLOCKED:
            } 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();
                }
                    break;
                case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION:
            } 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);
@@ -227,7 +223,6 @@ public class NotificationLockscreenUserManagerImpl implements
                            .obtain(notificationKey, true);
                    mClickNotifier.onNotificationClick(notificationKey, nv);
                }
                    break;
            }
        }
    };
@@ -403,6 +398,10 @@ public class NotificationLockscreenUserManagerImpl implements
        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 @@ public class NotificationLockscreenUserManagerImpl implements
        }
    }

    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:");
+59 −0
Original line number Diff line number Diff line
@@ -22,14 +22,18 @@ import static android.app.NotificationManager.VISIBILITY_NO_OVERRIDE;
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 @@ import java.util.concurrent.Executor;
@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 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
        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) {
+12 −1
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
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 @@ public class NotificationManagerService extends SystemService {
                    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 @@ public class NotificationManagerService extends SystemService {
                }
            }
        }
        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 @@ public class NotificationManagerService extends SystemService {
        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();
+27 −1
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import static android.os.UserHandle.USER_SYSTEM;
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.UserHandle;
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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        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,