Delay cleaning user tasks until user is removed
Fixes #24301208 No recent apps shows when switching
between users.
Instead of cleaning up when stopping a user, we
should remove tasks when removing a user, since
recents tasks should be persisted across reboots.
Reboots are similar to stopping and starting users.
Change-Id: I9a250792077cca5f18ae1a10bc36f7b97e8ea867
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 0577d59..7d8dc04 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.IStopUserCallback;
import android.app.admin.DevicePolicyManager;
@@ -64,7 +65,7 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
-import com.android.server.accounts.AccountManagerService;
+import com.android.server.LocalServices;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -242,13 +243,15 @@
synchronized (mPackagesLock) {
// Prune out any partially created/partially removed users.
ArrayList<UserInfo> partials = new ArrayList<UserInfo>();
- for (int i = 0; i < mUsers.size(); i++) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i);
if ((ui.partial || ui.guestToRemove) && i != 0) {
partials.add(ui);
}
}
- for (int i = 0; i < partials.size(); i++) {
+ final int partialsSize = partials.size();
+ for (int i = 0; i < partialsSize; i++) {
UserInfo ui = partials.get(i);
Slog.w(LOG_TAG, "Removing partially created user " + ui.id
+ " (name=" + ui.name + ")");
@@ -272,7 +275,8 @@
public UserInfo getPrimaryUser() {
checkManageUsersPermission("query users");
synchronized (mPackagesLock) {
- for (int i = 0; i < mUsers.size(); i++) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i);
if (ui.isPrimary()) {
return ui;
@@ -287,7 +291,8 @@
checkManageUsersPermission("query users");
synchronized (mPackagesLock) {
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
- for (int i = 0; i < mUsers.size(); i++) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
UserInfo ui = mUsers.valueAt(i);
if (ui.partial) {
continue;
@@ -323,7 +328,8 @@
// Probably a dying user
return users;
}
- for (int i = 0; i < mUsers.size(); i++) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
UserInfo profile = mUsers.valueAt(i);
if (!isProfileOf(user, profile)) {
continue;
@@ -978,7 +984,8 @@
serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
writeRestrictionsLocked(serializer, mGuestRestrictions);
serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
- for (int i = 0; i < mUsers.size(); i++) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
UserInfo user = mUsers.valueAt(i);
serializer.startTag(null, TAG_USER);
serializer.attribute(null, ATTR_ID, Integer.toString(user.id));
@@ -1555,6 +1562,9 @@
}
new Thread() {
public void run() {
+ // Clean up any ActivityManager state
+ LocalServices.getService(ActivityManagerInternal.class)
+ .onUserRemoved(userHandle);
synchronized (mInstallLock) {
synchronized (mPackagesLock) {
removeUserStateLocked(userHandle);
@@ -1919,14 +1929,15 @@
*/
private void updateUserIdsLocked() {
int num = 0;
- for (int i = 0; i < mUsers.size(); i++) {
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
if (!mUsers.valueAt(i).partial) {
num++;
}
}
final int[] newUsers = new int[num];
int n = 0;
- for (int i = 0; i < mUsers.size(); i++) {
+ for (int i = 0; i < userSize; i++) {
if (!mUsers.valueAt(i).partial) {
newUsers[n++] = mUsers.keyAt(i);
}