Loading cmds/statsd/src/atoms.proto +2 −0 Original line number Diff line number Diff line Loading @@ -3768,6 +3768,7 @@ message AppStartOccurred { WARM = 1; HOT = 2; COLD = 3; RELAUNCH = 4; } // The transition type. optional TransitionType type = 3; Loading Loading @@ -3829,6 +3830,7 @@ message AppStartCanceled { WARM = 1; HOT = 2; COLD = 3; RELAUNCH = 4; } // The transition type. optional TransitionType type = 3; Loading core/java/android/app/WaitResult.java +17 −1 Original line number Diff line number Diff line Loading @@ -40,13 +40,20 @@ public class WaitResult implements Parcelable { */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"LAUNCH_STATE_"}, value = { LAUNCH_STATE_UNKNOWN, LAUNCH_STATE_COLD, LAUNCH_STATE_WARM, LAUNCH_STATE_HOT LAUNCH_STATE_HOT, LAUNCH_STATE_RELAUNCH }) public @interface LaunchState { } /** * Not considered as a launch event, e.g. the activity is already on top. */ public static final int LAUNCH_STATE_UNKNOWN = 0; /** * Cold launch sequence: a new process has started. */ Loading @@ -62,6 +69,13 @@ public class WaitResult implements Parcelable { */ public static final int LAUNCH_STATE_HOT = 3; /** * Relaunch launch sequence: process reused, but activity has to be destroyed and created. * E.g. the current device configuration is different from the background activity that will be * brought to foreground, and the activity doesn't declare to handle the change. */ public static final int LAUNCH_STATE_RELAUNCH = 4; public static final int INVALID_DELAY = -1; public int result; public boolean timeout; Loading Loading @@ -124,6 +138,8 @@ public class WaitResult implements Parcelable { return "WARM"; case LAUNCH_STATE_HOT: return "HOT"; case LAUNCH_STATE_RELAUNCH: return "RELAUNCH"; default: return "UNKNOWN (" + type + ")"; } Loading services/core/java/com/android/server/wm/ActivityMetricsLogger.java +22 −14 Original line number Diff line number Diff line Loading @@ -3,8 +3,10 @@ package com.android.server.wm; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityManager.processStateAmToProto; import static android.app.WaitResult.INVALID_DELAY; import static android.app.WaitResult.LAUNCH_STATE_COLD; import static android.app.WaitResult.LAUNCH_STATE_HOT; import static android.app.WaitResult.LAUNCH_STATE_RELAUNCH; import static android.app.WaitResult.LAUNCH_STATE_WARM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; Loading Loading @@ -130,7 +132,6 @@ class ActivityMetricsLogger { * transition, in the case the launch is standalone (e.g. from recents). */ private static final int IGNORE_CALLER = -1; private static final int INVALID_DELAY = -1; // Preallocated strings we are sending to tron, so we don't have to allocate a new one every // time we log. Loading Loading @@ -220,6 +221,8 @@ class ActivityMetricsLogger { boolean mLoggedStartingWindowDrawn; /** If the any app transitions have been logged as starting. */ boolean mLoggedTransitionStarting; /** Whether any activity belonging to this transition has relaunched. */ boolean mRelaunched; /** Non-null if the application has reported drawn but its window hasn't. */ @Nullable Runnable mPendingFullyDrawn; Loading Loading @@ -351,6 +354,7 @@ class ActivityMetricsLogger { */ final int windowsFullyDrawnDelayMs; final int activityRecordIdHashCode; final boolean relaunched; private TransitionInfoSnapshot(TransitionInfo info) { this(info, info.mLastLaunchedActivity, INVALID_DELAY); Loading Loading @@ -379,6 +383,7 @@ class ActivityMetricsLogger { launchedActivityShortComponentName = launchedActivity.shortComponentName; activityRecordIdHashCode = System.identityHashCode(launchedActivity); this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs; relaunched = info.mRelaunched; } @WaitResult.LaunchState int getLaunchState() { Loading @@ -386,7 +391,7 @@ class ActivityMetricsLogger { case TYPE_TRANSITION_WARM_LAUNCH: return LAUNCH_STATE_WARM; case TYPE_TRANSITION_HOT_LAUNCH: return LAUNCH_STATE_HOT; return relaunched ? LAUNCH_STATE_RELAUNCH : LAUNCH_STATE_HOT; case TYPE_TRANSITION_COLD_LAUNCH: return LAUNCH_STATE_COLD; default: Loading Loading @@ -673,6 +678,13 @@ class ActivityMetricsLogger { } } void notifyActivityRelaunched(ActivityRecord r) { final TransitionInfo info = getActiveTransitionInfo(r); if (info != null) { info.mRelaunched = true; } } /** Makes sure that the reference to the removed activity is cleared. */ void notifyActivityRemoved(@NonNull ActivityRecord r) { mLastTransitionInfo.remove(r); Loading Loading @@ -800,13 +812,13 @@ class ActivityMetricsLogger { FrameworkStatsLog.APP_START_CANCELED, activity.info.applicationInfo.uid, activity.packageName, convertAppStartTransitionType(type), getAppStartTransitionType(type, info.mRelaunched), activity.info.name); if (DEBUG_METRICS) { Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)", activity.info.applicationInfo.uid, activity.packageName, convertAppStartTransitionType(type), getAppStartTransitionType(type, info.mRelaunched), activity.info.name)); } } Loading Loading @@ -871,7 +883,7 @@ class ActivityMetricsLogger { FrameworkStatsLog.APP_START_OCCURRED, info.applicationInfo.uid, info.packageName, convertAppStartTransitionType(info.type), getAppStartTransitionType(info.type, info.relaunched), info.launchedActivityName, info.launchedActivityLaunchedFromPackage, isInstantApp, Loading @@ -891,7 +903,7 @@ class ActivityMetricsLogger { Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)", info.applicationInfo.uid, info.packageName, convertAppStartTransitionType(info.type), getAppStartTransitionType(info.type, info.relaunched), info.launchedActivityName, info.launchedActivityLaunchedFromPackage)); } Loading @@ -918,7 +930,7 @@ class ActivityMetricsLogger { Log.i(TAG, sb.toString()); } private int convertAppStartTransitionType(int tronType) { private static int getAppStartTransitionType(int tronType, boolean relaunched) { if (tronType == TYPE_TRANSITION_COLD_LAUNCH) { return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD; } Loading @@ -926,17 +938,13 @@ class ActivityMetricsLogger { return FrameworkStatsLog.APP_START_OCCURRED__TYPE__WARM; } if (tronType == TYPE_TRANSITION_HOT_LAUNCH) { return FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT; return relaunched ? FrameworkStatsLog.APP_START_OCCURRED__TYPE__RELAUNCH : FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT; } return FrameworkStatsLog.APP_START_OCCURRED__TYPE__UNKNOWN; } /** @return the last known window drawn delay of the given activity. */ int getLastDrawnDelayMs(ActivityRecord r) { final TransitionInfo info = mLastTransitionInfo.get(r); return info != null ? info.mWindowsDrawnDelayMs : INVALID_DELAY; } /** @see android.app.Activity#reportFullyDrawn */ TransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r, boolean restoredFromBundle) { Loading services/core/java/com/android/server/wm/ActivityRecord.java +6 −8 Original line number Diff line number Diff line Loading @@ -226,7 +226,7 @@ import android.app.ActivityOptions; import android.app.PendingIntent; import android.app.PictureInPictureParams; import android.app.ResultInfo; import android.app.WaitResult.LaunchState; import android.app.WaitResult; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityRelaunchItem; Loading Loading @@ -3130,6 +3130,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void finishRelaunching() { mTaskSupervisor.getActivityMetricsLogger().notifyActivityRelaunched(this); unfreezeBounds(); if (mPendingRelaunchCount > 0) { Loading Loading @@ -5435,14 +5436,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs); final boolean validInfo = info != null; final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY; final @LaunchState int launchState = validInfo ? info.getLaunchState() : -1; final @WaitResult.LaunchState int launchState = validInfo ? info.getLaunchState() : WaitResult.LAUNCH_STATE_UNKNOWN; // The activity may have been requested to be invisible (another activity has been launched) // so there is no valid info. But if it is the current top activity (e.g. sleeping), the // invalid state is still reported to make sure the waiting result is notified. if (validInfo || this == getDisplayArea().topRunningActivity()) { mTaskSupervisor.reportActivityLaunchedLocked(false /* timeout */, this, windowsDrawnDelayMs, launchState); mTaskSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs); mTaskSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs, launchState); } finishLaunchTickingLocked(); if (task != null) { Loading Loading @@ -7163,11 +7165,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else { mRelaunchReason = RELAUNCH_REASON_NONE; } if (!attachedToProcess()) { ProtoLog.v(WM_DEBUG_CONFIGURATION, "Config is destroying non-running %s", this); destroyImmediately("config"); } else if (mState == PAUSING) { if (mState == PAUSING) { // A little annoying: we are waiting for this activity to finish pausing. Let's not // do anything now, but just flag that it needs to be restarted when done pausing. ProtoLog.v(WM_DEBUG_CONFIGURATION, Loading services/core/java/com/android/server/wm/ActivityStarter.java +0 −4 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WaitResult.LAUNCH_STATE_COLD; import static android.app.WaitResult.LAUNCH_STATE_HOT; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; Loading Loading @@ -819,8 +817,6 @@ class ActivityStarter { break; } case START_TASK_TO_FRONT: { mRequest.waitResult.launchState = r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD; // ActivityRecord may represent a different activity, but it should not be // in the resumed state. if (r.nowVisible && r.isState(RESUMED)) { Loading Loading
cmds/statsd/src/atoms.proto +2 −0 Original line number Diff line number Diff line Loading @@ -3768,6 +3768,7 @@ message AppStartOccurred { WARM = 1; HOT = 2; COLD = 3; RELAUNCH = 4; } // The transition type. optional TransitionType type = 3; Loading Loading @@ -3829,6 +3830,7 @@ message AppStartCanceled { WARM = 1; HOT = 2; COLD = 3; RELAUNCH = 4; } // The transition type. optional TransitionType type = 3; Loading
core/java/android/app/WaitResult.java +17 −1 Original line number Diff line number Diff line Loading @@ -40,13 +40,20 @@ public class WaitResult implements Parcelable { */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"LAUNCH_STATE_"}, value = { LAUNCH_STATE_UNKNOWN, LAUNCH_STATE_COLD, LAUNCH_STATE_WARM, LAUNCH_STATE_HOT LAUNCH_STATE_HOT, LAUNCH_STATE_RELAUNCH }) public @interface LaunchState { } /** * Not considered as a launch event, e.g. the activity is already on top. */ public static final int LAUNCH_STATE_UNKNOWN = 0; /** * Cold launch sequence: a new process has started. */ Loading @@ -62,6 +69,13 @@ public class WaitResult implements Parcelable { */ public static final int LAUNCH_STATE_HOT = 3; /** * Relaunch launch sequence: process reused, but activity has to be destroyed and created. * E.g. the current device configuration is different from the background activity that will be * brought to foreground, and the activity doesn't declare to handle the change. */ public static final int LAUNCH_STATE_RELAUNCH = 4; public static final int INVALID_DELAY = -1; public int result; public boolean timeout; Loading Loading @@ -124,6 +138,8 @@ public class WaitResult implements Parcelable { return "WARM"; case LAUNCH_STATE_HOT: return "HOT"; case LAUNCH_STATE_RELAUNCH: return "RELAUNCH"; default: return "UNKNOWN (" + type + ")"; } Loading
services/core/java/com/android/server/wm/ActivityMetricsLogger.java +22 −14 Original line number Diff line number Diff line Loading @@ -3,8 +3,10 @@ package com.android.server.wm; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityManager.processStateAmToProto; import static android.app.WaitResult.INVALID_DELAY; import static android.app.WaitResult.LAUNCH_STATE_COLD; import static android.app.WaitResult.LAUNCH_STATE_HOT; import static android.app.WaitResult.LAUNCH_STATE_RELAUNCH; import static android.app.WaitResult.LAUNCH_STATE_WARM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; Loading Loading @@ -130,7 +132,6 @@ class ActivityMetricsLogger { * transition, in the case the launch is standalone (e.g. from recents). */ private static final int IGNORE_CALLER = -1; private static final int INVALID_DELAY = -1; // Preallocated strings we are sending to tron, so we don't have to allocate a new one every // time we log. Loading Loading @@ -220,6 +221,8 @@ class ActivityMetricsLogger { boolean mLoggedStartingWindowDrawn; /** If the any app transitions have been logged as starting. */ boolean mLoggedTransitionStarting; /** Whether any activity belonging to this transition has relaunched. */ boolean mRelaunched; /** Non-null if the application has reported drawn but its window hasn't. */ @Nullable Runnable mPendingFullyDrawn; Loading Loading @@ -351,6 +354,7 @@ class ActivityMetricsLogger { */ final int windowsFullyDrawnDelayMs; final int activityRecordIdHashCode; final boolean relaunched; private TransitionInfoSnapshot(TransitionInfo info) { this(info, info.mLastLaunchedActivity, INVALID_DELAY); Loading Loading @@ -379,6 +383,7 @@ class ActivityMetricsLogger { launchedActivityShortComponentName = launchedActivity.shortComponentName; activityRecordIdHashCode = System.identityHashCode(launchedActivity); this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs; relaunched = info.mRelaunched; } @WaitResult.LaunchState int getLaunchState() { Loading @@ -386,7 +391,7 @@ class ActivityMetricsLogger { case TYPE_TRANSITION_WARM_LAUNCH: return LAUNCH_STATE_WARM; case TYPE_TRANSITION_HOT_LAUNCH: return LAUNCH_STATE_HOT; return relaunched ? LAUNCH_STATE_RELAUNCH : LAUNCH_STATE_HOT; case TYPE_TRANSITION_COLD_LAUNCH: return LAUNCH_STATE_COLD; default: Loading Loading @@ -673,6 +678,13 @@ class ActivityMetricsLogger { } } void notifyActivityRelaunched(ActivityRecord r) { final TransitionInfo info = getActiveTransitionInfo(r); if (info != null) { info.mRelaunched = true; } } /** Makes sure that the reference to the removed activity is cleared. */ void notifyActivityRemoved(@NonNull ActivityRecord r) { mLastTransitionInfo.remove(r); Loading Loading @@ -800,13 +812,13 @@ class ActivityMetricsLogger { FrameworkStatsLog.APP_START_CANCELED, activity.info.applicationInfo.uid, activity.packageName, convertAppStartTransitionType(type), getAppStartTransitionType(type, info.mRelaunched), activity.info.name); if (DEBUG_METRICS) { Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)", activity.info.applicationInfo.uid, activity.packageName, convertAppStartTransitionType(type), getAppStartTransitionType(type, info.mRelaunched), activity.info.name)); } } Loading Loading @@ -871,7 +883,7 @@ class ActivityMetricsLogger { FrameworkStatsLog.APP_START_OCCURRED, info.applicationInfo.uid, info.packageName, convertAppStartTransitionType(info.type), getAppStartTransitionType(info.type, info.relaunched), info.launchedActivityName, info.launchedActivityLaunchedFromPackage, isInstantApp, Loading @@ -891,7 +903,7 @@ class ActivityMetricsLogger { Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)", info.applicationInfo.uid, info.packageName, convertAppStartTransitionType(info.type), getAppStartTransitionType(info.type, info.relaunched), info.launchedActivityName, info.launchedActivityLaunchedFromPackage)); } Loading @@ -918,7 +930,7 @@ class ActivityMetricsLogger { Log.i(TAG, sb.toString()); } private int convertAppStartTransitionType(int tronType) { private static int getAppStartTransitionType(int tronType, boolean relaunched) { if (tronType == TYPE_TRANSITION_COLD_LAUNCH) { return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD; } Loading @@ -926,17 +938,13 @@ class ActivityMetricsLogger { return FrameworkStatsLog.APP_START_OCCURRED__TYPE__WARM; } if (tronType == TYPE_TRANSITION_HOT_LAUNCH) { return FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT; return relaunched ? FrameworkStatsLog.APP_START_OCCURRED__TYPE__RELAUNCH : FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT; } return FrameworkStatsLog.APP_START_OCCURRED__TYPE__UNKNOWN; } /** @return the last known window drawn delay of the given activity. */ int getLastDrawnDelayMs(ActivityRecord r) { final TransitionInfo info = mLastTransitionInfo.get(r); return info != null ? info.mWindowsDrawnDelayMs : INVALID_DELAY; } /** @see android.app.Activity#reportFullyDrawn */ TransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r, boolean restoredFromBundle) { Loading
services/core/java/com/android/server/wm/ActivityRecord.java +6 −8 Original line number Diff line number Diff line Loading @@ -226,7 +226,7 @@ import android.app.ActivityOptions; import android.app.PendingIntent; import android.app.PictureInPictureParams; import android.app.ResultInfo; import android.app.WaitResult.LaunchState; import android.app.WaitResult; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityRelaunchItem; Loading Loading @@ -3130,6 +3130,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void finishRelaunching() { mTaskSupervisor.getActivityMetricsLogger().notifyActivityRelaunched(this); unfreezeBounds(); if (mPendingRelaunchCount > 0) { Loading Loading @@ -5435,14 +5436,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs); final boolean validInfo = info != null; final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY; final @LaunchState int launchState = validInfo ? info.getLaunchState() : -1; final @WaitResult.LaunchState int launchState = validInfo ? info.getLaunchState() : WaitResult.LAUNCH_STATE_UNKNOWN; // The activity may have been requested to be invisible (another activity has been launched) // so there is no valid info. But if it is the current top activity (e.g. sleeping), the // invalid state is still reported to make sure the waiting result is notified. if (validInfo || this == getDisplayArea().topRunningActivity()) { mTaskSupervisor.reportActivityLaunchedLocked(false /* timeout */, this, windowsDrawnDelayMs, launchState); mTaskSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs); mTaskSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs, launchState); } finishLaunchTickingLocked(); if (task != null) { Loading Loading @@ -7163,11 +7165,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } else { mRelaunchReason = RELAUNCH_REASON_NONE; } if (!attachedToProcess()) { ProtoLog.v(WM_DEBUG_CONFIGURATION, "Config is destroying non-running %s", this); destroyImmediately("config"); } else if (mState == PAUSING) { if (mState == PAUSING) { // A little annoying: we are waiting for this activity to finish pausing. Let's not // do anything now, but just flag that it needs to be restarted when done pausing. ProtoLog.v(WM_DEBUG_CONFIGURATION, Loading
services/core/java/com/android/server/wm/ActivityStarter.java +0 −4 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WaitResult.LAUNCH_STATE_COLD; import static android.app.WaitResult.LAUNCH_STATE_HOT; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; Loading Loading @@ -819,8 +817,6 @@ class ActivityStarter { break; } case START_TASK_TO_FRONT: { mRequest.waitResult.launchState = r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD; // ActivityRecord may represent a different activity, but it should not be // in the resumed state. if (r.nowVisible && r.isState(RESUMED)) { Loading