Fixes DPMS.getEnforcingAdminAndUserDetailsInternal()

It was not properly setting the admin when the user restriction was
set by both DPC and system (for example, location being disabled for
work profile by Settings).

Similarly, RestrictedLockUtilsInternal.checkIfRestrictionEnforced()
was not setting the EnforcedAdmin user when there were multiple
sources.

Test: manual verification using CtsVerifier

Bug: 128928355
Fixes: 208501696

Change-Id: Ia0c1489ba0eadd67b9a8e802eb8640c9c1236e44
This commit is contained in:
Felipe Leme
2021-12-14 13:20:37 -08:00
parent 238c6d65d0
commit 0754ce945b
2 changed files with 61 additions and 5 deletions

View File

@@ -38,6 +38,7 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.MenuItem;
import android.widget.TextView;
@@ -54,6 +55,7 @@ import java.util.List;
public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
private static final String LOG_TAG = "RestrictedLockUtils";
private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
/**
* @return drawables for displaying with settings that are locked by a device admin.
@@ -92,14 +94,25 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
}
final UserManager um = UserManager.get(context);
final UserHandle userHandle = UserHandle.of(userId);
final List<UserManager.EnforcingUser> enforcingUsers =
um.getUserRestrictionSources(userRestriction, UserHandle.of(userId));
um.getUserRestrictionSources(userRestriction, userHandle);
if (enforcingUsers.isEmpty()) {
// Restriction is not enforced.
return null;
} else if (enforcingUsers.size() > 1) {
return EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
}
final int size = enforcingUsers.size();
if (size > 1) {
final EnforcedAdmin enforcedAdmin = EnforcedAdmin
.createDefaultEnforcedAdminWithRestriction(userRestriction);
enforcedAdmin.user = userHandle;
if (DEBUG) {
Log.d(LOG_TAG, "Multiple (" + size + ") enforcing users for restriction '"
+ userRestriction + "' on user " + userHandle + "; returning default admin "
+ "(" + enforcedAdmin + ")");
}
return enforcedAdmin;
}
final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource();

View File

@@ -258,6 +258,7 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager.UserRestrictionSource;
import android.os.storage.StorageManager;
import android.permission.AdminPermissionControlParams;
import android.permission.IPermissionManager;
@@ -286,6 +287,7 @@ import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.DebugUtils;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Pair;
@@ -13225,14 +13227,29 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
try {
List<UserManager.EnforcingUser> sources = mUserManager
.getUserRestrictionSources(restriction, UserHandle.of(userId));
if (sources == null || sources.isEmpty()) {
if (sources == null) {
// The restriction is not enforced.
return null;
} else if (sources.size() > 1) {
}
int sizeBefore = sources.size();
if (sizeBefore > 1) {
Slogf.d(LOG_TAG, "getEnforcingAdminAndUserDetailsInternal(%d, %s): "
+ "%d sources found, excluding those set by UserManager",
userId, restriction, sizeBefore);
sources = getDevicePolicySources(sources);
}
if (sources.isEmpty()) {
// The restriction is not enforced (or is just enforced by the system)
return null;
}
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.
Slogf.w(LOG_TAG, "getEnforcingAdminAndUserDetailsInternal(%d, %s): multiple "
+ "sources for restriction %s on user %d", restriction, userId);
result = new Bundle();
result.putInt(Intent.EXTRA_USER_ID, userId);
return result;
@@ -13277,6 +13294,32 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return null;
}
/**
* Excludes restrictions imposed by UserManager.
*/
private List<UserManager.EnforcingUser> getDevicePolicySources(
List<UserManager.EnforcingUser> sources) {
int sizeBefore = sources.size();
List<UserManager.EnforcingUser> realSources = new ArrayList<>(sizeBefore);
for (int i = 0; i < sizeBefore; i++) {
UserManager.EnforcingUser source = sources.get(i);
int type = source.getUserRestrictionSource();
if (type != UserManager.RESTRICTION_SOURCE_PROFILE_OWNER
&& type != UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
// TODO(b/128928355): add unit test
Slogf.d(LOG_TAG, "excluding source of type %s at index %d",
userRestrictionSourceToString(type), i);
continue;
}
realSources.add(source);
}
return realSources;
}
private static String userRestrictionSourceToString(@UserRestrictionSource int source) {
return DebugUtils.flagsToString(UserManager.class, "RESTRICTION_", source);
}
/**
* @param restriction The restriction enforced by admin. It could be any user restriction or
* policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA} and