Loading core/java/android/app/ActivityManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,17 @@ public abstract class ActivityManagerInternal { public abstract void setVoiceInteractionManagerProvider( @Nullable VoiceInteractionManagerProvider provider); /** * Get whether or not the previous user's packages will be killed before the user is * stopped during a user switch. * * <p> The primary use case of this method is for {@link com.android.server.SystemService} * classes to call this API in their * {@link com.android.server.SystemService#onUserSwitching} method implementation to prevent * restarting any of the previous user's processes that will be killed during the user switch. */ public abstract boolean isEarlyPackageKillEnabledForUserSwitch(int fromUserId, int toUserId); /** * Sets whether the current foreground user (and its profiles) should be stopped after switched * out. Loading core/java/android/content/pm/multiuser.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,13 @@ flag { bug: "330351042" } flag { name: "stop_previous_user_apps" namespace: "multiuser" description: "Stop the previous user apps early in a user switch" bug: "323200731" } flag { name: "disable_private_space_items_on_home" namespace: "profile_experiences" Loading services/core/java/com/android/server/am/ActiveServices.java +16 −3 Original line number Diff line number Diff line Loading @@ -6962,7 +6962,8 @@ public final class ActiveServices { } private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses, boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services) { boolean evenPersistent, boolean doit, int minOomAdj, ArrayMap<ComponentName, ServiceRecord> services) { boolean didSomething = false; for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord service = services.valueAt(i); Loading @@ -6970,6 +6971,11 @@ public final class ActiveServices { || (service.packageName.equals(packageName) && (filterByClasses == null || filterByClasses.contains(service.name.getClassName()))); if (service.app != null && service.app.mState.getCurAdj() < minOomAdj) { Slog.i(TAG, "Skip force stopping service " + service + ": below minimum oom adj level"); continue; } if (sameComponent && (service.app == null || evenPersistent || !service.app.isPersistent())) { if (!doit) { Loading @@ -6993,6 +6999,12 @@ public final class ActiveServices { boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses, int userId, boolean evenPersistent, boolean fullStop, boolean doit) { return bringDownDisabledPackageServicesLocked(packageName, filterByClasses, userId, evenPersistent, fullStop, doit, ProcessList.INVALID_ADJ); } boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses, int userId, boolean evenPersistent, boolean fullStop, boolean doit, int minOomAdj) { boolean didSomething = false; if (mTmpCollectionResults != null) { Loading @@ -7002,7 +7014,8 @@ public final class ActiveServices { if (userId == UserHandle.USER_ALL) { for (int i = mServiceMap.size() - 1; i >= 0; i--) { didSomething |= collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, mServiceMap.valueAt(i).mServicesByInstanceName); evenPersistent, doit, minOomAdj, mServiceMap.valueAt(i).mServicesByInstanceName); if (!doit && didSomething) { return true; } Loading @@ -7015,7 +7028,7 @@ public final class ActiveServices { if (smap != null) { ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByInstanceName; didSomething = collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, items); evenPersistent, doit, minOomAdj, items); } if (doit && filterByClasses == null) { forceStopPackageLocked(packageName, userId); Loading services/core/java/com/android/server/am/ActivityManagerService.java +28 −3 Original line number Diff line number Diff line Loading @@ -4376,6 +4376,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } @GuardedBy("this") final boolean forceStopUserPackagesLocked(int userId, String reasonString, boolean evenImportantServices) { int minOomAdj = evenImportantServices ? ProcessList.INVALID_ADJ : ProcessList.FOREGROUND_APP_ADJ; return forceStopPackageInternalLocked(null, -1, false, false, true, false, false, false, userId, reasonString, ApplicationExitInfo.REASON_USER_STOPPED, minOomAdj); } @GuardedBy("this") final boolean forceStopPackageLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, Loading @@ -4385,7 +4395,6 @@ public class ActivityManagerService extends IActivityManager.Stub : ApplicationExitInfo.REASON_USER_REQUESTED; return forceStopPackageLocked(packageName, appId, callerWillRestart, purgeCache, doit, evenPersistent, uninstalling, packageStateStopped, userId, reasonString, reason); } @GuardedBy("this") Loading @@ -4393,6 +4402,16 @@ public class ActivityManagerService extends IActivityManager.Stub boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, boolean packageStateStopped, int userId, String reasonString, int reason) { return forceStopPackageInternalLocked(packageName, appId, callerWillRestart, purgeCache, doit, evenPersistent, uninstalling, packageStateStopped, userId, reasonString, reason, ProcessList.INVALID_ADJ); } @GuardedBy("this") private boolean forceStopPackageInternalLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, boolean packageStateStopped, int userId, String reasonString, int reason, int minOomAdj) { int i; if (userId == UserHandle.USER_ALL && packageName == null) { Loading Loading @@ -4431,7 +4450,7 @@ public class ActivityManagerService extends IActivityManager.Stub } didSomething |= mProcessList.killPackageProcessesLSP(packageName, appId, userId, ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit, minOomAdj, callerWillRestart, false /* allowRestart */, doit, evenPersistent, true /* setRemoved */, uninstalling, reason, subReason, Loading @@ -4440,7 +4459,8 @@ public class ActivityManagerService extends IActivityManager.Stub } if (mServices.bringDownDisabledPackageServicesLocked( packageName, null /* filterByClasses */, userId, evenPersistent, true, doit)) { packageName, null /* filterByClasses */, userId, evenPersistent, true, doit, minOomAdj)) { if (!doit) { return true; } Loading Loading @@ -19871,6 +19891,11 @@ public class ActivityManagerService extends IActivityManager.Stub ActivityManagerService.this.setVoiceInteractionManagerProvider(provider); } @Override public boolean isEarlyPackageKillEnabledForUserSwitch(int fromUserId, int toUserId) { return mUserController.isEarlyPackageKillEnabledForUserSwitch(fromUserId, toUserId); } @Override public void setStopUserOnSwitch(int value) { ActivityManagerService.this.setStopUserOnSwitch(value); services/core/java/com/android/server/am/UserController.java +57 −9 Original line number Diff line number Diff line Loading @@ -439,6 +439,15 @@ class UserController implements Handler.Callback { @GuardedBy("mLock") private final List<PendingUserStart> mPendingUserStarts = new ArrayList<>(); /** * Contains users which cannot abort the shutdown process. * * <p> For example, we don't abort shutdown for users whose processes have already been stopped * due to {@link #isEarlyPackageKillEnabledForUserSwitch(int, int)}. */ @GuardedBy("mLock") private final ArraySet<Integer> mDoNotAbortShutdownUserIds = new ArraySet<>(); private final UserLifecycleListener mUserLifecycleListener = new UserLifecycleListener() { @Override public void onUserCreated(UserInfo user, Object token) { Loading Loading @@ -509,11 +518,11 @@ class UserController implements Handler.Callback { } } private boolean shouldStopUserOnSwitch() { private boolean isStopUserOnSwitchEnabled() { synchronized (mLock) { if (mStopUserOnSwitch != STOP_USER_ON_SWITCH_DEFAULT) { final boolean value = mStopUserOnSwitch == STOP_USER_ON_SWITCH_TRUE; Slogf.i(TAG, "shouldStopUserOnSwitch(): returning overridden value (%b)", value); Slogf.i(TAG, "isStopUserOnSwitchEnabled(): returning overridden value (%b)", value); return value; } } Loading @@ -521,6 +530,26 @@ class UserController implements Handler.Callback { return property == -1 ? mDelayUserDataLocking : property == 1; } /** * Get whether or not the previous user's packages will be killed before the user is * stopped during a user switch. * * <p> The primary use case of this method is for {@link com.android.server.SystemService} * classes to call this API in their * {@link com.android.server.SystemService#onUserSwitching} method implementation to prevent * restarting any of the previous user's processes that will be killed during the user switch. */ boolean isEarlyPackageKillEnabledForUserSwitch(int fromUserId, int toUserId) { // NOTE: The logic in this method could be extended to cover other cases where // the previous user is also stopped like: guest users, ephemeral users, // and users with DISALLOW_RUN_IN_BACKGROUND. Currently, this is not done // because early killing is not enabled for these cases by default. if (fromUserId == UserHandle.USER_SYSTEM) { return false; } return isStopUserOnSwitchEnabled(); } void finishUserSwitch(UserState uss) { // This call holds the AM lock so we post to the handler. mHandler.post(() -> { Loading Loading @@ -1247,6 +1276,7 @@ class UserController implements Handler.Callback { return; } uss.setState(UserState.STATE_SHUTDOWN); mDoNotAbortShutdownUserIds.remove(userId); } TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("setUserState-STATE_SHUTDOWN-" + userId + "-[stopUser]"); Loading Loading @@ -1555,7 +1585,8 @@ class UserController implements Handler.Callback { private void stopPackagesOfStoppedUser(@UserIdInt int userId, String reason) { if (DEBUG_MU) Slogf.i(TAG, "stopPackagesOfStoppedUser(%d): %s", userId, reason); mInjector.activityManagerForceStopPackage(userId, reason); mInjector.activityManagerForceStopUserPackages(userId, reason, /* evenImportantServices= */ true); if (mInjector.getUserManager().isPreCreated(userId)) { // Don't fire intent for precreated. return; Loading Loading @@ -1608,6 +1639,21 @@ class UserController implements Handler.Callback { } } private void stopPreviousUserPackagesIfEnabled(int fromUserId, int toUserId) { if (!android.multiuser.Flags.stopPreviousUserApps() || !isEarlyPackageKillEnabledForUserSwitch(fromUserId, toUserId)) { return; } // Stop the previous user's packages early to reduce resource usage // during user switching. Only do this when the previous user will // be stopped regardless. synchronized (mLock) { mDoNotAbortShutdownUserIds.add(fromUserId); } mInjector.activityManagerForceStopUserPackages(fromUserId, "early stop user packages", /* evenImportantServices= */ false); } void scheduleStartProfiles() { // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no Loading Loading @@ -1889,7 +1935,8 @@ class UserController implements Handler.Callback { updateStartedUserArrayLU(); needStart = true; updateUmState = true; } else if (uss.state == UserState.STATE_SHUTDOWN) { } else if (uss.state == UserState.STATE_SHUTDOWN || mDoNotAbortShutdownUserIds.contains(userId)) { Slogf.i(TAG, "User #" + userId + " is shutting down - will start after full shutdown"); mPendingUserStarts.add(new PendingUserStart(userId, userStartMode, Loading Loading @@ -2293,7 +2340,7 @@ class UserController implements Handler.Callback { hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, oldUserId); synchronized (mLock) { // If running in background is disabled or mStopUserOnSwitch mode, stop the user. if (hasRestriction || shouldStopUserOnSwitch()) { if (hasRestriction || isStopUserOnSwitchEnabled()) { Slogf.i(TAG, "Stopping user %d and its profiles on user switch", oldUserId); stopUsersLU(oldUserId, /* allowDelayedLocking= */ false, null, null); return; Loading Loading @@ -3425,7 +3472,7 @@ class UserController implements Handler.Callback { pw.println(" mLastActiveUsersForDelayedLocking:" + mLastActiveUsersForDelayedLocking); pw.println(" mDelayUserDataLocking:" + mDelayUserDataLocking); pw.println(" mAllowUserUnlocking:" + mAllowUserUnlocking); pw.println(" shouldStopUserOnSwitch():" + shouldStopUserOnSwitch()); pw.println(" isStopUserOnSwitchEnabled():" + isStopUserOnSwitchEnabled()); pw.println(" mStopUserOnSwitch:" + mStopUserOnSwitch); pw.println(" mMaxRunningUsers:" + mMaxRunningUsers); pw.println(" mBackgroundUserScheduledStopTimeSecs:" Loading Loading @@ -3522,6 +3569,7 @@ class UserController implements Handler.Callback { Integer.toString(msg.arg1), msg.arg1); mInjector.getSystemServiceManager().onUserSwitching(msg.arg2, msg.arg1); stopPreviousUserPackagesIfEnabled(msg.arg2, msg.arg1); scheduleOnUserCompletedEvent(msg.arg1, UserCompletedEventType.EVENT_TYPE_USER_SWITCHING, USER_COMPLETED_EVENT_DELAY_MS); Loading Loading @@ -3896,10 +3944,10 @@ class UserController implements Handler.Callback { }.sendNext(); } void activityManagerForceStopPackage(@UserIdInt int userId, String reason) { void activityManagerForceStopUserPackages(@UserIdInt int userId, String reason, boolean evenImportantServices) { synchronized (mService) { mService.forceStopPackageLocked(null, -1, false, false, true, false, false, false, userId, reason); mService.forceStopUserPackagesLocked(userId, reason, evenImportantServices); } }; Loading Loading
core/java/android/app/ActivityManagerInternal.java +11 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,17 @@ public abstract class ActivityManagerInternal { public abstract void setVoiceInteractionManagerProvider( @Nullable VoiceInteractionManagerProvider provider); /** * Get whether or not the previous user's packages will be killed before the user is * stopped during a user switch. * * <p> The primary use case of this method is for {@link com.android.server.SystemService} * classes to call this API in their * {@link com.android.server.SystemService#onUserSwitching} method implementation to prevent * restarting any of the previous user's processes that will be killed during the user switch. */ public abstract boolean isEarlyPackageKillEnabledForUserSwitch(int fromUserId, int toUserId); /** * Sets whether the current foreground user (and its profiles) should be stopped after switched * out. Loading
core/java/android/content/pm/multiuser.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -287,6 +287,13 @@ flag { bug: "330351042" } flag { name: "stop_previous_user_apps" namespace: "multiuser" description: "Stop the previous user apps early in a user switch" bug: "323200731" } flag { name: "disable_private_space_items_on_home" namespace: "profile_experiences" Loading
services/core/java/com/android/server/am/ActiveServices.java +16 −3 Original line number Diff line number Diff line Loading @@ -6962,7 +6962,8 @@ public final class ActiveServices { } private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses, boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services) { boolean evenPersistent, boolean doit, int minOomAdj, ArrayMap<ComponentName, ServiceRecord> services) { boolean didSomething = false; for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord service = services.valueAt(i); Loading @@ -6970,6 +6971,11 @@ public final class ActiveServices { || (service.packageName.equals(packageName) && (filterByClasses == null || filterByClasses.contains(service.name.getClassName()))); if (service.app != null && service.app.mState.getCurAdj() < minOomAdj) { Slog.i(TAG, "Skip force stopping service " + service + ": below minimum oom adj level"); continue; } if (sameComponent && (service.app == null || evenPersistent || !service.app.isPersistent())) { if (!doit) { Loading @@ -6993,6 +6999,12 @@ public final class ActiveServices { boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses, int userId, boolean evenPersistent, boolean fullStop, boolean doit) { return bringDownDisabledPackageServicesLocked(packageName, filterByClasses, userId, evenPersistent, fullStop, doit, ProcessList.INVALID_ADJ); } boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses, int userId, boolean evenPersistent, boolean fullStop, boolean doit, int minOomAdj) { boolean didSomething = false; if (mTmpCollectionResults != null) { Loading @@ -7002,7 +7014,8 @@ public final class ActiveServices { if (userId == UserHandle.USER_ALL) { for (int i = mServiceMap.size() - 1; i >= 0; i--) { didSomething |= collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, mServiceMap.valueAt(i).mServicesByInstanceName); evenPersistent, doit, minOomAdj, mServiceMap.valueAt(i).mServicesByInstanceName); if (!doit && didSomething) { return true; } Loading @@ -7015,7 +7028,7 @@ public final class ActiveServices { if (smap != null) { ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByInstanceName; didSomething = collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, items); evenPersistent, doit, minOomAdj, items); } if (doit && filterByClasses == null) { forceStopPackageLocked(packageName, userId); Loading
services/core/java/com/android/server/am/ActivityManagerService.java +28 −3 Original line number Diff line number Diff line Loading @@ -4376,6 +4376,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } @GuardedBy("this") final boolean forceStopUserPackagesLocked(int userId, String reasonString, boolean evenImportantServices) { int minOomAdj = evenImportantServices ? ProcessList.INVALID_ADJ : ProcessList.FOREGROUND_APP_ADJ; return forceStopPackageInternalLocked(null, -1, false, false, true, false, false, false, userId, reasonString, ApplicationExitInfo.REASON_USER_STOPPED, minOomAdj); } @GuardedBy("this") final boolean forceStopPackageLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, Loading @@ -4385,7 +4395,6 @@ public class ActivityManagerService extends IActivityManager.Stub : ApplicationExitInfo.REASON_USER_REQUESTED; return forceStopPackageLocked(packageName, appId, callerWillRestart, purgeCache, doit, evenPersistent, uninstalling, packageStateStopped, userId, reasonString, reason); } @GuardedBy("this") Loading @@ -4393,6 +4402,16 @@ public class ActivityManagerService extends IActivityManager.Stub boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, boolean packageStateStopped, int userId, String reasonString, int reason) { return forceStopPackageInternalLocked(packageName, appId, callerWillRestart, purgeCache, doit, evenPersistent, uninstalling, packageStateStopped, userId, reasonString, reason, ProcessList.INVALID_ADJ); } @GuardedBy("this") private boolean forceStopPackageInternalLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, boolean packageStateStopped, int userId, String reasonString, int reason, int minOomAdj) { int i; if (userId == UserHandle.USER_ALL && packageName == null) { Loading Loading @@ -4431,7 +4450,7 @@ public class ActivityManagerService extends IActivityManager.Stub } didSomething |= mProcessList.killPackageProcessesLSP(packageName, appId, userId, ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit, minOomAdj, callerWillRestart, false /* allowRestart */, doit, evenPersistent, true /* setRemoved */, uninstalling, reason, subReason, Loading @@ -4440,7 +4459,8 @@ public class ActivityManagerService extends IActivityManager.Stub } if (mServices.bringDownDisabledPackageServicesLocked( packageName, null /* filterByClasses */, userId, evenPersistent, true, doit)) { packageName, null /* filterByClasses */, userId, evenPersistent, true, doit, minOomAdj)) { if (!doit) { return true; } Loading Loading @@ -19871,6 +19891,11 @@ public class ActivityManagerService extends IActivityManager.Stub ActivityManagerService.this.setVoiceInteractionManagerProvider(provider); } @Override public boolean isEarlyPackageKillEnabledForUserSwitch(int fromUserId, int toUserId) { return mUserController.isEarlyPackageKillEnabledForUserSwitch(fromUserId, toUserId); } @Override public void setStopUserOnSwitch(int value) { ActivityManagerService.this.setStopUserOnSwitch(value);
services/core/java/com/android/server/am/UserController.java +57 −9 Original line number Diff line number Diff line Loading @@ -439,6 +439,15 @@ class UserController implements Handler.Callback { @GuardedBy("mLock") private final List<PendingUserStart> mPendingUserStarts = new ArrayList<>(); /** * Contains users which cannot abort the shutdown process. * * <p> For example, we don't abort shutdown for users whose processes have already been stopped * due to {@link #isEarlyPackageKillEnabledForUserSwitch(int, int)}. */ @GuardedBy("mLock") private final ArraySet<Integer> mDoNotAbortShutdownUserIds = new ArraySet<>(); private final UserLifecycleListener mUserLifecycleListener = new UserLifecycleListener() { @Override public void onUserCreated(UserInfo user, Object token) { Loading Loading @@ -509,11 +518,11 @@ class UserController implements Handler.Callback { } } private boolean shouldStopUserOnSwitch() { private boolean isStopUserOnSwitchEnabled() { synchronized (mLock) { if (mStopUserOnSwitch != STOP_USER_ON_SWITCH_DEFAULT) { final boolean value = mStopUserOnSwitch == STOP_USER_ON_SWITCH_TRUE; Slogf.i(TAG, "shouldStopUserOnSwitch(): returning overridden value (%b)", value); Slogf.i(TAG, "isStopUserOnSwitchEnabled(): returning overridden value (%b)", value); return value; } } Loading @@ -521,6 +530,26 @@ class UserController implements Handler.Callback { return property == -1 ? mDelayUserDataLocking : property == 1; } /** * Get whether or not the previous user's packages will be killed before the user is * stopped during a user switch. * * <p> The primary use case of this method is for {@link com.android.server.SystemService} * classes to call this API in their * {@link com.android.server.SystemService#onUserSwitching} method implementation to prevent * restarting any of the previous user's processes that will be killed during the user switch. */ boolean isEarlyPackageKillEnabledForUserSwitch(int fromUserId, int toUserId) { // NOTE: The logic in this method could be extended to cover other cases where // the previous user is also stopped like: guest users, ephemeral users, // and users with DISALLOW_RUN_IN_BACKGROUND. Currently, this is not done // because early killing is not enabled for these cases by default. if (fromUserId == UserHandle.USER_SYSTEM) { return false; } return isStopUserOnSwitchEnabled(); } void finishUserSwitch(UserState uss) { // This call holds the AM lock so we post to the handler. mHandler.post(() -> { Loading Loading @@ -1247,6 +1276,7 @@ class UserController implements Handler.Callback { return; } uss.setState(UserState.STATE_SHUTDOWN); mDoNotAbortShutdownUserIds.remove(userId); } TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("setUserState-STATE_SHUTDOWN-" + userId + "-[stopUser]"); Loading Loading @@ -1555,7 +1585,8 @@ class UserController implements Handler.Callback { private void stopPackagesOfStoppedUser(@UserIdInt int userId, String reason) { if (DEBUG_MU) Slogf.i(TAG, "stopPackagesOfStoppedUser(%d): %s", userId, reason); mInjector.activityManagerForceStopPackage(userId, reason); mInjector.activityManagerForceStopUserPackages(userId, reason, /* evenImportantServices= */ true); if (mInjector.getUserManager().isPreCreated(userId)) { // Don't fire intent for precreated. return; Loading Loading @@ -1608,6 +1639,21 @@ class UserController implements Handler.Callback { } } private void stopPreviousUserPackagesIfEnabled(int fromUserId, int toUserId) { if (!android.multiuser.Flags.stopPreviousUserApps() || !isEarlyPackageKillEnabledForUserSwitch(fromUserId, toUserId)) { return; } // Stop the previous user's packages early to reduce resource usage // during user switching. Only do this when the previous user will // be stopped regardless. synchronized (mLock) { mDoNotAbortShutdownUserIds.add(fromUserId); } mInjector.activityManagerForceStopUserPackages(fromUserId, "early stop user packages", /* evenImportantServices= */ false); } void scheduleStartProfiles() { // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no Loading Loading @@ -1889,7 +1935,8 @@ class UserController implements Handler.Callback { updateStartedUserArrayLU(); needStart = true; updateUmState = true; } else if (uss.state == UserState.STATE_SHUTDOWN) { } else if (uss.state == UserState.STATE_SHUTDOWN || mDoNotAbortShutdownUserIds.contains(userId)) { Slogf.i(TAG, "User #" + userId + " is shutting down - will start after full shutdown"); mPendingUserStarts.add(new PendingUserStart(userId, userStartMode, Loading Loading @@ -2293,7 +2340,7 @@ class UserController implements Handler.Callback { hasUserRestriction(UserManager.DISALLOW_RUN_IN_BACKGROUND, oldUserId); synchronized (mLock) { // If running in background is disabled or mStopUserOnSwitch mode, stop the user. if (hasRestriction || shouldStopUserOnSwitch()) { if (hasRestriction || isStopUserOnSwitchEnabled()) { Slogf.i(TAG, "Stopping user %d and its profiles on user switch", oldUserId); stopUsersLU(oldUserId, /* allowDelayedLocking= */ false, null, null); return; Loading Loading @@ -3425,7 +3472,7 @@ class UserController implements Handler.Callback { pw.println(" mLastActiveUsersForDelayedLocking:" + mLastActiveUsersForDelayedLocking); pw.println(" mDelayUserDataLocking:" + mDelayUserDataLocking); pw.println(" mAllowUserUnlocking:" + mAllowUserUnlocking); pw.println(" shouldStopUserOnSwitch():" + shouldStopUserOnSwitch()); pw.println(" isStopUserOnSwitchEnabled():" + isStopUserOnSwitchEnabled()); pw.println(" mStopUserOnSwitch:" + mStopUserOnSwitch); pw.println(" mMaxRunningUsers:" + mMaxRunningUsers); pw.println(" mBackgroundUserScheduledStopTimeSecs:" Loading Loading @@ -3522,6 +3569,7 @@ class UserController implements Handler.Callback { Integer.toString(msg.arg1), msg.arg1); mInjector.getSystemServiceManager().onUserSwitching(msg.arg2, msg.arg1); stopPreviousUserPackagesIfEnabled(msg.arg2, msg.arg1); scheduleOnUserCompletedEvent(msg.arg1, UserCompletedEventType.EVENT_TYPE_USER_SWITCHING, USER_COMPLETED_EVENT_DELAY_MS); Loading Loading @@ -3896,10 +3944,10 @@ class UserController implements Handler.Callback { }.sendNext(); } void activityManagerForceStopPackage(@UserIdInt int userId, String reason) { void activityManagerForceStopUserPackages(@UserIdInt int userId, String reason, boolean evenImportantServices) { synchronized (mService) { mService.forceStopPackageLocked(null, -1, false, false, true, false, false, false, userId, reason); mService.forceStopUserPackagesLocked(userId, reason, evenImportantServices); } }; Loading