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

Commit a9aff9a8 authored by Felipe Leme's avatar Felipe Leme
Browse files

Improvements on SystemServiceManager:

- Renamed some user-related methods to be consistent with the
  equivalent SystemService method it calls.
- Added EventLogs calls on these methods.
- Added warning about renaming strings used by performance tests.

Bug: 168334562
Test: adb logcat -b events | egrep '(I am_crash|I am_user_| I uc_ | I ssm_)'

Change-Id: I4bc883e09a2862b984db1164e12a763fa9ac2014
parent 2dbc9473
Loading
Loading
Loading
Loading
+36 −24
Original line number Diff line number Diff line
@@ -26,12 +26,14 @@ import android.os.SystemClock;
import android.os.Trace;
import android.os.UserManagerInternal;
import android.util.ArrayMap;
import android.util.EventLog;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService.TargetUser;
import com.android.server.am.EventLogTags;
import com.android.server.utils.TimingsTraceAndSlog;

import dalvik.system.PathClassLoader;
@@ -53,12 +55,14 @@ public final class SystemServiceManager {
    private static final int SERVICE_CALL_WARN_TIME_MS = 50;

    // Constants used on onUser(...)
    private static final String START = "Start";
    private static final String UNLOCKING = "Unlocking";
    private static final String UNLOCKED = "Unlocked";
    private static final String SWITCH = "Switch";
    private static final String STOP = "Stop";
    private static final String CLEANUP = "Cleanup";
    // 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";
    private static final String USER_UNLOCKING = "Unlocking";
    private static final String USER_UNLOCKED = "Unlocked";
    private static final String USER_SWITCHING = "Switch";
    private static final String USER_STOPPING = "Stop";
    private static final String USER_STOPPED = "Cleanup";

    private static File sSystemDir;
    private final Context mContext;
@@ -86,7 +90,7 @@ public final class SystemServiceManager {

    /**
     * Reference to the current user, it's used to set the {@link TargetUser} on
     * {@link #switchUser(int, int)} as the previous user might have been removed already.
     * {@link #onUserSwitching(int, int)} as the previous user might have been removed already.
     */
    @GuardedBy("mTargetUsers")
    private @Nullable TargetUser mCurrentUser;
@@ -275,33 +279,38 @@ public final class SystemServiceManager {
    /**
     * Starts the given user.
     */
    public void startUser(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId) {
    public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId) {
        EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId);

        final TargetUser targetUser = newTargetUser(userId);
        synchronized (mTargetUsers) {
            mTargetUsers.put(userId, targetUser);
        }

        onUser(t, START, /* prevUser= */ null, targetUser);
        onUser(t, USER_STARTING, /* prevUser= */ null, targetUser);
    }

    /**
     * Unlocks the given user.
     */
    public void unlockUser(@UserIdInt int userId) {
        onUser(UNLOCKING, userId);
    public void onUserUnlocking(@UserIdInt int userId) {
        EventLog.writeEvent(EventLogTags.SSM_USER_UNLOCKING, userId);
        onUser(USER_UNLOCKING, userId);
    }

    /**
     * Called after the user was unlocked.
     */
    public void onUserUnlocked(@UserIdInt int userId) {
        onUser(UNLOCKED, userId);
        EventLog.writeEvent(EventLogTags.SSM_USER_UNLOCKED, userId);
        onUser(USER_UNLOCKED, userId);
    }

    /**
     * Switches to the given user.
     */
    public void switchUser(@UserIdInt int from, @UserIdInt int to) {
    public void onUserSwitching(@UserIdInt int from, @UserIdInt int to) {
        EventLog.writeEvent(EventLogTags.SSM_USER_SWITCHING, from, to);
        final TargetUser curUser, prevUser;
        synchronized (mTargetUsers) {
            if (mCurrentUser == null) {
@@ -321,21 +330,23 @@ public final class SystemServiceManager {
                Slog.d(TAG, "Set mCurrentUser to " + mCurrentUser);
            }
        }
        onUser(TimingsTraceAndSlog.newAsyncLog(), SWITCH, prevUser, curUser);
        onUser(TimingsTraceAndSlog.newAsyncLog(), USER_SWITCHING, prevUser, curUser);
    }

    /**
     * Stops the given user.
     */
    public void stopUser(@UserIdInt int userId) {
        onUser(STOP, userId);
    public void onUserStopping(@UserIdInt int userId) {
        EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId);
        onUser(USER_STOPPING, userId);
    }

    /**
     * Cleans up the given user.
     */
    public void cleanupUser(@UserIdInt int userId) {
        onUser(CLEANUP, userId);
    public void onUserStopped(@UserIdInt int userId) {
        EventLog.writeEvent(EventLogTags.SSM_USER_STOPPED, userId);
        onUser(USER_STOPPED, userId);

        // Remove cached TargetUser
        synchronized (mTargetUsers) {
@@ -351,6 +362,7 @@ public final class SystemServiceManager {
    private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
            @Nullable TargetUser prevUser, @NonNull TargetUser curUser) {
        final int curUserId = curUser.getUserIdentifier();
        // NOTE: do not change label below, or it might break performance tests that rely on it.
        t.traceBegin("ssm." + onWhat + "User-" + curUserId);
        Slog.i(TAG, "Calling on" + onWhat + "User " + curUserId
                + (prevUser != null ? " (from " + prevUser + ")" : ""));
@@ -381,22 +393,22 @@ public final class SystemServiceManager {
            long time = SystemClock.elapsedRealtime();
            try {
                switch (onWhat) {
                    case SWITCH:
                    case USER_SWITCHING:
                        service.onUserSwitching(prevUser, curUser);
                        break;
                    case START:
                    case USER_STARTING:
                        service.onUserStarting(curUser);
                        break;
                    case UNLOCKING:
                    case USER_UNLOCKING:
                        service.onUserUnlocking(curUser);
                        break;
                    case UNLOCKED:
                    case USER_UNLOCKED:
                        service.onUserUnlocked(curUser);
                        break;
                    case STOP:
                    case USER_STOPPING:
                        service.onUserStopping(curUser);
                        break;
                    case CLEANUP:
                    case USER_STOPPED:
                        service.onUserStopped(curUser);
                        break;
                    default:
+1 −1
Original line number Diff line number Diff line
@@ -7361,7 +7361,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
        if (bootingSystemUser) {
            mSystemServiceManager.startUser(t, currentUserId);
            mSystemServiceManager.onUserStarting(t, currentUserId);
        }
        synchronized (this) {
+11 −3
Original line number Diff line number Diff line
@@ -104,6 +104,14 @@ option java_package com.android.server.am
30076 uc_start_user_internal (userId|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)
30080 uc_continue_user_switch (oldUserId|1|5) (newUserId|1|5)
30079 uc_dispatch_user_switch (oldUserId|1|5),(newUserId|1|5)
30080 uc_continue_user_switch (oldUserId|1|5),(newUserId|1|5)
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)
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)
30087 ssm_user_stopped (userId|1|5)
+8 −8
Original line number Diff line number Diff line
@@ -952,7 +952,7 @@ class UserController implements Handler.Callback {
        mInjector.batteryStatsServiceNoteEvent(
                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
                Integer.toString(userId), userId);
        mInjector.getSystemServiceManager().stopUser(userId);
        mInjector.getSystemServiceManager().onUserStopping(userId);

        Runnable finishUserStoppedAsync = () ->
                mHandler.post(() -> finishUserStopped(uss, allowDelayedLocking));
@@ -1028,7 +1028,7 @@ class UserController implements Handler.Callback {
        }

        if (stopped) {
            mInjector.systemServiceManagerCleanupUser(userId);
            mInjector.systemServiceManagerOnUserStopped(userId);
            mInjector.stackSupervisorRemoveUser(userId);

            // Remove the user if it is ephemeral.
@@ -2494,8 +2494,8 @@ class UserController implements Handler.Callback {
                logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_START_USER,
                        USER_LIFECYCLE_EVENT_STATE_BEGIN);

                mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(),
                        msg.arg1);
                mInjector.getSystemServiceManager().onUserStarting(
                        TimingsTraceAndSlog.newAsyncLog(), msg.arg1);

                logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_START_USER,
                        USER_LIFECYCLE_EVENT_STATE_FINISH);
@@ -2503,7 +2503,7 @@ class UserController implements Handler.Callback {
                break;
            case USER_UNLOCK_MSG:
                final int userId = msg.arg1;
                mInjector.getSystemServiceManager().unlockUser(userId);
                mInjector.getSystemServiceManager().onUserUnlocking(userId);
                // Loads recents on a worker thread that allows disk I/O
                FgThread.getHandler().post(() -> {
                    mInjector.loadUserRecents(userId);
@@ -2528,7 +2528,7 @@ class UserController implements Handler.Callback {
                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
                        Integer.toString(msg.arg1), msg.arg1);

                mInjector.getSystemServiceManager().switchUser(msg.arg2, msg.arg1);
                mInjector.getSystemServiceManager().onUserSwitching(msg.arg2, msg.arg1);
                break;
            case FOREGROUND_PROFILE_CHANGED_MSG:
                dispatchForegroundProfileChanged(msg.arg1);
@@ -2781,8 +2781,8 @@ class UserController implements Handler.Callback {
            LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
        }

        void systemServiceManagerCleanupUser(@UserIdInt int userId) {
            mService.mSystemServiceManager.cleanupUser(userId);
        void systemServiceManagerOnUserStopped(@UserIdInt int userId) {
            mService.mSystemServiceManager.onUserStopped(userId);
        }

        protected UserManagerService getUserManager() {
+1 −1
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ public class UserControllerTest {
            doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
            doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any());
            doNothing().when(mInjector).stackSupervisorResumeFocusedStackTopActivity();
            doNothing().when(mInjector).systemServiceManagerCleanupUser(anyInt());
            doNothing().when(mInjector).systemServiceManagerOnUserStopped(anyInt());
            doNothing().when(mInjector).activityManagerForceStopPackage(anyInt(), anyString());
            doNothing().when(mInjector).activityManagerOnUserStopped(anyInt());
            doNothing().when(mInjector).clearBroadcastQueueForUser(anyInt());