summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityManagerInternal.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java8
-rw-r--r--services/core/java/com/android/server/am/UserController.java9
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java23
5 files changed, 44 insertions, 8 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 999db18a1229..6151b8e2ef0a 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -142,6 +142,15 @@ public abstract class ActivityManagerInternal {
String processName, String abiOverride, int uid, Runnable crashHandler);
/**
+ * Called when a user is being deleted. This can happen during normal device usage
+ * or just at startup, when partially removed users are purged. Any state persisted by the
+ * ActivityManager should be purged now.
+ *
+ * @param userId The user being cleaned up.
+ */
+ public abstract void onUserRemoving(@UserIdInt int userId);
+
+ /**
* Called when a user has been deleted. This can happen during normal device usage
* or just at startup, when partially removed users are purged. Any state persisted by the
* ActivityManager should be purged now.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5c14c4a2aabe..61d439b2defe 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16659,7 +16659,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public void onUserRemoved(@UserIdInt int userId) {
+ public void onUserRemoving(@UserIdInt int userId) {
// Clean up any ActivityTaskManager state (by telling it the user is stopped)
mAtmInternal.onUserStopped(userId);
// Clean up various services by removing the user
@@ -16673,6 +16673,12 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void onUserRemoved(int userId) {
+ // Clean up UserController state
+ mUserController.onUserRemoved(userId);
+ }
+
+ @Override
public boolean startUserInBackground(final int userId) {
return ActivityManagerService.this.startUserInBackground(userId);
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 9f302fed626f..d76c04ac7f31 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -445,11 +445,6 @@ class UserController implements Handler.Callback {
public void onUserCreated(UserInfo user, Object token) {
onUserAdded(user);
}
-
- @Override
- public void onUserRemoved(UserInfo user) {
- UserController.this.onUserRemoved(user.id);
- }
};
UserController(ActivityManagerService service) {
@@ -3357,10 +3352,12 @@ class UserController implements Handler.Callback {
if (mUserProfileGroupIds.keyAt(i) == userId
|| mUserProfileGroupIds.valueAt(i) == userId) {
mUserProfileGroupIds.removeAt(i);
-
}
}
mCurrentProfileIds = ArrayUtils.removeInt(mCurrentProfileIds, userId);
+ mUserLru.remove((Integer) userId);
+ mStartedUsers.remove(userId);
+ updateStartedUserArrayLU();
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8249d65868cd..81956fbb55e6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -6661,7 +6661,7 @@ public class UserManagerService extends IUserManager.Stub {
+ userId);
}
new Thread(() -> {
- getActivityManagerInternal().onUserRemoved(userId);
+ getActivityManagerInternal().onUserRemoving(userId);
removeUserState(userId);
}).start();
}
@@ -6701,6 +6701,7 @@ public class UserManagerService extends IUserManager.Stub {
synchronized (mUsersLock) {
removeUserDataLU(userId);
mIsUserManaged.delete(userId);
+ getActivityManagerInternal().onUserRemoved(userId);
}
synchronized (mUserStates) {
mUserStates.delete(userId);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index 0bf419ec242c..998c1d1a23b1 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -35,6 +36,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.DropBoxManager;
@@ -48,6 +50,7 @@ import android.os.Parcel;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.provider.Settings;
@@ -68,6 +71,7 @@ import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -150,6 +154,25 @@ public class ActivityManagerTest {
}
@Test
+ public void testRemovedUserShouldNotBeRunning() throws Exception {
+ final UserManager userManager = mContext.getSystemService(UserManager.class);
+ assertNotNull("UserManager should not be null", userManager);
+ final UserInfo user = userManager.createUser(
+ "TestUser", UserManager.USER_TYPE_FULL_SECONDARY, 0);
+
+ mService.startUserInBackground(user.id);
+ assertTrue("User should be running", mService.isUserRunning(user.id, 0));
+ assertTrue("User should be in running users",
+ Arrays.stream(mService.getRunningUserIds()).anyMatch(x -> x == user.id));
+
+ userManager.removeUser(user.id);
+ mService.startUserInBackground(user.id);
+ assertFalse("Removed user should not be running", mService.isUserRunning(user.id, 0));
+ assertFalse("Removed user should not be in running users",
+ Arrays.stream(mService.getRunningUserIds()).anyMatch(x -> x == user.id));
+ }
+
+ @Test
public void testServiceUnbindAndKilling() {
for (int i = TEST_LOOPS; i > 0; i--) {
runOnce(i);