Loading core/java/android/app/admin/DevicePolicyManager.java +15 −1 Original line number Diff line number Diff line Loading @@ -2304,7 +2304,7 @@ public class DevicePolicyManager { * Determine whether the current password the user has set is sufficient to meet the policy * requirements (e.g. quality, minimum length) that have been requested by the admins of this * user and its participating profiles. Restrictions on profiles that have a separate challenge * are not taken into account. * are not taken into account. The user must be unlocked in order to perform the check. * <p> * The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has Loading @@ -2317,6 +2317,7 @@ public class DevicePolicyManager { * @return Returns true if the password meets the current requirements, else false. * @throws SecurityException if the calling application does not own an active administrator * that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws InvalidStateException if the user is not unlocked. */ public boolean isActivePasswordSufficient() { if (mService != null) { Loading Loading @@ -3824,6 +3825,19 @@ public class DevicePolicyManager { } } /** * @hide */ public void reportPasswordChanged(@UserIdInt int userId) { if (mService != null) { try { mService.reportPasswordChanged(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * @hide */ Loading core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ interface IDevicePolicyManager { boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle); void setActivePasswordState(in PasswordMetrics metrics, int userHandle); void reportPasswordChanged(int userId); void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); void reportFailedFingerprintAttempt(int userHandle); Loading core/java/com/android/internal/widget/LockPatternUtils.java +3 −18 Original line number Diff line number Diff line Loading @@ -590,8 +590,6 @@ public class LockPatternUtils { setCredentialRequiredToDecrypt(false); } getDevicePolicyManager().setActivePasswordState(new PasswordMetrics(), userHandle); onAfterChangingPassword(userHandle); } Loading Loading @@ -644,6 +642,7 @@ public class LockPatternUtils { + MIN_LOCK_PATTERN_SIZE + " dots long."); } setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); getLockSettings().setLockPattern(patternToString(pattern), savedPattern, userId); DevicePolicyManager dpm = getDevicePolicyManager(); Loading @@ -659,10 +658,6 @@ public class LockPatternUtils { } setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId); setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); dpm.setActivePasswordState(new PasswordMetrics( DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size()), userId); onAfterChangingPassword(userId); } catch (RemoteException re) { Log.e(TAG, "Couldn't save lock pattern " + re); Loading Loading @@ -775,10 +770,9 @@ public class LockPatternUtils { + "of length " + MIN_LOCK_PASSWORD_SIZE); } final int computedQuality = PasswordMetrics.computeForPassword(password).quality; setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); getLockSettings().setLockPassword(password, savedPassword, userHandle); getLockSettings().setSeparateProfileChallengeEnabled(userHandle, true, null); final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); final int computedQuality = metrics.quality; // Update the device encryption password. if (userHandle == UserHandle.USER_SYSTEM Loading @@ -796,15 +790,6 @@ public class LockPatternUtils { } } setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { metrics.quality = Math.max(quality, metrics.quality); dpm.setActivePasswordState(metrics, userHandle); } else { // The password is not anything. dpm.setActivePasswordState(new PasswordMetrics(), userHandle); } // Add the password to the password history. We assume all // password hashes have the same length for simplicity of implementation. String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle); Loading services/core/java/com/android/server/LockSettingsService.java +38 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.server; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.backup.BackupManager; import android.app.trust.IStrongAuthTracker; import android.app.trust.TrustManager; Loading Loading @@ -931,6 +933,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSeparateChallengeLock) { setLockPatternInternal(pattern, savedCredential, userId); setSeparateProfileChallengeEnabled(userId, true, null); notifyPasswordChanged(userId); } } Loading @@ -945,6 +948,7 @@ public class LockSettingsService extends ILockSettings.Stub { setKeystorePassword(null, userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); notifyActivePasswordMetricsAvailable(null, userId); return; } Loading Loading @@ -994,6 +998,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSeparateChallengeLock) { setLockPasswordInternal(password, savedCredential, userId); setSeparateProfileChallengeEnabled(userId, true, null); notifyPasswordChanged(userId); } } Loading @@ -1007,6 +1012,7 @@ public class LockSettingsService extends ILockSettings.Stub { setKeystorePassword(null, userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); notifyActivePasswordMetricsAvailable(null, userId); return; } Loading Loading @@ -1420,6 +1426,7 @@ public class LockSettingsService extends ILockSettings.Stub { // migrate credential to GateKeeper credentialUtil.setCredential(credential, null, userId); if (!hasChallenge) { notifyActivePasswordMetricsAvailable(credential, userId); return VerifyCredentialResponse.OK; } // Fall through to get the auth token. Technically this should never happen, Loading Loading @@ -1459,6 +1466,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (progressCallback != null) { progressCallback.onCredentialVerified(); } notifyActivePasswordMetricsAvailable(credential, userId); unlockKeystore(credential, userId); Slog.i(TAG, "Unlocking user " + userId + Loading @@ -1482,6 +1490,36 @@ public class LockSettingsService extends ILockSettings.Stub { return response; } private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) { final PasswordMetrics metrics; if (password == null) { metrics = new PasswordMetrics(); } else { metrics = PasswordMetrics.computeForPassword(password); metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId); } // Asynchronous to avoid dead lock mHandler.post(() -> { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.setActivePasswordState(metrics, userId); }); } /** * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before * reporting the password changed. */ private void notifyPasswordChanged(@UserIdInt int userId) { // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering mHandler.post(() -> { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.reportPasswordChanged(userId); }); } @Override public boolean checkVoldPassword(int userId) throws RemoteException { if (!mFirstCallToVold) { Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +47 −53 Original line number Diff line number Diff line Loading @@ -253,7 +253,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED = "device-provisioning-config-applied"; private static final String ATTR_DEVICE_PAIRED = "device-paired"; private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer"; private static final String ATTR_APPLICATION_RESTRICTIONS_MANAGER = "application-restrictions-manager"; Loading Loading @@ -2342,20 +2341,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, "failed-password-attempts"); } final PasswordMetrics metrics = policy.mActivePasswordMetrics; if (!metrics.isDefault()) { out.startTag(null, "active-password"); out.attribute(null, "quality", Integer.toString(metrics.quality)); out.attribute(null, "length", Integer.toString(metrics.length)); out.attribute(null, "uppercase", Integer.toString(metrics.upperCase)); out.attribute(null, "lowercase", Integer.toString(metrics.lowerCase)); out.attribute(null, "letters", Integer.toString(metrics.letters)); out.attribute(null, "numeric", Integer.toString(metrics.numeric)); out.attribute(null, "symbols", Integer.toString(metrics.symbols)); out.attribute(null, "nonletter", Integer.toString(metrics.nonLetter)); out.endTag(null, "active-password"); } for (int i = 0; i < policy.mAcceptedCaCertificates.size(); i++) { out.startTag(null, TAG_ACCEPTED_CA_CERTIFICATES); out.attribute(null, ATTR_NAME, policy.mAcceptedCaCertificates.valueAt(i)); Loading Loading @@ -2456,6 +2441,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { JournaledFile journal = makeJournaledFile(userHandle); FileInputStream stream = null; File file = journal.chooseForRead(); boolean needsRewrite = false; try { stream = new FileInputStream(file); XmlPullParser parser = Xml.newPullParser(); Loading Loading @@ -2542,16 +2528,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if ("password-owner".equals(tag)) { policy.mPasswordOwner = Integer.parseInt( parser.getAttributeValue(null, "value")); } else if ("active-password".equals(tag)) { final PasswordMetrics m = policy.mActivePasswordMetrics; m.quality = Integer.parseInt(parser.getAttributeValue(null, "quality")); m.length = Integer.parseInt(parser.getAttributeValue(null, "length")); m.upperCase = Integer.parseInt(parser.getAttributeValue(null, "uppercase")); m.lowerCase = Integer.parseInt(parser.getAttributeValue(null, "lowercase")); m.letters = Integer.parseInt(parser.getAttributeValue(null, "letters")); m.numeric = Integer.parseInt(parser.getAttributeValue(null, "numeric")); m.symbols = Integer.parseInt(parser.getAttributeValue(null, "symbols")); m.nonLetter = Integer.parseInt(parser.getAttributeValue(null, "nonletter")); } else if (TAG_ACCEPTED_CA_CERTIFICATES.equals(tag)) { policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME)); } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) { Loading @@ -2577,6 +2553,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending); } else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) { policy.mInitBundle = PersistableBundle.restoreFromXml(parser); } else if ("active-password".equals(tag)) { needsRewrite = true; } else { Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); Loading @@ -2596,27 +2574,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Ignore } // Might need to upgrade the file by rewriting it if (needsRewrite) { saveSettingsLocked(userHandle); } // Generate a list of admins from the admin map policy.mAdminList.addAll(policy.mAdminMap.values()); // Validate that what we stored for the password quality matches // sufficiently what is currently set. Note that this is only // a sanity check in case the two get out of sync; this should // never normally happen. final long identity = mInjector.binderClearCallingIdentity(); try { int actualPasswordQuality = mLockPatternUtils.getActivePasswordQuality(userHandle); if (actualPasswordQuality < policy.mActivePasswordMetrics.quality) { Slog.w(LOG_TAG, "Active password quality 0x" + Integer.toHexString(policy.mActivePasswordMetrics.quality) + " does not match actual quality 0x" + Integer.toHexString(actualPasswordQuality)); policy.mActivePasswordMetrics = new PasswordMetrics(); } } finally { mInjector.binderRestoreCallingIdentity(identity); } validatePasswordOwnerLocked(policy); updateMaximumTimeToLockLocked(userHandle); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle); Loading Loading @@ -3850,6 +3815,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private boolean isActivePasswordSufficientForUserLocked( DevicePolicyData policy, int userHandle, boolean parent) { enforceUserUnlocked(userHandle, parent); final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent); if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) { return false; Loading Loading @@ -4924,33 +4891,52 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } enforceFullCrossUsersPermission(userHandle); mContext.enforceCallingOrSelfPermission( android.Manifest.permission.BIND_DEVICE_ADMIN, null); // If the managed profile doesn't have a separate password, set the metrics to default if (isManagedProfile(userHandle) && !isSeparateProfileChallengeEnabled(userHandle)) { metrics = new PasswordMetrics(); } validateQualityConstant(metrics.quality); DevicePolicyData policy = getUserData(userHandle); synchronized (this) { policy.mActivePasswordMetrics = metrics; } } @Override public void reportPasswordChanged(@UserIdInt int userId) { if (!mHasFeature) { return; } enforceFullCrossUsersPermission(userId); // Managed Profile password can only be changed when it has a separate challenge. if (!isSeparateProfileChallengeEnabled(userHandle)) { enforceNotManagedProfile(userHandle, "set the active password"); if (!isSeparateProfileChallengeEnabled(userId)) { enforceNotManagedProfile(userId, "set the active password"); } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.BIND_DEVICE_ADMIN, null); validateQualityConstant(metrics.quality); DevicePolicyData policy = getUserData(userHandle); DevicePolicyData policy = getUserData(userId); long ident = mInjector.binderClearCallingIdentity(); try { synchronized (this) { policy.mActivePasswordMetrics = metrics; policy.mFailedPasswordAttempts = 0; saveSettingsLocked(userHandle); updatePasswordExpirationsLocked(userHandle); setExpirationAlarmCheckLocked(mContext, userHandle, /* parent */ false); saveSettingsLocked(userId); updatePasswordExpirationsLocked(userId); setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false); // Send a broadcast to each profile using this password as its primary unlock. sendAdminCommandForLockscreenPoliciesLocked( DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle); DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userId); } removeCaApprovalsIfNeeded(userHandle); removeCaApprovalsIfNeeded(userId); } finally { mInjector.binderRestoreCallingIdentity(ident); } Loading Loading @@ -6598,6 +6584,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { "User must be running and unlocked"); } private void enforceUserUnlocked(@UserIdInt int userId, boolean parent) { if (parent) { enforceUserUnlocked(getProfileParentId(userId)); } else { enforceUserUnlocked(userId); } } private void enforceManageUsers() { final int callingUid = mInjector.binderGetCallingUid(); if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +15 −1 Original line number Diff line number Diff line Loading @@ -2304,7 +2304,7 @@ public class DevicePolicyManager { * Determine whether the current password the user has set is sufficient to meet the policy * requirements (e.g. quality, minimum length) that have been requested by the admins of this * user and its participating profiles. Restrictions on profiles that have a separate challenge * are not taken into account. * are not taken into account. The user must be unlocked in order to perform the check. * <p> * The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call this method; if it has Loading @@ -2317,6 +2317,7 @@ public class DevicePolicyManager { * @return Returns true if the password meets the current requirements, else false. * @throws SecurityException if the calling application does not own an active administrator * that uses {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} * @throws InvalidStateException if the user is not unlocked. */ public boolean isActivePasswordSufficient() { if (mService != null) { Loading Loading @@ -3824,6 +3825,19 @@ public class DevicePolicyManager { } } /** * @hide */ public void reportPasswordChanged(@UserIdInt int userId) { if (mService != null) { try { mService.reportPasswordChanged(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } /** * @hide */ Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ interface IDevicePolicyManager { boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle); void setActivePasswordState(in PasswordMetrics metrics, int userHandle); void reportPasswordChanged(int userId); void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); void reportFailedFingerprintAttempt(int userHandle); Loading
core/java/com/android/internal/widget/LockPatternUtils.java +3 −18 Original line number Diff line number Diff line Loading @@ -590,8 +590,6 @@ public class LockPatternUtils { setCredentialRequiredToDecrypt(false); } getDevicePolicyManager().setActivePasswordState(new PasswordMetrics(), userHandle); onAfterChangingPassword(userHandle); } Loading Loading @@ -644,6 +642,7 @@ public class LockPatternUtils { + MIN_LOCK_PATTERN_SIZE + " dots long."); } setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); getLockSettings().setLockPattern(patternToString(pattern), savedPattern, userId); DevicePolicyManager dpm = getDevicePolicyManager(); Loading @@ -659,10 +658,6 @@ public class LockPatternUtils { } setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId); setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId); dpm.setActivePasswordState(new PasswordMetrics( DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size()), userId); onAfterChangingPassword(userId); } catch (RemoteException re) { Log.e(TAG, "Couldn't save lock pattern " + re); Loading Loading @@ -775,10 +770,9 @@ public class LockPatternUtils { + "of length " + MIN_LOCK_PASSWORD_SIZE); } final int computedQuality = PasswordMetrics.computeForPassword(password).quality; setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); getLockSettings().setLockPassword(password, savedPassword, userHandle); getLockSettings().setSeparateProfileChallengeEnabled(userHandle, true, null); final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password); final int computedQuality = metrics.quality; // Update the device encryption password. if (userHandle == UserHandle.USER_SYSTEM Loading @@ -796,15 +790,6 @@ public class LockPatternUtils { } } setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle); if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { metrics.quality = Math.max(quality, metrics.quality); dpm.setActivePasswordState(metrics, userHandle); } else { // The password is not anything. dpm.setActivePasswordState(new PasswordMetrics(), userHandle); } // Add the password to the password history. We assume all // password hashes have the same length for simplicity of implementation. String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle); Loading
services/core/java/com/android/server/LockSettingsService.java +38 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package com.android.server; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; import android.app.admin.PasswordMetrics; import android.app.backup.BackupManager; import android.app.trust.IStrongAuthTracker; import android.app.trust.TrustManager; Loading Loading @@ -931,6 +933,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSeparateChallengeLock) { setLockPatternInternal(pattern, savedCredential, userId); setSeparateProfileChallengeEnabled(userId, true, null); notifyPasswordChanged(userId); } } Loading @@ -945,6 +948,7 @@ public class LockSettingsService extends ILockSettings.Stub { setKeystorePassword(null, userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); notifyActivePasswordMetricsAvailable(null, userId); return; } Loading Loading @@ -994,6 +998,7 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSeparateChallengeLock) { setLockPasswordInternal(password, savedCredential, userId); setSeparateProfileChallengeEnabled(userId, true, null); notifyPasswordChanged(userId); } } Loading @@ -1007,6 +1012,7 @@ public class LockSettingsService extends ILockSettings.Stub { setKeystorePassword(null, userId); fixateNewestUserKeyAuth(userId); onUserLockChanged(userId); notifyActivePasswordMetricsAvailable(null, userId); return; } Loading Loading @@ -1420,6 +1426,7 @@ public class LockSettingsService extends ILockSettings.Stub { // migrate credential to GateKeeper credentialUtil.setCredential(credential, null, userId); if (!hasChallenge) { notifyActivePasswordMetricsAvailable(credential, userId); return VerifyCredentialResponse.OK; } // Fall through to get the auth token. Technically this should never happen, Loading Loading @@ -1459,6 +1466,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (progressCallback != null) { progressCallback.onCredentialVerified(); } notifyActivePasswordMetricsAvailable(credential, userId); unlockKeystore(credential, userId); Slog.i(TAG, "Unlocking user " + userId + Loading @@ -1482,6 +1490,36 @@ public class LockSettingsService extends ILockSettings.Stub { return response; } private void notifyActivePasswordMetricsAvailable(String password, @UserIdInt int userId) { final PasswordMetrics metrics; if (password == null) { metrics = new PasswordMetrics(); } else { metrics = PasswordMetrics.computeForPassword(password); metrics.quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId); } // Asynchronous to avoid dead lock mHandler.post(() -> { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.setActivePasswordState(metrics, userId); }); } /** * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before * reporting the password changed. */ private void notifyPasswordChanged(@UserIdInt int userId) { // Same handler as notifyActivePasswordMetricsAvailable to ensure correct ordering mHandler.post(() -> { DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); dpm.reportPasswordChanged(userId); }); } @Override public boolean checkVoldPassword(int userId) throws RemoteException { if (!mFirstCallToVold) { Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +47 −53 Original line number Diff line number Diff line Loading @@ -253,7 +253,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String ATTR_DEVICE_PROVISIONING_CONFIG_APPLIED = "device-provisioning-config-applied"; private static final String ATTR_DEVICE_PAIRED = "device-paired"; private static final String ATTR_DELEGATED_CERT_INSTALLER = "delegated-cert-installer"; private static final String ATTR_APPLICATION_RESTRICTIONS_MANAGER = "application-restrictions-manager"; Loading Loading @@ -2342,20 +2341,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, "failed-password-attempts"); } final PasswordMetrics metrics = policy.mActivePasswordMetrics; if (!metrics.isDefault()) { out.startTag(null, "active-password"); out.attribute(null, "quality", Integer.toString(metrics.quality)); out.attribute(null, "length", Integer.toString(metrics.length)); out.attribute(null, "uppercase", Integer.toString(metrics.upperCase)); out.attribute(null, "lowercase", Integer.toString(metrics.lowerCase)); out.attribute(null, "letters", Integer.toString(metrics.letters)); out.attribute(null, "numeric", Integer.toString(metrics.numeric)); out.attribute(null, "symbols", Integer.toString(metrics.symbols)); out.attribute(null, "nonletter", Integer.toString(metrics.nonLetter)); out.endTag(null, "active-password"); } for (int i = 0; i < policy.mAcceptedCaCertificates.size(); i++) { out.startTag(null, TAG_ACCEPTED_CA_CERTIFICATES); out.attribute(null, ATTR_NAME, policy.mAcceptedCaCertificates.valueAt(i)); Loading Loading @@ -2456,6 +2441,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { JournaledFile journal = makeJournaledFile(userHandle); FileInputStream stream = null; File file = journal.chooseForRead(); boolean needsRewrite = false; try { stream = new FileInputStream(file); XmlPullParser parser = Xml.newPullParser(); Loading Loading @@ -2542,16 +2528,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if ("password-owner".equals(tag)) { policy.mPasswordOwner = Integer.parseInt( parser.getAttributeValue(null, "value")); } else if ("active-password".equals(tag)) { final PasswordMetrics m = policy.mActivePasswordMetrics; m.quality = Integer.parseInt(parser.getAttributeValue(null, "quality")); m.length = Integer.parseInt(parser.getAttributeValue(null, "length")); m.upperCase = Integer.parseInt(parser.getAttributeValue(null, "uppercase")); m.lowerCase = Integer.parseInt(parser.getAttributeValue(null, "lowercase")); m.letters = Integer.parseInt(parser.getAttributeValue(null, "letters")); m.numeric = Integer.parseInt(parser.getAttributeValue(null, "numeric")); m.symbols = Integer.parseInt(parser.getAttributeValue(null, "symbols")); m.nonLetter = Integer.parseInt(parser.getAttributeValue(null, "nonletter")); } else if (TAG_ACCEPTED_CA_CERTIFICATES.equals(tag)) { policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME)); } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) { Loading @@ -2577,6 +2553,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending); } else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) { policy.mInitBundle = PersistableBundle.restoreFromXml(parser); } else if ("active-password".equals(tag)) { needsRewrite = true; } else { Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); Loading @@ -2596,27 +2574,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Ignore } // Might need to upgrade the file by rewriting it if (needsRewrite) { saveSettingsLocked(userHandle); } // Generate a list of admins from the admin map policy.mAdminList.addAll(policy.mAdminMap.values()); // Validate that what we stored for the password quality matches // sufficiently what is currently set. Note that this is only // a sanity check in case the two get out of sync; this should // never normally happen. final long identity = mInjector.binderClearCallingIdentity(); try { int actualPasswordQuality = mLockPatternUtils.getActivePasswordQuality(userHandle); if (actualPasswordQuality < policy.mActivePasswordMetrics.quality) { Slog.w(LOG_TAG, "Active password quality 0x" + Integer.toHexString(policy.mActivePasswordMetrics.quality) + " does not match actual quality 0x" + Integer.toHexString(actualPasswordQuality)); policy.mActivePasswordMetrics = new PasswordMetrics(); } } finally { mInjector.binderRestoreCallingIdentity(identity); } validatePasswordOwnerLocked(policy); updateMaximumTimeToLockLocked(userHandle); updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle); Loading Loading @@ -3850,6 +3815,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private boolean isActivePasswordSufficientForUserLocked( DevicePolicyData policy, int userHandle, boolean parent) { enforceUserUnlocked(userHandle, parent); final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent); if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) { return false; Loading Loading @@ -4924,33 +4891,52 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } enforceFullCrossUsersPermission(userHandle); mContext.enforceCallingOrSelfPermission( android.Manifest.permission.BIND_DEVICE_ADMIN, null); // If the managed profile doesn't have a separate password, set the metrics to default if (isManagedProfile(userHandle) && !isSeparateProfileChallengeEnabled(userHandle)) { metrics = new PasswordMetrics(); } validateQualityConstant(metrics.quality); DevicePolicyData policy = getUserData(userHandle); synchronized (this) { policy.mActivePasswordMetrics = metrics; } } @Override public void reportPasswordChanged(@UserIdInt int userId) { if (!mHasFeature) { return; } enforceFullCrossUsersPermission(userId); // Managed Profile password can only be changed when it has a separate challenge. if (!isSeparateProfileChallengeEnabled(userHandle)) { enforceNotManagedProfile(userHandle, "set the active password"); if (!isSeparateProfileChallengeEnabled(userId)) { enforceNotManagedProfile(userId, "set the active password"); } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.BIND_DEVICE_ADMIN, null); validateQualityConstant(metrics.quality); DevicePolicyData policy = getUserData(userHandle); DevicePolicyData policy = getUserData(userId); long ident = mInjector.binderClearCallingIdentity(); try { synchronized (this) { policy.mActivePasswordMetrics = metrics; policy.mFailedPasswordAttempts = 0; saveSettingsLocked(userHandle); updatePasswordExpirationsLocked(userHandle); setExpirationAlarmCheckLocked(mContext, userHandle, /* parent */ false); saveSettingsLocked(userId); updatePasswordExpirationsLocked(userId); setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false); // Send a broadcast to each profile using this password as its primary unlock. sendAdminCommandForLockscreenPoliciesLocked( DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle); DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userId); } removeCaApprovalsIfNeeded(userHandle); removeCaApprovalsIfNeeded(userId); } finally { mInjector.binderRestoreCallingIdentity(ident); } Loading Loading @@ -6598,6 +6584,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { "User must be running and unlocked"); } private void enforceUserUnlocked(@UserIdInt int userId, boolean parent) { if (parent) { enforceUserUnlocked(getProfileParentId(userId)); } else { enforceUserUnlocked(userId); } } private void enforceManageUsers() { final int callingUid = mInjector.binderGetCallingUid(); if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) { Loading