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

Commit 19a4ebfa authored by Tony Huang's avatar Tony Huang Committed by Android (Google) Code Review
Browse files

Merge "Implement center aligned parallax resizng effect" into tm-dev

parents ad0a9c26 084bdd9e
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
                mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
                mRootTaskInfo.configuration, this /* layoutChangeListener */,
                mParentContainerCallbacks, mDisplayImeController, mController.getTaskOrganizer(),
                true /* applyDismissingParallax */);
                SplitLayout.PARALLAX_DISMISSING);
        mDisplayInsetsController.addInsetsChangedListener(mRootTaskInfo.displayId, mSplitLayout);

        final WindowContainerToken token1 = task1.token;
@@ -327,13 +327,15 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
    @Override
    public void onLayoutPositionChanging(SplitLayout layout) {
        mSyncQueue.runInSync(t ->
                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2));
                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2,
                        true /* applyResizingOffset */));
    }

    @Override
    public void onLayoutSizeChanging(SplitLayout layout) {
        mSyncQueue.runInSync(t ->
                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2));
                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2,
                        true /* applyResizingOffset */));
    }

    @Override
@@ -342,7 +344,8 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
        layout.applyTaskChanges(wct, mTaskInfo1, mTaskInfo2);
        mSyncQueue.queue(wct);
        mSyncQueue.runInSync(t ->
                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2));
                layout.applySurfaceChanges(t, mTaskLeash1, mTaskLeash2, mDimLayer1, mDimLayer2,
                        false /* applyResizingOffset */));
    }

    @Override
+97 −36
Original line number Diff line number Diff line
@@ -72,6 +72,10 @@ import java.io.PrintWriter;
 */
public final class SplitLayout implements DisplayInsetsController.OnInsetsChangedListener {

    public static final int PARALLAX_NONE = 0;
    public static final int PARALLAX_DISMISSING = 1;
    public static final int PARALLAX_ALIGN_CENTER = 2;

    private final int mDividerWindowWidth;
    private final int mDividerInsets;
    private final int mDividerSize;
@@ -87,7 +91,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    private final SplitWindowManager mSplitWindowManager;
    private final DisplayImeController mDisplayImeController;
    private final ImePositionProcessor mImePositionProcessor;
    private final DismissingEffectPolicy mDismissingEffectPolicy;
    private final ResizingEffectPolicy mSurfaceEffectPolicy;
    private final ShellTaskOrganizer mTaskOrganizer;
    private final InsetsState mInsetsState = new InsetsState();

@@ -105,7 +109,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            SplitLayoutHandler splitLayoutHandler,
            SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
            DisplayImeController displayImeController, ShellTaskOrganizer taskOrganizer,
            boolean applyDismissingParallax) {
            int parallaxType) {
        mContext = context.createConfigurationContext(configuration);
        mOrientation = configuration.orientation;
        mRotation = configuration.windowConfiguration.getRotation();
@@ -115,7 +119,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                parentContainerCallbacks);
        mTaskOrganizer = taskOrganizer;
        mImePositionProcessor = new ImePositionProcessor(mContext.getDisplayId());
        mDismissingEffectPolicy = new DismissingEffectPolicy(applyDismissingParallax);
        mSurfaceEffectPolicy = new ResizingEffectPolicy(parallaxType);

        final Resources resources = context.getResources();
        mDividerSize = resources.getDimensionPixelSize(R.dimen.split_divider_bar_width);
@@ -281,7 +285,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        }
        DockedDividerUtils.sanitizeStackBounds(mBounds1, true /** topLeft */);
        DockedDividerUtils.sanitizeStackBounds(mBounds2, false /** topLeft */);
        mDismissingEffectPolicy.applyDividerPosition(position, isLandscape);
        mSurfaceEffectPolicy.applyDividerPosition(position, isLandscape);
    }

    /** Inflates {@link DividerView} on the root surface. */
@@ -486,7 +490,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange

    /** Apply recorded surface layout to the {@link SurfaceControl.Transaction}. */
    public void applySurfaceChanges(SurfaceControl.Transaction t, SurfaceControl leash1,
            SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
            SurfaceControl leash2, SurfaceControl dimLayer1, SurfaceControl dimLayer2,
            boolean applyResizingOffset) {
        final SurfaceControl dividerLeash = getDividerLeash();
        if (dividerLeash != null) {
            mTempRect.set(getRefDividerBounds());
@@ -506,7 +511,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            return;
        }

        mDismissingEffectPolicy.adjustDismissingSurface(t, leash1, leash2, dimLayer1, dimLayer2);
        mSurfaceEffectPolicy.adjustDimSurface(t, dimLayer1, dimLayer2);
        if (applyResizingOffset) {
            mSurfaceEffectPolicy.adjustRootSurface(t, leash1, leash2);
        }
    }

    /** Apply recorded task layout to the {@link WindowContainerTransaction}. */
