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

Commit 42c4a925 authored by Rubin Xu's avatar Rubin Xu Committed by android-build-merger
Browse files

Merge "Fix deadlock in KeyguardDisableHandler" into qt-dev

am: 6cf5ea63

Change-Id: I0fe67a4ad6e6a2598123662de4f543735b78ceb9
parents 6b48f40c 6cf5ea63
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -43,6 +43,12 @@ public abstract class DevicePolicyCache {
     */
     */
    public abstract boolean getScreenCaptureDisabled(@UserIdInt int userHandle);
    public abstract boolean getScreenCaptureDisabled(@UserIdInt int userHandle);


    /**
     * Caches {@link DevicePolicyManager#getPasswordQuality(android.content.ComponentName)} of the
     * given user with {@code null} passed in as argument.
     */
    public abstract int getPasswordQuality(@UserIdInt int userHandle);

    /**
    /**
     * Empty implementation.
     * Empty implementation.
     */
     */
@@ -53,5 +59,10 @@ public abstract class DevicePolicyCache {
        public boolean getScreenCaptureDisabled(int userHandle) {
        public boolean getScreenCaptureDisabled(int userHandle) {
            return false;
            return false;
        }
        }

        @Override
        public int getPasswordQuality(int userHandle) {
            return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
        }
    }
    }
}
}
+2 −3
Original line number Original line Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;


import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Context;
import android.os.Handler;
import android.os.Handler;
@@ -125,9 +126,7 @@ class KeyguardDisableHandler {
        return new KeyguardDisableHandler(new Injector() {
        return new KeyguardDisableHandler(new Injector() {
            @Override
            @Override
            public boolean dpmRequiresPassword(int userId) {
            public boolean dpmRequiresPassword(int userId) {
                DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                return DevicePolicyCache.getInstance().getPasswordQuality(userId)
                        Context.DEVICE_POLICY_SERVICE);
                return dpm == null || dpm.getPasswordQuality(null, userId)
                        != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
                        != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
            }
            }


+31 −0
Original line number Original line Diff line number Diff line
@@ -15,11 +15,16 @@
 */
 */
package com.android.server.devicepolicy;
package com.android.server.devicepolicy;


import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
import android.util.SparseBooleanArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;


import java.io.PrintWriter;

/**
/**
 * Implementation of {@link DevicePolicyCache}, to which {@link DevicePolicyManagerService} pushes
 * Implementation of {@link DevicePolicyCache}, to which {@link DevicePolicyManagerService} pushes
 * policies.
 * policies.
@@ -36,9 +41,13 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private final SparseBooleanArray mScreenCaptureDisabled = new SparseBooleanArray();
    private final SparseBooleanArray mScreenCaptureDisabled = new SparseBooleanArray();


    @GuardedBy("mLock")
    private final SparseIntArray mPasswordQuality = new SparseIntArray();

    public void onUserRemoved(int userHandle) {
    public void onUserRemoved(int userHandle) {
        synchronized (mLock) {
        synchronized (mLock) {
            mScreenCaptureDisabled.delete(userHandle);
            mScreenCaptureDisabled.delete(userHandle);
            mPasswordQuality.delete(userHandle);
        }
        }
    }
    }


@@ -54,4 +63,26 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
            mScreenCaptureDisabled.put(userHandle, disabled);
            mScreenCaptureDisabled.put(userHandle, disabled);
        }
        }
    }
    }

    @Override
    public int getPasswordQuality(@UserIdInt int userHandle) {
        synchronized (mLock) {
            return mPasswordQuality.get(userHandle,
                    DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
        }
    }

    /** Updat the password quality cache for the given user */
    public void setPasswordQuality(int userHandle, int quality) {
        synchronized (mLock) {
            mPasswordQuality.put(userHandle, quality);
        }
    }

    /** Dump content */
    public void dump(String prefix, PrintWriter pw) {
        pw.println("Device policy cache");
        pw.println(prefix + "Screen capture disabled: " + mScreenCaptureDisabled.toString());
        pw.println(prefix + "Password quality: " + mPasswordQuality.toString());
    }
}
}
+54 −10
Original line number Original line Diff line number Diff line
@@ -2333,8 +2333,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                Slog.w(LOG_TAG, "Tried to remove device policy file for user 0! Ignoring.");
                Slog.w(LOG_TAG, "Tried to remove device policy file for user 0! Ignoring.");
                return;
                return;
            }
            }
            updatePasswordQualityCacheForUserGroup(userHandle);
            mPolicyCache.onUserRemoved(userHandle);
            mPolicyCache.onUserRemoved(userHandle);
            mOwners.removeProfileOwner(userHandle);
            mOwners.removeProfileOwner(userHandle);
            mOwners.writeProfileOwner(userHandle);
            mOwners.writeProfileOwner(userHandle);
