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

Commit ce2425c3 authored by Zoltan Szatmary-Ban's avatar Zoltan Szatmary-Ban Committed by Android (Google) Code Review
Browse files

Merge "Add isActiveAdminWithPolicy to DevicePolicyManagerInternal"

parents 51914e7e 1181ed8a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -60,4 +60,13 @@ public abstract class DevicePolicyManagerInternal {
     */
    public abstract void addOnCrossProfileWidgetProvidersChangeListener(
            OnCrossProfileWidgetProvidersChangeListener listener);

    /**
     * Checks if an app with given uid is an active device admin of its user and has the policy
     * specified.
     * @param uid App uid.
     * @param reqPolicy Required policy, for policies see {@link DevicePolicyManager}.
     * @return true if the uid is an active admin with the given policy.
     */
    public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);
}
+65 −42
Original line number Diff line number Diff line
@@ -1140,70 +1140,85 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
            throws SecurityException {
        final int callingUid = Binder.getCallingUid();
        final int userHandle = UserHandle.getUserId(callingUid);
        final DevicePolicyData policy = getUserData(userHandle);

        List<ActiveAdmin> candidates = new ArrayList<ActiveAdmin>();
        ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid);
        if (result != null) {
            return result;
        }

        if (who != null) {
            final int userId = UserHandle.getUserId(callingUid);
            final DevicePolicyData policy = getUserData(userId);
            ActiveAdmin admin = policy.mAdminMap.get(who);
            if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
                throw new SecurityException("Admin " + admin.info.getComponent()
                         + " does not own the device");
            }
            if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
                throw new SecurityException("Admin " + admin.info.getComponent()
                        + " does not own the profile");
            }
            throw new SecurityException("Admin " + admin.info.getComponent()
                    + " did not specify uses-policy for: "
                    + admin.info.getTagForPolicy(reqPolicy));
        } else {
            throw new SecurityException("No active admin owned by uid "
                    + Binder.getCallingUid() + " for policy #" + reqPolicy);
        }
    }

        // Build a list of admins for this uid matching the given ComponentName
    private ActiveAdmin getActiveAdminWithPolicyForUidLocked(ComponentName who, int reqPolicy,
            int uid) {
        // Try to find an admin which can use reqPolicy
        final int userId = UserHandle.getUserId(uid);
        final DevicePolicyData policy = getUserData(userId);
        if (who != null) {
            ActiveAdmin admin = policy.mAdminMap.get(who);
            if (admin == null) {
                throw new SecurityException("No active admin " + who);
            }
            if (admin.getUid() != callingUid) {
            if (admin.getUid() != uid) {
                throw new SecurityException("Admin " + who + " is not owned by uid "
                        + Binder.getCallingUid());
            }
            candidates.add(admin);
            if (isActiveAdminWithPolicyForUserLocked(admin, reqPolicy, userId)) {
                return admin;
            }
        } else {
            for (ActiveAdmin admin : policy.mAdminList) {
                if (admin.getUid() == callingUid) {
                    candidates.add(admin);
                if (admin.getUid() == uid && isActiveAdminWithPolicyForUserLocked(admin, reqPolicy,
                        userId)) {
                    return admin;
                }
            }
        }

        // Try to find an admin which can use reqPolicy
        for (ActiveAdmin admin : candidates) {
        return null;
    }

    private boolean isActiveAdminWithPolicyForUserLocked(ActiveAdmin admin, int reqPolicy,
            int userId) {
        boolean ownsDevice = isDeviceOwner(admin.info.getPackageName());
            boolean ownsProfile = (getProfileOwner(userHandle) != null
                    && getProfileOwner(userHandle).getPackageName()
        boolean ownsProfile = (getProfileOwner(userId) != null
                && getProfileOwner(userId).getPackageName()
                    .equals(admin.info.getPackageName()));
        boolean ownsInitialization = isDeviceInitializer(admin.info.getPackageName())
                    && !hasUserSetupCompleted(userHandle);
                && !hasUserSetupCompleted(userId);

        if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
                if (ownsDevice || (userHandle == UserHandle.USER_OWNER && ownsInitialization)) {
                    return admin;
            if (ownsDevice || (userId == UserHandle.USER_OWNER && ownsInitialization)) {
                return true;
            }
        } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
            if (ownsDevice || ownsProfile || ownsInitialization) {
                    return admin;
                return true;
            }
        } else {
            if (admin.info.usesPolicy(reqPolicy)) {
                    return admin;
                }
            }
        }

        if (who != null) {
            if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) {
                throw new SecurityException("Admin " + candidates.get(0).info.getComponent()
                         + " does not own the device");
            }
            if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) {
                throw new SecurityException("Admin " + candidates.get(0).info.getComponent()
                        + " does not own the profile");
                return true;
            }
            throw new SecurityException("Admin " + candidates.get(0).info.getComponent()
                    + " did not specify uses-policy for: "
                    + candidates.get(0).info.getTagForPolicy(reqPolicy));
        } else {
            throw new SecurityException("No active admin owned by uid "
                    + Binder.getCallingUid() + " for policy #" + reqPolicy);
        }
        return false;
    }

    void sendAdminCommandLocked(ActiveAdmin admin, String action) {
@@ -5702,6 +5717,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
        }

        @Override
        public boolean isActiveAdminWithPolicy(int uid, int reqPolicy) {
            final int userId = UserHandle.getUserId(uid);
            synchronized(DevicePolicyManagerService.this) {
                return getActiveAdminWithPolicyForUidLocked(null, reqPolicy, uid) != null;
            }
        }

        private void notifyCrossProfileProvidersChanged(int userId, List<String> packages) {
            final List<OnCrossProfileWidgetProvidersChangeListener> listeners;
            synchronized (DevicePolicyManagerService.this) {