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

Commit bb43d4a5 authored by Evan Rosky's avatar Evan Rosky Committed by Android (Google) Code Review
Browse files

Merge "Add tranistion combine trace-events" into main

parents 3f34d20e c72d49af
Loading
Loading
Loading
Loading
+68 −3
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.server.wm;

import static android.view.WindowManager.transitTypeToString;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Trace;
import android.util.Slog;

import com.android.window.flags.Flags;
@@ -216,6 +219,18 @@ public class ActionChain {
        }
    }

    /**
     * @return The chain link where this chain was first associated with a transition.
     */
    private ActionChain getTransitionSource() {
        if (mTransition == null) return null;
        ActionChain out = this;
        while (out.mPrevious != null && out.mPrevious.mTransition != null) {
            out = out.mPrevious;
        }
        return out;
    }

    private static class AsyncStart {
        final int mStackPos;
        long mThreadId;
@@ -243,6 +258,8 @@ public class ActionChain {
        /** Stack of suspended actions for dealing with async-start "gaps". */
        private final ArrayList<AsyncStart> mAsyncStarts = new ArrayList<>();

        private final Stats mStats = new Stats();

        Tracker(ActivityTaskManagerService atm) {
            mAtm = atm;
        }
@@ -364,7 +381,14 @@ public class ActionChain {
         */
        @NonNull
        ActionChain start(String source, Transition transit) {
            return makeChain(source, TYPE_NORMAL, transit);
            boolean isTransitionNew = transit.mChainHead == null;
            final ActionChain out = makeChain(source, TYPE_NORMAL, transit);
            if (isTransitionNew) {
                mStats.onTransitionCreated(out);
            } else {
                mStats.onTransitionContinued(out);
            }
            return out;
        }

        /** @see #TYPE_DEFAULT */
@@ -375,11 +399,15 @@ public class ActionChain {

        /**
         * Create a chain-link for a decision-point between making a new transition or using the
         * global collecting one.
         * global collecting one. A new transition is the desired outcome in this case.
         */
        @NonNull
        ActionChain startTransit(String source) {
            return makeChain(source, TYPE_DEFAULT);
            final ActionChain out = makeChain(source, TYPE_DEFAULT);
            if (out.isCollecting()) {
                mStats.onTransitionCombined(out);
            }
            return out;
        }

        /**
@@ -414,4 +442,41 @@ public class ActionChain {
    static ActionChain testFinish(Transition toFinish) {
        return new ActionChain("test", TYPE_FINISH, toFinish);
    }

    static class Stats {
        void onTransitionCreated(ActionChain head) {
        }

        /**
         * A chain link was added for a unique transition that was forced to be combined into an
         * already-collecting transition.
         */
        void onTransitionCombined(ActionChain head) {
            final Transition transit = head.getTransition();
            final String tsum = transitSummary(transit);
            final ActionChain tsource = head.getTransitionSource();
            Trace.instantForTrack(Trace.TRACE_TAG_WINDOW_MANAGER, "TransitCombine",
                    head.mSource + "->" + tsum + ":" + tsource.mSource);
            Slog.w(TAG, "Combining " + head.mSource + " into " + "#" + transit.getSyncId()
                    + "(" + tsum + ") from " + tsource.mSource);
        }

        /**
         * A chain link was added to continue an already-collecting transition.
         */
        void onTransitionContinued(ActionChain head) {
            if (!Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
                return;
            }
            final String tsum = transitSummary(head.getTransition());
            final ActionChain tsource = head.getTransitionSource();
            Trace.instantForTrack(Trace.TRACE_TAG_WINDOW_MANAGER, "TransitContinue",
                    head.mSource + "->" + tsum + ":" + tsource.mSource);
        }

        private static String transitSummary(Transition t) {
            return transitTypeToString(t.mType) + "|" + (t.mLogger.mFromPlayer ? "" : "R")
                    + "|0x" + Integer.toHexString(t.getFlags());
        }
    }
}
+10 −1
Original line number Diff line number Diff line
@@ -3587,7 +3587,16 @@ final class ActivityRecord extends WindowToken {
                // root task is not visible if it only contains finishing activities.
                && mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask);

        final ActionChain chain = mAtmService.mChainTracker.startTransit("AR.finish");
        final ActionChain chain;
        final Transition sourceTransit = mTransitionController.getCollectingTransition();
        if (sourceTransit != null
                && (sourceTransit.isSourceActivity(this) || sourceTransit.isInTransition(this))) {
            // TODO(b/294925498): Until we have accurate ready tracking, assume that
            //                    membership or "sourceActivity" means this is expected.
            chain = mAtmService.mChainTracker.start("AR.finish-" + reason, sourceTransit);
        } else {
            chain = mAtmService.mChainTracker.startTransit("AR.finish-" + reason);
        }
        mAtmService.deferWindowLayout();
        try {
            mTaskSupervisor.mNoHistoryActivities.remove(this);
+16 −2
Original line number Diff line number Diff line
@@ -1508,22 +1508,36 @@ class ActivityStarter {
            mService.resumeAppSwitches();
        }

        final ActionChain chain = mService.mChainTracker.startTransit("startAct");
        // Because startActivity must run immediately, it can get combined with another
        // transition meaning it is no-longer independent. This is NOT desirable, but is the
        // only option for the time being.
        boolean isIndependent = false;
        final ActionChain chain;
        final Transition sourceTransit = r.mTransitionController.getCollectingTransition();
        final String actionType = r.isActivityTypeHomeOrRecents() ? "startHomeAct" : "startAct";
        if (sourceRecord != null && sourceTransit != null
                && sourceTransit.isInTransition(sourceRecord)) {
            // TODO(b/294925498): Until we have accurate ready tracking, assume that
            //                    sourceRecord membership means this is expected.
            chain = mService.mChainTracker.start(actionType, sourceTransit);
        } else {
            chain = mService.mChainTracker.startTransit(actionType);
        }
        if (!chain.isCollecting()) {
            // Only do the create here since startActivityInner can abort. If it doesn't abort,
            // the requestStart will be sent in handleStartRequest.
            chain.attachTransition(r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN));
            isIndependent = chain.getTransition() != null;
        }
        final Transition transition = chain.getTransition();
        if (transition != null && sourceRecord != null) {
            transition.addSourceActivity(sourceRecord);
        }

        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, checkedOptions,
                inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid,
                chain.getTransition(), isIndependent);
                transition, isIndependent);

        // Because the pending-intent usage in the waitAsyncStart hack "exits" ATMS into
        // AMS and re-enters, this can be nested.
