Merge "Migrate account management disabled policy" into udc-dev

This commit is contained in:
Kholoud Mohamed
2023-04-17 09:49:24 +00:00
committed by Android (Google) Code Review
3 changed files with 128 additions and 31 deletions

View File

@@ -631,6 +631,38 @@ final class DevicePolicyEngine {
}
}
/**
* Returns all the {@code policyKeys} set by any admin that share the same
* {@link PolicyKey#getIdentifier()} as the provided {@code policyDefinition}.
*
* <p>For example, getLocalPolicyKeysSetByAllAdmins(PERMISSION_GRANT) returns all permission
* grants set by any admin.
*
* <p>Note that this will always return at most one item for policies that do not require
* additional params (e.g. {@link PolicyDefinition#LOCK_TASK} vs
* {@link PolicyDefinition#PERMISSION_GRANT(String, String)}).
*
*/
@NonNull
<V> Set<PolicyKey> getLocalPolicyKeysSetByAllAdmins(
@NonNull PolicyDefinition<V> policyDefinition,
int userId) {
Objects.requireNonNull(policyDefinition);
synchronized (mLock) {
if (policyDefinition.isGlobalOnlyPolicy() || !mLocalPolicies.contains(userId)) {
return Set.of();
}
Set<PolicyKey> keys = new HashSet<>();
for (PolicyKey key : mLocalPolicies.get(userId).keySet()) {
if (key.hasSameIdentifierAs(policyDefinition.getPolicyKey())) {
keys.add(key);
}
}
return keys;
}
}
/**
* Returns all user restriction policies set by the given admin.
*

View File

@@ -280,6 +280,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.app.admin.AccountTypePolicyKey;
import android.app.admin.BooleanPolicyValue;
import android.app.admin.BundlePolicyValue;
import android.app.admin.ComponentNamePolicyValue;
@@ -14019,16 +14020,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
caller = getCallerIdentity(who);
}
synchronized (getLockObject()) {
final ActiveAdmin ap;
if (isPermissionCheckFlagEnabled()) {
int affectedUser = getAffectedUser(parent);
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who,
MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT,
caller.getPackageName(),
getAffectedUser(parent)
affectedUser
);
ap = enforcingAdmin.getActiveAdmin();
if (disabled) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
enforcingAdmin,
new BooleanPolicyValue(disabled),
affectedUser);
} else {
mDevicePolicyEngine.removeLocalPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
enforcingAdmin,
affectedUser);
}
} else {
final ActiveAdmin ap;
Objects.requireNonNull(who, "ComponentName is null");
/*
* When called on the parent DPM instance (parent == true), affects active admin
@@ -14045,13 +14058,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
ap = getParentOfAdminIfRequired(
getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
}
if (disabled) {
ap.accountTypesWithManagementDisabled.add(accountType);
} else {
ap.accountTypesWithManagementDisabled.remove(accountType);
}
saveSettingsLocked(UserHandle.getCallingUserId());
}
if (disabled) {
ap.accountTypesWithManagementDisabled.add(accountType);
} else {
ap.accountTypesWithManagementDisabled.remove(accountType);
}
saveSettingsLocked(UserHandle.getCallingUserId());
}
}
@@ -14069,41 +14082,64 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
CallerIdentity caller;
Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
final ArraySet<String> resultSet = new ArraySet<>();
if (isPermissionCheckFlagEnabled()) {
int affectedUser = parent ? getProfileParentId(userId) : userId;
caller = getCallerIdentity(callerPackageName);
if (!hasPermission(MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT,
caller.getPackageName(), userId)
callerPackageName, affectedUser)
&& !hasFullCrossUsersPermission(caller, userId)) {
throw new SecurityException("Caller does not have permission to call this on user: "
+ userId);
+ affectedUser);
}
} else {
caller = getCallerIdentity();
Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
}
Set<PolicyKey> keys = mDevicePolicyEngine.getLocalPolicyKeysSetByAllAdmins(
PolicyDefinition.GENERIC_ACCOUNT_MANAGEMENT_DISABLED,
affectedUser);
synchronized (getLockObject()) {
final ArraySet<String> resultSet = new ArraySet<>();
for (PolicyKey key : keys) {
if (!(key instanceof AccountTypePolicyKey)) {
throw new IllegalStateException("PolicyKey for "
+ "MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT is not of type "
+ "AccountTypePolicyKey");
}
AccountTypePolicyKey parsedKey =
(AccountTypePolicyKey) key;
String accountType = Objects.requireNonNull(parsedKey.getAccountType());
if (!parent) {
final DevicePolicyData policy = getUserData(userId);
for (ActiveAdmin admin : policy.mAdminList) {
resultSet.addAll(admin.accountTypesWithManagementDisabled);
Boolean disabled = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
affectedUser);
if (disabled != null && disabled) {
resultSet.add(accountType);
}
}
// Check if there's a profile owner of an org-owned device and the method is called for
// the parent user of this profile owner.
final ActiveAdmin orgOwnedAdmin =
getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
final boolean shouldGetParentAccounts = orgOwnedAdmin != null && (parent
|| UserHandle.getUserId(orgOwnedAdmin.getUid()) != userId);
if (shouldGetParentAccounts) {
resultSet.addAll(
orgOwnedAdmin.getParentActiveAdmin().accountTypesWithManagementDisabled);
} else {
caller = getCallerIdentity();
Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
synchronized (getLockObject()) {
if (!parent) {
final DevicePolicyData policy = getUserData(userId);
for (ActiveAdmin admin : policy.mAdminList) {
resultSet.addAll(admin.accountTypesWithManagementDisabled);
}
}
// Check if there's a profile owner of an org-owned device and the method is called
// for the parent user of this profile owner.
final ActiveAdmin orgOwnedAdmin =
getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
final boolean shouldGetParentAccounts = orgOwnedAdmin != null && (parent
|| UserHandle.getUserId(orgOwnedAdmin.getUid()) != userId);
if (shouldGetParentAccounts) {
resultSet.addAll(
orgOwnedAdmin.getParentActiveAdmin()
.accountTypesWithManagementDisabled);
}
}
return resultSet.toArray(new String[resultSet.size()]);
}
return resultSet.toArray(new String[resultSet.size()]);
}
@Override

View File

@@ -18,6 +18,7 @@ package com.android.server.devicepolicy;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.admin.AccountTypePolicyKey;
import android.app.admin.BooleanPolicyValue;
import android.app.admin.DevicePolicyIdentifiers;
import android.app.admin.DevicePolicyManager;
@@ -281,6 +282,32 @@ final class PolicyDefinition<V> {
DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, packageName));
}
// This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
// actual policy with the correct arguments (i.e. packageName) when reading the policies from
// xml.
static PolicyDefinition<Boolean> GENERIC_ACCOUNT_MANAGEMENT_DISABLED =
new PolicyDefinition<>(
new AccountTypePolicyKey(
DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY),
TRUE_MORE_RESTRICTIVE,
POLICY_FLAG_LOCAL_ONLY_POLICY,
// Nothing is enforced, we just need to store it
(Boolean value, Context context, Integer userId, PolicyKey policyKey) -> true,
new BooleanPolicySerializer());
/**
* Passing in {@code null} for {@code accountType} will return
* {@link #GENERIC_ACCOUNT_MANAGEMENT_DISABLED}.
*/
static PolicyDefinition<Boolean> ACCOUNT_MANAGEMENT_DISABLED(String accountType) {
if (accountType == null) {
return GENERIC_ACCOUNT_MANAGEMENT_DISABLED;
}
return GENERIC_ACCOUNT_MANAGEMENT_DISABLED.createPolicyDefinition(
new AccountTypePolicyKey(
DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY, accountType));
}
private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
@@ -304,6 +331,8 @@ final class PolicyDefinition<V> {
KEYGUARD_DISABLED_FEATURES);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY,
GENERIC_APPLICATION_HIDDEN);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY,
GENERIC_ACCOUNT_MANAGEMENT_DISABLED);
// User Restriction Policies
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);