Merge "Restart the user only after the key is evicted." into qt-dev

This commit is contained in:
TreeHugger Robot
2019-05-09 23:58:37 +00:00
committed by Android (Google) Code Review
3 changed files with 48 additions and 27 deletions

View File

@@ -17369,7 +17369,7 @@ public class ActivityManagerService extends IActivityManager.Stub
@Override
public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
return mUserController.stopUser(userId, force, callback);
return mUserController.stopUser(userId, force, callback, null /* keyEvictedCallback */);
}
@Override

View File

@@ -98,6 +98,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.SystemServiceManager;
import com.android.server.am.UserState.KeyEvictedCallback;
import com.android.server.pm.UserManagerService;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerService;
@@ -319,7 +320,7 @@ class UserController implements Handler.Callback {
// Owner/System user and current user can't be stopped
continue;
}
if (stopUsersLU(userId, false, null) == USER_OP_SUCCESS) {
if (stopUsersLU(userId, false, null, null) == USER_OP_SUCCESS) {
iterator.remove();
}
}
@@ -586,19 +587,18 @@ class UserController implements Handler.Callback {
}
int restartUser(final int userId, final boolean foreground) {
return stopUser(userId, /* force */ true, new IStopUserCallback.Stub() {
return stopUser(userId, /* force */ true, null, new KeyEvictedCallback() {
@Override
public void userStopped(final int userId) {
public void keyEvicted(@UserIdInt int userId) {
// Post to the same handler that this callback is called from to ensure the user
// cleanup is complete before restarting.
mHandler.post(() -> startUser(userId, foreground));
mHandler.post(() -> UserController.this.startUser(userId, foreground));
}
@Override
public void userStopAborted(final int userId) {}
});
}
int stopUser(final int userId, final boolean force, final IStopUserCallback callback) {
int stopUser(final int userId, final boolean force, final IStopUserCallback stopUserCallback,
KeyEvictedCallback keyEvictedCallback) {
if (mInjector.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: switchUser() from pid="
@@ -613,7 +613,7 @@ class UserController implements Handler.Callback {
}
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
synchronized (mLock) {
return stopUsersLU(userId, force, callback);
return stopUsersLU(userId, force, stopUserCallback, keyEvictedCallback);
}
}
@@ -622,7 +622,8 @@ class UserController implements Handler.Callback {
* {@link #getUsersToStopLU(int)} to determine the list of users that should be stopped.
*/
@GuardedBy("mLock")
private int stopUsersLU(final int userId, boolean force, final IStopUserCallback callback) {
private int stopUsersLU(final int userId, boolean force,
final IStopUserCallback stopUserCallback, KeyEvictedCallback keyEvictedCallback) {
if (userId == UserHandle.USER_SYSTEM) {
return USER_OP_ERROR_IS_SYSTEM;
}
@@ -640,7 +641,7 @@ class UserController implements Handler.Callback {
if (force) {
Slog.i(TAG,
"Force stop user " + userId + ". Related users will not be stopped");
stopSingleUserLU(userId, callback);
stopSingleUserLU(userId, stopUserCallback, keyEvictedCallback);
return USER_OP_SUCCESS;
}
return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
@@ -648,22 +649,25 @@ class UserController implements Handler.Callback {
}
if (DEBUG_MU) Slog.i(TAG, "stopUsersLocked usersToStop=" + Arrays.toString(usersToStop));
for (int userIdToStop : usersToStop) {
stopSingleUserLU(userIdToStop, userIdToStop == userId ? callback : null);
stopSingleUserLU(userIdToStop,
userIdToStop == userId ? stopUserCallback : null,
userIdToStop == userId ? keyEvictedCallback : null);
}
return USER_OP_SUCCESS;
}
@GuardedBy("mLock")
private void stopSingleUserLU(final int userId, final IStopUserCallback callback) {
private void stopSingleUserLU(final int userId, final IStopUserCallback stopUserCallback,
KeyEvictedCallback keyEvictedCallback) {
if (DEBUG_MU) Slog.i(TAG, "stopSingleUserLocked userId=" + userId);
final UserState uss = mStartedUsers.get(userId);
if (uss == null) {
// User is not started, nothing to do... but we do need to
// callback if requested.
if (callback != null) {
if (stopUserCallback != null) {
mHandler.post(() -> {
try {
callback.userStopped(userId);
stopUserCallback.userStopped(userId);
} catch (RemoteException e) {
}
});
@@ -671,8 +675,11 @@ class UserController implements Handler.Callback {
return;
}
if (callback != null) {
uss.mStopCallbacks.add(callback);
if (stopUserCallback != null) {
uss.mStopCallbacks.add(stopUserCallback);
}
if (keyEvictedCallback != null) {
uss.mKeyEvictedCallbacks.add(keyEvictedCallback);
}
if (uss.state != UserState.STATE_STOPPING
@@ -753,10 +760,12 @@ class UserController implements Handler.Callback {
final int userId = uss.mHandle.getIdentifier();
final boolean stopped;
boolean lockUser = true;
ArrayList<IStopUserCallback> callbacks;
final ArrayList<IStopUserCallback> stopCallbacks;
final ArrayList<KeyEvictedCallback> keyEvictedCallbacks;
int userIdToLock = userId;
synchronized (mLock) {
callbacks = new ArrayList<>(uss.mStopCallbacks);
stopCallbacks = new ArrayList<>(uss.mStopCallbacks);
keyEvictedCallbacks = new ArrayList<>(uss.mKeyEvictedCallbacks);
if (mStartedUsers.get(userId) != uss || uss.state != UserState.STATE_SHUTDOWN) {
stopped = false;
} else {
@@ -779,11 +788,11 @@ class UserController implements Handler.Callback {
forceStopUser(userId, "finish user");
}
for (int i = 0; i < callbacks.size(); i++) {
for (final IStopUserCallback callback : stopCallbacks) {
try {
if (stopped) callbacks.get(i).userStopped(userId);
else callbacks.get(i).userStopAborted(userId);
} catch (RemoteException e) {
if (stopped) callback.userStopped(userId);
else callback.userStopAborted(userId);
} catch (RemoteException ignored) {
}
}
@@ -814,6 +823,11 @@ class UserController implements Handler.Callback {
} catch (RemoteException re) {
throw re.rethrowAsRuntimeException();
}
if (userIdToLockF == userId) {
for (final KeyEvictedCallback callback : keyEvictedCallbacks) {
callback.keyEvicted(userId);
}
}
});
}
}
@@ -912,7 +926,7 @@ class UserController implements Handler.Callback {
if (userInfo.isGuest() || userInfo.isEphemeral()) {
// This is a user to be stopped.
synchronized (mLock) {
stopUsersLU(oldUserId, true, null);
stopUsersLU(oldUserId, true, null, null);
}
}
}
@@ -1392,7 +1406,7 @@ class UserController implements Handler.Callback {
synchronized (mLock) {
if (DEBUG_MU) Slog.i(TAG, "stopBackgroundUsersIfEnforced stopping " + oldUserId
+ " and related users");
stopUsersLU(oldUserId, false, null);
stopUsersLU(oldUserId, false, null, null);
}
}

View File

@@ -19,6 +19,7 @@ package com.android.server.am;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.annotation.UserIdInt;
import android.app.IStopUserCallback;
import android.os.Trace;
import android.os.UserHandle;
@@ -48,15 +49,21 @@ public final class UserState {
public final static int STATE_SHUTDOWN = 5;
public final UserHandle mHandle;
public final ArrayList<IStopUserCallback> mStopCallbacks
= new ArrayList<IStopUserCallback>();
public final ArrayList<IStopUserCallback> mStopCallbacks = new ArrayList<>();
public final ProgressReporter mUnlockProgress;
public final ArrayList<KeyEvictedCallback> mKeyEvictedCallbacks = new ArrayList<>();
public int state = STATE_BOOTING;
public int lastState = STATE_BOOTING;
public boolean switching;
public boolean tokenProvided;
/** Callback for key eviction. */
public interface KeyEvictedCallback {
/** Invoked when the key is evicted. */
void keyEvicted(@UserIdInt int userId);
}
/**
* The last time that a provider was reported to usage stats as being brought to important
* foreground procstate.