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

Commit fceeaddf authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Trigger PiP movement on KCA changes

Make sure KCA areas and further updates
are respected under certain conditions,
such as when we haven't interacted with PiP directly.

Make sure that shelf becoming invisible after KCA updates
only triggers a delayed transition (similar to PiP1) to avoid
double animations due to IME changes;

For example, tapping quicksearch,
triggers both IME and shelf turning invisible,
and we want to avoid these race conditions or multiple
sequantial animations.

Bug: 356508169
Flag: com.android.wm.shell.enable_pip2_implementation
Test: swipe up to enter PiP, open all apps, close all apps
Change-Id: I2a54711c7abff0aeb5b2cf39507d66b3a3d6c00f
parent 7f0f2c78
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -346,6 +346,7 @@ public class PipController implements ConfigurationChangeListener,
            mPipBoundsState.setNamedUnrestrictedKeepClearArea(
                    PipBoundsState.NAMED_KCA_LAUNCHER_SHELF, null);
        }
        mPipTouchHandler.onShelfVisibilityChanged(visible, height);
    }

    @Override
+37 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.util.Size;
import android.view.DisplayCutout;
@@ -78,6 +79,8 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha

    private static final String TAG = "PipTouchHandler";
    private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;
    private static final long PIP_KEEP_CLEAR_AREAS_DELAY =
            SystemProperties.getLong("persist.wm.debug.pip_keep_clear_areas_delay", 200);

    // Allow PIP to resize to a slightly bigger state upon touch
    private boolean mEnableResize;
@@ -134,6 +137,10 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
    // Temp vars
    private final Rect mTmpBounds = new Rect();

    // Callbacks
    private final Runnable mMoveOnShelVisibilityChanged;


    /**
     * A listener for the PIP menu activity.
     */
@@ -217,6 +224,26 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
                mPipPerfHintController);
        mPipBoundsState.addOnAspectRatioChangedCallback(this::updateMinMaxSize);

        mMoveOnShelVisibilityChanged = () -> {
            if (mIsImeShowing && mImeHeight > mShelfHeight) {
                // Early bail-out if IME is visible with a larger height present;
                // this should block unnecessary PiP movement since we delay checking for
                // KCA triggered movement to wait for other transitions (e.g. due to IME changes).
                return;
            }
            mPipTransitionState.setOnIdlePipTransitionStateRunnable(() -> {
                boolean hasUserInteracted = (mPipBoundsState.hasUserMovedPip()
                        || mPipBoundsState.hasUserResizedPip());
                int delta = mPipBoundsAlgorithm.getEntryDestinationBounds().top
                        - mPipBoundsState.getBounds().top;

                if (!mIsImeShowing && !hasUserInteracted && delta != 0) {
                    // If the user hasn't interacted with PiP, we respect the keep clear areas
                    mMotionHelper.animateToOffset(mPipBoundsState.getBounds(), delta);
                }
            });
        };

        if (PipUtils.isPip2ExperimentEnabled()) {
            shellInit.addInitCallback(this::onInit, this);
        }
@@ -375,6 +402,16 @@ public class PipTouchHandler implements PipTransitionState.PipTransitionStateCha
    void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
        mIsShelfShowing = shelfVisible;
        mShelfHeight = shelfHeight;

        // We need to remove the callback even if the shelf is visible, in case it the delayed
        // callback hasn't been executed yet to avoid the wrong final state.
        mMainExecutor.removeCallbacks(mMoveOnShelVisibilityChanged);
        if (shelfVisible) {
            mMoveOnShelVisibilityChanged.run();
        } else {
            // Postpone moving in response to hide of Launcher in case there's another change
            mMainExecutor.executeDelayed(mMoveOnShelVisibilityChanged, PIP_KEEP_CLEAR_AREAS_DELAY);
        }
    }

    /**