summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2022-05-24 23:37:29 -0600
committer Riddle Hsu <riddlehsu@google.com> 2022-05-25 18:20:08 +0800
commit0cbe47f3c9821dd42f40c7da6e9f9393917a2724 (patch)
tree0a9e187799511c0e5c10ed7a98d71b1c7ebe63d9
parent054f5c15c9b17413e9c5a4e013adbc10ab1f5ace (diff)
Make sure instance launch trace for an id only appears once
A consecutive launch may contain multiple activities with different windowing modes or target displays. The separated transition should not end the trace of the initial launch. e.g. start A---------------------->A drawn |-A starts B-->B drawn (on a different display) There will still be 2 traces "launching: A" and "launching: B". But there should be only one trace "launchingActivity" which is ended by "A drawn". Bug: 231612200 Test: atest ActivityMetricsLaunchObserverTests# \ testConsecutiveLaunchOnDifferentDisplay Change-Id: Ied39e000ef6c8c60b56e228cbdc86b6f9dbe2e6c
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java22
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java3
2 files changed, 19 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index f2bcd1dbf544..d6c0ab6b124b 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -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);
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 2fea2284ff2a..5b909a343a59 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -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