Merge "Prevent ManagedServices from running in clone profiles" into tm-qpr-dev am: 3315391bf7
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19776117
Change-Id: I772ec56e36d1f44d6118fe6469d7ddb3a08f0dfe
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 5a40b30..0fac808 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 @@
* 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 @@
}
}
- 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 edf607e..f826f20 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.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 @@
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 @@
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 @@
}
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 @@
} 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 @@
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 @@
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 @@
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 8ba9af0..49879efe 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.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 @@
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 @@
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 @@
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 d78ca1b..e85d7db 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.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.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 @@
@Mock
UserManager mUm;
@Mock
+ UserManagerInternal mUmInternal;
+ @Mock
NotificationHistoryManager mHistoryManager;
@Mock
StatsManager mStatsManager;
@@ -394,6 +400,8 @@
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 @@
}
@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 @@
+ "<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 @@
+ "<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,