diff options
4 files changed, 125 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 5a40b30551b6..0fac808fb13b 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -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; } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2f34ccdb5c03..d44a3b7f5b48 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -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; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index 8ba9af0d85d0..49879efe4b51 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -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); 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 d78ca1bd7b67..e85d7dba82be 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -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); @@ -4464,6 +4472,33 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @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\">" + "<ranking></ranking>" @@ -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, |