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

Commit 9b967997 authored by Yvonne Jiang's avatar Yvonne Jiang
Browse files

Add DPMI methods for setting and clearing local restrictions from a

system entity EnforcingAdmin.

Also update existing method for clearing a Role-based EnforcingAdmin's
policies to take a list of admin packages instead of just 1.

Bug: 383624414
Flag: android.app.supervision.flags.supervision_manager_apis
Test: atest SupervisionServiceTest
Change-Id: I3daf12ee9eaebd28b187a6ff03b7134127010f34
parent 9a77cf21
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -330,11 +330,13 @@ public abstract class DevicePolicyManagerInternal {
    public abstract List<Bundle> getApplicationRestrictionsPerAdminForUser(
            String packageName, @UserIdInt int userId);

    /**
     *  Returns a list of users who set a user restriction on a given user.
     */
    public abstract List<EnforcingUser> getUserRestrictionSources(String restriction,
                @UserIdInt int userId);
    /** Returns a list of users who set a user restriction on a given user. */
    public abstract List<EnforcingUser> getUserRestrictionSources(
            String restriction, @UserIdInt int userId);

    /** Sets a user restriction on a given user. */
    public abstract void setUserRestrictionForUser(
            @NonNull String systemEntity, String key, boolean enabled, @UserIdInt int targetUser);

    /**
     * Enforces resolved security logging policy, should only be invoked from device policy engine.
@@ -352,9 +354,14 @@ public abstract class DevicePolicyManagerInternal {
    public abstract void setInternalEventsCallback(
            @Nullable Consumer<List<SecurityLog.SecurityEvent>> callback);

    /** Removes all policies associated with admins with the given `packageNames` and `userId`. */
    public abstract void removePoliciesForAdmins(
            @UserIdInt int userId, @NonNull List<String> packageNames);

    /**
     * Removes all policies associated with admins with `packageName` and `userId`.
     * Removes all local policies for the given `userId` associated with admins with the given
     * `systemEntities` authorities.
     */
    public abstract void removePoliciesForAdmins(
            @NonNull String packageName, @UserIdInt int userId);
    public abstract void removeLocalPoliciesForSystemEntities(
            @UserIdInt int userId, @NonNull List<String> systemEntities);
}
+38 −19
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;