+27 −0
Original line number Diff line number Diff line
@@ -349,6 +349,13 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
    /** The current head of the chain of actions related to this transition. */
    ActionChain mChainHead = null;

    /**
     * List of activities which have initiated actions in this transition. For now, assume that
     * if an activity has initiated at-least one action in this transition, any following actions
     * initiated by that activity (during collection) are intentionally in the same transition.
     */
    ArrayList<ActivityRecord> mSourceActivities = null;

    @VisibleForTesting
    Transition(@TransitionType int type, @TransitionFlags int flags,
            TransitionController controller, BLASTSyncEngine syncEngine) {
@@ -973,6 +980,26 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
        }
    }

    /**
     * Record an activity as being a source of actions in this transition.
     */
    void addSourceActivity(ActivityRecord r) {
        if (mSourceActivities == null) {
            mSourceActivities = new ArrayList<>();
        } else if (mSourceActivities.contains(r)) {
            return;
        }
        mSourceActivities.add(r);
    }

    /**
     * @return whether {@param r} is a source of actions in this transition.
     */
    boolean isSourceActivity(ActivityRecord r) {
        if (mSourceActivities == null) return false;
        return mSourceActivities.contains(r);
    }

    /**
     * @return {@code true} if `wc` is a participant or is a descendant of one.
     */
+1 −0
Original line number Diff line number Diff line
@@ -1753,6 +1753,7 @@ class TransitionController {
        WindowContainerTransaction mStartWCT;
        int mSyncId;
        TransitionInfo mInfo;
        boolean mFromPlayer;

        private String buildOnSendLog() {
            StringBuilder sb = new StringBuilder("Sent Transition (#").append(mSyncId)
Loading