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

Commit 584e9b13 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by android-build-merger
Browse files

Remove lock contention when unlocking users

am: 6f4d7b39

Change-Id: I71a426b184dab8dab285a6d3607882d662624a90
parents ca023af1 6f4d7b39
Loading
Loading
Loading
Loading
+30 −15
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ final class UserController {
     */
    private void finishUserUnlocking(final UserState uss) {
        final int userId = uss.mHandle.getIdentifier();
        boolean proceedWithUnlock = false;
        synchronized (mService) {
            // Bail if we ended up with a stale user
            if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
@@ -288,6 +289,11 @@ final class UserController {

            if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
                getUserManagerInternal().setUserState(userId, uss.state);
                proceedWithUnlock = true;
            }
        }

        if (proceedWithUnlock) {
            uss.mUnlockProgress.start();

            // Prepare app storage before we go any further
@@ -302,7 +308,6 @@ final class UserController {
                    .sendToTarget();
        }
    }
    }

    /**
     * Step from {@link UserState#STATE_RUNNING_UNLOCKING} to
@@ -962,6 +967,7 @@ final class UserController {

    boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
            IProgressListener listener) {
        UserState uss;
        synchronized (mService) {
            // TODO Move this block outside of synchronized if it causes lock contention
            if (!StorageManager.isUserKeyUnlocked(userId)) {
@@ -976,7 +982,7 @@ final class UserController {
            }
            // Bail if user isn't actually running, otherwise register the given
            // listener to watch for unlock progress
            final UserState uss = mStartedUsers.get(userId);
            uss = mStartedUsers.get(userId);
            if (uss == null) {
                notifyFinished(userId, listener);
                return false;
@@ -984,9 +990,13 @@ final class UserController {
                uss.mUnlockProgress.addListener(listener);
                uss.tokenProvided = (token != null);
            }
        }

        finishUserUnlocking(uss);

        final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
        synchronized (mService) {

            // We just unlocked a user, so let's now attempt to unlock any
            // managed profiles under that user.
            for (int i = 0; i < mStartedUsers.size(); i++) {
@@ -995,11 +1005,16 @@ final class UserController {
                if (parent != null && parent.id == userId && testUserId != userId) {
                    Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
                            + "): attempting unlock because parent was just unlocked");
                    maybeUnlockUser(testUserId);
                    childProfilesToUnlock.add(testUserId);
                }
            }
        }

        final int size = childProfilesToUnlock.size();
        for (int i = 0; i < size; i++) {
            maybeUnlockUser(childProfilesToUnlock.valueAt(i));
        }

        return true;
    }