/**
 * Class responsible for setting, resolving, and enforcing policies set by multiple management
@@ -2075,33 +2076,51 @@ final class DevicePolicyEngine {
    }

    /**
     * Removes all local and global policies set by enforcing admins with
     * `packageName` and `userId`.
     * Removes all local and global policies set by enforcing admins with a package `packageNames`
     * and `userId`.
     */
    void removePoliciesForAdmins(
            String packageName, @UserIdInt int userId) {
    void removePoliciesForAdmins(@UserIdInt int userId, List<String> packageNames) {
        synchronized (mLock) {
            Set<PolicyKey> globalPolicies = new HashSet<>(mGlobalPolicies.keySet());
            for (PolicyKey policy : globalPolicies) {
                PolicyState<?> policyState = mGlobalPolicies.get(policy);
            for (PolicyState<?> policyState : mGlobalPolicies.values()) {
                for (EnforcingAdmin admin : policyState.getPoliciesSetByAdmins().keySet()) {
                    if (admin.getPackageName().equals(packageName) &&
                            admin.getUserId() == userId) {
                    if (packageNames.contains(admin.getPackageName())
                            && admin.getUserId() == userId) {
                        removeGlobalPolicy(policyState.getPolicyDefinition(), admin);
                    }
                }
            }

            removeLocalPoliciesForAdminsLocked(
                    userId,
                    admin ->
                            packageNames.contains(admin.getPackageName())
                                    && admin.getUserId() == userId);
        }
    }

    /**
     * Removes all local policies set by enforcing admins with a system entity in `systemEntities`
     * for the given `userId`.
     */
    void removeLocalPoliciesForSystemEntities(@UserIdInt int userId, List<String> systemEntities) {
        synchronized (mLock) {
            removeLocalPoliciesForAdminsLocked(
                    userId, admin -> systemEntities.contains(admin.getSystemEntity()));
        }
    }

    /**
     * Removes all local policies set on the given `userId` by EnforcingAdmins matching the given
     * `adminPredicate`.
     */
    void removeLocalPoliciesForAdminsLocked(
            @UserIdInt int userId, Predicate<EnforcingAdmin> adminPredicate) {
        if (mLocalPolicies.containsKey(userId)) {
                Set<PolicyKey> localPolicies = new HashSet<>(mLocalPolicies.get(userId).keySet());
                for (PolicyKey policy : localPolicies) {
                    PolicyState<?> policyState = mLocalPolicies.get(userId).get(policy);
            for (PolicyState<?> policyState : mLocalPolicies.get(userId).values()) {
                for (EnforcingAdmin admin : policyState.getPoliciesSetByAdmins().keySet()) {
                        if (admin.getPackageName().equals(packageName) &&
                                admin.getUserId() == userId) {
                            removeLocalPolicy(
                                    policyState.getPolicyDefinition(), admin, userId);
                        }
                    if (adminPredicate.test(admin)) {
                        CompletableFuture<Integer> unused =
                                removeLocalPolicy(policyState.getPolicyDefinition(), admin, userId);
                    }
                }
            }
+18 −2
Original line number Diff line number Diff line
@@ -16462,6 +16462,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return enforcingUsers;
        }
        @Override
        public void setUserRestrictionForUser(
                @NonNull String systemEntity,
                String key,
                boolean enabled,
                @UserIdInt int targetUser) {
            DevicePolicyManagerService.this.setUserRestrictionForUser(
                    systemEntity, key, enabled, targetUser);
        }
        @Override
        public void enforceSecurityLoggingPolicy(boolean enabled) {
            Boolean auditLoggingEnabled = mDevicePolicyEngine.getResolvedPolicy(
@@ -16484,8 +16494,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        @Override
        public void removePoliciesForAdmins(
                @NonNull String packageName, @UserIdInt int userId) {
            mDevicePolicyEngine.removePoliciesForAdmins(packageName, userId);
                @UserIdInt int userId, @NonNull List<String> packageNames) {
            mDevicePolicyEngine.removePoliciesForAdmins(userId, packageNames);
        }
        @Override
        public void removeLocalPoliciesForSystemEntities(
                @UserIdInt int userId, @NonNull List<String> systemEntities) {
            mDevicePolicyEngine.removeLocalPoliciesForSystemEntities(userId, systemEntities);
        }
        private List<EnforcingUser> getEnforcingUsers(Set<EnforcingAdmin> admins) {
+5 −0
Original line number Diff line number Diff line
@@ -289,6 +289,11 @@ final class EnforcingAdmin {
        return mComponentName;
    }

    @Nullable
    String getSystemEntity() {
        return mSystemEntity;
    }

    @NonNull
    android.app.admin.EnforcingAdmin getParcelableAdmin() {
        Authority authority;
+10 −7
Original line number Diff line number Diff line
@@ -459,22 +459,25 @@ public class SupervisionService extends ISupervisionManager.Stub {
        enforcePermission(MANAGE_ROLE_HOLDERS);
        List<String> roles =  Arrays.asList(RoleManager.ROLE_SYSTEM_SUPERVISION,
                RoleManager.ROLE_SUPERVISION);
        List<String> supervisionPackages = new ArrayList<>();
        for (String role : roles) {
            List<String> supervisionPackages =
            List<String> supervisionPackagesPerRole =
                    mInjector.getRoleHoldersAsUser(role, UserHandle.of(userId));
            for (String supervisionPackage : supervisionPackages) {
                clearDevicePoliciesAndSuspendedPackagesFor(userId, supervisionPackage, role);
            }
            supervisionPackages.addAll(supervisionPackagesPerRole);
            // TODO(b/432705581): Consider adding a method that takes a list of packages to clear
            // suspension for, instead of calling for each package in a loop.
            for (String supervisionPackage : supervisionPackagesPerRole) {
                clearSuspendedPackagesFor(userId, supervisionPackage, role);
            }
        }

    private void clearDevicePoliciesAndSuspendedPackagesFor(int userId, String supervisionPackage,
            String roleName) {
        DevicePolicyManagerInternal dpmi = mInjector.getDpmInternal();
        if (dpmi != null) {
            dpmi.removePoliciesForAdmins(supervisionPackage, userId);
            dpmi.removePoliciesForAdmins(userId, supervisionPackages);
        }
    }

    private void clearSuspendedPackagesFor(int userId, String supervisionPackage, String roleName) {
        PackageManagerInternal pmi = mInjector.getPackageManagerInternal();
        if (pmi != null) {
            pmi.unsuspendForSuspendingPackage(supervisionPackage, userId, userId);
Loading