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

Commit 71d3f5bb authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Add multi-user jank monitoring

Created CUJ for monitoring jank when switching users, including guest
users, but excluding the "Add User" user journey.

Bug: 200160966
Test: switch users manually, look at logs
Test: atest KeyguardUpdateMonitorTest
Test: atest UserSwitcherControllerTest
Change-Id: I5570133a1f96a58d39a8f053f9f480cdaada8df1
parent 9fbadb5a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_IN
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_ROW_SWIPE;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__SHADE_SCROLL_FLING;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH;
import static com.android.internal.util.FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION;

import android.annotation.IntDef;
@@ -171,6 +172,7 @@ public class InteractionJankMonitor {
    public static final int CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP = 34;
    public static final int CUJ_PIP_TRANSITION = 35;
    public static final int CUJ_WALLPAPER_TRANSITION = 36;
    public static final int CUJ_USER_SWITCH = 37;

    private static final int NO_STATSD_LOGGING = -1;

@@ -216,6 +218,7 @@ public class InteractionJankMonitor {
            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__PIP_TRANSITION,
            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__WALLPAPER_TRANSITION,
            UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__USER_SWITCH,
    };

    private static volatile InteractionJankMonitor sInstance;
@@ -272,6 +275,7 @@ public class InteractionJankMonitor {
            CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
            CUJ_PIP_TRANSITION,
            CUJ_WALLPAPER_TRANSITION,
            CUJ_USER_SWITCH,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface CujType {
@@ -642,6 +646,8 @@ public class InteractionJankMonitor {
                return "PIP_TRANSITION";
            case CUJ_WALLPAPER_TRANSITION:
                return "WALLPAPER_TRANSITION";
            case CUJ_USER_SWITCH:
                return "USER_SWITCH";
        }
        return "UNKNOWN";
    }
+7 −1
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.fuelgauge.BatteryStatus;
@@ -321,6 +322,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private boolean mIsDreaming;
    private final DevicePolicyManager mDevicePolicyManager;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final InteractionJankMonitor mInteractionJankMonitor;
    private boolean mLogoutEnabled;
    // cached value to avoid IPCs
    private boolean mIsUdfpsEnrolled;
@@ -1770,6 +1772,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            AuthController authController,
            TelephonyListenerManager telephonyListenerManager,
            FeatureFlags featureFlags,
            InteractionJankMonitor interactionJankMonitor,
            @Nullable Vibrator vibrator) {
        mContext = context;
        mSubscriptionManager = SubscriptionManager.from(context);
@@ -1778,6 +1781,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
        mBackgroundExecutor = backgroundExecutor;
        mBroadcastDispatcher = broadcastDispatcher;
        mInteractionJankMonitor = interactionJankMonitor;
        mRingerModeTracker = ringerModeTracker;
        mStatusBarStateController = statusBarStateController;
        mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
@@ -2637,7 +2641,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    /**
     * Handle {@link #MSG_USER_SWITCH_COMPLETE}
     */
    private void handleUserSwitchComplete(int userId) {
    @VisibleForTesting
    void handleUserSwitchComplete(int userId) {
        Assert.isMainThread();
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -2645,6 +2650,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                cb.onUserSwitchComplete(userId);
            }
        }
        mInteractionJankMonitor.end(InteractionJankMonitor.CUJ_USER_SWITCH);
    }

    /**
+7 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.view.inputmethod.InputMethodManager;

import com.android.internal.app.IBatteryStats;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.LatencyTracker;
import com.android.systemui.dagger.qualifiers.DisplayId;
@@ -218,6 +219,12 @@ public class FrameworkServicesModule {
        return context.getSystemService(FingerprintManager.class);
    }

    @Provides
    @Singleton
    static InteractionJankMonitor provideInteractionJankMonitor() {
        return InteractionJankMonitor.getInstance();
    }

    @Provides
    @Singleton
    static InputMethodManager provideInputMethodManager(Context context) {
+2 −0
Original line number Diff line number Diff line
@@ -1139,6 +1139,8 @@ public class StatusBar extends SystemUI implements
        mNotificationPanelViewController.addExpansionListener(
                this::dispatchPanelExpansionForKeyguardDismiss);

        mUserSwitcherController.init(mNotificationShadeWindowView);

        // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
        mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
        mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
+19 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.IActivityManager;
import android.app.IActivityTaskManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
@@ -55,6 +56,7 @@ import android.view.WindowManagerGlobal;
import android.widget.BaseAdapter;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.RestrictedLockUtilsInternal;
@@ -75,6 +77,7 @@ import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.QSUserSwitcherEvent;
import com.android.systemui.qs.tiles.UserDetailView;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.telephony.TelephonyListenerManager;
import com.android.systemui.user.CreateUserActivity;
@@ -107,6 +110,7 @@ public class UserSwitcherController implements Dumpable {
    private static final int PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000;

    private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
    private static final long MULTI_USER_JOURNEY_TIMEOUT = 20000l;

    protected final Context mContext;
    protected final UserTracker mUserTracker;
@@ -123,6 +127,7 @@ public class UserSwitcherController implements Dumpable {
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final TelephonyListenerManager mTelephonyListenerManager;
    private final IActivityTaskManager mActivityTaskManager;
    private final InteractionJankMonitor mInteractionJankMonitor;

    private ArrayList<UserRecord> mUsers = new ArrayList<>();
    @VisibleForTesting
@@ -141,15 +146,18 @@ public class UserSwitcherController implements Dumpable {
    private Intent mSecondaryUserServiceIntent;
    private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
    private final UiEventLogger mUiEventLogger;
    private final IActivityManager mActivityManager;
    public final DetailAdapter mUserDetailAdapter;
    private final Executor mBgExecutor;
    private final boolean mGuestUserAutoCreated;
    private final AtomicBoolean mGuestIsResetting;
    private final AtomicBoolean mGuestCreationScheduled;
    private FalsingManager mFalsingManager;
    private NotificationShadeWindowView mRootView;

    @Inject
    public UserSwitcherController(Context context,
            IActivityManager activityManager,
            UserManager userManager,
            UserTracker userTracker,
            KeyguardStateController keyguardStateController,
@@ -165,14 +173,17 @@ public class UserSwitcherController implements Dumpable {
            UserDetailAdapter userDetailAdapter,
            SecureSettings secureSettings,
            @Background Executor bgExecutor,
            InteractionJankMonitor interactionJankMonitor,
            DumpManager dumpManager) {
        mContext = context;
        mActivityManager = activityManager;
        mUserTracker = userTracker;
        mBroadcastDispatcher = broadcastDispatcher;
        mTelephonyListenerManager = telephonyListenerManager;
        mActivityTaskManager = activityTaskManager;
        mUiEventLogger = uiEventLogger;
        mFalsingManager = falsingManager;
        mInteractionJankMonitor = interactionJankMonitor;
        mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
                this, mUserTracker, mUiEventLogger, secureSettings);
        mUserDetailAdapter = userDetailAdapter;
@@ -485,8 +496,11 @@ public class UserSwitcherController implements Dumpable {

    protected void switchToUserId(int id) {
        try {
            mInteractionJankMonitor.begin(InteractionJankMonitor.Configuration.Builder
                    .withView(InteractionJankMonitor.CUJ_USER_SWITCH, mRootView)
                    .setTimeout(MULTI_USER_JOURNEY_TIMEOUT));
            pauseRefreshUsers();
            ActivityManager.getService().switchUser(id);
            mActivityManager.switchUser(id);
        } catch (RemoteException e) {
            Log.e(TAG, "Couldn't switch user.", e);
        }
@@ -793,6 +807,10 @@ public class UserSwitcherController implements Dumpable {
        return guest.id;
    }

    public void init(NotificationShadeWindowView notificationShadeWindowView) {
        mRootView = notificationShadeWindowView;
    }

    public static abstract class BaseUserAdapter extends BaseAdapter {

        final UserSwitcherController mController;
Loading