diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java index c5f63ced989cf..a6d5c19395b01 100644 --- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java @@ -285,9 +285,9 @@ class ActivityMetricsLogger { final LaunchingState mLaunchingState; /** The type can be cold (new process), warm (new activity), or hot (bring to front). */ - final int mTransitionType; + int mTransitionType; /** Whether the process was already running when the transition started. */ - final boolean mProcessRunning; + boolean mProcessRunning; /** whether the process of the launching activity didn't have any active activity. */ final boolean mProcessSwitch; /** The process state of the launching activity prior to the launch */ @@ -972,6 +972,19 @@ class ActivityMetricsLogger { // App isn't attached to record yet, so match with info. if (info.mLastLaunchedActivity.info.applicationInfo == appInfo) { info.mBindApplicationDelayMs = info.calculateCurrentDelay(); + if (info.mProcessRunning) { + // It was HOT/WARM launch, but the process was died somehow right after the + // launch request. + info.mProcessRunning = false; + info.mTransitionType = TYPE_TRANSITION_COLD_LAUNCH; + final String msg = "Process " + info.mLastLaunchedActivity.info.processName + + " restarted"; + Slog.i(TAG, msg); + if (info.mLaunchingState.mTraceName != null) { + Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, msg + "#" + + LaunchingState.sTraceSeqId); + } + } } } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java index 5c3102d870d01..65e77dcd4ca91 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java @@ -182,12 +182,12 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { @Test public void testLaunchState() { - final ToIntFunction launchTemplate = doRelaunch -> { + final ToIntFunction launchTemplate = action -> { clearInvocations(mLaunchObserver); onActivityLaunched(mTopActivity); notifyTransitionStarting(mTopActivity); - if (doRelaunch) { - mActivityMetricsLogger.notifyActivityRelaunched(mTopActivity); + if (action != null) { + action.run(); } final ActivityMetricsLogger.TransitionInfoSnapshot info = notifyWindowsDrawn(mTopActivity); @@ -199,21 +199,27 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase { // Assume that the process is started (ActivityBuilder has mocked the returned value of // ATMS#getProcessController) but the activity has not attached process. mTopActivity.app = null; - assertWithMessage("Warm launch").that(launchTemplate.applyAsInt(false /* doRelaunch */)) + assertWithMessage("Warm launch").that(launchTemplate.applyAsInt(null)) .isEqualTo(WaitResult.LAUNCH_STATE_WARM); mTopActivity.app = app; mNewActivityCreated = false; - assertWithMessage("Hot launch").that(launchTemplate.applyAsInt(false /* doRelaunch */)) + assertWithMessage("Hot launch").that(launchTemplate.applyAsInt(null)) .isEqualTo(WaitResult.LAUNCH_STATE_HOT); - assertWithMessage("Relaunch").that(launchTemplate.applyAsInt(true /* doRelaunch */)) + assertWithMessage("Relaunch").that(launchTemplate.applyAsInt( + () -> mActivityMetricsLogger.notifyActivityRelaunched(mTopActivity))) .isEqualTo(WaitResult.LAUNCH_STATE_RELAUNCH); + assertWithMessage("Cold launch by restart").that(launchTemplate.applyAsInt( + () -> mActivityMetricsLogger.notifyBindApplication( + mTopActivity.info.applicationInfo))) + .isEqualTo(WaitResult.LAUNCH_STATE_COLD); + mTopActivity.app = null; mNewActivityCreated = true; doReturn(null).when(mAtm).getProcessController(app.mName, app.mUid); - assertWithMessage("Cold launch").that(launchTemplate.applyAsInt(false /* doRelaunch */)) + assertWithMessage("Cold launch").that(launchTemplate.applyAsInt(null)) .isEqualTo(WaitResult.LAUNCH_STATE_COLD); }