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

Commit 4bede49b authored by Chris Li's avatar Chris Li Committed by Automerger Merge Worker
Browse files

Merge "Hook up shell transit to metrics and interleave abort with merge" into...

Merge "Hook up shell transit to metrics and interleave abort with merge" into sc-v2-dev am: ed5ea3b8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14939982

Change-Id: Ic4b32cf8bb175e6d65a12591e9e1586d789f8795
parents 28fe53e9 ed5ea3b8
Loading
Loading
Loading
Loading
+40 −16
Original line number Diff line number Diff line
@@ -97,12 +97,13 @@ public class Transitions implements RemoteCallable<Transitions> {
    private float mTransitionAnimationScaleSetting = 1.0f;

    private static final class ActiveTransition {
        IBinder mToken = null;
        TransitionHandler mHandler = null;
        boolean mMerged = false;
        TransitionInfo mInfo = null;
        SurfaceControl.Transaction mStartT = null;
        SurfaceControl.Transaction mFinishT = null;
        IBinder mToken;
        TransitionHandler mHandler;
        boolean mMerged;
        boolean mAborted;
        TransitionInfo mInfo;
        SurfaceControl.Transaction mStartT;
        SurfaceControl.Transaction mFinishT;
    }

    /** Keeps track of currently playing transitions in the order of receipt. */
@@ -422,17 +423,19 @@ public class Transitions implements RemoteCallable<Transitions> {

    /** Special version of finish just for dealing with no-op/invalid transitions. */
    private void onAbort(IBinder transition) {
        final int activeIdx = findActiveTransition(transition);
        if (activeIdx < 0) return;
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                "Transition animation aborted due to no-op, notifying core %s", transition);
        mActiveTransitions.remove(activeIdx);
        mOrganizer.finishTransition(transition, null /* wct */, null /* wctCB */);
        onFinish(transition, null /* wct */, null /* wctCB */, true /* abort */);
    }

    private void onFinish(IBinder transition,
            @Nullable WindowContainerTransaction wct,
            @Nullable WindowContainerTransactionCallback wctCB) {
        onFinish(transition, wct, wctCB, false /* abort */);
    }

    private void onFinish(IBinder transition,
            @Nullable WindowContainerTransaction wct,
            @Nullable WindowContainerTransactionCallback wctCB,
            boolean abort) {
        int activeIdx = findActiveTransition(transition);
        if (activeIdx < 0) {
            Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or "
@@ -440,28 +443,37 @@ public class Transitions implements RemoteCallable<Transitions> {
            return;
        } else if (activeIdx > 0) {
            // This transition was merged.
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s",
                    transition);
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged (abort=%b:"
                    + " %s", abort, transition);
            final ActiveTransition active = mActiveTransitions.get(activeIdx);
            active.mMerged = true;
            active.mAborted = abort;
            if (active.mHandler != null) {
                active.mHandler.onTransitionMerged(active.mToken);
            }
            return;
        }
        mActiveTransitions.get(activeIdx).mAborted = abort;
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
                "Transition animation finished, notifying core %s", transition);
                "Transition animation finished (abort=%b), notifying core %s", abort, transition);
        // Merge all relevant transactions together
        SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT;
        for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) {
            final ActiveTransition toMerge = mActiveTransitions.get(iA);
            if (!toMerge.mMerged) break;
            // aborted transitions have no start/finish transactions
            if (mActiveTransitions.get(iA).mStartT == null) break;
            if (fullFinish == null) {
                fullFinish = new SurfaceControl.Transaction();
            }
            // Include start. It will be a no-op if it was already applied. Otherwise, we need it
            // to maintain consistent state.
            fullFinish.merge(mActiveTransitions.get(iA).mStartT);
            fullFinish.merge(mActiveTransitions.get(iA).mFinishT);
        }
        if (fullFinish != null) {
            fullFinish.apply();
        }
        // Now perform all the finishes.
        mActiveTransitions.remove(activeIdx);
        mOrganizer.finishTransition(transition, wct, wctCB);
@@ -470,6 +482,12 @@ public class Transitions implements RemoteCallable<Transitions> {
            ActiveTransition merged = mActiveTransitions.remove(activeIdx);
            mOrganizer.finishTransition(merged.mToken, null /* wct */, null /* wctCB */);
        }
        // sift through aborted transitions
        while (mActiveTransitions.size() > activeIdx
                && mActiveTransitions.get(activeIdx).mAborted) {
            ActiveTransition aborted = mActiveTransitions.remove(activeIdx);
            mOrganizer.finishTransition(aborted.mToken, null /* wct */, null /* wctCB */);
        }
        if (mActiveTransitions.size() <= activeIdx) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "All active transition animations "
                    + "finished");
