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

Commit 5d391fa6 authored by Galia Peycheva's avatar Galia Peycheva Committed by Automerger Merge Worker
Browse files

Merge "Fix pip update transaction out of order" into tm-qpr-dev am: 16712430

parents 01974b59 16712430
Loading
Loading
Loading
Loading
+41 −5
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import android.graphics.Rect;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.Choreographer;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -179,8 +180,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                // This is necessary in case there was a resize animation ongoing when exit PIP
                // started, in which case the first resize will be skipped to let the exit
                // operation handle the final resize out of PIP mode. See b/185306679.
                finishResizeDelayedIfNeeded(() -> {
                    finishResize(tx, destinationBounds, direction, animationType);
                    sendOnPipTransitionFinished(direction);
                });
            }
        }

@@ -196,6 +199,39 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        }
    };

    /**
     * Finishes resizing the PiP, delaying the operation if it has to be synced with the PiP menu.
     *
     * This is done to avoid a race condition between the last transaction applied in
     * onPipAnimationUpdate and the finishResize in onPipAnimationEnd. The transaction in
     * onPipAnimationUpdate is applied directly from WmShell, while onPipAnimationEnd creates a
     * WindowContainerTransaction in finishResize, which is to be applied by WmCore later. Normally,
     * the WCT should be the last transaction to finish the animation. However, it  may happen that
     * it gets applied *before* the transaction created by the last onPipAnimationUpdate. This
     * happens only when the PiP surface transaction has to be synced with the PiP menu due to the
     * necessity for a delay when syncing the PiP surface animation with the PiP menu surface
     * animation and redrawing the PiP menu contents. As a result, the PiP surface gets scaled after
     * the new bounds are applied by WmCore, which makes the PiP surface have unexpected bounds.
     *
     * To avoid this, we delay the finishResize operation until
     * the next frame. This aligns the last onAnimationUpdate transaction with the WCT application.
     */
    private void finishResizeDelayedIfNeeded(Runnable finishResizeRunnable) {
        if (!shouldSyncPipTransactionWithMenu()) {
            finishResizeRunnable.run();
            return;
        }

        // Delay the finishResize to the next frame
        Choreographer.getInstance().postCallback(Choreographer.CALLBACK_COMMIT, () -> {
            mMainExecutor.execute(finishResizeRunnable);
        }, null);
    }

    private boolean shouldSyncPipTransactionWithMenu() {
        return mPipMenuController.isMenuVisible();
    }

    @VisibleForTesting
    final PipTransitionController.PipTransitionCallback mPipTransitionCallback =
            new PipTransitionController.PipTransitionCallback() {
@@ -221,7 +257,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                @Override
                public boolean handlePipTransaction(SurfaceControl leash,
                        SurfaceControl.Transaction tx, Rect destinationBounds) {
                    if (mPipMenuController.isMenuVisible()) {
                    if (shouldSyncPipTransactionWithMenu()) {
                        mPipMenuController.movePipMenu(leash, tx, destinationBounds);
                        return true;
                    }
@@ -1223,7 +1259,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mSurfaceTransactionHelper
                .crop(tx, mLeash, toBounds)
                .round(tx, mLeash, mPipTransitionState.isInPip());
        if (mPipMenuController.isMenuVisible()) {
        if (shouldSyncPipTransactionWithMenu()) {
            mPipMenuController.resizePipMenu(mLeash, tx, toBounds);
        } else {
            tx.apply();
@@ -1265,7 +1301,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mSurfaceTransactionHelper
                .scale(tx, mLeash, startBounds, toBounds, degrees)
                .round(tx, mLeash, startBounds, toBounds);
        if (mPipMenuController.isMenuVisible()) {
        if (shouldSyncPipTransactionWithMenu()) {
            mPipMenuController.movePipMenu(mLeash, tx, toBounds);
        } else {
            tx.apply();