Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e861d161 authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Added user visibility callbacks on SystemService."

parents 61d755d8 9edf758f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+12 −0
Original line number Diff line number Diff line
@@ -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
+49 −14
Original line number Diff line number Diff line
@@ -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;
@@ -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.
     */
@@ -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);
        }
    }

    /**
@@ -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,
@@ -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?");
                }
+6 −6
Original line number Diff line number Diff line
@@ -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) {
+4 −3
Original line number Diff line number Diff line
@@ -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)
@@ -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