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

Commit 3315391b authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Prevent ManagedServices from running in clone profiles" into tm-qpr-dev

parents 97cf25f2 4b21177a
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -1786,8 +1786,8 @@ abstract public class ManagedServices {
         * from receiving events from the profile.
         */
        public boolean isPermittedForProfile(int userId) {
            if (!mUserProfiles.isManagedProfile(userId)) {
                return true;
            if (!mUserProfiles.canProfileUseBoundServices(userId)) {
                return false;
            }
            DevicePolicyManager dpm =
                    (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE);
@@ -1862,10 +1862,16 @@ abstract public class ManagedServices {
            }
        }

        public boolean isManagedProfile(int userId) {
        public boolean canProfileUseBoundServices(int userId) {
            synchronized (mCurrentProfiles) {
                UserInfo user = mCurrentProfiles.get(userId);
                return user != null && user.isManagedProfile();
                if (user == null) {
                    return false;
                }
                if (user.isManagedProfile() || user.isCloneProfile()) {
                    return false;
                }
                return true;
            }
        }
    }
+11 −5
Original line number Diff line number Diff line
@@ -303,6 +303,7 @@ import com.android.server.notification.toast.CustomToastRecord;
import com.android.server.notification.toast.TextToastRecord;
import com.android.server.notification.toast.ToastRecord;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -532,6 +533,7 @@ public class NotificationManagerService extends SystemService {
    private UriGrantsManagerInternal mUgmInternal;
    private volatile RoleObserver mRoleObserver;
    private UserManager mUm;
    private UserManagerInternal mUmInternal;
    private IPlatformCompat mPlatformCompat;
    private ShortcutHelper mShortcutHelper;
    private PermissionHelper mPermissionHelper;
@@ -818,7 +820,8 @@ public class NotificationManagerService extends SystemService {
        final List<UserInfo> activeUsers = mUm.getUsers();
        for (UserInfo userInfo : activeUsers) {
            int userId = userInfo.getUserHandle().getIdentifier();
            if (isNASMigrationDone(userId) || mUm.isManagedProfile(userId)) {
            if (isNASMigrationDone(userId)
                    || userInfo.isManagedProfile() || userInfo.isCloneProfile()) {
                continue;
            }
            List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
@@ -949,7 +952,9 @@ public class NotificationManagerService extends SystemService {
        }
        XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
        boolean migratedManagedServices = false;
        boolean ineligibleForManagedServices = forRestore && mUm.isManagedProfile(userId);
        UserInfo userInfo = mUmInternal.getUserInfo(userId);
        boolean ineligibleForManagedServices = forRestore &&
                (userInfo.isManagedProfile() || userInfo.isCloneProfile());
        int outerDepth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
            if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
@@ -1823,7 +1828,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.isManagedProfile(userId)) {
                if (mUserProfiles.canProfileUseBoundServices(userId)) {
                    // reload per-user settings
                    mSettingsObserver.update(null);
                    // Refresh managed services
@@ -1837,7 +1842,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.isManagedProfile(userId)) {
                    if (mUserProfiles.canProfileUseBoundServices(userId)) {
                        allowDefaultApprovedServices(userId);
                    }
                }
@@ -1855,7 +1860,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.isManagedProfile(userId)) {
                if (mUserProfiles.canProfileUseBoundServices(userId)) {
                    mConditionProviders.onUserUnlocked(userId);
                    mListeners.onUserUnlocked(userId);
                    mZenModeHelper.onUserUnlocked(userId);
@@ -2217,6 +2222,7 @@ public class NotificationManagerService extends SystemService {
        mPackageManagerClient = packageManagerClient;
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
        mUmInternal = LocalServices.getService(UserManagerInternal.class);
        mUsageStatsManagerInternal = usageStatsManagerInternal;
        mAppOps = appOps;
        mAppOpsService = iAppOps;
+61 −0
Original line number Diff line number Diff line
@@ -15,6 +15,11 @@
 */
package com.android.server.notification;

import static android.content.Context.DEVICE_POLICY_SERVICE;
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 com.android.server.notification.ManagedServices.APPROVAL_BY_COMPONENT;
import static com.android.server.notification.ManagedServices.APPROVAL_BY_PACKAGE;

@@ -34,6 +39,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -94,6 +101,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
    private UserManager mUm;
    @Mock
    private ManagedServices.UserProfiles mUserProfiles;
    @Mock private DevicePolicyManager mDpm;
    Object mLock = new Object();

    UserInfo mZero = new UserInfo(0, "zero", 0);
@@ -122,6 +130,7 @@ public class ManagedServicesTest extends UiServiceTestCase {

        getContext().setMockPackageManager(mPm);
        getContext().addMockSystemService(Context.USER_SERVICE, mUm);
        getContext().addMockSystemService(DEVICE_POLICY_SERVICE, mDpm);

        List<UserInfo> users = new ArrayList<>();
        users.add(mZero);
@@ -1694,6 +1703,58 @@ public class ManagedServicesTest extends UiServiceTestCase {
        assertEquals(new ArrayMap(), mService.mIsUserChanged);
    }

    @Test
    public void testInfoIsPermittedForProfile_notAllowed() {
        when(mUserProfiles.canProfileUseBoundServices(anyInt())).thenReturn(false);

        IInterface service = mock(IInterface.class);
        when(service.asBinder()).thenReturn(mock(IBinder.class));
        ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
                mIpm, APPROVAL_BY_PACKAGE);
        services.registerSystemService(service, null, 10, 1000);
        ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);

        assertFalse(info.isPermittedForProfile(0));
    }

    @Test
    public void testInfoIsPermittedForProfile_allows() {
        when(mUserProfiles.canProfileUseBoundServices(anyInt())).thenReturn(true);
        when(mDpm.isNotificationListenerServicePermitted(anyString(), anyInt())).thenReturn(true);

        IInterface service = mock(IInterface.class);
        when(service.asBinder()).thenReturn(mock(IBinder.class));
        ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
                mIpm, APPROVAL_BY_PACKAGE);
        services.registerSystemService(service, null, 10, 1000);
        ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
        info.component = new ComponentName("a","b");

        assertTrue(info.isPermittedForProfile(0));
    }

    @Test
    public void testUserProfiles_canProfileUseBoundServices_managedProfile() {
        List<UserInfo> users = new ArrayList<>();
        UserInfo profile = new UserInfo(ActivityManager.getCurrentUser(), "current", 0);
        profile.userType = USER_TYPE_FULL_SECONDARY;
        users.add(profile);
        UserInfo managed = new UserInfo(12, "12", 0);
        managed.userType = USER_TYPE_PROFILE_MANAGED;
        users.add(managed);
        UserInfo clone = new UserInfo(13, "13", 0);
        clone.userType = USER_TYPE_PROFILE_CLONE;
        users.add(clone);
        when(mUm.getProfiles(ActivityManager.getCurrentUser())).thenReturn(users);

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

        assertTrue(profiles.canProfileUseBoundServices(ActivityManager.getCurrentUser()));
        assertFalse(profiles.canProfileUseBoundServices(12));
        assertFalse(profiles.canProfileUseBoundServices(13));
    }

    private void resetComponentsAndPackages() {
        ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1);
        ArrayMap<Integer, String> emptyPkgs = new ArrayMap(0);
+43 −2
Original line number Diff line number Diff line
@@ -58,6 +58,9 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.O_MR1;
import static android.os.Build.VERSION_CODES.P;
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.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -212,6 +215,7 @@ import com.android.server.lights.LogicalLight;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.UserManagerInternal;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -353,6 +357,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    @Mock
    UserManager mUm;
    @Mock
    UserManagerInternal mUmInternal;
    @Mock
    NotificationHistoryManager mHistoryManager;
    @Mock
    StatsManager mStatsManager;
@@ -394,6 +400,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        DeviceIdleInternal deviceIdleInternal = mock(DeviceIdleInternal.class);
        when(deviceIdleInternal.getNotificationAllowlistDuration()).thenReturn(3000L);

        LocalServices.removeServiceForTest(UserManagerInternal.class);
        LocalServices.addService(UserManagerInternal.class, mUmInternal);
        LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
        LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
        LocalServices.removeServiceForTest(WindowManagerInternal.class);
@@ -4463,6 +4471,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        verify(mAssistants, times(2)).resetDefaultAssistantsIfNecessary();
    }

    @Test
    public void testReadPolicyXml_doesNotRestoreManagedServicesForCloneUser() throws Exception {
        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();
        ui.id = 10;
        ui.userType = USER_TYPE_PROFILE_CLONE;
        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_doesNotRestoreManagedServicesForManagedUser() throws Exception {
        final String policyXml = "<notification-policy version=\"1\">"
@@ -4477,7 +4512,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</dnd_apps>"
                + "</notification-policy>";
        when(mUm.isManagedProfile(10)).thenReturn(true);
        UserInfo ui = new UserInfo();
        ui.id = 10;
        ui.userType = USER_TYPE_PROFILE_MANAGED;
        when(mUmInternal.getUserInfo(10)).thenReturn(ui);
        mService.readPolicyXml(
                new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
                true,
@@ -4501,7 +4539,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                + "<service_listing approved=\"test\" user=\"10\" primary=\"true\" />"
                + "</dnd_apps>"
                + "</notification-policy>";
        when(mUm.isManagedProfile(10)).thenReturn(false);
        UserInfo ui = new UserInfo();
        ui.id = 10;
        ui.userType = USER_TYPE_FULL_SECONDARY;
        when(mUmInternal.getUserInfo(10)).thenReturn(ui);
        mService.readPolicyXml(
                new BufferedInputStream(new ByteArrayInputStream(policyXml.getBytes())),
                true,