Update to cold launch if the process is restarted during launching
The current common case is that the process of the resuming activity
is just unfrozen but its binder buffer is full (someone still sends
async binder call to it when it is frozen) and the process could
be killed because binder transaction failed. Then the process will
attach again so the launch type can be corrected to COLD to avoid
disturb the distribution of metrics.
Bug: 291599121
Test: atest ActivityMetricsLaunchObserverTests#testLaunchState
Change-Id: I26252410508d21aacacd35bd6cc305dc7a0fc9f9
(cherry picked from commit e4207adfe3)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,12 +182,12 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testLaunchState() {
|
||||
final ToIntFunction<Boolean> launchTemplate = doRelaunch -> {
|
||||
final ToIntFunction<Runnable> 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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user