Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51dfc7d0 authored by Kholoud Mohamed's avatar Kholoud Mohamed Committed by Android (Google) Code Review
Browse files

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
parents 1b2eeb06 3da2cf7d
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -81,6 +81,10 @@ import java.util.Set;
final class 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 =
            DevicePolicyIdentifiers.getIdentifierForUserRestriction(
                    UserManager.DISALLOW_CELLULAR_2G);
@@ -1010,12 +1014,22 @@ final class DevicePolicyEngine {
    /**
     * 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) {
            return;
        }
        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);
        }
    }

    /**
     * Handles internal state related to a user getting removed.
@@ -1032,6 +1046,28 @@ final class DevicePolicyEngine {
        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) {
        if (!user.isProfile()) {
            return;
+188 −28
Original line number Diff line number Diff line
@@ -259,7 +259,6 @@ import android.Manifest.permission;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.annotation.IntDef;
@@ -1450,8 +1449,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    && (owner.getPackageName().equals(packageName))) {
                startOwnerService(userHandle, "package-broadcast");
            }
            if (isPermissionCheckFlagEnabled()) {
                mDevicePolicyEngine.handlePackageChanged(packageName, userHandle);
            if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) {
                mDevicePolicyEngine.handlePackageChanged(packageName, userHandle, removedAdmin);
            }
            // Persist updates if the removed package was an admin or delegate.
            if (removedAdmin || removedDelegate) {
@@ -12294,13 +12293,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
                        who, MANAGE_DEVICE_POLICY_INPUT_METHODS,
                        caller.getPackageName(), userId);
                if (packageList == null) {
                    mDevicePolicyEngine.removeLocalPolicy(
                            PolicyDefinition.PERMITTED_INPUT_METHODS,
                            admin,
                            userId);
                } else {
                    mDevicePolicyEngine.setLocalPolicy(
                            PolicyDefinition.PERMITTED_INPUT_METHODS,
                            admin,
                        packageList == null
                                ? null
                                : new StringSetPolicyValue(new HashSet<>(packageList)),
                            new StringSetPolicyValue(new HashSet<>(packageList)),
                            userId);
                }
            } else {
                ActiveAdmin admin = getParentOfAdminIfRequired(
                        getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()),
@@ -12337,14 +12341,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
        CallerIdentity caller;
        if (isPermissionCheckFlagEnabled()) {
        if (isPolicyEngineForFinanceFlagEnabled()) {
            caller = getCallerIdentity(who, callerPackageName);
        } else {
            caller = getCallerIdentity(who);
            Objects.requireNonNull(who, "ComponentName is null");
        }
        if (!isPermissionCheckFlagEnabled()) {
        if (!isPolicyEngineForFinanceFlagEnabled()) {
            if (calledOnParentInstance) {
                Preconditions.checkCallAuthorization(
                        isProfileOwnerOfOrganizationOwnedDevice(caller));
@@ -12742,7 +12746,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        final int userId = user.id;
        if (isPermissionCheckFlagEnabled()) {
        if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) {
            mDevicePolicyEngine.handleUserCreated(user);
        }
@@ -14268,7 +14272,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    resultSet.add(accountType);
                }
            }
        } else {
            caller = getCallerIdentity();
            Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
@@ -15153,6 +15156,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            for (ActiveAdmin admin : policy.mAdminList) {
                final boolean ownsDevice = isDeviceOwner(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 (isEnabled) {
                        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
@@ -22681,6 +22699,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        @Override
        public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
            mDevicePolicyEngine.handleRoleChanged(roleName, user.getIdentifier());
            if (RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
                handleDevicePolicyManagementRoleChange(user);
                return;
@@ -24065,6 +24084,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    private boolean hasNonTestOnlyActiveAdmins() {
        return mInjector.binderWithCleanCallingIdentity(() -> {
            for (UserInfo userInfo : mUserManager.getUsers()) {
                synchronized (getLockObject()) {
                    List<ComponentName> activeAdmins = getActiveAdmins(userInfo.id);
                    if (activeAdmins == null) {
                        continue;
@@ -24075,13 +24095,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                        }
                    }
                }
            }
            return false;
        });
    }
    private boolean shouldMigrateToDevicePolicyEngine() {
        return mInjector.binderWithCleanCallingIdentity(() ->
                isPermissionCheckFlagEnabled() && !mOwners.isMigratedToPolicyEngine());
                (isPermissionCheckFlagEnabled() || isPolicyEngineForFinanceFlagEnabled())
                        && !mOwners.isMigratedToPolicyEngine());
    }
    /**
@@ -24090,13 +24112,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    private boolean migratePoliciesToDevicePolicyEngine() {
        return mInjector.binderWithCleanCallingIdentity(() -> {
            try {
                Slogf.i(LOG_TAG, "Started device policies migration to the device policy engine.");
                synchronized (getLockObject()) {
                    Slogf.i(LOG_TAG,
                            "Started device policies migration to the device policy engine.");
                    if (isUnicornFlagEnabled()) {
                        migrateAutoTimezonePolicy();
                        migratePermissionGrantStatePolicies();
                // TODO(b/258811766): add migration logic for all policies
                    }
                    migrateScreenCapturePolicyLocked();
                    migratePermittedInputMethodsPolicyLocked();
                    migrateAccountManagementDisabledPolicyLocked();
                    migrateUserControlDisabledPackagesLocked();
                    mOwners.markMigrationToPolicyEngine();
                    return true;
                }
            } catch (Exception e) {
                mDevicePolicyEngine.clearAllPolicies();
                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) {
        return mInjector.binderWithCleanCallingIdentity(() ->
                mContext.getPackageManager().getInstalledPackagesAsUser(
+8 −17
Original line number Diff line number Diff line
@@ -93,22 +93,6 @@ final class EnforcingAdmin {
                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,
            ActiveAdmin activeAdmin) {
        Objects.requireNonNull(componentName);
@@ -190,12 +174,18 @@ final class EnforcingAdmin {
    }

    private Set<String> getAuthorities() {
        if (mAuthorities == null) {
        if (mAuthorities == null && mIsRoleAuthority) {
            mAuthorities = getRoleAuthoritiesOrDefault(mPackageName, mUserId);
        }
        return mAuthorities;
    }

    void reloadRoleAuthorities() {
        if (mIsRoleAuthority) {
            mAuthorities = getRoleAuthoritiesOrDefault(mPackageName, mUserId);
        }
    }

    boolean hasAuthority(String authority) {
        return getAuthorities().contains(authority);
    }
@@ -304,6 +294,7 @@ final class EnforcingAdmin {
        int userId = parser.getAttributeInt(/* namespace= */ null, ATTR_USER_ID);

        if (isRoleAuthority) {
            // TODO(b/281697976): load active admin
            return new EnforcingAdmin(packageName, userId, null);
        } else {
            String className = parser.getAttributeValue(/* namespace= */ null, ATTR_CLASS_NAME);
+4 −6
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.devicepolicy;

import static com.android.server.devicepolicy.DevicePolicyEngine.DEVICE_LOCK_CONTROLLER_ROLE;

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