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

Commit 3ffda8da authored by Hongwei Wang's avatar Hongwei Wang Committed by Automerger Merge Worker
Browse files

Merge "Ignores entering PiP animation on seamless rotation" into rvc-dev am: 047a5509

Change-Id: Id425cf6f338f1b03cb69a41210f5525002cf14a5
parents 40670822 047a5509
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -46,4 +46,13 @@ oneway interface IDisplayWindowListener {
     */
    void onDisplayRemoved(int displayId);

    /**
     * Called when fixed rotation is started on a display.
     */
    void onFixedRotationStarted(int displayId, int newRotation);

    /**
     * Called when the previous fixed rotation on a display is finished.
     */
    void onFixedRotationFinished(int displayId);
}
+84 −32
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import com.android.internal.os.SomeArgs;
import com.android.systemui.R;
import com.android.systemui.pip.phone.PipUpdateThread;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.wm.DisplayController;

import java.io.PrintWriter;
import java.util.ArrayList;
@@ -82,8 +83,10 @@ import javax.inject.Singleton;
 * see also {@link com.android.systemui.pip.phone.PipMotionHelper}.
 */
@Singleton
public class PipTaskOrganizer extends TaskOrganizer {
public class PipTaskOrganizer extends TaskOrganizer implements
        DisplayController.OnDisplaysChangedListener {
    private static final String TAG = PipTaskOrganizer.class.getSimpleName();
    private static final boolean DEBUG = false;

    private static final int MSG_RESIZE_IMMEDIATE = 1;
    private static final int MSG_RESIZE_ANIMATE = 2;
@@ -206,10 +209,17 @@ public class PipTaskOrganizer extends TaskOrganizer {
            mSurfaceControlTransactionFactory;
    private PictureInPictureParams mPictureInPictureParams;

    /**
     * If set to {@code true}, the entering animation will be skipped and we will wait for
     * {@link #onFixedRotationFinished(int)} callback to actually enter PiP.
     */
    private boolean mShouldDeferEnteringPip;

    @Inject
    public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
            @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
            @Nullable Divider divider) {
            @Nullable Divider divider,
            @NonNull DisplayController displayController) {
        mMainHandler = new Handler(Looper.getMainLooper());
        mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
        mPipBoundsHandler = boundsHandler;
@@ -219,6 +229,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
        mPipAnimationController = new PipAnimationController(context, surfaceTransactionHelper);
        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
        mSplitDivider = divider;
        displayController.addDisplayWindowListener(this);
    }

    public Handler getUpdateHandler() {
@@ -281,7 +292,8 @@ public class PipTaskOrganizer extends TaskOrganizer {
            final int direction = syncWithSplitScreenBounds(destinationBounds)
                    ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
                    : TRANSITION_DIRECTION_TO_FULLSCREEN;
            final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
            final SurfaceControl.Transaction tx =
                    mSurfaceControlTransactionFactory.getTransaction();
            mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
                    mLastReportedBounds);
            tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
@@ -325,29 +337,47 @@ public class PipTaskOrganizer extends TaskOrganizer {
    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
        Objects.requireNonNull(info, "Requires RunningTaskInfo");
        mPictureInPictureParams = info.pictureInPictureParams;
        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                info.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
                null /* bounds */, getMinimalSize(info.topActivityInfo));
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        mTaskInfo = info;
        mToken = mTaskInfo.token;
        mInPip = true;
        mLeash = leash;
        mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
        mPictureInPictureParams = mTaskInfo.pictureInPictureParams;

        // TODO: Skip enter animation when entering pip from another orientation
        if (mShouldDeferEnteringPip) {
            if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing");
            // if deferred, hide the surface till fixed rotation is completed
            final SurfaceControl.Transaction tx =
                    mSurfaceControlTransactionFactory.getTransaction();
            tx.setAlpha(mLeash, 0f);
            tx.apply();
            return;
        }

        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
                null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
        final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
        mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));

