Merge "Make sure instance launch trace for an id only appears once" into tm-dev

This commit is contained in:
Riddle Hsu
2022-05-26 10:05:42 +00:00
committed by Android (Google) Code Review
2 changed files with 19 additions and 6 deletions

View File

@@ -192,11 +192,10 @@ class ActivityMetricsLogger {
/** The sequence id for trace. It is used to map the traces before resolving intent. */
private static int sTraceSeqId;
/** The trace format is "launchingActivity#$seqId:$state(:$packageName)". */
final String mTraceName;
String mTraceName;
LaunchingState() {
if (!Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
mTraceName = null;
return;
}
// Use an id because the launching app is not yet known before resolving intent.
@@ -205,8 +204,14 @@ class ActivityMetricsLogger {
Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName, 0);
}
void stopTrace(boolean abort) {
void stopTrace(boolean abort, TransitionInfo endInfo) {
if (mTraceName == null) return;
if (!abort && endInfo != mAssociatedTransitionInfo) {
// Multiple TransitionInfo can be associated with the same LaunchingState (e.g. a
// launching activity launches another activity in a different windowing mode or
// display). Only the original associated info can emit a "completed" trace.
return;
}
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName, 0);
final String launchResult;
if (mAssociatedTransitionInfo == null) {
@@ -218,6 +223,7 @@ class ActivityMetricsLogger {
}
// Put a supplement trace as the description of the async trace with the same id.
Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName + launchResult);
mTraceName = null;
}
@VisibleForTesting
@@ -321,7 +327,11 @@ class ActivityMetricsLogger {
mProcessSwitch = processSwitch;
mTransitionDeviceUptimeMs = launchingState.mCurrentUpTimeMs;
setLatestLaunchedActivity(r);
launchingState.mAssociatedTransitionInfo = this;
// The launching state can be reused by consecutive launch. Its original association
// shouldn't be changed by a separated transition.
if (launchingState.mAssociatedTransitionInfo == null) {
launchingState.mAssociatedTransitionInfo = this;
}
if (options != null) {
final SourceInfo sourceInfo = options.getSourceInfo();
if (sourceInfo != null) {
@@ -908,7 +918,7 @@ class ActivityMetricsLogger {
return;
}
if (DEBUG_METRICS) Slog.i(TAG, "abort launch cause=" + cause);
state.stopTrace(true /* abort */);
state.stopTrace(true /* abort */, null /* endInfo */);
launchObserverNotifyIntentFailed(state.mCurrentTransitionStartTimeNs);
}
@@ -924,7 +934,7 @@ class ActivityMetricsLogger {
Slog.i(TAG, "done abort=" + abort + " cause=" + cause + " timestamp=" + timestampNs
+ " info=" + info);
}
info.mLaunchingState.stopTrace(abort);
info.mLaunchingState.stopTrace(abort, info);
stopLaunchTrace(info);
final Boolean isHibernating =
mLastHibernationStates.remove(info.mLastLaunchedActivity.packageName);

View File

@@ -532,6 +532,9 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
setLastExpectedStartedId(activityOnNewDisplay);
transitToDrawnAndVerifyOnLaunchFinished(activityOnNewDisplay);
assertWithMessage("The launching state must not include the separated launch")
.that(mLaunchingState.contains(activityOnNewDisplay)).isFalse();
}
@Test