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

Commit 02586d4c authored by Eric Biggers's avatar Eric Biggers
Browse files

LockSettingsService: simplify querying of credential shareability

Instead of creating a UserManager for the desired userId and then
calling the deprecated method
UserManager#isCredentialSharableWithParent(), use
UserManagerInternal#getUserProperties(userId).isCredentialShareableWithParent().
UserManagerInternal is the preferred way to get user properties in
system_server itself, since it avoids unnecessary checks and an
unnecessary copy of the UserProperties object.

Also add the missing "e" to
LockSettingsService#isCredentialSharableWithParent().

Bug: 403355811
Test: atest FrameworksServicesTests:com.android.server.locksettings
Flag: EXEMPT refactor
Change-Id: I43d11c3cd87f798a3d782146994e17041e55b268
parent a5bb866c
Loading
Loading
Loading
Loading
+18 −38
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
@@ -1070,7 +1067,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 +1636,7 @@ public class LockSettingsService extends ILockSettings.Stub {
            Thread.currentThread().interrupt();
        }

        if (isCredentialSharableWithParent(userId)) {
        if (isCredentialShareableWithParent(userId)) {
            if (!hasUnifiedChallenge(userId)) {
                mBiometricDeferredQueue.processPendingLockoutResets();
            }
@@ -1648,7 +1645,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 +1682,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 +1690,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 +1725,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 +1734,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 +1761,7 @@ public class LockSettingsService extends ILockSettings.Stub {
    }

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

@@ -1886,7 +1883,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 +1918,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 +2047,10 @@ 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);
        }
    }

    @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 = mInjector.getUserManagerInternal().getUserProperties(userId);
        return props != null && props.isCredentialShareableWithParent();
    }

    /** Register the given WeakEscrowTokenRemovedListener. */
@@ -2305,7 +2286,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 +3068,7 @@ public class LockSettingsService extends ILockSettings.Stub {

        activateEscrowTokens(sp, userId);

        if (isCredentialSharableWithParent(userId)) {
        if (isCredentialShareableWithParent(userId)) {
            if (getSeparateProfileChallengeEnabledInternal(userId)) {
                setDeviceUnlockedForUser(userId);
            } else {
@@ -3260,8 +3241,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();
    }