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

Commit 9af145dc authored by Andrew Scull's avatar Andrew Scull Committed by android-build-merger
Browse files

resolve merge conflicts of ad4aa1ce to nyc-mr1-dev am: eb35ad99

am: 3aac3ebe

Change-Id: Idf677426c40799b17d08e0a8ac7dfafc2f2609b2
parents 88002e8e 3aac3ebe
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -2016,7 +2016,8 @@ 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. If the user has a password, it must have been entered in order to
     * perform this 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
@@ -2029,6 +2030,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 IllegalStateException if the user has a password but has not entered it yet.
     */
    public boolean isActivePasswordSufficient() {
        if (mService != null) {
@@ -3538,6 +3540,19 @@ public class DevicePolicyManager {
        }
    }

    /**
     * @hide
     */
    public void reportPasswordChanged(int userId) {
        if (mService != null) {
            try {
                mService.reportPasswordChanged(userId);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * @hide
     */
+1 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ interface IDevicePolicyManager {

    void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase,
        int numbers, int symbols, int nonletter, int userHandle);
    void reportPasswordChanged(int userId);
    void reportFailedPasswordAttempt(int userHandle);
    void reportSuccessfulPasswordAttempt(int userHandle);
    void reportFailedFingerprintAttempt(int userHandle);
+3 −42
Original line number Diff line number Diff line
@@ -593,9 +593,6 @@ public class LockPatternUtils {
            setCredentialRequiredToDecrypt(false);
        }

        getDevicePolicyManager().setActivePasswordState(
                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0, userHandle);

        onAfterChangingPassword(userHandle);
    }

@@ -642,6 +639,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();

@@ -658,9 +656,6 @@ public class LockPatternUtils {

            setBoolean(PATTERN_EVER_CHOSEN_KEY, true, userId);

            setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
            dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
                    pattern.size(), 0, 0, 0, 0, 0, 0, userId);
            onAfterChangingPassword(userId);
        } catch (RemoteException re) {
            Log.e(TAG, "Couldn't save lock pattern " + re);
@@ -863,9 +858,9 @@ public class LockPatternUtils {
                        + "of length " + MIN_LOCK_PASSWORD_SIZE);
            }

            final int computedQuality = computePasswordQuality(password);
            setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
            getLockSettings().setLockPassword(password, savedPassword, userHandle);
            getLockSettings().setSeparateProfileChallengeEnabled(userHandle, true, null);
            int computedQuality = computePasswordQuality(password);

            // Update the device encryption password.
            if (userHandle == UserHandle.USER_SYSTEM
@@ -883,40 +878,6 @@ public class LockPatternUtils {
                }
            }

            setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
            if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                int letters = 0;
                int uppercase = 0;
                int lowercase = 0;
                int numbers = 0;
                int symbols = 0;
                int nonletter = 0;
                for (int i = 0; i < password.length(); i++) {
                    char c = password.charAt(i);
                    if (c >= 'A' && c <= 'Z') {
                        letters++;
                        uppercase++;
                    } else if (c >= 'a' && c <= 'z') {
                        letters++;
                        lowercase++;
                    } else if (c >= '0' && c <= '9') {
                        numbers++;
                        nonletter++;
                    } else {
                        symbols++;
                        nonletter++;
                    }
                }
                dpm.setActivePasswordState(Math.max(quality, computedQuality),
                        password.length(), letters, uppercase, lowercase,
                        numbers, symbols, nonletter, userHandle);
            } else {
                // The password is not anything.
                dpm.setActivePasswordState(
                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
                        0, 0, 0, 0, 0, 0, 0, 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);
+60 −0
Original line number Diff line number Diff line
@@ -927,6 +927,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        synchronized (mSeparateChallengeLock) {
            setLockPatternInternal(pattern, savedCredential, userId);
            setSeparateProfileChallengeEnabled(userId, true, null);
            notifyPasswordChanged(userId);
        }
    }

@@ -941,6 +942,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            setKeystorePassword(null, userId);
            fixateNewestUserKeyAuth(userId);
            onUserLockChanged(userId);
            notifyActivePasswordMetricsAvailable(null, userId);
            return;
        }

@@ -990,6 +992,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        synchronized (mSeparateChallengeLock) {
            setLockPasswordInternal(password, savedCredential, userId);
            setSeparateProfileChallengeEnabled(userId, true, null);
            notifyPasswordChanged(userId);
        }
    }

