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

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

Add isPrivateProfile chack to profile checks in Notifications

Context: http://shortn/_sGk5N1MDCQ

Bug: 327297121
Test: Manual - verified listeners are not disabled when private profile is unlocked as reported in b/327297121
Test: atest ManagedServicesTest
Test: atest NotificationManagerServiceTest

Change-Id: I9f31b4486c4d5d75cf3dfcabb2690b35f0c6be0b
parent fdbf8c14
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_SYSTEM;
import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;

import static com.android.server.notification.NotificationManagerService.privateSpaceFlagsEnabled;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -1433,7 +1435,7 @@ abstract public class ManagedServices {
    protected void rebindServices(boolean forceRebind, int userToRebind) {
        if (DEBUG) Slog.d(TAG, "rebindServices " + forceRebind + " " + userToRebind);
        IntArray userIds = mUserProfiles.getCurrentProfileIds();
        boolean rebindAllCurrentUsers = mUserProfiles.isProfileUser(userToRebind)
        boolean rebindAllCurrentUsers = mUserProfiles.isProfileUser(userToRebind, mContext)
                && allowRebindForParentUser();
        if (userToRebind != USER_ALL && !rebindAllCurrentUsers) {
            userIds = new IntArray(1);
@@ -1958,7 +1960,7 @@ abstract public class ManagedServices {
         * from receiving events from the profile.
         */
        public boolean isPermittedForProfile(int userId) {
            if (!mUserProfiles.isProfileUser(userId)) {
            if (!mUserProfiles.isProfileUser(userId, mContext)) {
                return true;
            }
            DevicePolicyManager dpm =
@@ -2036,16 +2038,26 @@ abstract public class ManagedServices {
            }
        }

        public boolean isProfileUser(int userId) {
        public boolean isProfileUser(int userId, Context context) {
            synchronized (mCurrentProfiles) {
                UserInfo user = mCurrentProfiles.get(userId);
                if (user == null) {
                    return false;
                }
                if (user.isManagedProfile() || user.isCloneProfile()) {
                    return true;
                if (privateSpaceFlagsEnabled()) {
                    return user.isProfile() && hasParent(user, context);
                }
                return false;
                return user.isManagedProfile() || user.isCloneProfile();
            }
        }

        boolean hasParent(UserInfo profile, Context context) {
            final long identity = Binder.clearCallingIdentity();
            try {
                UserManager um = context.getSystemService(UserManager.class);
                return um.getProfileParent(profile.id) != null;
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }
    }
+17 −8
Original line number Diff line number Diff line
@@ -957,8 +957,7 @@ public class NotificationManagerService extends SystemService {
        final List<UserInfo> activeUsers = mUm.getUsers();
        for (UserInfo userInfo : activeUsers) {
            int userId = userInfo.getUserHandle().getIdentifier();
            if (isNASMigrationDone(userId)
                    || userInfo.isManagedProfile() || userInfo.isCloneProfile()) {
            if (isNASMigrationDone(userId) || isProfileUser(userInfo)) {
                continue;
            }
            List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
@@ -989,6 +988,17 @@ public class NotificationManagerService extends SystemService {
                Settings.Secure.NAS_SETTINGS_UPDATED, 0, userId) == 1);
    }
    boolean isProfileUser(UserInfo userInfo) {
        if (privateSpaceFlagsEnabled()) {
            return userInfo.isProfile() && hasParent(userInfo);
        }
        return userInfo.isManagedProfile() || userInfo.isCloneProfile();
    }
    boolean hasParent(UserInfo profile) {
        return mUmInternal.getProfileParentId(profile.id) != profile.id;
    }
    protected void setDefaultAssistantForUser(int userId) {
        String overrideDefaultAssistantString = DeviceConfig.getProperty(
                DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -1097,8 +1107,7 @@ public class NotificationManagerService extends SystemService {
        XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
        boolean migratedManagedServices = false;
        UserInfo userInfo = mUmInternal.getUserInfo(userId);
        boolean ineligibleForManagedServices = forRestore &&
                (userInfo.isManagedProfile() || userInfo.isCloneProfile());
        boolean ineligibleForManagedServices = forRestore && isProfileUser(userInfo);
        int outerDepth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
            if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
@@ -1205,7 +1214,7 @@ public class NotificationManagerService extends SystemService {
        }
    }
    private static boolean privateSpaceFlagsEnabled() {
    protected static boolean privateSpaceFlagsEnabled() {
        return allowPrivateProfile() && android.multiuser.Flags.enablePrivateSpaceFeatures();
    }
@@ -2106,7 +2115,7 @@ public class NotificationManagerService extends SystemService {
            } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                mUserProfiles.updateCache(context);
                if (!mUserProfiles.isProfileUser(userId)) {
                if (!mUserProfiles.isProfileUser(userId, context)) {
                    // reload per-user settings
                    mSettingsObserver.update(null);
                    // Refresh managed services
@@ -2121,7 +2130,7 @@ public class NotificationManagerService extends SystemService {
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                if (userId != USER_NULL) {
                    mUserProfiles.updateCache(context);
                    if (!mUserProfiles.isProfileUser(userId)) {
                    if (!mUserProfiles.isProfileUser(userId, context)) {
                        allowDefaultApprovedServices(userId);
                    }
                    mHistoryManager.onUserAdded(userId);
@@ -2142,7 +2151,7 @@ public class NotificationManagerService extends SystemService {
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                mUserProfiles.updateCache(context);
                mAssistants.onUserUnlocked(userId);
                if (!mUserProfiles.isProfileUser(userId)) {
                if (!mUserProfiles.isProfileUser(userId, context)) {
                    mConditionProviders.onUserUnlocked(userId);
                    mListeners.onUserUnlocked(userId);
                    if (!android.app.Flags.modesApi()) {
+21 −10
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@ import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR;
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.UserManager.USER_TYPE_PROFILE_PRIVATE;
import static android.service.notification.NotificationListenerService.META_DATA_DEFAULT_AUTOBIND;

import static com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT;
import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE;
import static com.android.server.notification.NotificationManagerService.privateSpaceFlagsEnabled;

import static com.google.common.truth.Truth.assertThat;

@@ -1803,7 +1805,7 @@ public class ManagedServicesTest extends UiServiceTestCase {

    @Test
    public void testInfoIsPermittedForProfile_notProfile() {
        when(mUserProfiles.isProfileUser(anyInt())).thenReturn(false);
        when(mUserProfiles.isProfileUser(anyInt(), any(Context.class))).thenReturn(false);

        IInterface service = mock(IInterface.class);
        when(service.asBinder()).thenReturn(mock(IBinder.class));
@@ -1817,7 +1819,7 @@ public class ManagedServicesTest extends UiServiceTestCase {

    @Test
    public void testInfoIsPermittedForProfile_profileAndDpmAllows() {
        when(mUserProfiles.isProfileUser(anyInt())).thenReturn(true);
        when(mUserProfiles.isProfileUser(anyInt(), any(Context.class))).thenReturn(true);
        when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(true);

        IInterface service = mock(IInterface.class);
@@ -1833,7 +1835,7 @@ public class ManagedServicesTest extends UiServiceTestCase {

    @Test
    public void testInfoIsPermittedForProfile_profileAndDpmDenies() {
        when(mUserProfiles.isProfileUser(anyInt())).thenReturn(true);
        when(mUserProfiles.isProfileUser(anyInt(), any(Context.class))).thenReturn(true);
        when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(false);

        IInterface service = mock(IInterface.class);
@@ -1853,20 +1855,29 @@ public class ManagedServicesTest extends UiServiceTestCase {
        UserInfo profile = new UserInfo(ActivityManager.getCurrentUser(), "current", 0);
        profile.userType = USER_TYPE_FULL_SECONDARY;
        users.add(profile);
        UserInfo managed = new UserInfo(12, "12", 0);
        UserInfo managed = new UserInfo(12, "12", UserInfo.FLAG_PROFILE);
        managed.userType = USER_TYPE_PROFILE_MANAGED;
        users.add(managed);
        UserInfo clone = new UserInfo(13, "13", 0);
        UserInfo clone = new UserInfo(13, "13", UserInfo.FLAG_PROFILE);
        clone.userType = USER_TYPE_PROFILE_CLONE;
        users.add(clone);
        UserInfo privateProfile = new UserInfo(14, "14", UserInfo.FLAG_PROFILE);
        if (privateSpaceFlagsEnabled()) {
            privateProfile.userType = USER_TYPE_PROFILE_PRIVATE;
            users.add(privateProfile);
        }
        when(mUm.getProfiles(ActivityManager.getCurrentUser())).thenReturn(users);
        when(mUm.getProfileParent(anyInt())).thenReturn(new UserInfo(0, "primary", 0));

        ManagedServices.UserProfiles profiles = new ManagedServices.UserProfiles();
        profiles.updateCache(mContext);

        assertFalse(profiles.isProfileUser(ActivityManager.getCurrentUser()));
        assertTrue(profiles.isProfileUser(12));
        assertTrue(profiles.isProfileUser(13));
        assertFalse(profiles.isProfileUser(ActivityManager.getCurrentUser(), mContext));
        assertTrue(profiles.isProfileUser(12, mContext));
        assertTrue(profiles.isProfileUser(13, mContext));
        if (privateSpaceFlagsEnabled()) {
            assertTrue(profiles.isProfileUser(14, mContext));
        }
    }

    @Test
@@ -2015,7 +2026,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
    @Test
    public void isComponentEnabledForCurrentProfiles_profileUserId() {
        final int profileUserId = 10;
        when(mUserProfiles.isProfileUser(profileUserId)).thenReturn(true);
        when(mUserProfiles.isProfileUser(profileUserId, mContext)).thenReturn(true);
        // Only approve for parent user (0)
        mService.addApprovedList("pkg1/cmp1:pkg2/cmp2:pkg3/cmp3", 0, true);

@@ -2028,7 +2039,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
    @Test
    public void isComponentEnabledForCurrentProfiles_profileUserId_NAS() {
        final int profileUserId = 10;
        when(mUserProfiles.isProfileUser(profileUserId)).thenReturn(true);
        when(mUserProfiles.isProfileUser(profileUserId, mContext)).thenReturn(true);
        // Do not rebind for parent users (NAS use-case)
        ManagedServices service = spy(mService);
        when(service.allowRebindForParentUser()).thenReturn(false);
+31 −4
Original line number Diff line number Diff line
@@ -81,6 +81,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.UserManager.USER_TYPE_PROFILE_PRIVATE;
import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS;
@@ -5619,8 +5620,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</dnd_apps>"
                + "</notification-policy>";
        UserInfo ui = new UserInfo();
        ui.id = 10;
        UserInfo ui = new UserInfo(10, "Clone", UserInfo.FLAG_PROFILE);
        ui.userType = USER_TYPE_PROFILE_CLONE;
        when(mUmInternal.getUserInfo(10)).thenReturn(ui);
        mService.readPolicyXml(
@@ -5646,8 +5646,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</dnd_apps>"
                + "</notification-policy>";
        UserInfo ui = new UserInfo();
        ui.id = 10;
        UserInfo ui = new UserInfo(10, "Work", UserInfo.FLAG_PROFILE);
        ui.userType = USER_TYPE_PROFILE_MANAGED;
        when(mUmInternal.getUserInfo(10)).thenReturn(ui);
        mService.readPolicyXml(
@@ -5659,6 +5658,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        verify(mAssistants, never()).readXml(any(), any(), eq(true), eq(10));
    }
    @Test
    public void testReadPolicyXml_doesNotRestoreManagedServicesForPrivateUser() throws Exception {
        mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
                android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
        final String policyXml = "<notification-policy version=\"1\">"
                + "<ranking></ranking>"
                + "<enabled_listeners>"
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</enabled_listeners>"
                + "<enabled_assistants>"
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</enabled_assistants>"
                + "<dnd_apps>"
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</dnd_apps>"
                + "</notification-policy>";
        UserInfo ui = new UserInfo(10, "Private", UserInfo.FLAG_PROFILE);
        ui.userType = USER_TYPE_PROFILE_PRIVATE;
        when(mUmInternal.getUserInfo(10)).thenReturn(ui);
        mService.readPolicyXml(
                new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
                true,
                10);
        verify(mListeners, never()).readXml(any(), any(), eq(true), eq(10));
        verify(mConditionProviders, never()).readXml(any(), any(), eq(true), eq(10));
        verify(mAssistants, never()).readXml(any(), any(), eq(true), eq(10));
    }
    @Test
    public void testReadPolicyXml_restoresManagedServicesForNonManagedUser() throws Exception {
        final String policyXml = "<notification-policy version=\"1\">"