diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java index 6f4e22fa8a043..79d795ee613fc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java @@ -32,6 +32,7 @@ import static android.view.Surface.ROTATION_90; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; @@ -336,6 +337,12 @@ public class DisplayLayout { return navigationBarPosition(res, mWidth, mHeight, mRotation); } + /** @return {@link DisplayCutout} instance. */ + @Nullable + public DisplayCutout getDisplayCutout() { + return mCutout; + } + /** * Calculates the stable insets if we already have the non-decor insets. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index 147a272f46459..ac7b9033b2b9f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -36,6 +36,7 @@ import android.graphics.PointF; import android.graphics.Rect; import android.provider.DeviceConfig; import android.util.Size; +import android.view.DisplayCutout; import android.view.InputEvent; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -959,21 +960,38 @@ public class PipTouchHandler { } private boolean shouldStash(PointF vel, Rect motionBounds) { + final boolean flingToLeft = vel.x < -mStashVelocityThreshold; + final boolean flingToRight = vel.x > mStashVelocityThreshold; + final int offset = motionBounds.width() / 2; + final boolean droppingOnLeft = + motionBounds.left < mPipBoundsState.getDisplayBounds().left - offset; + final boolean droppingOnRight = + motionBounds.right > mPipBoundsState.getDisplayBounds().right + offset; + + // Do not allow stash if the destination edge contains display cutout. We only + // compare the left and right edges since we do not allow stash on top / bottom. + final DisplayCutout displayCutout = + mPipBoundsState.getDisplayLayout().getDisplayCutout(); + if (displayCutout != null) { + if ((flingToLeft || droppingOnLeft) + && !displayCutout.getBoundingRectLeft().isEmpty()) { + return false; + } else if ((flingToRight || droppingOnRight) + && !displayCutout.getBoundingRectRight().isEmpty()) { + return false; + } + } + // If user flings the PIP window above the minimum velocity, stash PIP. // Only allow stashing to the edge if PIP wasn't previously stashed on the opposite // edge. - final boolean stashFromFlingToEdge = ((vel.x < -mStashVelocityThreshold - && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT) - || (vel.x > mStashVelocityThreshold - && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT)); + final boolean stashFromFlingToEdge = + (flingToLeft && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT) + || (flingToRight && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT); // If User releases the PIP window while it's out of the display bounds, put // PIP into stashed mode. - final int offset = motionBounds.width() / 2; - final boolean stashFromDroppingOnEdge = - (motionBounds.right > mPipBoundsState.getDisplayBounds().right + offset - || motionBounds.left - < mPipBoundsState.getDisplayBounds().left - offset); + final boolean stashFromDroppingOnEdge = droppingOnLeft || droppingOnRight; return stashFromFlingToEdge || stashFromDroppingOnEdge; }