@@ -3650,6 +3650,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        updateScreenCaptureDisabled(userId,
        updateScreenCaptureDisabled(userId,
                getScreenCaptureDisabled(null, userId));
                getScreenCaptureDisabled(null, userId));
        pushUserRestrictions(userId);
        pushUserRestrictions(userId);
        // When system user is started (device boot), load cache for all users.
        // This is to mitigate the potential race between loading the cache and keyguard
        // reading the value during user switch, due to onStartUser() being asynchronous.
        updatePasswordQualityCacheForUserGroup(
                userId == UserHandle.USER_SYSTEM ? UserHandle.USER_ALL : userId);
        startOwnerService(userId, "start-user");
        startOwnerService(userId, "start-user");
    }
    }
@@ -4135,13 +4140,19 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
            ActiveAdmin ap = getActiveAdminForCallerLocked(
            ActiveAdmin ap = getActiveAdminForCallerLocked(
                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
                    who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, parent);
            final long ident = mInjector.binderClearCallingIdentity();
            try {
                final PasswordMetrics metrics = ap.minimumPasswordMetrics;
                final PasswordMetrics metrics = ap.minimumPasswordMetrics;
                if (metrics.quality != quality) {
                if (metrics.quality != quality) {
                    metrics.quality = quality;
                    metrics.quality = quality;
                    updatePasswordValidityCheckpointLocked(userId, parent);
                    updatePasswordValidityCheckpointLocked(userId, parent);
                    updatePasswordQualityCacheForUserGroup(userId);
                    saveSettingsLocked(userId);
                    saveSettingsLocked(userId);
                }
                }
                maybeLogPasswordComplexitySet(who, userId, parent, metrics);
                maybeLogPasswordComplexitySet(who, userId, parent, metrics);
            } finally {
                mInjector.binderRestoreCallingIdentity(ident);
            }
        }
        }
        DevicePolicyEventLogger
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_PASSWORD_QUALITY)
                .createEvent(DevicePolicyEnums.SET_PASSWORD_QUALITY)
@@ -4173,6 +4184,32 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        saveSettingsLocked(credentialOwner);
        saveSettingsLocked(credentialOwner);
    }
    }
    /**
     * Update password quality values in policy cache for all users in the same user group as
     * the given user. The cached password quality for user X is the aggregated quality among all
     * admins who have influence of user X's screenlock, i.e. it's equivalent to the return value of
     * getPasswordQuality(null, user X, false).
     *
     * Caches for all users in the same user group often need to be updated alltogether because a
     * user's admin policy can affect another's aggregated password quality in some situation.
     * For example a managed profile's policy will affect the parent user if the profile has unified
     * challenge. A profile can also explicitly set a parent password quality which will affect the
     * aggregated password quality of the parent user.
     */
    private void updatePasswordQualityCacheForUserGroup(@UserIdInt int userId) {
        final List<UserInfo> users;
        if (userId == UserHandle.USER_ALL) {
            users = mUserManager.getUsers();
        } else {
            users = mUserManager.getProfiles(userId);
        }
        for (UserInfo userInfo : users) {
            final int currentUserId = userInfo.id;
            mPolicyCache.setPasswordQuality(currentUserId,
                    getPasswordQuality(null, currentUserId, false));
        }
    }
    @Override
    @Override
    public int getPasswordQuality(ComponentName who, int userHandle, boolean parent) {
    public int getPasswordQuality(ComponentName who, int userHandle, boolean parent) {
        if (!mHasFeature) {
        if (!mHasFeature) {
@@ -8849,6 +8886,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            mStatLogger.dump(pw, "  ");
            mStatLogger.dump(pw, "  ");
            pw.println();
            pw.println();
            pw.println("  Encryption Status: " + getEncryptionStatusName(getEncryptionStatus()));
            pw.println("  Encryption Status: " + getEncryptionStatusName(getEncryptionStatus()));
            pw.println();
            mPolicyCache.dump("  ", pw);
        }
        }
    }
    }
@@ -11319,8 +11358,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        @Override
        @Override
        public void reportSeparateProfileChallengeChanged(@UserIdInt int userId) {
        public void reportSeparateProfileChallengeChanged(@UserIdInt int userId) {
            final long ident = mInjector.binderClearCallingIdentity();
            try {
                synchronized (getLockObject()) {
                synchronized (getLockObject()) {
                    updateMaximumTimeToLockLocked(userId);
                    updateMaximumTimeToLockLocked(userId);
                    updatePasswordQualityCacheForUserGroup(userId);
                }
            } finally {
                mInjector.binderRestoreCallingIdentity(ident);
            }
            }
            DevicePolicyEventLogger
            DevicePolicyEventLogger
                    .createEvent(DevicePolicyEnums.SEPARATE_PROFILE_CHALLENGE_CHANGED)
                    .createEvent(DevicePolicyEnums.SEPARATE_PROFILE_CHALLENGE_CHANGED)
@@ -11336,7 +11381,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        @Override
        @Override
        public CharSequence getPrintingDisabledReasonForUser(@UserIdInt int userId) {
        public CharSequence getPrintingDisabledReasonForUser(@UserIdInt int userId) {
            synchronized (getLockObject()) {
            synchronized (getLockObject()) {
                DevicePolicyData policy = getUserData(userId);
                if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
                if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_PRINTING,
                        UserHandle.of(userId))) {
                        UserHandle.of(userId))) {
                    Log.e(LOG_TAG, "printing is enabled");
                    Log.e(LOG_TAG, "printing is enabled");