        if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
            scheduleAnimateResizePip(currentBounds, destinationBounds,
                    TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
                    null /* updateBoundsCallback */);
        } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
            enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration);
            mOneShotAnimationType = ANIM_TYPE_BOUNDS;
        } else {
            throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
        }
    }

    private void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) {
        // If we are fading the PIP in, then we should move the pip to the final location as
        // soon as possible, but set the alpha immediately since the transaction can take a
        // while to process
            final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
        final SurfaceControl.Transaction tx =
                mSurfaceControlTransactionFactory.getTransaction();
        tx.setAlpha(mLeash, 0f);
        tx.apply();
        final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -362,14 +392,10 @@ public class PipTaskOrganizer extends TaskOrganizer {
                        .getAnimator(mLeash, destinationBounds, 0f, 1f)
                        .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
                        .setPipAnimationCallback(mPipAnimationCallback)
                            .setDuration(mEnterExitAnimationDuration)
                        .setDuration(durationMs)
                        .start());
            }
        });
            mOneShotAnimationType = ANIM_TYPE_BOUNDS;
        } else {
            throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
        }
    }

    /**
@@ -391,6 +417,7 @@ public class PipTaskOrganizer extends TaskOrganizer {
            Log.wtf(TAG, "Unrecognized token: " + token);
            return;
        }
        mShouldDeferEnteringPip = false;
        mPictureInPictureParams = null;
        mInPip = false;
    }
@@ -416,6 +443,23 @@ public class PipTaskOrganizer extends TaskOrganizer {
        // Do nothing
    }

    @Override
    public void onFixedRotationStarted(int displayId, int newRotation) {
        mShouldDeferEnteringPip = true;
    }

    @Override
    public void onFixedRotationFinished(int displayId) {
        if (mShouldDeferEnteringPip && mInPip) {
            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
                    mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
                    null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
            // schedule a regular animation to ensure all the callbacks are still being sent
            enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
        }
        mShouldDeferEnteringPip = false;
    }

    /**
     * TODO(b/152809058): consolidate the display info handling logic in SysUI
     *
@@ -476,6 +520,10 @@ public class PipTaskOrganizer extends TaskOrganizer {
     */
    public void scheduleAnimateResizePip(Rect toBounds, int duration,
            Consumer<Rect> updateBoundsCallback) {
        if (mShouldDeferEnteringPip) {
            Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
            return;
        }
        scheduleAnimateResizePip(mLastReportedBounds, toBounds,
                TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback);
    }
@@ -567,6 +615,10 @@ public class PipTaskOrganizer extends TaskOrganizer {
            // can be initiated in other component, ignore if we are no longer in PIP
            return;
        }
        if (mShouldDeferEnteringPip) {
            Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred");
            return;
        }
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = updateBoundsCallback;
        args.arg2 = originalBounds;
+43 −0
Original line number Diff line number Diff line
@@ -134,6 +134,39 @@ public class DisplayController {
                        }
                    });
                }

                @Override
                public void onFixedRotationStarted(int displayId, int newRotation) {
                    mHandler.post(() -> {
                        synchronized (mDisplays) {
                            if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
                                Slog.w(TAG, "Skipping onFixedRotationStarted on unknown"
                                        + " display, displayId=" + displayId);
                                return;
                            }
                            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
                                mDisplayChangedListeners.get(i).onFixedRotationStarted(
                                        displayId, newRotation);
                            }
                        }
                    });
                }

                @Override
                public void onFixedRotationFinished(int displayId) {
                    mHandler.post(() -> {
                        synchronized (mDisplays) {
                            if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
                                Slog.w(TAG, "Skipping onFixedRotationFinished on unknown"
                                        + " display, displayId=" + displayId);
                                return;
                            }
                            for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
                                mDisplayChangedListeners.get(i).onFixedRotationFinished(displayId);
                            }
                        }
                    });
                }
            };

    @Inject
