Show correct restriction enforcement info for unknown apps installs.
Obtain the correct admin and dialog information when a restriction prevents the
user from installing apps from unknown sources.
Bug: 118881180
Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest
Change-Id: I8112aaca64f85d421ee1029edc5c47909e31f12f
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 4ff5d61..1b85b06 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11176,48 +11176,51 @@
@Override
public Intent createUserRestrictionSupportIntent(int userId, String userRestriction) {
- int source;
- long ident = mInjector.binderClearCallingIdentity();
+ final long ident = mInjector.binderClearCallingIdentity();
try {
- source = mUserManager.getUserRestrictionSource(userRestriction,
- UserHandle.of(userId));
+ final List<UserManager.EnforcingUser> sources = mUserManager
+ .getUserRestrictionSources(userRestriction, UserHandle.of(userId));
+ if (sources == null || sources.isEmpty()) {
+ // The restriction is not enforced.
+ return null;
+ } else if (sources.size() > 1) {
+ // In this case, we'll show an admin support dialog that does not
+ // specify the admin.
+ // TODO(b/128928355): if this restriction is enforced by multiple DPCs, return
+ // the admin for the calling user.
+ return DevicePolicyManagerService.this.createShowAdminSupportIntent(
+ null, userId);
+ }
+ final UserManager.EnforcingUser enforcingUser = sources.get(0);
+ final int sourceType = enforcingUser.getUserRestrictionSource();
+ final int enforcingUserId = enforcingUser.getUserHandle().getIdentifier();
+ if (sourceType == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) {
+ // Restriction was enforced by PO
+ final ComponentName profileOwner = mOwners.getProfileOwnerComponent(
+ enforcingUserId);
+ if (profileOwner != null) {
+ return DevicePolicyManagerService.this.createShowAdminSupportIntent(
+ profileOwner, enforcingUserId);
+ }
+ } else if (sourceType == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
+ // Restriction was enforced by DO
+ final Pair<Integer, ComponentName> deviceOwner =
+ mOwners.getDeviceOwnerUserIdAndComponent();
+ if (deviceOwner != null) {
+ return DevicePolicyManagerService.this.createShowAdminSupportIntent(
+ deviceOwner.second, deviceOwner.first);
+ }
+ } else if (sourceType == UserManager.RESTRICTION_SOURCE_SYSTEM) {
+ /*
+ * In this case, the user restriction is enforced by the system.
+ * So we won't show an admin support intent, even if it is also
+ * enforced by a profile/device owner.
+ */
+ return null;
+ }
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
- if ((source & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
- /*
- * In this case, the user restriction is enforced by the system.
- * So we won't show an admin support intent, even if it is also
- * enforced by a profile/device owner.
- */
- return null;
- }
- boolean enforcedByDo = (source & UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) != 0;
- boolean enforcedByPo = (source & UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) != 0;
- if (enforcedByDo && enforcedByPo) {
- // In this case, we'll show an admin support dialog that does not
- // specify the admin.
- return DevicePolicyManagerService.this.createShowAdminSupportIntent(null, userId);
- } else if (enforcedByPo) {
- final ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
- if (profileOwner != null) {
- return DevicePolicyManagerService.this
- .createShowAdminSupportIntent(profileOwner, userId);
- }
- // This could happen if another thread has changed the profile owner since we called
- // getUserRestrictionSource
- return null;
- } else if (enforcedByDo) {
- final Pair<Integer, ComponentName> deviceOwner
- = mOwners.getDeviceOwnerUserIdAndComponent();
- if (deviceOwner != null) {
- return DevicePolicyManagerService.this
- .createShowAdminSupportIntent(deviceOwner.second, deviceOwner.first);
- }
- // This could happen if another thread has changed the device owner since we called
- // getUserRestrictionSource
- return null;
- }
return null;
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index bd7774a..57ccadd 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -99,7 +99,6 @@
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.File;
@@ -241,29 +240,23 @@
final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
// UM.setApplicationRestrictions() will save to appRestrictions.
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- String pkg = (String) invocation.getArguments()[0];
- Bundle bundle = (Bundle) invocation.getArguments()[1];
- UserHandle user = (UserHandle) invocation.getArguments()[2];
+ doAnswer((Answer<Void>) invocation -> {
+ String pkg = (String) invocation.getArguments()[0];
+ Bundle bundle = (Bundle) invocation.getArguments()[1];
+ UserHandle user = (UserHandle) invocation.getArguments()[2];
- appRestrictions.put(Pair.create(pkg, user), bundle);
+ appRestrictions.put(Pair.create(pkg, user), bundle);
- return null;
- }
+ return null;
}).when(getServices().userManager).setApplicationRestrictions(
anyString(), nullable(Bundle.class), any(UserHandle.class));
// UM.getApplicationRestrictions() will read from appRestrictions.
- doAnswer(new Answer<Bundle>() {
- @Override
- public Bundle answer(InvocationOnMock invocation) throws Throwable {
- String pkg = (String) invocation.getArguments()[0];
- UserHandle user = (UserHandle) invocation.getArguments()[1];
+ doAnswer((Answer<Bundle>) invocation -> {
+ String pkg = (String) invocation.getArguments()[0];
+ UserHandle user = (UserHandle) invocation.getArguments()[1];
- return appRestrictions.get(Pair.create(pkg, user));
- }
+ return appRestrictions.get(Pair.create(pkg, user));
}).when(getServices().userManager).getApplicationRestrictions(
anyString(), any(UserHandle.class));
@@ -2242,11 +2235,13 @@
intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
assertNull(intent);
- // Permission that is set by device owner returns correct intent
- when(getServices().userManager.getUserRestrictionSource(
+ // UM.getUserRestrictionSources() will return a list of size 1 with the caller resource.
+ doAnswer((Answer<List<UserManager.EnforcingUser>>) invocation -> Collections.singletonList(
+ new UserManager.EnforcingUser(
+ UserHandle.myUserId(), UserManager.RESTRICTION_SOURCE_DEVICE_OWNER))
+ ).when(getServices().userManager).getUserRestrictionSources(
eq(UserManager.DISALLOW_ADJUST_VOLUME),
- eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
- .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+ eq(UserHandle.getUserHandleForUid(UserHandle.myUserId())));
intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
assertNotNull(intent);
assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());