Loading core/java/android/app/ActivityManagerInternal.java +9 −0 Original line number Diff line number Diff line Loading @@ -55,4 +55,13 @@ public abstract class ActivityManagerInternal { * @param userId ID of the user or {@link android.os.UserHandle#USER_ALL} */ public abstract ComponentName getHomeActivityForUser(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. * * @param userId The user being cleaned up. */ public abstract void onUserRemoved(int userId); } services/core/java/com/android/server/am/ActivityManagerService.java +13 −4 Original line number Diff line number Diff line Loading @@ -11893,7 +11893,8 @@ public final class ActivityManagerService extends ActivityManagerNative updateCurrentProfileIdsLocked(); mRecentTasks.clear(); mRecentTasks.addAll(mTaskPersister.restoreTasksLocked()); mRecentTasks.addAll(mTaskPersister.restoreTasksLocked( getUserManagerLocked().getUserIds())); mRecentTasks.cleanupLocked(UserHandle.USER_ALL); mTaskPersister.startPersisting(); Loading Loading @@ -20644,9 +20645,6 @@ public final class ActivityManagerService extends ActivityManagerNative // Kill all the processes for the user. forceStopUserLocked(userId, "finish user"); } // Explicitly remove the old information in mRecentTasks. mRecentTasks.removeTasksForUserLocked(userId); } for (int i=0; i<callbacks.size(); i++) { Loading @@ -20665,6 +20663,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } void onUserRemovedLocked(int userId) { mRecentTasks.removeTasksForUserLocked(userId); } @Override public UserInfo getCurrentUser() { if ((checkCallingPermission(INTERACT_ACROSS_USERS) Loading Loading @@ -20949,6 +20951,13 @@ public final class ActivityManagerService extends ActivityManagerNative return homeActivity == null ? null : homeActivity.realActivity; } } @Override public void onUserRemoved(int userId) { synchronized (ActivityManagerService.this) { ActivityManagerService.this.onUserRemovedLocked(userId); } } } private final class SleepTokenImpl extends SleepToken { services/core/java/com/android/server/am/TaskPersister.java +8 −4 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.SparseArray; import android.util.Xml; import android.os.Process; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; Loading Loading @@ -330,7 +331,7 @@ public class TaskPersister { return null; } ArrayList<TaskRecord> restoreTasksLocked() { ArrayList<TaskRecord> restoreTasksLocked(final int [] validUserIds) { final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>(); ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>(); Loading Loading @@ -362,15 +363,18 @@ public class TaskPersister { if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" + task); if (task != null) { task.isPersistable = true; // XXX Don't add to write queue... there is no reason to write // out the stuff we just read, if we don't write it we will // read the same thing again. //mWriteQueue.add(new TaskWriteQueueItem(task)); tasks.add(task); final int taskId = task.taskId; recoveredTaskIds.add(taskId); mStackSupervisor.setNextTaskId(taskId); // Check if it's a valid user id. Don't add tasks for removed users. if (ArrayUtils.contains(validUserIds, task.userId)) { task.isPersistable = true; tasks.add(task); recoveredTaskIds.add(taskId); } } else { Slog.e(TAG, "Unable to restore taskFile=" + taskFile + ": " + fileToString(taskFile)); Loading services/core/java/com/android/server/pm/UserManagerService.java +20 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.accounts.Account; 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; Loading Loading @@ -64,7 +65,7 @@ import com.android.internal.annotations.VisibleForTesting; 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; Loading Loading @@ -242,13 +243,15 @@ public class UserManagerService extends IUserManager.Stub { 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 + ")"); Loading @@ -272,7 +275,8 @@ public class UserManagerService extends IUserManager.Stub { 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; Loading @@ -287,7 +291,8 @@ public class UserManagerService extends IUserManager.Stub { 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; Loading Loading @@ -323,7 +328,8 @@ public class UserManagerService extends IUserManager.Stub { // 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; Loading Loading @@ -1010,7 +1016,8 @@ public class UserManagerService extends IUserManager.Stub { 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)); Loading Loading @@ -1587,6 +1594,9 @@ public class UserManagerService extends IUserManager.Stub { } new Thread() { public void run() { // Clean up any ActivityManager state LocalServices.getService(ActivityManagerInternal.class) .onUserRemoved(userHandle); synchronized (mInstallLock) { synchronized (mPackagesLock) { removeUserStateLocked(userHandle); Loading Loading @@ -1951,14 +1961,15 @@ public class UserManagerService extends IUserManager.Stub { */ 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); } Loading Loading
core/java/android/app/ActivityManagerInternal.java +9 −0 Original line number Diff line number Diff line Loading @@ -55,4 +55,13 @@ public abstract class ActivityManagerInternal { * @param userId ID of the user or {@link android.os.UserHandle#USER_ALL} */ public abstract ComponentName getHomeActivityForUser(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. * * @param userId The user being cleaned up. */ public abstract void onUserRemoved(int userId); }
services/core/java/com/android/server/am/ActivityManagerService.java +13 −4 Original line number Diff line number Diff line Loading @@ -11893,7 +11893,8 @@ public final class ActivityManagerService extends ActivityManagerNative updateCurrentProfileIdsLocked(); mRecentTasks.clear(); mRecentTasks.addAll(mTaskPersister.restoreTasksLocked()); mRecentTasks.addAll(mTaskPersister.restoreTasksLocked( getUserManagerLocked().getUserIds())); mRecentTasks.cleanupLocked(UserHandle.USER_ALL); mTaskPersister.startPersisting(); Loading Loading @@ -20644,9 +20645,6 @@ public final class ActivityManagerService extends ActivityManagerNative // Kill all the processes for the user. forceStopUserLocked(userId, "finish user"); } // Explicitly remove the old information in mRecentTasks. mRecentTasks.removeTasksForUserLocked(userId); } for (int i=0; i<callbacks.size(); i++) { Loading @@ -20665,6 +20663,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } void onUserRemovedLocked(int userId) { mRecentTasks.removeTasksForUserLocked(userId); } @Override public UserInfo getCurrentUser() { if ((checkCallingPermission(INTERACT_ACROSS_USERS) Loading Loading @@ -20949,6 +20951,13 @@ public final class ActivityManagerService extends ActivityManagerNative return homeActivity == null ? null : homeActivity.realActivity; } } @Override public void onUserRemoved(int userId) { synchronized (ActivityManagerService.this) { ActivityManagerService.this.onUserRemovedLocked(userId); } } } private final class SleepTokenImpl extends SleepToken {
services/core/java/com/android/server/am/TaskPersister.java +8 −4 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.util.SparseArray; import android.util.Xml; import android.os.Process; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; Loading Loading @@ -330,7 +331,7 @@ public class TaskPersister { return null; } ArrayList<TaskRecord> restoreTasksLocked() { ArrayList<TaskRecord> restoreTasksLocked(final int [] validUserIds) { final ArrayList<TaskRecord> tasks = new ArrayList<TaskRecord>(); ArraySet<Integer> recoveredTaskIds = new ArraySet<Integer>(); Loading Loading @@ -362,15 +363,18 @@ public class TaskPersister { if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" + task); if (task != null) { task.isPersistable = true; // XXX Don't add to write queue... there is no reason to write // out the stuff we just read, if we don't write it we will // read the same thing again. //mWriteQueue.add(new TaskWriteQueueItem(task)); tasks.add(task); final int taskId = task.taskId; recoveredTaskIds.add(taskId); mStackSupervisor.setNextTaskId(taskId); // Check if it's a valid user id. Don't add tasks for removed users. if (ArrayUtils.contains(validUserIds, task.userId)) { task.isPersistable = true; tasks.add(task); recoveredTaskIds.add(taskId); } } else { Slog.e(TAG, "Unable to restore taskFile=" + taskFile + ": " + fileToString(taskFile)); Loading
services/core/java/com/android/server/pm/UserManagerService.java +20 −9 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.accounts.Account; 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; Loading Loading @@ -64,7 +65,7 @@ import com.android.internal.annotations.VisibleForTesting; 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; Loading Loading @@ -242,13 +243,15 @@ public class UserManagerService extends IUserManager.Stub { 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 + ")"); Loading @@ -272,7 +275,8 @@ public class UserManagerService extends IUserManager.Stub { 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; Loading @@ -287,7 +291,8 @@ public class UserManagerService extends IUserManager.Stub { 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; Loading Loading @@ -323,7 +328,8 @@ public class UserManagerService extends IUserManager.Stub { // 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; Loading Loading @@ -1010,7 +1016,8 @@ public class UserManagerService extends IUserManager.Stub { 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)); Loading Loading @@ -1587,6 +1594,9 @@ public class UserManagerService extends IUserManager.Stub { } new Thread() { public void run() { // Clean up any ActivityManager state LocalServices.getService(ActivityManagerInternal.class) .onUserRemoved(userHandle); synchronized (mInstallLock) { synchronized (mPackagesLock) { removeUserStateLocked(userHandle); Loading Loading @@ -1951,14 +1961,15 @@ public class UserManagerService extends IUserManager.Stub { */ 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); } Loading