@@ -590,7 +598,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
         * Calls when resizing the split bounds.
         *
         * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl,
         * SurfaceControl, SurfaceControl)
         * SurfaceControl, SurfaceControl, boolean)
         */
        void onLayoutSizeChanging(SplitLayout layout);

@@ -600,7 +608,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
         * @see #applyTaskChanges(WindowContainerTransaction, ActivityManager.RunningTaskInfo,
         * ActivityManager.RunningTaskInfo)
         * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl,
         * SurfaceControl, SurfaceControl)
         * SurfaceControl, SurfaceControl, boolean)
         */
        void onLayoutSizeChanged(SplitLayout layout);

@@ -609,7 +617,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
         * panel.
         *
         * @see #applySurfaceChanges(SurfaceControl.Transaction, SurfaceControl, SurfaceControl,
         * SurfaceControl, SurfaceControl)
         * SurfaceControl, SurfaceControl, boolean)
         */
        void onLayoutPositionChanging(SplitLayout layout);

@@ -637,21 +645,25 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
     * Calculates and applies proper dismissing parallax offset and dimming value to hint users
     * dismissing gesture.
     */
    private class DismissingEffectPolicy {
    private class ResizingEffectPolicy {
        /** Indicates whether to offset splitting bounds to hint dismissing progress or not. */
        private final boolean mApplyParallax;
        private final int mParallaxType;

        int mShrinkSide = DOCKED_INVALID;

        // The current dismissing side.
        int mDismissingSide = DOCKED_INVALID;

        // The parallax offset to hint the dismissing side and progress.
        final Point mDismissingParallaxOffset = new Point();
        final Point mParallaxOffset = new Point();

        // The dimming value to hint the dismissing side and progress.
        float mDismissingDimValue = 0.0f;
        final Rect mContentBounds = new Rect();
        final Rect mSurfaceBounds = new Rect();

        DismissingEffectPolicy(boolean applyDismissingParallax) {
            mApplyParallax = applyDismissingParallax;
        ResizingEffectPolicy(int parallaxType) {
            mParallaxType = parallaxType;
        }

        /**
@@ -662,7 +674,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
         */
        void applyDividerPosition(int position, boolean isLandscape) {
            mDismissingSide = DOCKED_INVALID;
            mDismissingParallaxOffset.set(0, 0);
            mParallaxOffset.set(0, 0);
            mDismissingDimValue = 0;

            int totalDismissingDistance = 0;
@@ -676,15 +688,39 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
                        - mDividerSnapAlgorithm.getDismissEndTarget().position;
            }

            final boolean topLeftShrink = isLandscape
                    ? position < mWinBounds1.right : position < mWinBounds1.bottom;
            if (topLeftShrink) {
                mShrinkSide = isLandscape ? DOCKED_LEFT : DOCKED_TOP;
                mContentBounds.set(mWinBounds1);
                mSurfaceBounds.set(mBounds1);
            } else {
                mShrinkSide = isLandscape ? DOCKED_RIGHT : DOCKED_BOTTOM;
                mContentBounds.set(mWinBounds2);
                mSurfaceBounds.set(mBounds2);
            }

            if (mDismissingSide != DOCKED_INVALID) {
                float fraction = Math.max(0,
                        Math.min(mDividerSnapAlgorithm.calculateDismissingFraction(position), 1f));
                mDismissingDimValue = DIM_INTERPOLATOR.getInterpolation(fraction);
                if (mParallaxType == PARALLAX_DISMISSING) {
                    fraction = calculateParallaxDismissingFraction(fraction, mDismissingSide);
                    if (isLandscape) {
                    mDismissingParallaxOffset.x = (int) (fraction * totalDismissingDistance);
                        mParallaxOffset.x = (int) (fraction * totalDismissingDistance);
                    } else {
                        mParallaxOffset.y = (int) (fraction * totalDismissingDistance);
                    }
                }
            }

            if (mParallaxType == PARALLAX_ALIGN_CENTER) {
                if (isLandscape) {
                    mParallaxOffset.x =
                            (mSurfaceBounds.width() - mContentBounds.width()) / 2;
                } else {
                    mDismissingParallaxOffset.y = (int) (fraction * totalDismissingDistance);
                    mParallaxOffset.y =
                            (mSurfaceBounds.height() - mContentBounds.height()) / 2;
                }
            }
        }
@@ -704,41 +740,66 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        }

        /** Applies parallax offset and dimming value to the root surface at the dismissing side. */
        boolean adjustDismissingSurface(SurfaceControl.Transaction t,
                SurfaceControl leash1, SurfaceControl leash2,
                SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
            SurfaceControl targetLeash, targetDimLayer;
        void adjustRootSurface(SurfaceControl.Transaction t,
                SurfaceControl leash1, SurfaceControl leash2) {
            SurfaceControl targetLeash = null;

            if (mParallaxType == PARALLAX_DISMISSING) {
                switch (mDismissingSide) {
                    case DOCKED_TOP:
                    case DOCKED_LEFT:
                        targetLeash = leash1;
                    targetDimLayer = dimLayer1;
                        mTempRect.set(mBounds1);
                        break;
                    case DOCKED_BOTTOM:
                    case DOCKED_RIGHT:
                        targetLeash = leash2;
                    targetDimLayer = dimLayer2;
                        mTempRect.set(mBounds2);
                        break;
                case DOCKED_INVALID:
                default:
                    t.setAlpha(dimLayer1, 0).hide(dimLayer1);
                    t.setAlpha(dimLayer2, 0).hide(dimLayer2);
                    return false;
                }

            if (mApplyParallax) {
            } else if (mParallaxType == PARALLAX_ALIGN_CENTER) {
                switch (mShrinkSide) {
                    case DOCKED_TOP:
                    case DOCKED_LEFT:
                        targetLeash = leash1;
                        mTempRect.set(mBounds1);
                        break;
                    case DOCKED_BOTTOM:
                    case DOCKED_RIGHT:
                        targetLeash = leash2;
                        mTempRect.set(mBounds2);
                        break;
                }
            }
            if (mParallaxType != PARALLAX_NONE && targetLeash != null) {
                t.setPosition(targetLeash,
                        mTempRect.left + mDismissingParallaxOffset.x,
                        mTempRect.top + mDismissingParallaxOffset.y);
                        mTempRect.left + mParallaxOffset.x, mTempRect.top + mParallaxOffset.y);
                // Transform the screen-based split bounds to surface-based crop bounds.
                mTempRect.offsetTo(-mDismissingParallaxOffset.x, -mDismissingParallaxOffset.y);
                mTempRect.offsetTo(-mParallaxOffset.x, -mParallaxOffset.y);
                t.setWindowCrop(targetLeash, mTempRect);
            }
        }

        void adjustDimSurface(SurfaceControl.Transaction t,
                SurfaceControl dimLayer1, SurfaceControl dimLayer2) {
            SurfaceControl targetDimLayer;
            switch (mDismissingSide) {
                case DOCKED_TOP:
                case DOCKED_LEFT:
                    targetDimLayer = dimLayer1;
                    break;
                case DOCKED_BOTTOM:
                case DOCKED_RIGHT:
                    targetDimLayer = dimLayer2;
                    break;
                case DOCKED_INVALID:
                default:
                    t.setAlpha(dimLayer1, 0).hide(dimLayer1);
                    t.setAlpha(dimLayer2, 0).hide(dimLayer2);
                    return;
            }
            t.setAlpha(targetDimLayer, mDismissingDimValue)
                    .setVisibility(targetDimLayer, mDismissingDimValue > 0.001f);
            return true;
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -377,7 +377,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
                    return;
                }

                mStageCoordinator.updateSurfaceBounds(null /* layout */, t);
                mStageCoordinator.updateSurfaceBounds(null /* layout */, t,
                        false /* applyResizingOffset */);
                for (int i = 0; i < apps.length; ++i) {
                    if (apps[i].mode == MODE_OPENING) {
                        t.show(apps[i].leash);
+20 −15
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.transitTypeToString;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;

import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
@@ -495,7 +496,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,

        // Using legacy transitions, so we can't use blast sync since it conflicts.
        mTaskOrganizer.applyTransaction(wct);
        mSyncQueue.runInSync(t -> updateSurfaceBounds(mSplitLayout, t));
        mSyncQueue.runInSync(t ->
                updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
    }

    /**
@@ -704,9 +706,11 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop);
        wct.reorder(mRootTaskInfo.token, false /* onTop */);
        mTaskOrganizer.applyTransaction(wct);
        mSyncQueue.runInSync(t -> t
                .setWindowCrop(mMainStage.mRootLeash, null)
                .setWindowCrop(mSideStage.mRootLeash, null));
        mSyncQueue.runInSync(t -> {
            setResizingSplits(false /* resizing */);
            t.setWindowCrop(mMainStage.mRootLeash, null)
                    .setWindowCrop(mSideStage.mRootLeash, null);
        });

        // Hide divider and reset its position.
        mSplitLayout.resetDividerPosition();
@@ -780,7 +784,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    void finishEnterSplitScreen(SurfaceControl.Transaction t) {
        mSplitLayout.init();
        setDividerVisibility(true, t);
        updateSurfaceBounds(mSplitLayout, t);
        updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
        setSplitsVisible(true);
        mShouldUpdateRecents = true;
        updateRecentTasksSplitPair();
@@ -925,7 +929,8 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        if (mSplitLayout == null) {
            mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
                    mRootTaskInfo.configuration, this, mParentContainerCallbacks,
                    mDisplayImeController, mTaskOrganizer, false /* applyDismissingParallax */);
                    mDisplayImeController, mTaskOrganizer,
                    PARALLAX_ALIGN_CENTER /* parallaxType */);
            mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout);
        }

@@ -1075,7 +1080,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            prepareEnterSplitScreen(wct);
            mSyncQueue.queue(wct);
            mSyncQueue.runInSync(t -> {
                updateSurfaceBounds(mSplitLayout, t);
                updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
                setDividerVisibility(true, t);
            });
        }