@@ -1003,6 +1006,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            setKeystorePassword(null, userId);
            fixateNewestUserKeyAuth(userId);
            onUserLockChanged(userId);
            notifyActivePasswordMetricsAvailable(null, userId);
            return;
        }

@@ -1412,6 +1416,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,
@@ -1451,6 +1456,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            if (progressCallback != null) {
                progressCallback.onCredentialVerified();
            }
            notifyActivePasswordMetricsAvailable(credential, userId);
            unlockKeystore(credential, userId);

            Slog.i(TAG, "Unlocking user " + userId +
@@ -1474,6 +1480,60 @@ public class LockSettingsService extends ILockSettings.Stub {
        return response;
    }

    private void notifyActivePasswordMetricsAvailable(final String password, int userId) {
        final int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality(userId);

        // Asynchronous to avoid dead lock
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                int length = 0;
                int letters = 0;
                int uppercase = 0;
                int lowercase = 0;
                int numbers = 0;
                int symbols = 0;
                int nonletter = 0;
                if (password != null) {
                    length = password.length();
                    for (int i = 0; i < length; i++) {
                        char c = password.charAt(i);
                        if (c >= 'A' && c <= 'Z') {
                            letters++;
                            uppercase++;
                        } else if (c >= 'a' && c <= 'z') {
                            letters++;
                            lowercase++;
                        } else if (c >= '0' && c <= '9') {
                            numbers++;
                            nonletter++;
                        } else {
                            symbols++;
                            nonletter++;
                        }
                    }
                }
                DevicePolicyManager dpm = (DevicePolicyManager)
                        mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
                dpm.setActivePasswordState(quality, length, letters, uppercase, lowercase, numbers,
                        symbols, nonletter, userId);
            }
        });
    }

    /**
     * Call after {@link #notifyActivePasswordMetricsAvailable} so metrics are updated before
     * reporting the password changed.
     */
    private void notifyPasswordChanged(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) {
+86 −61
Original line number Diff line number Diff line
@@ -2273,10 +2273,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                out.endTag(null, "failed-password-attempts");
            }

            if (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0
            // Don't save metrics for FBE devices
            if (!mInjector.storageManagerIsFileBasedEncryptionEnabled()
                    && (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0
                    || policy.mActivePasswordUpperCase != 0 || policy.mActivePasswordLowerCase != 0
                    || policy.mActivePasswordLetters != 0 || policy.mActivePasswordNumeric != 0
                    || policy.mActivePasswordSymbols != 0 || policy.mActivePasswordNonLetter != 0) {
                    || policy.mActivePasswordSymbols != 0
                    || policy.mActivePasswordNonLetter != 0)) {
                out.startTag(null, "active-password");
                out.attribute(null, "quality", Integer.toString(policy.mActivePasswordQuality));
                out.attribute(null, "length", Integer.toString(policy.mActivePasswordLength));
@@ -2369,6 +2372,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();
@@ -2455,7 +2459,27 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                } else if ("password-owner".equals(tag)) {
                    policy.mPasswordOwner = Integer.parseInt(
                            parser.getAttributeValue(null, "value"));
                } else if (TAG_ACCEPTED_CA_CERTIFICATES.equals(tag)) {
                    policy.mAcceptedCaCertificates.add(parser.getAttributeValue(null, ATTR_NAME));
                } else if (TAG_LOCK_TASK_COMPONENTS.equals(tag)) {
                    policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name"));
                } else if (TAG_STATUS_BAR.equals(tag)) {
                    policy.mStatusBarDisabled = Boolean.parseBoolean(
                            parser.getAttributeValue(null, ATTR_DISABLED));
                } else if (DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML.equals(tag)) {
                    policy.doNotAskCredentialsOnBoot = true;
                } else if (TAG_AFFILIATION_ID.equals(tag)) {
                    policy.mAffiliationIds.add(parser.getAttributeValue(null, "id"));
                } else if (TAG_ADMIN_BROADCAST_PENDING.equals(tag)) {
                    String pending = parser.getAttributeValue(null, ATTR_VALUE);
                    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)) {
                    if (mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
                        // Remove this from FBE devices
                        needsRewrite = true;
                    } else {
                        policy.mActivePasswordQuality = Integer.parseInt(
                            parser.getAttributeValue(null, "quality"));
                        policy.mActivePasswordLength = Integer.parseInt(
@@ -2472,22 +2496,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                                parser.getAttributeValue(null, "symbols"));
                        policy.mActivePasswordNonLetter = 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)) {
                    policy.mLockTaskPackages.add(parser.getAttributeValue(null, "name"));
                } else if (TAG_STATUS_BAR.equals(tag)) {
                    policy.mStatusBarDisabled = Boolean.parseBoolean(
                            parser.getAttributeValue(null, ATTR_DISABLED));
                } else if (DO_NOT_ASK_CREDENTIALS_ON_BOOT_XML.equals(tag)) {
                    policy.doNotAskCredentialsOnBoot = true;
                } else if (TAG_AFFILIATION_ID.equals(tag)) {
                    policy.mAffiliationIds.add(parser.getAttributeValue(null, "id"));
                } else if (TAG_ADMIN_BROADCAST_PENDING.equals(tag)) {
                    String pending = parser.getAttributeValue(null, ATTR_VALUE);
                    policy.mAdminBroadcastPending = Boolean.toString(true).equals(pending);
                } else if (TAG_INITIALIZATION_BUNDLE.equals(tag)) {
                    policy.mInitBundle = PersistableBundle.restoreFromXml(parser);
                    }
                } else {
                    Slog.w(LOG_TAG, "Unknown tag: " + tag);
                    XmlUtils.skipCurrentTag(parser);
@@ -2507,34 +2516,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.mActivePasswordQuality) {
                Slog.w(LOG_TAG, "Active password quality 0x"
                        + Integer.toHexString(policy.mActivePasswordQuality)
                        + " does not match actual quality 0x"
                        + Integer.toHexString(actualPasswordQuality));
                policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
                policy.mActivePasswordLength = 0;
                policy.mActivePasswordUpperCase = 0;
                policy.mActivePasswordLowerCase = 0;
                policy.mActivePasswordLetters = 0;
                policy.mActivePasswordNumeric = 0;
                policy.mActivePasswordSymbols = 0;
                policy.mActivePasswordNonLetter = 0;
            }
        } finally {
            mInjector.binderRestoreCallingIdentity(identity);
        }

        validatePasswordOwnerLocked(policy);
        updateMaximumTimeToLockLocked(userHandle);
        updateLockTaskPackagesLocked(policy.mLockTaskPackages, userHandle);
