Loading services/core/java/com/android/server/am/UserController.java +25 −13 Original line number Original line Diff line number Diff line Loading @@ -400,6 +400,10 @@ class UserController implements Handler.Callback { // Call onBeforeUnlockUser on a worker thread that allows disk I/O // Call onBeforeUnlockUser on a worker thread that allows disk I/O FgThread.getHandler().post(() -> { FgThread.getHandler().post(() -> { if (!StorageManager.isUserKeyUnlocked(userId)) { Slog.w(TAG, "User key got locked unexpectedly, leaving user locked."); return; } mInjector.getUserManager().onBeforeUnlockUser(userId); mInjector.getUserManager().onBeforeUnlockUser(userId); synchronized (mLock) { synchronized (mLock) { // Do not proceed if unexpected state // Do not proceed if unexpected state Loading Loading @@ -714,14 +718,11 @@ class UserController implements Handler.Callback { void finishUserStopped(UserState uss) { void finishUserStopped(UserState uss) { final int userId = uss.mHandle.getIdentifier(); final int userId = uss.mHandle.getIdentifier(); boolean stopped; final boolean stopped; ArrayList<IStopUserCallback> callbacks; ArrayList<IStopUserCallback> callbacks; boolean forceStopUser = false; synchronized (mLock) { synchronized (mLock) { callbacks = new ArrayList<>(uss.mStopCallbacks); callbacks = new ArrayList<>(uss.mStopCallbacks); if (mStartedUsers.get(userId) != uss) { if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) { stopped = false; } else if (uss.state != UserState.STATE_SHUTDOWN) { stopped = false; stopped = false; } else { } else { stopped = true; stopped = true; Loading @@ -729,10 +730,10 @@ class UserController implements Handler.Callback { mStartedUsers.remove(userId); mStartedUsers.remove(userId); mUserLru.remove(Integer.valueOf(userId)); mUserLru.remove(Integer.valueOf(userId)); updateStartedUserArrayLU(); updateStartedUserArrayLU(); forceStopUser = true; } } } } if (forceStopUser) { if (stopped) { mInjector.getUserManagerInternal().removeUserState(userId); mInjector.getUserManagerInternal().removeUserState(userId); mInjector.activityManagerOnUserStopped(userId); mInjector.activityManagerOnUserStopped(userId); // Clean up all state and processes associated with the user. // Clean up all state and processes associated with the user. Loading @@ -755,12 +756,23 @@ class UserController implements Handler.Callback { if (getUserInfo(userId).isEphemeral()) { if (getUserInfo(userId).isEphemeral()) { mInjector.getUserManager().removeUserEvenWhenDisallowed(userId); mInjector.getUserManager().removeUserEvenWhenDisallowed(userId); } } // Evict the user's credential encryption key. // Evict the user's credential encryption key. Performed on FgThread to make it // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking // to prevent data corruption. FgThread.getHandler().post(() -> { synchronized (mLock) { if (mStartedUsers.get(userId) != null) { Slog.w(TAG, "User was restarted, skipping key eviction"); return; } } try { try { getStorageManager().lockUserKey(userId); getStorageManager().lockUserKey(userId); } catch (RemoteException re) { } catch (RemoteException re) { throw re.rethrowAsRuntimeException(); throw re.rethrowAsRuntimeException(); } } }); } } } } Loading Loading
services/core/java/com/android/server/am/UserController.java +25 −13 Original line number Original line Diff line number Diff line Loading @@ -400,6 +400,10 @@ class UserController implements Handler.Callback { // Call onBeforeUnlockUser on a worker thread that allows disk I/O // Call onBeforeUnlockUser on a worker thread that allows disk I/O FgThread.getHandler().post(() -> { FgThread.getHandler().post(() -> { if (!StorageManager.isUserKeyUnlocked(userId)) { Slog.w(TAG, "User key got locked unexpectedly, leaving user locked."); return; } mInjector.getUserManager().onBeforeUnlockUser(userId); mInjector.getUserManager().onBeforeUnlockUser(userId); synchronized (mLock) { synchronized (mLock) { // Do not proceed if unexpected state // Do not proceed if unexpected state Loading Loading @@ -714,14 +718,11 @@ class UserController implements Handler.Callback { void finishUserStopped(UserState uss) { void finishUserStopped(UserState uss) { final int userId = uss.mHandle.getIdentifier(); final int userId = uss.mHandle.getIdentifier(); boolean stopped; final boolean stopped; ArrayList<IStopUserCallback> callbacks; ArrayList<IStopUserCallback> callbacks; boolean forceStopUser = false; synchronized (mLock) { synchronized (mLock) { callbacks = new ArrayList<>(uss.mStopCallbacks); callbacks = new ArrayList<>(uss.mStopCallbacks); if (mStartedUsers.get(userId) != uss) { if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) { stopped = false; } else if (uss.state != UserState.STATE_SHUTDOWN) { stopped = false; stopped = false; } else { } else { stopped = true; stopped = true; Loading @@ -729,10 +730,10 @@ class UserController implements Handler.Callback { mStartedUsers.remove(userId); mStartedUsers.remove(userId); mUserLru.remove(Integer.valueOf(userId)); mUserLru.remove(Integer.valueOf(userId)); updateStartedUserArrayLU(); updateStartedUserArrayLU(); forceStopUser = true; } } } } if (forceStopUser) { if (stopped) { mInjector.getUserManagerInternal().removeUserState(userId); mInjector.getUserManagerInternal().removeUserState(userId); mInjector.activityManagerOnUserStopped(userId); mInjector.activityManagerOnUserStopped(userId); // Clean up all state and processes associated with the user. // Clean up all state and processes associated with the user. Loading @@ -755,12 +756,23 @@ class UserController implements Handler.Callback { if (getUserInfo(userId).isEphemeral()) { if (getUserInfo(userId).isEphemeral()) { mInjector.getUserManager().removeUserEvenWhenDisallowed(userId); mInjector.getUserManager().removeUserEvenWhenDisallowed(userId); } } // Evict the user's credential encryption key. // Evict the user's credential encryption key. Performed on FgThread to make it // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking // to prevent data corruption. FgThread.getHandler().post(() -> { synchronized (mLock) { if (mStartedUsers.get(userId) != null) { Slog.w(TAG, "User was restarted, skipping key eviction"); return; } } try { try { getStorageManager().lockUserKey(userId); getStorageManager().lockUserKey(userId); } catch (RemoteException re) { } catch (RemoteException re) { throw re.rethrowAsRuntimeException(); throw re.rethrowAsRuntimeException(); } } }); } } } } Loading