Migrate account management disabled policy
Bug: 251401809 Bug: 273494642 Bug: 273496614 Test: btest android.devicepolicy.cts.AccountManagementTest Test: btest a.d.c.DeviceManagementCoexistenceTest Change-Id: I890304b795d7d43fd3b585026dcac1b25e1a6d01
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
@@ -13978,16 +13979,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
|
||||
@@ -14004,13 +14017,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14028,41 +14041,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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user