Merge "Make sure instance launch trace for an id only appears once" into tm-dev
This commit is contained in:
@@ -192,11 +192,10 @@ class ActivityMetricsLogger {
|
|||||||
/** The sequence id for trace. It is used to map the traces before resolving intent. */
|
/** The sequence id for trace. It is used to map the traces before resolving intent. */
|
||||||
private static int sTraceSeqId;
|
private static int sTraceSeqId;
|
||||||
/** The trace format is "launchingActivity#$seqId:$state(:$packageName)". */
|
/** The trace format is "launchingActivity#$seqId:$state(:$packageName)". */
|
||||||
final String mTraceName;
|
String mTraceName;
|
||||||
|
|
||||||
LaunchingState() {
|
LaunchingState() {
|
||||||
if (!Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
|
if (!Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
|
||||||
mTraceName = null;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Use an id because the launching app is not yet known before resolving intent.
|
// 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);
|
Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopTrace(boolean abort) {
|
void stopTrace(boolean abort, TransitionInfo endInfo) {
|
||||||
if (mTraceName == null) return;
|
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);
|
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName, 0);
|
||||||
final String launchResult;
|
final String launchResult;
|
||||||
if (mAssociatedTransitionInfo == null) {
|
if (mAssociatedTransitionInfo == null) {
|
||||||
@@ -218,6 +223,7 @@ class ActivityMetricsLogger {
|
|||||||
}
|
}
|
||||||
// Put a supplement trace as the description of the async trace with the same id.
|
// Put a supplement trace as the description of the async trace with the same id.
|
||||||
Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName + launchResult);
|
Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, mTraceName + launchResult);
|
||||||
|
mTraceName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -321,7 +327,11 @@ class ActivityMetricsLogger {
|
|||||||
mProcessSwitch = processSwitch;
|
mProcessSwitch = processSwitch;
|
||||||
mTransitionDeviceUptimeMs = launchingState.mCurrentUpTimeMs;
|
mTransitionDeviceUptimeMs = launchingState.mCurrentUpTimeMs;
|
||||||
setLatestLaunchedActivity(r);
|
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) {
|
if (options != null) {
|
||||||
final SourceInfo sourceInfo = options.getSourceInfo();
|
final SourceInfo sourceInfo = options.getSourceInfo();
|
||||||
if (sourceInfo != null) {
|
if (sourceInfo != null) {
|
||||||
@@ -908,7 +918,7 @@ class ActivityMetricsLogger {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DEBUG_METRICS) Slog.i(TAG, "abort launch cause=" + cause);
|
if (DEBUG_METRICS) Slog.i(TAG, "abort launch cause=" + cause);
|
||||||
state.stopTrace(true /* abort */);
|
state.stopTrace(true /* abort */, null /* endInfo */);
|
||||||
launchObserverNotifyIntentFailed(state.mCurrentTransitionStartTimeNs);
|
launchObserverNotifyIntentFailed(state.mCurrentTransitionStartTimeNs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -924,7 +934,7 @@ class ActivityMetricsLogger {
|
|||||||
Slog.i(TAG, "done abort=" + abort + " cause=" + cause + " timestamp=" + timestampNs
|
Slog.i(TAG, "done abort=" + abort + " cause=" + cause + " timestamp=" + timestampNs
|
||||||
+ " info=" + info);
|
+ " info=" + info);
|
||||||
}
|
}
|
||||||
info.mLaunchingState.stopTrace(abort);
|
info.mLaunchingState.stopTrace(abort, info);
|
||||||
stopLaunchTrace(info);
|
stopLaunchTrace(info);
|
||||||
final Boolean isHibernating =
|
final Boolean isHibernating =
|
||||||
mLastHibernationStates.remove(info.mLastLaunchedActivity.packageName);
|
mLastHibernationStates.remove(info.mLastLaunchedActivity.packageName);
|
||||||
|
|||||||
@@ -532,6 +532,9 @@ public class ActivityMetricsLaunchObserverTests extends WindowTestsBase {
|
|||||||
transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
|
transitToDrawnAndVerifyOnLaunchFinished(mTopActivity);
|
||||||
setLastExpectedStartedId(activityOnNewDisplay);
|
setLastExpectedStartedId(activityOnNewDisplay);
|
||||||
transitToDrawnAndVerifyOnLaunchFinished(activityOnNewDisplay);
|
transitToDrawnAndVerifyOnLaunchFinished(activityOnNewDisplay);
|
||||||
|
|
||||||
|
assertWithMessage("The launching state must not include the separated launch")
|
||||||
|
.that(mLaunchingState.contains(activityOnNewDisplay)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user