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

Commit 62f6fe22 authored by Mateusz Cicheński's avatar Mateusz Cicheński
Browse files

Move PiP swiftly in response to IME with keep clear areas flag enabled.

If the keep clear algorithm is enabled, PiP window will avoid the
keep clear areas and move away from occluding keyboard.

When IME is shown, we trigger the movement right away, for a smoother
experience.
If there is another animation ongoing, we delay moving PiP again, so
that it's more smooth overall.
Finally, we always apply gravity bottom with keep clear areas flag on,
so that it goes back down after IME dismiss.

Test: manually, http://recall/-/blXo3gy66k4fDYh7gFkrpe
Bug: 183746978

Change-Id: I32c52e4b6dd3c083b2168fda6a8b3b13facdac69
parent 66f5377b
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -324,6 +324,19 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        return mPipTransitionController;
    }

    /**
     * Returns true if the PiP window is currently being animated.
     */
    public boolean isAnimating() {
        // TODO(b/183746978) move this to PipAnimationController, and inject that in PipController
        PipAnimationController.PipTransitionAnimator animator =
                mPipAnimationController.getCurrentAnimator();
        if (animator != null && animator.isRunning()) {
            return true;
        }
        return false;
    }

    public Rect getCurrentOrAnimatingBounds() {
        PipAnimationController.PipTransitionAnimator animator =
                mPipAnimationController.getCurrentAnimator();
+1 −6
Original line number Diff line number Diff line
@@ -54,13 +54,8 @@ public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithm {
                ? pipBoundsAlgorithm.getEntryDestinationBoundsIgnoringKeepClearAreas()
                : pipBoundsState.getBounds();
        float snapFraction = pipBoundsAlgorithm.getSnapFraction(startingBounds);
        int verticalGravity;
        int verticalGravity = Gravity.BOTTOM;
        int horizontalGravity;
        if (snapFraction < 1.5f || snapFraction >= 3.5f) {
            verticalGravity = Gravity.NO_GRAVITY;
        } else {
            verticalGravity = Gravity.BOTTOM;
        }
        if (snapFraction >= 0.5f && snapFraction < 2.5f) {
            horizontalGravity = Gravity.RIGHT;
        } else {
+39 −10
Original line number Diff line number Diff line
@@ -149,7 +149,42 @@ public class PipController implements PipTransitionController.PipTransitionCallb
    private final Rect mTmpInsetBounds = new Rect();
    private final int mEnterAnimationDuration;

    private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback;
    private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback =
            this::onKeepClearAreasChangedCallback;

    private void onKeepClearAreasChangedCallback() {
        if (!mEnablePipKeepClearAlgorithm) {
            // early bail out if the keep clear areas feature is disabled
            return;
        }
        // if there is another animation ongoing, wait for it to finish and try again
        if (mPipTaskOrganizer.isAnimating()) {
            mMainExecutor.removeCallbacks(
                    mMovePipInResponseToKeepClearAreasChangeCallback);
            mMainExecutor.executeDelayed(
                    mMovePipInResponseToKeepClearAreasChangeCallback,
                    PIP_KEEP_CLEAR_AREAS_DELAY);
            return;
        }
        updatePipPositionForKeepClearAreas();
    }

    private void updatePipPositionForKeepClearAreas() {
        if (!mEnablePipKeepClearAlgorithm) {
            // early bail out if the keep clear areas feature is disabled
            return;
        }
        // only move if already in pip, other transitions account for keep clear areas
        if (mPipTransitionState.hasEnteredPip()) {
            Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
                    mPipBoundsAlgorithm);
            // only move if the bounds are actually different
            if (destBounds != mPipBoundsState.getBounds()) {
                mPipTaskOrganizer.scheduleAnimateResizePip(destBounds,
                        mEnterAnimationDuration, null);
            }
        }
    }

    private boolean mIsInFixedRotation;
    private PipAnimationListener mPinnedStackAnimationRecentsCallback;
@@ -302,6 +337,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb
        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
            mPipBoundsState.setImeVisibility(imeVisible, imeHeight);
            mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
            if (imeVisible) {
                updatePipPositionForKeepClearAreas();
            }
        }

        @Override
@@ -414,15 +452,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb

        mEnterAnimationDuration = mContext.getResources()
                .getInteger(R.integer.config_pipEnterAnimationDuration);
        mMovePipInResponseToKeepClearAreasChangeCallback = () -> {
            // only move if already in pip, other transitions account for keep clear areas
            if (mPipTransitionState.hasEnteredPip()) {
                Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
                        mPipBoundsAlgorithm);
                mPipTaskOrganizer.scheduleAnimateResizePip(destBounds,
                        mEnterAnimationDuration, null);
            }
        };
        mPipParamsChangedForwarder = pipParamsChangedForwarder;
        mDisplayInsetsController = displayInsetsController;

+7 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.util.Size;
import android.view.DisplayCutout;
@@ -70,6 +71,9 @@ public class PipTouchHandler {
    private static final String TAG = "PipTouchHandler";
    private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;

    private static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
            SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false);

    // Allow PIP to resize to a slightly bigger state upon touch
    private boolean mEnableResize;
    private final Context mContext;
@@ -426,6 +430,9 @@ public class PipTouchHandler {
            if (mTouchState.isUserInteracting()) {
                // Defer the update of the current movement bounds until after the user finishes
                // touching the screen
            } else if (ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
                // Ignore moving PiP if keep clear algorithm is enabled, since IME and shelf height
                // now are accounted for in the keep clear algorithm calculations
            } else {
                final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
                final Rect toMovementBounds = new Rect();