Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cbe47f3 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

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
parent 054f5c15
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -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);
            // 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);
+3 −0
Original line number Diff line number Diff line
@@ -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