OSDN Git Service

DPM: Fix regression from I54376f60ac53451ace22965d331b47cd8c2e614e
[android-x86/frameworks-base.git] / services / devicepolicy / java / com / android / server / devicepolicy / DevicePolicyManagerService.java
index ed5cce8..aac341c 100644 (file)
@@ -2022,12 +2022,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
     private void setDeviceOwnerSystemPropertyLocked() {
         final boolean deviceProvisioned =
                 mInjector.settingsGlobalGetInt(Settings.Global.DEVICE_PROVISIONED, 0) != 0;
+        final boolean hasDeviceOwner = mOwners.hasDeviceOwner();
         // If the device is not provisioned and there is currently no device owner, do not set the
-        // read-only system property yet, since Device owner may still be provisioned. For Wear
-        // devices, if there is already a device owner then it's OK to set the property to true now,
-        // regardless the provision state.
-        final boolean isWatchWithDeviceOwner = mIsWatch && mOwners.hasDeviceOwner();
-        if (!isWatchWithDeviceOwner && !deviceProvisioned) {
+        // read-only system property yet, since Device owner may still be provisioned.
+        if (!hasDeviceOwner && !deviceProvisioned) {
             return;
         }
         // Still at the first stage of CryptKeeper double bounce, mOwners.hasDeviceOwner is
@@ -2036,20 +2034,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
             return;
         }
 
-        if (!TextUtils.isEmpty(mInjector.systemPropertiesGet(PROPERTY_DEVICE_OWNER_PRESENT))) {
+        if (!mInjector.systemPropertiesGet(PROPERTY_DEVICE_OWNER_PRESENT, "").isEmpty()) {
             Slog.w(LOG_TAG, "Trying to set ro.device_owner, but it has already been set?");
         } else {
-            if (mOwners.hasDeviceOwner()) {
-                mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, "true");
-                Slog.i(LOG_TAG, "Set ro.device_owner property to true");
+            final String value = Boolean.toString(hasDeviceOwner);
+            mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, value);
+            Slog.i(LOG_TAG, "Set ro.device_owner property to " + value);
 
-                if (mInjector.securityLogGetLoggingEnabledProperty()) {
-                    mSecurityLogMonitor.start();
-                    maybePauseDeviceWideLoggingLocked();
-                }
-            } else {
-                mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, "false");
-                Slog.i(LOG_TAG, "Set ro.device_owner property to false");
+            if (hasDeviceOwner && mInjector.securityLogGetLoggingEnabledProperty()) {
+                mSecurityLogMonitor.start();
+                maybePauseDeviceWideLoggingLocked();
             }
         }
     }
@@ -4085,6 +4079,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
             return true;
         }
         enforceFullCrossUsersPermission(userHandle);
+        enforceUserUnlocked(userHandle, parent);
 
         synchronized (this) {
             // This API can only be called by an active device admin,
@@ -4104,7 +4099,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         enforceManagedProfile(userHandle, "call APIs refering to the parent profile");
 
         synchronized (this) {
-            int targetUser = getProfileParentId(userHandle);
+            final int targetUser = getProfileParentId(userHandle);
+            enforceUserUnlocked(targetUser, false);
             DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, false));
             return isActivePasswordSufficientForUserLocked(policy, targetUser, false);
         }
@@ -4112,7 +4108,15 @@ 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 (requiredPasswordQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+            // A special case is when there is no required password quality, then we just return
+            // true since any password would be sufficient. This is for the scenario when a work
+            // profile is first created so there is no information about the current password but
+            // it should be considered sufficient as there is no password requirement either.
+            // This is useful since it short-circuits the password checkpoint for FDE device below.
+            return true;
+        }
 
         if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()
                 && !policy.mPasswordStateHasBeenSetSinceBoot) {
@@ -4124,7 +4128,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
             return policy.mPasswordValidAtLastCheckpoint;
         }
 
-        final int requiredPasswordQuality = getPasswordQuality(null, userHandle, parent);
         if (policy.mActivePasswordMetrics.quality < requiredPasswordQuality) {
             return false;
         }
@@ -4349,18 +4352,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                 quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
             }
             final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
-            if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
-                final int realQuality = metrics.quality;
-                if (realQuality < quality
-                        && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
-                    Slog.w(LOG_TAG, "resetPassword: password quality 0x"
-                            + Integer.toHexString(realQuality)
-                            + " does not meet required quality 0x"
-                            + Integer.toHexString(quality));
-                    return false;
-                }
-                quality = Math.max(realQuality, quality);
+            final int realQuality = metrics.quality;
+            if (realQuality < quality
+                    && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
+                Slog.w(LOG_TAG, "resetPassword: password quality 0x"
+                        + Integer.toHexString(realQuality)
+                        + " does not meet required quality 0x"
+                        + Integer.toHexString(quality));
+                return false;
             }
+            quality = Math.max(realQuality, quality);
             int length = getPasswordMinimumLength(null, userHandle, /* parent */ false);
             if (password.length() < length) {
                 Slog.w(LOG_TAG, "resetPassword: password length " + password.length()
@@ -4446,7 +4447,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                 result = mLockPatternUtils.setLockCredentialWithToken(password,
                         TextUtils.isEmpty(password) ? LockPatternUtils.CREDENTIAL_TYPE_NONE
                                 : LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                        tokenHandle, token, userHandle);
+                        quality, tokenHandle, token, userHandle);
             }
             boolean requireEntry = (flags & DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) != 0;
             if (requireEntry) {
@@ -5450,6 +5451,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
         }
     }
 
+    /**
+     * Notify DPMS regarding the metric of the current password. This happens when the user changes
+     * the password, but also when the user just unlocks the keyguard. In comparison,
+     * reportPasswordChanged() is only called when the user changes the password.
+     */
     @Override
     public void setActivePasswordState(PasswordMetrics metrics, int userHandle) {
         if (!mHasFeature) {