@@ -1094,8 +1099,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    @Override
    public void onSnappedToDismiss(boolean bottomOrRight) {
        setResizingSplits(false /* resizing */);

        final boolean mainStageToTop =
                bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
                        : mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
@@ -1104,6 +1107,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            return;
        }

        setResizingSplits(false /* resizing */);
        final int dismissTop = mainStageToTop ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
        final WindowContainerTransaction wct = new WindowContainerTransaction();
        prepareExitSplitScreen(dismissTop, wct);
@@ -1121,14 +1125,14 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,

    @Override
    public void onLayoutPositionChanging(SplitLayout layout) {
        mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t));
        mSyncQueue.runInSync(t -> updateSurfaceBounds(layout, t, false /* applyResizingOffset */));
    }

    @Override
    public void onLayoutSizeChanging(SplitLayout layout) {
        mSyncQueue.runInSync(t -> {
            setResizingSplits(true /* resizing */);
            updateSurfaceBounds(layout, t);
            updateSurfaceBounds(layout, t, true /* applyResizingOffset */);
            mMainStage.onResizing(getMainStageBounds(), t);
            mSideStage.onResizing(getSideStageBounds(), t);
        });
@@ -1142,7 +1146,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mSyncQueue.queue(wct);
        mSyncQueue.runInSync(t -> {
            setResizingSplits(false /* resizing */);
            updateSurfaceBounds(layout, t);
            updateSurfaceBounds(layout, t, false /* applyResizingOffset */);
            mMainStage.onResized(t);
            mSideStage.onResized(t);
        });
@@ -1174,13 +1178,15 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        layout.applyTaskChanges(wct, topLeftStage.mRootTaskInfo, bottomRightStage.mRootTaskInfo);
    }

    void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t) {
    void updateSurfaceBounds(@Nullable SplitLayout layout, @NonNull SurfaceControl.Transaction t,
            boolean applyResizingOffset) {
        final StageTaskListener topLeftStage =
                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mSideStage : mMainStage;
        final StageTaskListener bottomRightStage =
                mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT ? mMainStage : mSideStage;
        (layout != null ? layout : mSplitLayout).applySurfaceChanges(t, topLeftStage.mRootLeash,
                bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer);
                bottomRightStage.mRootLeash, topLeftStage.mDimLayer, bottomRightStage.mDimLayer,
                applyResizingOffset);
    }

    void setResizingSplits(boolean resizing) {
@@ -1220,7 +1226,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mTaskOrganizer.applyTransaction(wct);
    }

    @Override
    public void onDisplayAdded(int displayId) {
        if (displayId != DEFAULT_DISPLAY) {
            return;
+2 −1
Original line number Diff line number Diff line
@@ -253,7 +253,8 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
                    RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                    IRemoteAnimationFinishedCallback finishedCallback,
                    SurfaceControl.Transaction t) {
                mStageCoordinator.updateSurfaceBounds(null /* layout */, t);
                mStageCoordinator.updateSurfaceBounds(null /* layout */, t,
                        false /* applyResizingOffset */);

                if (apps != null) {
                    for (int i = 0; i < apps.length; ++i) {
Loading