@@ -3758,6 +3747,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.mActivePasswordQuality < requiredPasswordQuality) {
            return false;
@@ -4832,20 +4823,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return;
        }
        enforceFullCrossUsersPermission(userHandle);
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.BIND_DEVICE_ADMIN, null);

        // Managed Profile password can only be changed when it has a separate challenge.
        if (!isSeparateProfileChallengeEnabled(userHandle)) {
            enforceNotManagedProfile(userHandle, "set the active password");
        // If the managed profile doesn't have a separate password, set the metrics to default
        if (isManagedProfile(userHandle) && !isSeparateProfileChallengeEnabled(userHandle)) {
            quality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
            length = 0;
            letters = 0;
            uppercase = 0;
            lowercase = 0;
            numbers = 0;
            symbols = 0;
            nonletter = 0;
        }

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
        validateQualityConstant(quality);

        DevicePolicyData policy = getUserData(userHandle);

        long ident = mInjector.binderClearCallingIdentity();
        try {
        synchronized (this) {
            policy.mActivePasswordQuality = quality;
            policy.mActivePasswordLength = length;
@@ -4855,17 +4849,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            policy.mActivePasswordNumeric = numbers;
            policy.mActivePasswordSymbols = symbols;
            policy.mActivePasswordNonLetter = nonletter;
        }
    }

    @Override
    public void reportPasswordChanged(int userId) {
        if (!mHasFeature) {
            return;
        }
        enforceFullCrossUsersPermission(userId);

        // Managed Profile password can only be changed when it has a separate challenge.
        if (!isSeparateProfileChallengeEnabled(userId)) {
            enforceNotManagedProfile(userId, "set the active password");
        }

        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.BIND_DEVICE_ADMIN, null);

        DevicePolicyData policy = getUserData(userId);

        long ident = mInjector.binderClearCallingIdentity();
        try {
            synchronized (this) {
                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);
        }
@@ -6454,6 +6471,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                "User must be running and unlocked");
    }

    private void enforceUserUnlocked(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)) {