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

Commit 15bbf373 authored by Tony Huang's avatar Tony Huang
Browse files

Reduce flicker when split pair switching

Checked this issue by winscope and found home task leash under
RecentsAnimationSplitTasks will become off screen bewteen the
transition, it lead to task thumbnail invisible and wallpaper show
then cause flicker.

Home suface going to off screen is caused by we will remove previous
RecentsAnimationSplitTasks when re-create it whether going to recents
or starting split.

Fix this by seperate mSplitTasksContainerLayer to two differents
surface for going to recents and starting split cases.

Fix: 246664520
Test: manual
Test: pass existing tests
Change-Id: I492cc8b82a15cc5abec06118b54232b355e880a0
parent e56320b8
Loading
Loading
Loading
Loading
+45 −32
Original line number Diff line number Diff line
@@ -154,7 +154,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    private StageCoordinator mStageCoordinator;
    // Only used for the legacy recents animation from splitscreen to allow the tasks to be animated
    // outside the bounds of the roots by being reparented into a higher level fullscreen container
    private SurfaceControl mSplitTasksContainerLayer;
    private SurfaceControl mGoingToRecentsTasksLayer;
    private SurfaceControl mStartingSplitTasksLayer;

    public SplitScreenController(Context context,
            ShellInit shellInit,
@@ -489,33 +490,33 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    }

    RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
        if (ENABLE_SHELL_TRANSITIONS) return null;

        if (isSplitScreenVisible()) {
            // Evict child tasks except the top visible one under split root to ensure it could be
            // launched as full screen when switching to it on recents.
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            mStageCoordinator.prepareEvictInvisibleChildTasks(wct);
            mSyncQueue.queue(wct);
        }
        return reparentSplitTasksForAnimation(apps, false /* enterSplitScreen */);
        } else {
            return null;
        }

    RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
        try {
            return reparentSplitTasksForAnimation(apps, true /* enterSplitScreen */);
        } finally {
            for (RemoteAnimationTarget appTarget : apps) {
                if (appTarget.leash != null) {
                    appTarget.leash.release();
                }
            }
        SurfaceControl.Transaction t = mTransactionPool.acquire();
        if (mGoingToRecentsTasksLayer != null) {
            t.remove(mGoingToRecentsTasksLayer);
        }
        mGoingToRecentsTasksLayer = reparentSplitTasksForAnimation(apps, t,
                "SplitScreenController#onGoingToRecentsLegacy" /* callsite */);
        t.apply();
        mTransactionPool.release(t);

        return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
    }

    private RemoteAnimationTarget[] reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
            boolean enterSplitScreen) {
    RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
        if (ENABLE_SHELL_TRANSITIONS) return null;

        if (enterSplitScreen) {
        int openingApps = 0;
        for (int i = 0; i < apps.length; ++i) {
            if (apps[i].mode == MODE_OPENING) openingApps++;
@@ -524,32 +525,44 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
            // Not having enough apps to enter split screen
            return null;
        }
        } else if (!isSplitScreenVisible()) {
            return null;

        SurfaceControl.Transaction t = mTransactionPool.acquire();
        if (mStartingSplitTasksLayer != null) {
            t.remove(mStartingSplitTasksLayer);
        }
        mStartingSplitTasksLayer = reparentSplitTasksForAnimation(apps, t,
                "SplitScreenController#onStartingSplitLegacy" /* callsite */);
        t.apply();
        mTransactionPool.release(t);

        final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
        if (mSplitTasksContainerLayer != null) {
            // Remove the previous layer before recreating
            transaction.remove(mSplitTasksContainerLayer);
        try {
            return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
        } finally {
            for (RemoteAnimationTarget appTarget : apps) {
                if (appTarget.leash != null) {
                    appTarget.leash.release();
                }
            }
        }
    }

    private SurfaceControl reparentSplitTasksForAnimation(RemoteAnimationTarget[] apps,
            SurfaceControl.Transaction t, String callsite) {
        final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession())
                .setContainerLayer()
                .setName("RecentsAnimationSplitTasks")
                .setHidden(false)
                .setCallsite("SplitScreenController#onGoingtoRecentsLegacy");
                .setCallsite(callsite);
        mRootTDAOrganizer.attachToDisplayArea(DEFAULT_DISPLAY, builder);
        mSplitTasksContainerLayer = builder.build();
        final SurfaceControl splitTasksLayer = builder.build();

        for (int i = 0; i < apps.length; ++i) {
            final RemoteAnimationTarget appTarget = apps[i];
            transaction.reparent(appTarget.leash, mSplitTasksContainerLayer);
            transaction.setPosition(appTarget.leash, appTarget.screenSpaceBounds.left,
            t.reparent(appTarget.leash, splitTasksLayer);
            t.setPosition(appTarget.leash, appTarget.screenSpaceBounds.left,
                    appTarget.screenSpaceBounds.top);
        }
        transaction.apply();
        mTransactionPool.release(transaction);
        return new RemoteAnimationTarget[]{mStageCoordinator.getDividerBarLegacyTarget()};
        return splitTasksLayer;
    }
    /**
     * Sets drag info to be logged when splitscreen is entered.