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

Commit c00dc581 authored by Ikram Gabiyev's avatar Ikram Gabiyev Committed by Android (Google) Code Review
Browse files

Merge "Adjust PiP bounds upon IME visibility change" into main

parents 161dba6c be1fd970
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ public abstract class Pip2Module {
            TaskStackListenerImpl taskStackListener,
            ShellTaskOrganizer shellTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipTouchHandler pipTouchHandler,
            @ShellMainThread ShellExecutor mainExecutor) {
        if (!PipUtils.isPip2ExperimentEnabled()) {
            return Optional.empty();
@@ -112,7 +113,7 @@ public abstract class Pip2Module {
                    context, shellInit, shellCommandHandler, shellController, displayController,
                    displayInsetsController, pipBoundsState, pipBoundsAlgorithm,
                    pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer,
                    pipTransitionState, mainExecutor));
                    pipTransitionState, pipTouchHandler, mainExecutor));
        }
    }

+8 −2
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public class PipController implements ConfigurationChangeListener,
    private final TaskStackListenerImpl mTaskStackListener;
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final PipTransitionState mPipTransitionState;
    private final PipTouchHandler mPipTouchHandler;
    private final ShellExecutor mMainExecutor;
    private final PipImpl mImpl;
    private Consumer<Boolean> mOnIsInPipStateChangedListener;
@@ -130,6 +131,7 @@ public class PipController implements ConfigurationChangeListener,
            TaskStackListenerImpl taskStackListener,
            ShellTaskOrganizer shellTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipTouchHandler pipTouchHandler,
            ShellExecutor mainExecutor) {
        mContext = context;
        mShellCommandHandler = shellCommandHandler;
@@ -144,6 +146,7 @@ public class PipController implements ConfigurationChangeListener,
        mShellTaskOrganizer = shellTaskOrganizer;
        mPipTransitionState = pipTransitionState;
        mPipTransitionState.addPipTransitionStateChangedListener(this);
        mPipTouchHandler = pipTouchHandler;
        mMainExecutor = mainExecutor;
        mImpl = new PipImpl();

@@ -168,6 +171,7 @@ public class PipController implements ConfigurationChangeListener,
            TaskStackListenerImpl taskStackListener,
            ShellTaskOrganizer shellTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipTouchHandler pipTouchHandler,
            ShellExecutor mainExecutor) {
        if (!context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
@@ -177,7 +181,7 @@ public class PipController implements ConfigurationChangeListener,
        return new PipController(context, shellInit, shellCommandHandler, shellController,
                displayController, displayInsetsController, pipBoundsState, pipBoundsAlgorithm,
                pipDisplayLayoutState, pipScheduler, taskStackListener, shellTaskOrganizer,
                pipTransitionState, mainExecutor);
                pipTransitionState, pipTouchHandler, mainExecutor);
    }

    public PipImpl getPipImpl() {
@@ -204,7 +208,9 @@ public class PipController implements ConfigurationChangeListener,
        mDisplayInsetsController.addInsetsChangedListener(mPipDisplayLayoutState.getDisplayId(),
                new ImeListener(mDisplayController, mPipDisplayLayoutState.getDisplayId()) {
                    @Override
                    public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
                    public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
                        mPipTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
                    }
                });

        // Allow other outside processes to bind to PiP controller using the key below.
