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

Commit ed5ea3b8 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

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

parents 2b28e171 dfe1fc55
Loading
Loading
Loading
Loading
+40 −16
Original line number Original line Diff line number Diff line
@@ -97,12 +97,13 @@ public class Transitions implements RemoteCallable<Transitions> {
    private float mTransitionAnimationScaleSetting = 1.0f;
    private float mTransitionAnimationScaleSetting = 1.0f;


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


    /** Keeps track of currently playing transitions in the order of receipt. */
    /** 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. */
    /** Special version of finish just for dealing with no-op/invalid transitions. */
    private void onAbort(IBinder transition) {
    private void onAbort(IBinder transition) {
        final int activeIdx = findActiveTransition(transition);
        onFinish(transition, null /* wct */, null /* wctCB */, true /* abort */);
        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 */);
    }
    }


    private void onFinish(IBinder transition,
    private void onFinish(IBinder transition,
            @Nullable WindowContainerTransaction wct,
            @Nullable WindowContainerTransaction wct,
            @Nullable WindowContainerTransactionCallback wctCB) {
            @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);
        int activeIdx = findActiveTransition(transition);
        if (activeIdx < 0) {
        if (activeIdx < 0) {
            Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or "
            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;
            return;
        } else if (activeIdx > 0) {
        } else if (activeIdx > 0) {
            // This transition was merged.
            // This transition was merged.
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s",
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged (abort=%b:"
                    transition);
                    + " %s", abort, transition);
            final ActiveTransition active = mActiveTransitions.get(activeIdx);
            final ActiveTransition active = mActiveTransitions.get(activeIdx);
            active.mMerged = true;
            active.mMerged = true;
            active.mAborted = abort;
            if (active.mHandler != null) {
            if (active.mHandler != null) {
                active.mHandler.onTransitionMerged(active.mToken);
                active.mHandler.onTransitionMerged(active.mToken);
            }
            }
            return;
            return;
        }
        }
        mActiveTransitions.get(activeIdx).mAborted = abort;
        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
        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
        // Merge all relevant transactions together
        SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT;
        SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT;
        for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) {
        for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) {
            final ActiveTransition toMerge = mActiveTransitions.get(iA);
            final ActiveTransition toMerge = mActiveTransitions.get(iA);
            if (!toMerge.mMerged) break;
            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
            // Include start. It will be a no-op if it was already applied. Otherwise, we need it
            // to maintain consistent state.
            // to maintain consistent state.
            fullFinish.merge(mActiveTransitions.get(iA).mStartT);
            fullFinish.merge(mActiveTransitions.get(iA).mStartT);
            fullFinish.merge(mActiveTransitions.get(iA).mFinishT);
            fullFinish.merge(mActiveTransitions.get(iA).mFinishT);
        }
        }
        if (fullFinish != null) {
            fullFinish.apply();
            fullFinish.apply();
        }
        // Now perform all the finishes.
        // Now perform all the finishes.
        mActiveTransitions.remove(activeIdx);
        mActiveTransitions.remove(activeIdx);
        mOrganizer.finishTransition(transition, wct, wctCB);
        mOrganizer.finishTransition(transition, wct, wctCB);
@@ -470,6 +482,12 @@ public class Transitions implements RemoteCallable<Transitions> {
            ActiveTransition merged = mActiveTransitions.remove(activeIdx);
            ActiveTransition merged = mActiveTransitions.remove(activeIdx);
            mOrganizer.finishTransition(merged.mToken, null /* wct */, null /* wctCB */);
            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) {
        if (mActiveTransitions.size() <= activeIdx) {
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "All active transition animations "
            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "All active transition animations "
                    + "finished");
                    + "finished");
@@ -500,6 +518,12 @@ public class Transitions implements RemoteCallable<Transitions> {
        int mergeIdx = activeIdx + 1;
        int mergeIdx = activeIdx + 1;
        while (mergeIdx < mActiveTransitions.size()) {
        while (mergeIdx < mActiveTransitions.size()) {
            ActiveTransition mergeCandidate = mActiveTransitions.get(mergeIdx);
            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) {
            if (mergeCandidate.mMerged) {
                throw new IllegalStateException("Can't merge a transition after not-merging"
                throw new IllegalStateException("Can't merge a transition after not-merging"
                        + " a preceding one.");
                        + " a preceding one.");
+16 −0
Original line number Original line Diff line number Diff line
@@ -665,6 +665,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    boolean allDrawn;
    boolean allDrawn;
    private boolean mLastAllDrawn;
    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 mLastContainsShowWhenLockedWindow;
    private boolean mLastContainsDismissKeyguardWindow;
    private boolean mLastContainsDismissKeyguardWindow;
    private boolean mLastContainsTurnScreenOnWindow;
    private boolean mLastContainsTurnScreenOnWindow;
@@ -9018,6 +9026,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return false;
        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 {
    static class Builder {
        private final ActivityTaskManagerService mAtmService;
        private final ActivityTaskManagerService mAtmService;
        private WindowProcessController mCallerApp;
        private WindowProcessController mCallerApp;
+4 −0
Original line number Original line Diff line number Diff line
@@ -166,6 +166,10 @@ class BLASTSyncEngine {
        setReady(id, true);
        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)
     * Aborts the sync (ie. it doesn't wait for ready or anything to finish)
     */
     */
+5 −1
Original line number Original line Diff line number Diff line
@@ -3100,7 +3100,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
            screenRotationAnimation.dumpDebug(proto, SCREEN_ROTATION_ANIMATION);
        }
        }
        mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
        mDisplayFrames.dumpDebug(proto, DISPLAY_FRAMES);
        if (mAtmService.getTransitionController().isShellTransitionsEnabled()) {
            mAtmService.getTransitionController().dumpDebugLegacy(proto, APP_TRANSITION);
        } else {
            mAppTransition.dumpDebug(proto, APP_TRANSITION);
            mAppTransition.dumpDebug(proto, APP_TRANSITION);
        }
        if (mFocusedApp != null) {
        if (mFocusedApp != null) {
            mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
            mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
        }
        }
+26 −0
Original line number Original line 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_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
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.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManager;
@@ -395,6 +398,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe


        handleNonAppWindowsInTransition(displayId, mType, mFlags);
        handleNonAppWindowsInTransition(displayId, mType, mFlags);


        reportStartReasonsToLogger();

        // Manually show any activities that are visibleRequested. This is needed to properly
        // Manually show any activities that are visibleRequested. This is needed to properly
        // support simultaneous animation queueing/merging. Specifically, if transition A makes
        // support simultaneous animation queueing/merging. Specifically, if transition A makes
        // an activity invisible, it's finishTransaction (which is applied *after* the animation)
        // 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
    @Override
    public String toString() {
    public String toString() {
        StringBuilder sb = new StringBuilder(64);
        StringBuilder sb = new StringBuilder(64);
@@ -953,6 +975,10 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
        return out;
        return out;
    }
    }


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

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