@@ -232,5 +265,15 @@ public class DisplayController {
         * Called when a display is removed.
         */
        default void onDisplayRemoved(int displayId) {}

        /**
         * Called when fixed rotation on a display is started.
         */
        default void onFixedRotationStarted(int displayId, int newRotation) {}

        /**
         * Called when fixed rotation on a display is finished.
         */
        default void onFixedRotationFinished(int displayId) {}
    }
}
+24 −7
Original line number Diff line number Diff line
@@ -493,10 +493,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     * The launching activity which is using fixed rotation transformation.
     *
     * @see #handleTopActivityLaunchingInDifferentOrientation
     * @see #setFixedRotationLaunchingApp
     * @see #setFixedRotationLaunchingApp(ActivityRecord, int)
     * @see DisplayRotation#shouldRotateSeamlessly
     */
    ActivityRecord mFixedRotationLaunchingApp;
    private ActivityRecord mFixedRotationLaunchingApp;

    final FixedRotationTransitionListener mFixedRotationTransitionListener =
            new FixedRotationTransitionListener();
@@ -1475,6 +1475,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        return true;
    }

    @Nullable ActivityRecord getFixedRotationLaunchingApp() {
        return mFixedRotationLaunchingApp;
    }

    void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r) {
        setFixedRotationLaunchingAppUnchecked(r, ROTATION_UNDEFINED);
    }

    void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r, int rotation) {
        if (mFixedRotationLaunchingApp == null && r != null) {
            mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this, rotation);
        } else if (mFixedRotationLaunchingApp != null && r == null) {
            mWmService.mDisplayNotificationController.dispatchFixedRotationFinished(this);
        }
        mFixedRotationLaunchingApp = r;
    }

    /**
     * Sets the provided record to {@link mFixedRotationLaunchingApp} if possible to apply fixed
     * rotation transform to it and indicate that the display may be rotated after it is launched.
@@ -1496,7 +1513,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (!r.hasFixedRotationTransform()) {
            startFixedRotationTransform(r, rotation);
        }
        mFixedRotationLaunchingApp = r;
        setFixedRotationLaunchingAppUnchecked(r, rotation);
        if (prevRotatedLaunchingApp != null) {
            prevRotatedLaunchingApp.finishFixedRotationTransform();
        }
@@ -1524,7 +1541,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    }

    /**
     * Clears the {@link mFixedRotationLaunchingApp} without applying rotation to display. It is
     * Clears the {@link #mFixedRotationLaunchingApp} without applying rotation to display. It is
     * used when the display won't rotate (e.g. the orientation from sensor has updated again before
     * applying rotation to display) but the launching app has been transformed. So the record need
     * to be cleared and restored to stop using seamless rotation and rotated configuration.
@@ -1534,7 +1551,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            return;
        }
        mFixedRotationLaunchingApp.finishFixedRotationTransform();
        mFixedRotationLaunchingApp = null;
        setFixedRotationLaunchingAppUnchecked(null);
    }

    private void startFixedRotationTransform(WindowToken token, int rotation) {
@@ -5260,7 +5277,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

        rotatedLaunchingApp.finishFixedRotationTransform(
                () -> applyRotation(oldRotation, newRotation));
        mFixedRotationLaunchingApp = null;
        setFixedRotationLaunchingAppUnchecked(null);
    }

    /** Checks whether the given activity is in size compatibility mode and notifies the change. */
@@ -5574,7 +5591,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            if (animatingRecents != null && animatingRecents == mFixedRotationLaunchingApp) {
                // Because it won't affect display orientation, just finish the transform.
                animatingRecents.finishFixedRotationTransform();
                mFixedRotationLaunchingApp = null;
                setFixedRotationLaunchingAppUnchecked(null);
            } else {
                // If there is already a launching activity that is not the recents, before its
                // transition is completed, the recents animation may be started. So if the recents
+1 −1
Original line number Diff line number Diff line
@@ -577,7 +577,7 @@ public class DisplayRotation {
    boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) {
        // Display doesn't need to be frozen because application has been started in correct
        // rotation already, so the rest of the windows can use seamless rotation.
        if (mDisplayContent.mFixedRotationLaunchingApp != null) {
        if (mDisplayContent.getFixedRotationLaunchingApp() != null) {
            return true;
        }

Loading