+39 −11
Original line number Diff line number Diff line
@@ -134,6 +134,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
    private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig =
            new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_NO_BOUNCY);

    @Nullable private Runnable mUpdateMovementBoundsRunnable;

    private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> {
        if (mPipBoundsState.getBounds().equals(newBounds)) {
            return;
@@ -141,6 +143,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,

        mMenuController.updateMenuLayout(newBounds);
        mPipBoundsState.setBounds(newBounds);
        maybeUpdateMovementBounds();
    };

    /**
@@ -566,11 +569,20 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
                            + " callers=\n%s", TAG, originalBounds, offset,
                    Debug.getCallers(5, "    "));
        }
        if (offset == 0) {
            return;
        }

        cancelPhysicsAnimation();
        /*
        mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
                mUpdateBoundsCallback);
         */

        Rect adjustedBounds = new Rect(originalBounds);
        adjustedBounds.offset(0, offset);

        setAnimatingToBounds(adjustedBounds);
        Bundle extra = new Bundle();
        extra.putBoolean(ANIMATING_BOUNDS_CHANGE, true);
        extra.putInt(ANIMATING_BOUNDS_CHANGE_DURATION, SHIFT_DURATION);
        mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra);
    }

    /**
@@ -585,11 +597,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
    /** Set new fling configs whose min/max values respect the given movement bounds. */
    private void rebuildFlingConfigs() {
        mFlingConfigX = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION,
                mPipBoundsAlgorithm.getMovementBounds(getBounds()).left,
                mPipBoundsAlgorithm.getMovementBounds(getBounds()).right);
                mPipBoundsState.getMovementBounds().left,
                mPipBoundsState.getMovementBounds().right);
        mFlingConfigY = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION,
                mPipBoundsAlgorithm.getMovementBounds(getBounds()).top,
                mPipBoundsAlgorithm.getMovementBounds(getBounds()).bottom);
                mPipBoundsState.getMovementBounds().top,
                mPipBoundsState.getMovementBounds().bottom);
        final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets();
        mStashConfigX = new PhysicsAnimator.FlingConfig(
                DEFAULT_FRICTION,
@@ -671,6 +683,16 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        cleanUpHighPerfSessionMaybe();
    }

    void setUpdateMovementBoundsRunnable(Runnable updateMovementBoundsRunnable) {
        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
    }

    private void maybeUpdateMovementBounds() {
        if (mUpdateMovementBoundsRunnable != null)  {
            mUpdateMovementBoundsRunnable.run();
        }
    }

    /**
     * Notifies the floating coordinator that we're moving, and sets the animating to bounds so
     * we return these bounds from
@@ -807,8 +829,14 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
                startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(),
                destinationBounds, duration, 0f /* angle */);
        animator.setAnimationEndCallback(() -> {
            mPipBoundsState.setBounds(destinationBounds);
            // All motion operations have actually finished, so make bounds cache updates.
            mUpdateBoundsCallback.accept(destinationBounds);

            // In case an ongoing drag/fling was present before a deterministic resize transition
            // kicked in, we need to update the update bounds properly before cleaning in-motion
            // state.
            mPipBoundsState.getMotionBoundsState().setBoundsInMotion(destinationBounds);
            settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);

            cleanUpHighPerfSessionMaybe();
            // Signal that we are done with resize transition
            mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */);
@@ -817,7 +845,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
    }

    private void settlePipBoundsAfterPhysicsAnimation(boolean animatingAfter) {
        if (!animatingAfter) {
        if (!animatingAfter && mPipBoundsState.getMotionBoundsState().isInMotion()) {
            // The physics animation ended, though we may not necessarily be done animating, such as
            // when we're still dragging after moving out of the magnetic target. Only set the final
            // bounds state and clear motion bounds completely if the whole animation is over.
+1 −1
Original line number Diff line number Diff line
@@ -146,8 +146,8 @@ public class PipResizeGestureHandler implements
        mUpdateResizeBoundsCallback = (rect) -> {
            mUserResizeBounds.set(rect);
            // mMotionHelper.synchronizePinnedStackBounds();
            mUpdateMovementBoundsRunnable.run();
            mPipBoundsState.setBounds(rect);
            mUpdateMovementBoundsRunnable.run();
            resetState();
        };
    }
+20 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
        mMenuController.addListener(new PipMenuListener());
        mGesture = new DefaultPipTouchGesture();
        mMotionHelper = pipMotionHelper;
        mMotionHelper.setUpdateMovementBoundsRunnable(this::updateMovementBounds);
        mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger,
                mMotionHelper, mainExecutor);
        mTouchState = new PipTouchState(ViewConfiguration.get(context),
@@ -317,6 +318,8 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
        mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
        mPipResizeGestureHandler.onActivityUnpinned();
        mPipInputConsumer.unregisterInputConsumer();
        mPipBoundsState.setHasUserMovedPip(false);
        mPipBoundsState.setHasUserResizedPip(false);
    }

    void onPinnedStackAnimationEnded(
@@ -346,6 +349,22 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
    void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
        mIsImeShowing = imeVisible;
        mImeHeight = imeHeight;

        // Cache new movement bounds using the new potential IME height.
        updateMovementBounds();

        mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
            int delta = mPipBoundsState.getMovementBounds().bottom
                    - mPipBoundsState.getBounds().top;

            boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
                    || mPipBoundsState.hasUserResizedPip());
            if ((imeVisible && delta < 0) || (!imeVisible && !hasUserInteracted)) {
                // The policy is to ignore an IME disappearing if user has interacted with PiP.
                // Otherwise, only offset due to an appearing IME if PiP occludes it.
                mMotionHelper.animateToOffset(mPipBoundsState.getBounds(), delta);
            }
        });
    }

    void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
@@ -1077,6 +1096,7 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
        switch (newState) {
            case PipTransitionState.ENTERED_PIP:
                onActivityPinned();
                updateMovementBounds();
                mTouchState.setAllowInputEvents(true);
                mTouchState.reset();
                break;
Loading