Loading core/proto/android/server/activitymanagerservice.proto +1 −0 Original line number Diff line number Diff line Loading @@ -977,6 +977,7 @@ message UserControllerProto { optional int32 profile = 2; } repeated UserProfile user_profile_group_ids = 4; repeated int32 visible_users_array = 5; } // sync with com.android.server.am.AppTimeTracker.java Loading services/core/java/com/android/server/SystemService.java +12 −0 Original line number Diff line number Diff line Loading @@ -472,6 +472,18 @@ public abstract class SystemService { public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { } /** * The {@link UserManager#isUserVisible() user visibility} changed. * * <p>This callback is called before the user starts or is switched to (or after it stops), when * its visibility changed because of that action. * * @hide */ // NOTE: change visible to int if this method becomes a @SystemApi public void onUserVisibilityChanged(@NonNull TargetUser user, boolean visible) { } /** * Called when an existing user is stopping, for system services to finalize any per-user * state they maintain for running users. This is called prior to sending the SHUTDOWN Loading services/core/java/com/android/server/SystemServiceManager.java +49 −14 Original line number Diff line number Diff line Loading @@ -75,13 +75,17 @@ public final class SystemServiceManager implements Dumpable { // Constants used on onUser(...) // NOTE: do not change their values, as they're used on Trace calls and changes might break // performance tests that rely on them. private static final String USER_STARTING = "Start"; // Logged as onStartUser private static final String USER_UNLOCKING = "Unlocking"; // Logged as onUnlockingUser private static final String USER_UNLOCKED = "Unlocked"; // Logged as onUnlockedUser private static final String USER_SWITCHING = "Switch"; // Logged as onSwitchUser private static final String USER_STOPPING = "Stop"; // Logged as onStopUser private static final String USER_STOPPED = "Cleanup"; // Logged as onCleanupUser private static final String USER_COMPLETED_EVENT = "CompletedEvent"; // onCompletedEventUser private static final String USER_STARTING = "Start"; // Logged as onUserStarting() private static final String USER_UNLOCKING = "Unlocking"; // Logged as onUserUnlocking() private static final String USER_UNLOCKED = "Unlocked"; // Logged as onUserUnlocked() private static final String USER_SWITCHING = "Switch"; // Logged as onUserSwitching() private static final String USER_STOPPING = "Stop"; // Logged as onUserStopping() private static final String USER_STOPPED = "Cleanup"; // Logged as onUserStopped() private static final String USER_COMPLETED_EVENT = "CompletedEvent"; // onUserCompletedEvent() private static final String USER_VISIBLE = "Visible"; // Logged on onUserVisible() and // onUserStarting() (when visible is true) private static final String USER_INVISIBLE = "Invisible"; // Logged on onUserStopping() // (when visibilityChanged is true) // The default number of threads to use if lifecycle thread pool is enabled. private static final int DEFAULT_MAX_USER_POOL_THREADS = 3; Loading Loading @@ -350,17 +354,40 @@ public final class SystemServiceManager implements Dumpable { /** * Starts the given user. */ public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId) { EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId); public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId, boolean visible) { EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId, visible ? 1 : 0); final TargetUser targetUser = newTargetUser(userId); synchronized (mTargetUsers) { mTargetUsers.put(userId, targetUser); } if (visible) { // Must send the user visiiblity change first, for 2 reasons: // 1. Automotive need to update the user-zone mapping ASAP and it's one of the few // services listening to this event (OTOH, there are manyy listeners to USER_STARTING // and some can take a while to process it) // 2. When a user is switched from bg to fg, the onUserVisibilityChanged() callback is // called onUserSwitching(), so calling it before onUserStarting() make it more // consistent with that onUser(t, USER_VISIBLE, /* prevUser= */ null, targetUser); } onUser(t, USER_STARTING, /* prevUser= */ null, targetUser); } /** * Updates the user visibility. * * <p><b>NOTE: </b>this method should only be called when a user that is already running become * visible; if the user is starting visible, callers should call * {@link #onUserStarting(TimingsTraceAndSlog, int, boolean)} instead */ public void onUserVisible(@UserIdInt int userId) { EventLog.writeEvent(EventLogTags.SSM_USER_VISIBLE, userId); onUser(USER_VISIBLE, userId); } /** * Unlocks the given user. */ Loading Loading @@ -408,9 +435,12 @@ public final class SystemServiceManager implements Dumpable { /** * Stops the given user. */ public void onUserStopping(@UserIdInt int userId) { EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId); public void onUserStopping(@UserIdInt int userId, boolean visibilityChanged) { EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId, visibilityChanged ? 1 : 0); onUser(USER_STOPPING, userId); if (visibilityChanged) { onUser(USER_INVISIBLE, userId); } } /** Loading Loading @@ -456,8 +486,7 @@ public final class SystemServiceManager implements Dumpable { TargetUser targetUser = getTargetUser(userId); Preconditions.checkState(targetUser != null, "No TargetUser for " + userId); onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, /* prevUser= */ null, targetUser); onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, /* prevUser= */ null, targetUser); } private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat, Loading Loading @@ -534,6 +563,12 @@ public final class SystemServiceManager implements Dumpable { threadPool.submit(getOnUserCompletedEventRunnable( t, service, serviceName, curUser, completedEventType)); break; case USER_VISIBLE: service.onUserVisibilityChanged(curUser, /* visible= */ true); break; case USER_INVISIBLE: service.onUserVisibilityChanged(curUser, /* visible= */ false); break; default: throw new IllegalArgumentException(onWhat + " what?"); } Loading services/core/java/com/android/server/am/ActivityManagerService.java +6 −6 Original line number Diff line number Diff line Loading @@ -8346,14 +8346,14 @@ public class ActivityManagerService extends IActivityManager.Stub mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); // On Automotive, at this point the system user has already been started and unlocked, // and some of the tasks we do here have already been done. So skip those in that case. // TODO(b/132262830, b/203885241): this workdound shouldn't be necessary once we move the // headless-user start logic to UserManager-land // On Automotive / Headless System User Mode, at this point the system user has already been // started and unlocked, and some of the tasks we do here have already been done. So skip // those in that case. // TODO(b/242195409): this workaround shouldn't be necessary once we move the headless-user // start logic to UserManager-land final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM; if (bootingSystemUser) { mSystemServiceManager.onUserStarting(t, currentUserId); mUserController.onSystemUserStarting(); } synchronized (this) { Loading services/core/java/com/android/server/am/EventLogTags.logtags +4 −3 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ option java_package com.android.server.am 30073 uc_finish_user_stopping (userId|1|5) 30074 uc_finish_user_stopped (userId|1|5) 30075 uc_switch_user (userId|1|5) 30076 uc_start_user_internal (userId|1|5) 30076 uc_start_user_internal (userId|1|5),(foreground|1),(displayId|1|5) 30077 uc_unlock_user (userId|1|5) 30078 uc_finish_user_boot (userId|1|5) 30079 uc_dispatch_user_switch (oldUserId|1|5),(newUserId|1|5) Loading @@ -109,13 +109,14 @@ option java_package com.android.server.am 30081 uc_send_user_broadcast (userId|1|5),(IntentAction|3) # Tags below are used by SystemServiceManager - although it's technically part of am, these are # also user switch events and useful to be analyzed together with events above. 30082 ssm_user_starting (userId|1|5) 30082 ssm_user_starting (userId|1|5),(visible|1) 30083 ssm_user_switching (oldUserId|1|5),(newUserId|1|5) 30084 ssm_user_unlocking (userId|1|5) 30085 ssm_user_unlocked (userId|1|5) 30086 ssm_user_stopping (userId|1|5) 30086 ssm_user_stopping (userId|1|5),(visibilityChanged|1) 30087 ssm_user_stopped (userId|1|5) 30088 ssm_user_completed_event (userId|1|5),(eventFlag|1|5) 30089 ssm_user_visible (userId|1|5) # Foreground service start/stop events. 30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) Loading Loading
core/proto/android/server/activitymanagerservice.proto +1 −0 Original line number Diff line number Diff line Loading @@ -977,6 +977,7 @@ message UserControllerProto { optional int32 profile = 2; } repeated UserProfile user_profile_group_ids = 4; repeated int32 visible_users_array = 5; } // sync with com.android.server.am.AppTimeTracker.java Loading
services/core/java/com/android/server/SystemService.java +12 −0 Original line number Diff line number Diff line Loading @@ -472,6 +472,18 @@ public abstract class SystemService { public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { } /** * The {@link UserManager#isUserVisible() user visibility} changed. * * <p>This callback is called before the user starts or is switched to (or after it stops), when * its visibility changed because of that action. * * @hide */ // NOTE: change visible to int if this method becomes a @SystemApi public void onUserVisibilityChanged(@NonNull TargetUser user, boolean visible) { } /** * Called when an existing user is stopping, for system services to finalize any per-user * state they maintain for running users. This is called prior to sending the SHUTDOWN Loading
services/core/java/com/android/server/SystemServiceManager.java +49 −14 Original line number Diff line number Diff line Loading @@ -75,13 +75,17 @@ public final class SystemServiceManager implements Dumpable { // Constants used on onUser(...) // NOTE: do not change their values, as they're used on Trace calls and changes might break // performance tests that rely on them. private static final String USER_STARTING = "Start"; // Logged as onStartUser private static final String USER_UNLOCKING = "Unlocking"; // Logged as onUnlockingUser private static final String USER_UNLOCKED = "Unlocked"; // Logged as onUnlockedUser private static final String USER_SWITCHING = "Switch"; // Logged as onSwitchUser private static final String USER_STOPPING = "Stop"; // Logged as onStopUser private static final String USER_STOPPED = "Cleanup"; // Logged as onCleanupUser private static final String USER_COMPLETED_EVENT = "CompletedEvent"; // onCompletedEventUser private static final String USER_STARTING = "Start"; // Logged as onUserStarting() private static final String USER_UNLOCKING = "Unlocking"; // Logged as onUserUnlocking() private static final String USER_UNLOCKED = "Unlocked"; // Logged as onUserUnlocked() private static final String USER_SWITCHING = "Switch"; // Logged as onUserSwitching() private static final String USER_STOPPING = "Stop"; // Logged as onUserStopping() private static final String USER_STOPPED = "Cleanup"; // Logged as onUserStopped() private static final String USER_COMPLETED_EVENT = "CompletedEvent"; // onUserCompletedEvent() private static final String USER_VISIBLE = "Visible"; // Logged on onUserVisible() and // onUserStarting() (when visible is true) private static final String USER_INVISIBLE = "Invisible"; // Logged on onUserStopping() // (when visibilityChanged is true) // The default number of threads to use if lifecycle thread pool is enabled. private static final int DEFAULT_MAX_USER_POOL_THREADS = 3; Loading Loading @@ -350,17 +354,40 @@ public final class SystemServiceManager implements Dumpable { /** * Starts the given user. */ public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId) { EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId); public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId, boolean visible) { EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId, visible ? 1 : 0); final TargetUser targetUser = newTargetUser(userId); synchronized (mTargetUsers) { mTargetUsers.put(userId, targetUser); } if (visible) { // Must send the user visiiblity change first, for 2 reasons: // 1. Automotive need to update the user-zone mapping ASAP and it's one of the few // services listening to this event (OTOH, there are manyy listeners to USER_STARTING // and some can take a while to process it) // 2. When a user is switched from bg to fg, the onUserVisibilityChanged() callback is // called onUserSwitching(), so calling it before onUserStarting() make it more // consistent with that onUser(t, USER_VISIBLE, /* prevUser= */ null, targetUser); } onUser(t, USER_STARTING, /* prevUser= */ null, targetUser); } /** * Updates the user visibility. * * <p><b>NOTE: </b>this method should only be called when a user that is already running become * visible; if the user is starting visible, callers should call * {@link #onUserStarting(TimingsTraceAndSlog, int, boolean)} instead */ public void onUserVisible(@UserIdInt int userId) { EventLog.writeEvent(EventLogTags.SSM_USER_VISIBLE, userId); onUser(USER_VISIBLE, userId); } /** * Unlocks the given user. */ Loading Loading @@ -408,9 +435,12 @@ public final class SystemServiceManager implements Dumpable { /** * Stops the given user. */ public void onUserStopping(@UserIdInt int userId) { EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId); public void onUserStopping(@UserIdInt int userId, boolean visibilityChanged) { EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId, visibilityChanged ? 1 : 0); onUser(USER_STOPPING, userId); if (visibilityChanged) { onUser(USER_INVISIBLE, userId); } } /** Loading Loading @@ -456,8 +486,7 @@ public final class SystemServiceManager implements Dumpable { TargetUser targetUser = getTargetUser(userId); Preconditions.checkState(targetUser != null, "No TargetUser for " + userId); onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, /* prevUser= */ null, targetUser); onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, /* prevUser= */ null, targetUser); } private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat, Loading Loading @@ -534,6 +563,12 @@ public final class SystemServiceManager implements Dumpable { threadPool.submit(getOnUserCompletedEventRunnable( t, service, serviceName, curUser, completedEventType)); break; case USER_VISIBLE: service.onUserVisibilityChanged(curUser, /* visible= */ true); break; case USER_INVISIBLE: service.onUserVisibilityChanged(curUser, /* visible= */ false); break; default: throw new IllegalArgumentException(onWhat + " what?"); } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +6 −6 Original line number Diff line number Diff line Loading @@ -8346,14 +8346,14 @@ public class ActivityManagerService extends IActivityManager.Stub mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); // On Automotive, at this point the system user has already been started and unlocked, // and some of the tasks we do here have already been done. So skip those in that case. // TODO(b/132262830, b/203885241): this workdound shouldn't be necessary once we move the // headless-user start logic to UserManager-land // On Automotive / Headless System User Mode, at this point the system user has already been // started and unlocked, and some of the tasks we do here have already been done. So skip // those in that case. // TODO(b/242195409): this workaround shouldn't be necessary once we move the headless-user // start logic to UserManager-land final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM; if (bootingSystemUser) { mSystemServiceManager.onUserStarting(t, currentUserId); mUserController.onSystemUserStarting(); } synchronized (this) { Loading
services/core/java/com/android/server/am/EventLogTags.logtags +4 −3 Original line number Diff line number Diff line Loading @@ -101,7 +101,7 @@ option java_package com.android.server.am 30073 uc_finish_user_stopping (userId|1|5) 30074 uc_finish_user_stopped (userId|1|5) 30075 uc_switch_user (userId|1|5) 30076 uc_start_user_internal (userId|1|5) 30076 uc_start_user_internal (userId|1|5),(foreground|1),(displayId|1|5) 30077 uc_unlock_user (userId|1|5) 30078 uc_finish_user_boot (userId|1|5) 30079 uc_dispatch_user_switch (oldUserId|1|5),(newUserId|1|5) Loading @@ -109,13 +109,14 @@ option java_package com.android.server.am 30081 uc_send_user_broadcast (userId|1|5),(IntentAction|3) # Tags below are used by SystemServiceManager - although it's technically part of am, these are # also user switch events and useful to be analyzed together with events above. 30082 ssm_user_starting (userId|1|5) 30082 ssm_user_starting (userId|1|5),(visible|1) 30083 ssm_user_switching (oldUserId|1|5),(newUserId|1|5) 30084 ssm_user_unlocking (userId|1|5) 30085 ssm_user_unlocked (userId|1|5) 30086 ssm_user_stopping (userId|1|5) 30086 ssm_user_stopping (userId|1|5),(visibilityChanged|1) 30087 ssm_user_stopped (userId|1|5) 30088 ssm_user_completed_event (userId|1|5),(eventFlag|1|5) 30089 ssm_user_visible (userId|1|5) # Foreground service start/stop events. 30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3) Loading