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

Commit 8c33f1cb authored by Eric Biggers's avatar Eric Biggers Committed by Android (Google) Code Review
Browse files

Merge changes If83c4ee8,I43d11c3c into main

* changes:
  LockSettingsService: always get user properties from UserManagerInternal
  LockSettingsService: simplify querying of credential shareability
parents c86ada05 98710a95
Loading
Loading
Loading
Loading
+27 −49
Original line number Diff line number Diff line
@@ -183,7 +183,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
@@ -340,8 +339,6 @@ public class LockSettingsService extends ILockSettings.Stub {
    private static final int[] SYSTEM_CREDENTIAL_UIDS = {
            Process.VPN_UID, Process.ROOT_UID, Process.SYSTEM_UID};

    private HashMap<UserHandle, UserManager> mUserManagerCache = new HashMap<>();

    private final CopyOnWriteArrayList<LockSettingsStateListener> mLockSettingsStateListeners =
            new CopyOnWriteArrayList<>();

@@ -455,7 +452,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    private void tieProfileLockIfNecessary(int profileUserId,
            LockscreenCredential profileUserPassword) {
        // Only for profiles that shares credential with parent
        if (!isCredentialSharableWithParent(profileUserId)) {
        if (!isCredentialShareableWithParent(profileUserId)) {
            return;
        }
        // Do not tie profile when separate challenge is enabled
@@ -850,7 +847,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        if (android.os.Flags.allowPrivateProfile()
                && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()
                && android.multiuser.Flags.enablePrivateSpaceFeatures()) {
            UserProperties userProperties = mUserManager.getUserProperties(UserHandle.of(userId));
            UserProperties userProperties = getUserProperties(userId);
            if (userProperties != null && userProperties.getAllowStoppingUserWithDelayedLocking()) {
                return;
            }
@@ -963,19 +960,13 @@ public class LockSettingsService extends ILockSettings.Stub {
                            && android.multiuser.Flags.enablePrivateSpaceFeatures()
                            && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) {
                        mHandler.post(() -> {
                            try {
                                UserProperties userProperties =
                                        mUserManager.getUserProperties(UserHandle.of(userId));
                            UserProperties userProperties = getUserProperties(userId);
                            if (userProperties != null && userProperties
                                    .getAllowStoppingUserWithDelayedLocking()) {
                                int strongAuthRequired = LockPatternUtils.StrongAuthTracker
                                        .getDefaultFlags(mContext);
                                requireStrongAuth(strongAuthRequired, userId);
                            }
                            } catch (IllegalArgumentException e) {
                                Slogf.d(TAG, "User %d does not exist or has been removed",
                                        userId);
                            }
                        });
                    }
                }};
@@ -1070,7 +1061,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        final int userCount = users.size();
        for (int i = 0; i < userCount; i++) {
            UserInfo user = users.get(i);
            if (isCredentialSharableWithParent(user.id)
            if (isCredentialShareableWithParent(user.id)
                    && !getSeparateProfileChallengeEnabledInternal(user.id)) {
                success &= SyntheticPasswordCrypto.migrateLockSettingsKey(
                        PROFILE_KEY_NAME_ENCRYPT + user.id);
@@ -1639,7 +1630,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            Thread.currentThread().interrupt();
        }

        if (isCredentialSharableWithParent(userId)) {
        if (isCredentialShareableWithParent(userId)) {
            if (!hasUnifiedChallenge(userId)) {
                mBiometricDeferredQueue.processPendingLockoutResets();
            }
@@ -1648,7 +1639,7 @@ public class LockSettingsService extends ILockSettings.Stub {

        for (UserInfo profile : mUserManager.getProfiles(userId)) {
            if (profile.id == userId) continue;
            if (!isCredentialSharableWithParent(profile.id)) continue;
            if (!isCredentialShareableWithParent(profile.id)) continue;

            if (hasUnifiedChallenge(profile.id)) {
                if (mUserManager.isUserRunning(profile.id)) {
@@ -1685,7 +1676,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    private Map<Integer, LockscreenCredential> getDecryptedPasswordsForAllTiedProfiles(int userId) {
        if (isCredentialSharableWithParent(userId)) {
        if (isCredentialShareableWithParent(userId)) {
            return null;
        }
        Map<Integer, LockscreenCredential> result = new ArrayMap<>();
@@ -1693,7 +1684,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        final int size = profiles.size();
        for (int i = 0; i < size; i++) {
            final UserInfo profile = profiles.get(i);
            if (!isCredentialSharableWithParent(profile.id)) {
            if (!isCredentialShareableWithParent(profile.id)) {
                continue;
            }
            final int profileUserId = profile.id;
@@ -1728,7 +1719,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     */
    private void synchronizeUnifiedChallengeForProfiles(int userId,
            Map<Integer, LockscreenCredential> profilePasswordMap) {
        if (isCredentialSharableWithParent(userId)) {
        if (isCredentialShareableWithParent(userId)) {
            return;
        }
        final boolean isSecure = isUserSecure(userId);
@@ -1737,7 +1728,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        for (int i = 0; i < size; i++) {
            final UserInfo profile = profiles.get(i);
            final int profileUserId = profile.id;
            if (isCredentialSharableWithParent(profileUserId)) {
            if (isCredentialShareableWithParent(profileUserId)) {
                if (getSeparateProfileChallengeEnabledInternal(profileUserId)) {
                    continue;
                }
@@ -1764,7 +1755,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

    private boolean isProfileWithUnifiedLock(int userId) {
        return isCredentialSharableWithParent(userId)
        return isCredentialShareableWithParent(userId)
                && !getSeparateProfileChallengeEnabledInternal(userId);
    }

@@ -1886,7 +1877,7 @@ public class LockSettingsService extends ILockSettings.Stub {
                setSeparateProfileChallengeEnabledLocked(userId, true, /* unused */ null);
                notifyPasswordChanged(credential, userId);
            }
            if (isCredentialSharableWithParent(userId)) {
            if (isCredentialShareableWithParent(userId)) {
                // Make sure the profile doesn't get locked straight after setting challenge.
                setDeviceUnlockedForUser(userId);
            }
@@ -1921,9 +1912,8 @@ public class LockSettingsService extends ILockSettings.Stub {
     * setting a new credential where there was none, updates the strong auth state for
     * {@param userId} to <tt>STRONG_AUTH_NOT_REQUIRED</tt>.
     *
     * @param savedCredential if the user is a profile with
     * {@link UserManager#isCredentialSharableWithParent()} with unified challenge and
     *   savedCredential is empty, LSS will try to re-derive the profile password internally.
     * @param savedCredential if the user is a profile with unified challenge and savedCredential is
     *     empty, LSS will try to re-derive the profile password internally.
     *     TODO (b/80170828): Fix this so profile password is always passed in.
     * @param isLockTiedToParent is {@code true} if {@code userId} is a profile and its new
     *     credentials are being tied to its parent's credentials.
@@ -2051,25 +2041,14 @@ public class LockSettingsService extends ILockSettings.Stub {
        return mInjector.getDevicePolicyManager().getPasswordHistoryLength(null, userId);
    }

    private UserManager getUserManagerFromCache(int userId) {
        UserHandle userHandle = UserHandle.of(userId);
        if (mUserManagerCache.containsKey(userHandle)) {
            return mUserManagerCache.get(userHandle);
        }

        try {
            Context userContext = mContext.createPackageContextAsUser("system", 0, userHandle);
            UserManager userManager = userContext.getSystemService(UserManager.class);
            mUserManagerCache.put(userHandle, userManager);
            return userManager;
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException("Failed to create context for user " + userHandle, e);
        }
    private @Nullable UserProperties getUserProperties(int userId) {
        return mInjector.getUserManagerInternal().getUserProperties(userId);
    }

    @VisibleForTesting /** Note: this method is overridden in unit tests */
    protected boolean isCredentialSharableWithParent(int userId) {
        return getUserManagerFromCache(userId).isCredentialSharableWithParent();
    protected boolean isCredentialShareableWithParent(int userId) {
        UserProperties props = getUserProperties(userId);
        return props != null && props.isCredentialShareableWithParent();
    }

    /** Register the given WeakEscrowTokenRemovedListener. */
@@ -2305,7 +2284,7 @@ public class LockSettingsService extends ILockSettings.Stub {
        final List<UserInfo> profiles = mUserManager.getProfiles(userId);
        for (UserInfo pi : profiles) {
            // Unlock profile which shares credential with parent with unified lock
            if (isCredentialSharableWithParent(pi.id)
            if (isCredentialShareableWithParent(pi.id)
                    && !getSeparateProfileChallengeEnabledInternal(pi.id)
                    && mStorage.hasChildProfileLock(pi.id)) {
                try {
@@ -3087,7 +3066,7 @@ public class LockSettingsService extends ILockSettings.Stub {

        activateEscrowTokens(sp, userId);

        if (isCredentialSharableWithParent(userId)) {
        if (isCredentialShareableWithParent(userId)) {
            if (getSeparateProfileChallengeEnabledInternal(userId)) {
                setDeviceUnlockedForUser(userId);
            } else {
@@ -3260,8 +3239,7 @@ public class LockSettingsService extends ILockSettings.Stub {
     * Returns a fixed pseudorandom byte string derived from the user's synthetic password.
     * This is used to salt the password history hash to protect the hash against offline
     * bruteforcing, since rederiving this value requires a successful authentication.
     * If user is a profile with {@link UserManager#isCredentialSharableWithParent()} true and with
     * unified challenge, currentCredential is ignored.
     * If user is a profile with unified challenge, currentCredential is ignored.
     */
    @Override
    public byte[] getHashFactor(LockscreenCredential currentCredential, int userId) {
+1 −1
Original line number Diff line number Diff line
@@ -203,7 +203,7 @@ public class LockSettingsServiceTestable extends LockSettingsService {
    }

    @Override
    protected boolean isCredentialSharableWithParent(int userId) {
    protected boolean isCredentialShareableWithParent(int userId) {
        UserInfo userInfo = mUserManager.getUserInfo(userId);
        return userInfo.isCloneProfile() || userInfo.isManagedProfile();
    }