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

Commit 7f51866c authored by Evan Rosky's avatar Evan Rosky
Browse files

Put activity-start into its own transition when recents collecting

If a touch through gesture-bar starts an activity, the touch itself
immediately starts recents, then the app (receiving the touch-through)
might start an activity. Because activity-launches must be handled
in sync (due to the API requiring a return value), it can't wait for
an ongoing transition like normal. Instead, if there is an ongoing
transition, it usually just gets added into it. Normally this is
fine (expected, even, for trampolines); however, in the recents
case, we don't want this because it causes a flicker.

In this CL, we basically allow startActivity to create its own
transition in parallel as long as the transition it is "interrupting"
is recents. This way the animations for recents and activity launch
are isolated.

Bug: 276755325
Test: in gmail, flip back-and-forth between it's activity-tabs by
      tapping through the gesture area
Change-Id: Id633baf17445938145132711b556effb852a5aea
parent b4963b6d
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -1468,9 +1468,8 @@ class ActivityStarter {
        // transition based on a sub-action.
        // Only do the create here (and defer requestStart) since startActivityInner might abort.
        final TransitionController transitionController = r.mTransitionController;
        Transition newTransition = (!transitionController.isCollecting()
                && transitionController.getTransitionPlayer() != null)
                ? transitionController.createTransition(TRANSIT_OPEN) : null;
        Transition newTransition = transitionController.isShellTransitionsEnabled()
                ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
        RemoteTransition remoteTransition = r.takeRemoteTransition();
        try {
            mService.deferWindowLayout();
+42 −4
Original line number Diff line number Diff line
@@ -858,7 +858,7 @@ class TransitionController {
        tryStartCollectFromQueue();
    }

    private boolean canStartCollectingNow(Transition queued) {
    private boolean canStartCollectingNow(@Nullable Transition queued) {
        if (mCollectingTransition == null) return true;
        // Population (collect until ready) is still serialized, so always wait for that.
        if (!mCollectingTransition.isPopulated()) return false;
@@ -931,14 +931,14 @@ class TransitionController {
     * `collecting` transition. It may still ultimately block in sync-engine or become dependent
     * in {@link #getIsIndependent} later.
     */
    boolean getCanBeIndependent(Transition collecting, Transition queued) {
    boolean getCanBeIndependent(Transition collecting, @Nullable Transition queued) {
        // For tests
        if (queued.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL
        if (queued != null && queued.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL
                && collecting.mParallelCollectType == Transition.PARALLEL_TYPE_MUTUAL) {
            return true;
        }
        // For recents
        if (queued.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
        if (queued != null && queued.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
            if (collecting.mParallelCollectType == Transition.PARALLEL_TYPE_RECENTS) {
                // Must serialize with itself.
                return false;
@@ -1235,6 +1235,44 @@ class TransitionController {
        return true;
    }

    /**
     * This will create and start collecting for a transition if possible. If there's no way to
     * start collecting for `parallelType` now, then this returns null.
     *
     * WARNING: ONLY use this if the transition absolutely cannot be deferred!
     */
    @NonNull
    Transition createAndStartCollecting(int type) {
        if (mTransitionPlayer == null) {
            return null;
        }
        if (!mQueuedTransitions.isEmpty()) {
            // There is a queue, so it's not possible to start immediately
            return null;
        }
        if (mSyncEngine.hasActiveSync()) {
            if (isCollecting()) {
                // Check if we can run in parallel here.
                if (canStartCollectingNow(null /* transit */)) {
                    // create and collect in parallel.
                    ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS_MIN, "Moving #%d from"
                            + " collecting to waiting.", mCollectingTransition.getSyncId());
                    mWaitingTransitions.add(mCollectingTransition);
                    mCollectingTransition = null;
                    Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine);
                    moveToCollecting(transit);
                    return transit;
                }
            } else {
                Slog.w(TAG, "Ongoing Sync outside of transition.");
            }
            return null;
        }
        Transition transit = new Transition(type, 0 /* flags */, this, mSyncEngine);
        moveToCollecting(transit);
        return transit;
    }

    /** Returns {@code true} if it started collecting, {@code false} if it was queued. */
    boolean startLegacySyncOrQueue(BLASTSyncEngine.SyncGroup syncGroup, Runnable applySync) {
        if (!mQueuedTransitions.isEmpty() || mSyncEngine.hasActiveSync()) {