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

Commit b54ca798 authored by Tony Huang's avatar Tony Huang
Browse files

Fix overview to split pair animation

Not very sure root cause but it caused by we changing to using
ILegacyTransition from normal remote animation callback.
Rollback to previous implementation for fixing this.

Fix: 246513837
Test: manual
Test: pass existing tests
Change-Id: I5fdde8a2304423153f60163d64c2f1ba2e642468
parent 2de34a74
Loading
Loading
Loading
Loading
+54 −57
Original line number Original line Diff line number Diff line
@@ -69,6 +69,7 @@ import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.IActivityTaskManager;
import android.app.IActivityTaskManager;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.app.WindowConfiguration;
import android.app.WindowConfiguration;
@@ -87,6 +88,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import android.view.Choreographer;
import android.view.Choreographer;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl;
@@ -563,7 +565,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        startWithLegacyTransition(wct, taskId, mainOptions, sidePosition, splitRatio, adapter);
        startWithLegacyTransition(wct, taskId, mainOptions, sidePosition, splitRatio, adapter);
    }
    }


    private void startWithLegacyTransition(WindowContainerTransaction sideWct, int mainTaskId,
    private void startWithLegacyTransition(WindowContainerTransaction wct, int mainTaskId,
            @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
            @Nullable Bundle mainOptions, @SplitPosition int sidePosition, float splitRatio,
            RemoteAnimationAdapter adapter) {
            RemoteAnimationAdapter adapter) {
        // Init divider first to make divider leash for remote animation target.
        // Init divider first to make divider leash for remote animation target.
@@ -574,59 +576,56 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mShouldUpdateRecents = false;
        mShouldUpdateRecents = false;
        mIsDividerRemoteAnimating = true;
        mIsDividerRemoteAnimating = true;


        LegacyTransitions.ILegacyTransition transition = new LegacyTransitions.ILegacyTransition() {
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
            @Override
        prepareEvictChildTasks(SPLIT_POSITION_TOP_OR_LEFT, evictWct);
            public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
        prepareEvictChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, evictWct);
                    RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                    IRemoteAnimationFinishedCallback finishedCallback,
                    SurfaceControl.Transaction t) {
                if (apps == null || apps.length == 0) {
                    updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
                    setDividerVisibility(true, t);
                    t.apply();
                    onRemoteAnimationFinished(apps);
                    try {
                        adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Error starting remote animation", e);
                    }
                    return;
                }

                // Wrap the divider bar into non-apps target to animate together.
                nonApps = ArrayUtils.appendElement(RemoteAnimationTarget.class, nonApps,
                        getDividerBarLegacyTarget());

                updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
                setDividerVisibility(true, t);
                for (int i = 0; i < apps.length; ++i) {
                    if (apps[i].mode == MODE_OPENING) {
                        t.show(apps[i].leash);
                        // Reset the surface position of the opening app to prevent double-offset.
                        t.setPosition(apps[i].leash, 0, 0);
                    }
                }
                t.apply();


        IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
            @Override
            public void onAnimationStart(@WindowManager.TransitionOldType int transit,
                    RemoteAnimationTarget[] apps,
                    RemoteAnimationTarget[] wallpapers,
                    RemoteAnimationTarget[] nonApps,
                    final IRemoteAnimationFinishedCallback finishedCallback) {
                IRemoteAnimationFinishedCallback wrapCallback =
                IRemoteAnimationFinishedCallback wrapCallback =
                        new IRemoteAnimationFinishedCallback.Stub() {
                        new IRemoteAnimationFinishedCallback.Stub() {
                            @Override
                            @Override
                            public void onAnimationFinished() throws RemoteException {
                            public void onAnimationFinished() throws RemoteException {
                                onRemoteAnimationFinished(apps);
                                onRemoteAnimationFinishedOrCancelled(false /* cancel */, evictWct);
                                finishedCallback.onAnimationFinished();
                                finishedCallback.onAnimationFinished();
                            }
                            }
                        };
                        };
                Transitions.setRunningRemoteTransitionDelegate(adapter.getCallingApplication());
                Transitions.setRunningRemoteTransitionDelegate(adapter.getCallingApplication());
                try {
                try {
                    adapter.getRunner().onAnimationStart(
                    adapter.getRunner().onAnimationStart(transit, apps, wallpapers,
                            transit, apps, wallpapers, nonApps, wrapCallback);
                            ArrayUtils.appendElement(RemoteAnimationTarget.class, nonApps,
                                    getDividerBarLegacyTarget()), wrapCallback);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Error starting remote animation", e);
                }
            }

            @Override
            public void onAnimationCancelled(boolean isKeyguardOccluded) {
                onRemoteAnimationFinishedOrCancelled(true /* cancel */, evictWct);
                try {
                    adapter.getRunner().onAnimationCancelled(isKeyguardOccluded);
                } catch (RemoteException e) {
                } catch (RemoteException e) {
                    Slog.e(TAG, "Error starting remote animation", e);
                    Slog.e(TAG, "Error starting remote animation", e);
                }
                }
            }
            }
        };
        };
        RemoteAnimationAdapter wrappedAdapter = new RemoteAnimationAdapter(
                wrapper, adapter.getDuration(), adapter.getStatusBarTransitionDelay());

        if (mainOptions == null) {
            mainOptions = ActivityOptions.makeRemoteAnimation(wrappedAdapter).toBundle();
        } else {
            ActivityOptions mainActivityOptions = ActivityOptions.fromBundle(mainOptions);
            mainActivityOptions.update(ActivityOptions.makeRemoteAnimation(wrappedAdapter));
            mainOptions = mainActivityOptions.toBundle();
        }


        final WindowContainerTransaction wct = new WindowContainerTransaction();
        setSideStagePosition(sidePosition, wct);
        setSideStagePosition(sidePosition, wct);
        if (!mMainStage.isActive()) {
        if (!mMainStage.isActive()) {
            mMainStage.activate(wct, false /* reparent */);
            mMainStage.activate(wct, false /* reparent */);
@@ -634,35 +633,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,


        if (mainOptions == null) mainOptions = new Bundle();
        if (mainOptions == null) mainOptions = new Bundle();
        addActivityOptions(mainOptions, mMainStage);
        addActivityOptions(mainOptions, mMainStage);
        wct.startTask(mainTaskId, mainOptions);
        wct.merge(sideWct, true);

        updateWindowBounds(mSplitLayout, wct);
        updateWindowBounds(mSplitLayout, wct);
        wct.startTask(mainTaskId, mainOptions);
        wct.reorder(mRootTaskInfo.token, true);
        wct.reorder(mRootTaskInfo.token, true);
        wct.setForceTranslucent(mRootTaskInfo.token, false);
        wct.setForceTranslucent(mRootTaskInfo.token, false);


        mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
        mSyncQueue.queue(wct);
        mSyncQueue.runInSync(t -> {
            setDividerVisibility(true, t);
            updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
        });
    }
    }


    private void onRemoteAnimationFinished(RemoteAnimationTarget[] apps) {
    private void onRemoteAnimationFinishedOrCancelled(boolean cancel,
            WindowContainerTransaction evictWct) {
        mIsDividerRemoteAnimating = false;
        mIsDividerRemoteAnimating = false;
        mShouldUpdateRecents = true;
        mShouldUpdateRecents = true;
        if (apps == null || apps.length == 0) return;
        // If any stage has no child after animation finished, it means that split will display

        // nothing, such status will happen if task and intent is same app but not support
        // If any stage has no child after finished animation, that side of the split will display
        // multi-instance, we should exit split and expand that app as full screen.
        // nothing. This might happen if starting the same app on the both sides while not
        if (!cancel && (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
        // supporting multi-instance. Exit the split screen and expand that app to full screen.
            mMainExecutor.execute(() ->
        if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
                    exitSplitScreen(mMainStage.getChildCount() == 0
            mMainExecutor.execute(() -> exitSplitScreen(mMainStage.getChildCount() == 0
                            ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
                            ? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
            return;
        } else {
        }

        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        prepareEvictNonOpeningChildTasks(SPLIT_POSITION_TOP_OR_LEFT, apps, evictWct);
        prepareEvictNonOpeningChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, apps, evictWct);
            mSyncQueue.queue(evictWct);
            mSyncQueue.queue(evictWct);
        }
        }
    }


    /**
    /**
     * Collects all the current child tasks of a specific split and prepares transaction to evict
     * Collects all the current child tasks of a specific split and prepares transaction to evict