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

Commit 1be7bd6a authored by Kholoud Mohamed's avatar Kholoud Mohamed
Browse files

Resolve policies that could be set locally and globally

Also added userControlDisabledPackages policy

Bug: 258442697
Bug: 232918480
Test: atest android.devicepolicy.cts.UserControlDisabledPackagesTest
Change-Id: I4ce87c0351f5b76ac77ba0ec556a9b4dbf6b0ac1
parent 6356f9de
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8160,6 +8160,7 @@ package android.app.admin {
    field @NonNull public static final android.app.admin.TargetUser GLOBAL;
    field @NonNull public static final android.app.admin.TargetUser LOCAL_USER;
    field @NonNull public static final android.app.admin.TargetUser PARENT_USER;
    field @NonNull public static final android.app.admin.TargetUser UNKNOWN_USER;
  }
  public final class UnsafeStateException extends java.lang.IllegalStateException implements android.os.Parcelable {
+6 −0
Original line number Diff line number Diff line
@@ -3996,6 +3996,12 @@ public class DevicePolicyManager {
     */
    public static final String LOCK_TASK_POLICY = "lockTask";
    // TODO: Expose this as SystemAPI once we add the query API
    /**
     * @hide
     */
    public static final String USER_CONTROL_DISABLED_PACKAGES = "userControlDisabledPackages";
    /**
     * This object is a single place to tack on invalidation and disable calls.  All
     * binder caches in this class derive from this Config, so all can be invalidated or
+14 −0
Original line number Diff line number Diff line
@@ -43,6 +43,11 @@ public final class TargetUser {
     */
    public static final int GLOBAL_USER_ID = -3;

    /**
     * @hide
     */
    public static final int UNKNOWN_USER_ID = -3;

    /**
     * Indicates that the policy relates to the user the admin is installed on.
     */
@@ -61,6 +66,15 @@ public final class TargetUser {
    @NonNull
    public static final TargetUser GLOBAL = new TargetUser(GLOBAL_USER_ID);

    /**
     * Indicates that the policy relates to some unknown user on the device. For example, if Admin1
     * has set a global policy on a device and Admin2 has set a conflicting local
     * policy on some other secondary user, Admin1 will get a policy update callback with
     * {@code UNKNOWN_USER} as the target user.
     */
    @NonNull
    public static final TargetUser UNKNOWN_USER = new TargetUser(UNKNOWN_USER_ID);

    private final int mUserId;

    /**
+278 −103

File changed.

Preview size limit exceeded, changes collapsed.

+86 −21
Original line number Diff line number Diff line
@@ -3300,7 +3300,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        List<String> protectedPackages = (owner == null || owner.protectedPackages == null)
                ? Collections.emptyList() : owner.protectedPackages;
                ? null : owner.protectedPackages;
        mInjector.binderWithCleanCallingIdentity(() ->
                mInjector.getPackageManagerInternal().setOwnerProtectedPackages(
                        targetUserId, protectedPackages));
@@ -12644,9 +12644,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                        admin,
                        caller.getUserId());
            } else {
                LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicy(
                LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicySetByAdmin(
                        PolicyDefinition.LOCK_TASK,
                        caller.getUserId()).getPoliciesSetByAdmins().get(admin);
                        admin,
                        caller.getUserId());
                LockTaskPolicy policy;
                if (currentPolicy == null) {
                    policy = new LockTaskPolicy(Set.of(packages));
@@ -12689,8 +12690,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        if (isCoexistenceEnabled(caller)) {
            LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK, userHandle).getCurrentResolvedPolicy();
            LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
                    PolicyDefinition.LOCK_TASK, userHandle);
            if (policy == null) {
                return new String[0];
            } else {
@@ -12719,8 +12720,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        // TODO(b/260560985): This is not the right check, as the flag could be enabled but there
        //  could be an admin that hasn't targeted U.
        if (isCoexistenceFlagEnabled()) {
            LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK, userId).getCurrentResolvedPolicy();
            LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
                    PolicyDefinition.LOCK_TASK, userId);
            if (policy == null) {
                return false;
            }
@@ -12754,9 +12755,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        if (isCoexistenceEnabled(caller)) {
            EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(who, userHandle);
            LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicy(
            LockTaskPolicy currentPolicy = mDevicePolicyEngine.getLocalPolicySetByAdmin(
                    PolicyDefinition.LOCK_TASK,
                    caller.getUserId()).getPoliciesSetByAdmins().get(admin);
                    admin,
                    caller.getUserId());
            if (currentPolicy == null) {
                throw new IllegalArgumentException("Can't set a lock task flags without setting "
                        + "lock task packages first.");
@@ -12793,8 +12795,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        if (isCoexistenceEnabled(caller)) {
            LockTaskPolicy policy = mDevicePolicyEngine.getLocalPolicy(
                    PolicyDefinition.LOCK_TASK, userHandle).getCurrentResolvedPolicy();
            LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy(
                    PolicyDefinition.LOCK_TASK, userHandle);
            if (policy == null) {
                // We default on the power button menu, in order to be consistent with pre-P
                // behaviour.
@@ -17672,6 +17674,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        checkCanExecuteOrThrowUnsafe(
                DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES);
        if (isCoexistenceEnabled(caller)) {
            if (packages.isEmpty()) {
                removeUserControlDisabledPackages(caller);
            } else {
                addUserControlDisabledPackages(caller, new HashSet<>(packages));
            }
        } else {
            synchronized (getLockObject()) {
                ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId());
                if (!Objects.equals(owner.protectedPackages, packages)) {
@@ -17680,6 +17689,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    pushUserControlDisabledPackagesLocked(caller.getUserId());
                }
            }
        }
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES)
@@ -17688,6 +17698,52 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                .write();
    }
    private void addUserControlDisabledPackages(CallerIdentity caller, Set<String> packages) {
        if (isCallerDeviceOwner(caller)) {
            mDevicePolicyEngine.setGlobalPolicy(
                    PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
                    // TODO(b/260573124): add correct enforcing admin when permission changes are
                    //  merged.
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(
                            caller.getComponentName(), caller.getUserId()),
                    packages);
        } else {
            mDevicePolicyEngine.setLocalPolicy(
                    PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
                    // TODO(b/260573124): add correct enforcing admin when permission changes are
                    //  merged.
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(
                            caller.getComponentName(), caller.getUserId()),
                    packages,
                    caller.getUserId());
        }
    }
    private void removeUserControlDisabledPackages(CallerIdentity caller) {
        if (isCallerDeviceOwner(caller)) {
            mDevicePolicyEngine.removeGlobalPolicy(
                    PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
                    // TODO(b/260573124): add correct enforcing admin when permission changes are
                    //  merged.
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(
                            caller.getComponentName(), caller.getUserId()));
        } else {
            mDevicePolicyEngine.removeLocalPolicy(
                    PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
                    // TODO(b/260573124): add correct enforcing admin when permission changes are
                    //  merged.
                    EnforcingAdmin.createEnterpriseEnforcingAdmin(
                            caller.getComponentName(), caller.getUserId()),
                    caller.getUserId());
        }
    }
    private boolean isCallerDeviceOwner(CallerIdentity caller) {
        synchronized (getLockObject()) {
            return getDeviceOwnerUserIdUncheckedLocked() == caller.getUserId();
        }
    }
    @Override
    public List<String> getUserControlDisabledPackages(ComponentName who) {
        Objects.requireNonNull(who, "ComponentName is null");
@@ -17696,12 +17752,21 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller)
                || isFinancedDeviceOwner(caller));
        if (isCoexistenceEnabled(caller)) {
            // This retrieves the policy for the calling user only, DOs for example can't know
            // what's enforced globally or on another user.
            Set<String> packages = mDevicePolicyEngine.getResolvedPolicy(
                    PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
                    caller.getUserId());
            return packages == null ? Collections.emptyList() : packages.stream().toList();
        } else {
            synchronized (getLockObject()) {
                ActiveAdmin deviceOwner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId());
                return deviceOwner.protectedPackages != null
                        ? deviceOwner.protectedPackages : Collections.emptyList();
            }
        }
    }
    @Override
    public void setCommonCriteriaModeEnabled(ComponentName who, boolean enabled) {
Loading