Merge changes from topic "dataMigration" into udc-dev

* changes:
  Fix lock task logging for permission based admins
  Remove policies for admins on role/package removal
  Migrate existing policies to the policy engine
This commit is contained in:
Kholoud Mohamed
2023-05-10 20:35:53 +00:00
committed by Android (Google) Code Review
4 changed files with 238 additions and 53 deletions

View File

@@ -81,6 +81,10 @@ import java.util.Set;
final class DevicePolicyEngine { final class DevicePolicyEngine {
static final String TAG = "DevicePolicyEngine"; static final String TAG = "DevicePolicyEngine";
// TODO(b/281701062): reference role name from role manager once its exposed.
static final String DEVICE_LOCK_CONTROLLER_ROLE =
"android.app.role.SYSTEM_FINANCED_DEVICE_CONTROLLER";
private static final String CELLULAR_2G_USER_RESTRICTION_ID = private static final String CELLULAR_2G_USER_RESTRICTION_ID =
DevicePolicyIdentifiers.getIdentifierForUserRestriction( DevicePolicyIdentifiers.getIdentifierForUserRestriction(
UserManager.DISALLOW_CELLULAR_2G); UserManager.DISALLOW_CELLULAR_2G);
@@ -1010,11 +1014,21 @@ final class DevicePolicyEngine {
/** /**
* Handles internal state related to packages getting updated. * Handles internal state related to packages getting updated.
*/ */
void handlePackageChanged(@Nullable String updatedPackage, int userId) { void handlePackageChanged(@Nullable String updatedPackage, int userId, boolean packageRemoved) {
if (updatedPackage == null) { if (updatedPackage == null) {
return; return;
} }
updateDeviceAdminServiceOnPackageChanged(updatedPackage, userId); if (packageRemoved) {
Set<EnforcingAdmin> admins = getEnforcingAdminsOnUser(userId);
for (EnforcingAdmin admin : admins) {
if (admin.getPackageName().equals(updatedPackage)) {
// remove policies for the uninstalled package
removePoliciesForAdmin(admin);
}
}
} else {
updateDeviceAdminServiceOnPackageChanged(updatedPackage, userId);
}
} }
/** /**
@@ -1032,6 +1046,28 @@ final class DevicePolicyEngine {
enforcePoliciesOnInheritableProfilesIfApplicable(user); enforcePoliciesOnInheritableProfilesIfApplicable(user);
} }
/**
* Handles internal state related to roles getting updated.
*/
void handleRoleChanged(@NonNull String roleName, int userId) {
// TODO(b/256852787): handle all roles changing.
if (!DEVICE_LOCK_CONTROLLER_ROLE.equals(roleName)) {
// We only support device lock controller role for now.
return;
}
String roleAuthority = EnforcingAdmin.getRoleAuthorityOf(roleName);
Set<EnforcingAdmin> admins = getEnforcingAdminsOnUser(userId);
for (EnforcingAdmin admin : admins) {
if (admin.hasAuthority(roleAuthority)) {
admin.reloadRoleAuthorities();
// remove admin policies if role was lost
if (!admin.hasAuthority(roleAuthority)) {
removePoliciesForAdmin(admin);
}
}
}
}
private void enforcePoliciesOnInheritableProfilesIfApplicable(UserInfo user) { private void enforcePoliciesOnInheritableProfilesIfApplicable(UserInfo user) {
if (!user.isProfile()) { if (!user.isProfile()) {
return; return;

View File

@@ -259,7 +259,6 @@ import android.Manifest.permission;
import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityServiceInfo;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException; import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException; import android.accounts.OperationCanceledException;
import android.annotation.IntDef; import android.annotation.IntDef;
@@ -1450,8 +1449,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
&& (owner.getPackageName().equals(packageName))) { && (owner.getPackageName().equals(packageName))) {
startOwnerService(userHandle, "package-broadcast"); startOwnerService(userHandle, "package-broadcast");
} }
if (isPermissionCheckFlagEnabled()) { if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handlePackageChanged(packageName, userHandle); mDevicePolicyEngine.handlePackageChanged(packageName, userHandle, removedAdmin);
} }
// Persist updates if the removed package was an admin or delegate. // Persist updates if the removed package was an admin or delegate.
if (removedAdmin || removedDelegate) { if (removedAdmin || removedDelegate) {
@@ -12294,13 +12293,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin( EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
who, MANAGE_DEVICE_POLICY_INPUT_METHODS, who, MANAGE_DEVICE_POLICY_INPUT_METHODS,
caller.getPackageName(), userId); caller.getPackageName(), userId);
mDevicePolicyEngine.setLocalPolicy( if (packageList == null) {
PolicyDefinition.PERMITTED_INPUT_METHODS, mDevicePolicyEngine.removeLocalPolicy(
admin, PolicyDefinition.PERMITTED_INPUT_METHODS,
packageList == null admin,
? null userId);
: new StringSetPolicyValue(new HashSet<>(packageList)), } else {
userId); mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.PERMITTED_INPUT_METHODS,
admin,
new StringSetPolicyValue(new HashSet<>(packageList)),
userId);
}
} else { } else {
ActiveAdmin admin = getParentOfAdminIfRequired( ActiveAdmin admin = getParentOfAdminIfRequired(
getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()),
@@ -12337,14 +12341,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
CallerIdentity caller; CallerIdentity caller;
if (isPermissionCheckFlagEnabled()) { if (isPolicyEngineForFinanceFlagEnabled()) {
caller = getCallerIdentity(who, callerPackageName); caller = getCallerIdentity(who, callerPackageName);
} else { } else {
caller = getCallerIdentity(who); caller = getCallerIdentity(who);
Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(who, "ComponentName is null");
} }
if (!isPermissionCheckFlagEnabled()) { if (!isPolicyEngineForFinanceFlagEnabled()) {
if (calledOnParentInstance) { if (calledOnParentInstance) {
Preconditions.checkCallAuthorization( Preconditions.checkCallAuthorization(
isProfileOwnerOfOrganizationOwnedDevice(caller)); isProfileOwnerOfOrganizationOwnedDevice(caller));
@@ -12742,7 +12746,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
final int userId = user.id; final int userId = user.id;
if (isPermissionCheckFlagEnabled()) { if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) {
mDevicePolicyEngine.handleUserCreated(user); mDevicePolicyEngine.handleUserCreated(user);
} }
@@ -14268,7 +14272,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
resultSet.add(accountType); resultSet.add(accountType);
} }
} }
} else { } else {
caller = getCallerIdentity(); caller = getCallerIdentity();
Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId)); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
@@ -15153,6 +15156,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
for (ActiveAdmin admin : policy.mAdminList) { for (ActiveAdmin admin : policy.mAdminList) {
final boolean ownsDevice = isDeviceOwner(admin.info.getComponent(), userHandle); final boolean ownsDevice = isDeviceOwner(admin.info.getComponent(), userHandle);
final boolean ownsProfile = isProfileOwner(admin.info.getComponent(), userHandle); final boolean ownsProfile = isProfileOwner(admin.info.getComponent(), userHandle);
// TODO(b/281738975): Should we be logging this for all admins?
if (ownsDevice || ownsProfile) { if (ownsDevice || ownsProfile) {
if (isEnabled) { if (isEnabled) {
sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_LOCK_TASK_ENTERING, sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_LOCK_TASK_ENTERING,
@@ -15169,6 +15173,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
} }
} }
// TODO(b/281738975): Should we be logging this for all admins?
for(EnforcingAdmin admin : mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
PolicyDefinition.LOCK_TASK, userHandle).keySet()) {
if (admin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
// already handled above
continue;
}
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.SET_LOCKTASK_MODE_ENABLED)
.setAdmin(admin.getPackageName())
.setBoolean(isEnabled)
.setStrings(pkg)
.write();
}
} }
@Override @Override
@@ -22681,6 +22699,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override @Override
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
mDevicePolicyEngine.handleRoleChanged(roleName, user.getIdentifier());
if (RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) { if (RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
handleDevicePolicyManagementRoleChange(user); handleDevicePolicyManagementRoleChange(user);
return; return;
@@ -24065,13 +24084,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private boolean hasNonTestOnlyActiveAdmins() { private boolean hasNonTestOnlyActiveAdmins() {
return mInjector.binderWithCleanCallingIdentity(() -> { return mInjector.binderWithCleanCallingIdentity(() -> {
for (UserInfo userInfo : mUserManager.getUsers()) { for (UserInfo userInfo : mUserManager.getUsers()) {
List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id); synchronized (getLockObject()) {
if (activeAdmins == null) { List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
continue; if (activeAdmins == null) {
} continue;
for (ComponentName admin : activeAdmins) { }
if (!isAdminTestOnlyLocked(admin, userInfo.id)) { for (ComponentName admin : activeAdmins) {
return true; if (!isAdminTestOnlyLocked(admin, userInfo.id)) {
return true;
}
} }
} }
} }
@@ -24081,7 +24102,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private boolean shouldMigrateToDevicePolicyEngine() { private boolean shouldMigrateToDevicePolicyEngine() {
return mInjector.binderWithCleanCallingIdentity(() -> return mInjector.binderWithCleanCallingIdentity(() ->
isPermissionCheckFlagEnabled() && !mOwners.isMigratedToPolicyEngine()); (isPermissionCheckFlagEnabled() || isPolicyEngineForFinanceFlagEnabled())
&& !mOwners.isMigratedToPolicyEngine());
} }
/** /**
@@ -24090,13 +24112,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private boolean migratePoliciesToDevicePolicyEngine() { private boolean migratePoliciesToDevicePolicyEngine() {
return mInjector.binderWithCleanCallingIdentity(() -> { return mInjector.binderWithCleanCallingIdentity(() -> {
try { try {
Slogf.i(LOG_TAG, "Started device policies migration to the device policy engine."); synchronized (getLockObject()) {
migrateAutoTimezonePolicy(); Slogf.i(LOG_TAG,
migratePermissionGrantStatePolicies(); "Started device policies migration to the device policy engine.");
// TODO(b/258811766): add migration logic for all policies if (isUnicornFlagEnabled()) {
migrateAutoTimezonePolicy();
migratePermissionGrantStatePolicies();
}
migrateScreenCapturePolicyLocked();
migratePermittedInputMethodsPolicyLocked();
migrateAccountManagementDisabledPolicyLocked();
migrateUserControlDisabledPackagesLocked();
mOwners.markMigrationToPolicyEngine(); mOwners.markMigrationToPolicyEngine();
return true; return true;
}
} catch (Exception e) { } catch (Exception e) {
mDevicePolicyEngine.clearAllPolicies(); mDevicePolicyEngine.clearAllPolicies();
Slogf.e(LOG_TAG, e, "Error occurred during device policy migration, will " Slogf.e(LOG_TAG, e, "Error occurred during device policy migration, will "
@@ -24160,6 +24190,136 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
} }
private void migrateScreenCapturePolicyLocked() {
Binder.withCleanCallingIdentity(() -> {
if (mPolicyCache.getScreenCaptureDisallowedUser() == UserHandle.USER_NULL) {
return;
}
ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
if (admin != null
&& ((isDeviceOwner(admin) && admin.disableScreenCapture)
|| (admin.getParentActiveAdmin() != null
&& admin.getParentActiveAdmin().disableScreenCapture))) {
EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
admin.info.getComponent(),
admin.getUserHandle().getIdentifier(),
admin);
mDevicePolicyEngine.setGlobalPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
enforcingAdmin,
new BooleanPolicyValue(true));
}
List<UserInfo> users = mUserManager.getUsers();
for (UserInfo userInfo : users) {
ActiveAdmin profileOwner = getProfileOwnerLocked(userInfo.id);
if (profileOwner != null && profileOwner.disableScreenCapture) {
EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
profileOwner.info.getComponent(),
profileOwner.getUserHandle().getIdentifier(),
profileOwner);
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
enforcingAdmin,
new BooleanPolicyValue(true),
profileOwner.getUserHandle().getIdentifier());
}
}
});
}
private void migratePermittedInputMethodsPolicyLocked() {
Binder.withCleanCallingIdentity(() -> {
List<UserInfo> users = mUserManager.getUsers();
for (UserInfo userInfo : users) {
ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id);
if (admin != null) {
EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
admin.info.getComponent(),
admin.getUserHandle().getIdentifier(),
admin);
if (admin.permittedInputMethods != null) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.PERMITTED_INPUT_METHODS,
enforcingAdmin,
new StringSetPolicyValue(
new HashSet<>(admin.permittedInputMethods)),
admin.getUserHandle().getIdentifier());
}
if (admin.getParentActiveAdmin() != null
&& admin.getParentActiveAdmin().permittedInputMethods != null) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.PERMITTED_INPUT_METHODS,
enforcingAdmin,
new StringSetPolicyValue(
new HashSet<>(admin.getParentActiveAdmin()
.permittedInputMethods)),
getProfileParentId(admin.getUserHandle().getIdentifier()));
}
}
}
});
}
private void migrateAccountManagementDisabledPolicyLocked() {
Binder.withCleanCallingIdentity(() -> {
List<UserInfo> users = mUserManager.getUsers();
for (UserInfo userInfo : users) {
ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id);
if (admin != null) {
EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
admin.info.getComponent(),
admin.getUserHandle().getIdentifier(),
admin);
for (String accountType : admin.accountTypesWithManagementDisabled) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
enforcingAdmin,
new BooleanPolicyValue(true),
admin.getUserHandle().getIdentifier());
}
if (admin.getParentActiveAdmin() != null) {
for (String accountType : admin.getParentActiveAdmin()
.accountTypesWithManagementDisabled) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
enforcingAdmin,
new BooleanPolicyValue(true),
getProfileParentId(admin.getUserHandle().getIdentifier()));
}
}
}
}
});
}
private void migrateUserControlDisabledPackagesLocked() {
Binder.withCleanCallingIdentity(() -> {
List<UserInfo> users = mUserManager.getUsers();
for (UserInfo userInfo : users) {
ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id);
if (admin != null && admin.protectedPackages != null) {
EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
admin.info.getComponent(),
admin.getUserHandle().getIdentifier(),
admin);
if (isDeviceOwner(admin)) {
mDevicePolicyEngine.setGlobalPolicy(
PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
enforcingAdmin,
new StringSetPolicyValue(new HashSet<>(admin.protectedPackages)));
} else {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
enforcingAdmin,
new StringSetPolicyValue(new HashSet<>(admin.protectedPackages)),
admin.getUserHandle().getIdentifier());
}
}
}
});
}
private List<PackageInfo> getInstalledPackagesOnUser(int userId) { private List<PackageInfo> getInstalledPackagesOnUser(int userId) {
return mInjector.binderWithCleanCallingIdentity(() -> return mInjector.binderWithCleanCallingIdentity(() ->
mContext.getPackageManager().getInstalledPackagesAsUser( mContext.getPackageManager().getInstalledPackagesAsUser(

View File

@@ -93,22 +93,6 @@ final class EnforcingAdmin {
activeAdmin); activeAdmin);
} }
static EnforcingAdmin createEnterpriseEnforcingAdmin(
@NonNull String packageName, int userId) {
Objects.requireNonNull(packageName);
return new EnforcingAdmin(
packageName, /* componentName= */ null, Set.of(DPC_AUTHORITY), userId,
/* activeAdmin= */ null);
}
static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId) {
Objects.requireNonNull(componentName);
return new EnforcingAdmin(
componentName.getPackageName(), componentName, Set.of(DEVICE_ADMIN_AUTHORITY),
userId, /* activeAdmin=*/ null);
}
static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId, static EnforcingAdmin createDeviceAdminEnforcingAdmin(ComponentName componentName, int userId,
ActiveAdmin activeAdmin) { ActiveAdmin activeAdmin) {
Objects.requireNonNull(componentName); Objects.requireNonNull(componentName);
@@ -190,12 +174,18 @@ final class EnforcingAdmin {
} }
private Set<String> getAuthorities() { private Set<String> getAuthorities() {
if (mAuthorities == null) { if (mAuthorities == null && mIsRoleAuthority) {
mAuthorities = getRoleAuthoritiesOrDefault(mPackageName, mUserId); mAuthorities = getRoleAuthoritiesOrDefault(mPackageName, mUserId);
} }
return mAuthorities; return mAuthorities;
} }
void reloadRoleAuthorities() {
if (mIsRoleAuthority) {
mAuthorities = getRoleAuthoritiesOrDefault(mPackageName, mUserId);
}
}
boolean hasAuthority(String authority) { boolean hasAuthority(String authority) {
return getAuthorities().contains(authority); return getAuthorities().contains(authority);
} }
@@ -304,6 +294,7 @@ final class EnforcingAdmin {
int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID); int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID);
if (isRoleAuthority) { if (isRoleAuthority) {
// TODO(b/281697976): load active admin
return new EnforcingAdmin(packageName, userId, null); return new EnforcingAdmin(packageName, userId, null);
} else { } else {
String className = parser.getAttributeValue(/* namespace= */ null, ATTR_CLASS_NAME); String className = parser.getAttributeValue(/* namespace= */ null, ATTR_CLASS_NAME);

View File

@@ -16,6 +16,8 @@
package com.android.server.devicepolicy; package com.android.server.devicepolicy;
import static com.android.server.devicepolicy.DevicePolicyEngine.DEVICE_LOCK_CONTROLLER_ROLE;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.admin.AccountTypePolicyKey; import android.app.admin.AccountTypePolicyKey;
@@ -131,9 +133,7 @@ final class PolicyDefinition<V> {
static PolicyDefinition<LockTaskPolicy> LOCK_TASK = new PolicyDefinition<>( static PolicyDefinition<LockTaskPolicy> LOCK_TASK = new PolicyDefinition<>(
new NoArgsPolicyKey(DevicePolicyIdentifiers.LOCK_TASK_POLICY), new NoArgsPolicyKey(DevicePolicyIdentifiers.LOCK_TASK_POLICY),
new TopPriority<>(List.of( new TopPriority<>(List.of(
// TODO(b/258166155): add correct device lock role name EnforcingAdmin.getRoleAuthorityOf(DEVICE_LOCK_CONTROLLER_ROLE),
EnforcingAdmin.getRoleAuthorityOf(
"android.app.role.SYSTEM_FINANCED_DEVICE_CONTROLLER"),
EnforcingAdmin.DPC_AUTHORITY)), EnforcingAdmin.DPC_AUTHORITY)),
POLICY_FLAG_LOCAL_ONLY_POLICY, POLICY_FLAG_LOCAL_ONLY_POLICY,
(LockTaskPolicy value, Context context, Integer userId, PolicyKey policyKey) -> (LockTaskPolicy value, Context context, Integer userId, PolicyKey policyKey) ->
@@ -157,9 +157,7 @@ final class PolicyDefinition<V> {
new IntentFilterPolicyKey( new IntentFilterPolicyKey(
DevicePolicyIdentifiers.PERSISTENT_PREFERRED_ACTIVITY_POLICY), DevicePolicyIdentifiers.PERSISTENT_PREFERRED_ACTIVITY_POLICY),
new TopPriority<>(List.of( new TopPriority<>(List.of(
// TODO(b/258166155): add correct device lock role name EnforcingAdmin.getRoleAuthorityOf(DEVICE_LOCK_CONTROLLER_ROLE),
EnforcingAdmin.getRoleAuthorityOf(
"android.app.role.SYSTEM_FINANCED_DEVICE_CONTROLLER"),
EnforcingAdmin.DPC_AUTHORITY)), EnforcingAdmin.DPC_AUTHORITY)),
POLICY_FLAG_LOCAL_ONLY_POLICY, POLICY_FLAG_LOCAL_ONLY_POLICY,
PolicyEnforcerCallbacks::addPersistentPreferredActivity, PolicyEnforcerCallbacks::addPersistentPreferredActivity,