Merge "Fix deadlock in KeyguardDisableHandler" into qt-dev
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 PasswordMetrics metrics = ap.minimumPasswordMetrics;
|
final long ident = mInjector.binderClearCallingIdentity();
|
||||||
if (metrics.quality != quality) {
|
try {
|
||||||
metrics.quality = quality;
|
final PasswordMetrics metrics = ap.minimumPasswordMetrics;
|
||||||
updatePasswordValidityCheckpointLocked(userId, parent);
|
if (metrics.quality != quality) {
|
||||||
saveSettingsLocked(userId);
|
metrics.quality = quality;
|
||||||
|
updatePasswordValidityCheckpointLocked(userId, parent);
|
||||||
|
updatePasswordQualityCacheForUserGroup(userId);
|
||||||
|
saveSettingsLocked(userId);
|
||||||
|
}
|
||||||
|
maybeLogPasswordComplexitySet(who, userId, parent, metrics);
|
||||||
|
} finally {
|
||||||
|
mInjector.binderRestoreCallingIdentity(ident);
|
||||||
}
|
}
|
||||||
maybeLogPasswordComplexitySet(who, userId, parent, metrics);
|
|
||||||
}
|
}
|
||||||
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) {
|
||||||
synchronized (getLockObject()) {
|
final long ident = mInjector.binderClearCallingIdentity();
|
||||||
updateMaximumTimeToLockLocked(userId);
|
try {
|
||||||
|
synchronized (getLockObject()) {
|
||||||
|
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");
|
||||||
|
|||||||
Reference in New Issue
Block a user