@@ -500,6 +518,12 @@ public class Transitions implements RemoteCallable<Transitions> {
        int mergeIdx = activeIdx + 1;
        while (mergeIdx < mActiveTransitions.size()) {
            ActiveTransition mergeCandidate = mActiveTransitions.get(mergeIdx);
            if (mergeCandidate.mAborted) {
                // transition was aborted, so we can skip for now (still leave it in the list
                // so that it gets cleaned-up in the right order).
                ++mergeIdx;
                continue;
            }
            if (mergeCandidate.mMerged) {
                throw new IllegalStateException("Can't merge a transition after not-merging"
                        + " a preceding one.");
+16 −0
Original line number Diff line number Diff line
@@ -665,6 +665,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    boolean allDrawn;
    private boolean mLastAllDrawn;

    /**
     * Solely for reporting to ActivityMetricsLogger. Just tracks whether, the last time this
     * Actiivty was part of a syncset, all windows were ready by the time the sync was ready (vs.
     * only the top-occluding ones). The assumption here is if some were not ready, they were
     * covered with starting-window/splash-screen.
     */
    boolean mLastAllReadyAtSync = false;

    private boolean mLastContainsShowWhenLockedWindow;
    private boolean mLastContainsDismissKeyguardWindow;
    private boolean mLastContainsTurnScreenOnWindow;
@@ -9018,6 +9026,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return false;
    }

    @Override
    void finishSync(Transaction outMergedTransaction, boolean cancel) {
        // This override is just for getting metrics. allFinished needs to be checked before
        // finish because finish resets all the states.
        mLastAllReadyAtSync = allSyncFinished();
        super.finishSync(outMergedTransaction, cancel);
    }

    static class Builder {
        private final ActivityTaskManagerService mAtmService;
        private WindowProcessController mCallerApp;
+4 −0
Original line number Diff line number Diff line
@@ -166,6 +166,10 @@ class BLASTSyncEngine {
        setReady(id, true);
    }

    boolean isReady(int id) {
        return mActiveSyncs.get(id).mReady;
    }

    /**
     * Aborts the sync (ie. it doesn't wait for ready or anything to finish)
     */
+5 −1
Original line number Diff line number Diff line
@@ -3100,7 +3100,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
        }
        mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
        if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
            mAtmService.getTransitionController().dumpDebugLegacy(proto, APP_TRANSITION);
        } else {
            mAppTransition.dumpDebug(proto, APP_TRANSITION);
        }
        if (mFocusedApp != null) {
            mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
        }
+26 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;

import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -395,6 +398,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe

        handleNonAppWindowsInTransition(displayId, mType, mFlags);

        reportStartReasonsToLogger();

        // Manually show any activities that are visibleRequested. This is needed to properly
        // support simultaneous animation queueing/merging. Specifically, if transition A makes
        // an activity invisible, it's finishTransaction (which is applied *after* the animation)
@@ -575,6 +580,23 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        }
    }

    private void reportStartReasonsToLogger() {
        // Record transition start in metrics logger. We just assume everything is "DRAWN"
        // at this point since splash-screen is a presentation (shell) detail.
        ArrayMap<WindowContainer, Integer> reasons = new ArrayMap<>();
        for (int i = mParticipants.size() - 1; i >= 0; --i) {
            ActivityRecord r = mParticipants.valueAt(i).asActivityRecord();
            if (r == null) continue;
            // At this point, r is "ready", but if it's not "ALL ready" then it is probably only
            // ready due to starting-window.
            reasons.put(r, (r.mStartingData instanceof SplashScreenStartingData
                    && !r.mLastAllReadyAtSync)
                    ? APP_TRANSITION_SPLASH_SCREEN : APP_TRANSITION_WINDOWS_DRAWN);
        }
        mController.mAtm.mTaskSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
                reasons);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(64);
@@ -953,6 +975,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        return out;
    }

    boolean getLegacyIsReady() {
        return mState == STATE_STARTED && mSyncId >= 0 && mSyncEngine.isReady(mSyncId);
    }

    static Transition fromBinder(IBinder binder) {
        return (Transition) binder;
    }
Loading