diff options
12 files changed, 133 insertions, 188 deletions
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml b/libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml deleted file mode 100644 index 2104be48d1d9..000000000000 --- a/libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml +++ /dev/null @@ -1,28 +0,0 @@ -<!-- - ~ Copyright (C) 2020 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<!-- - The transparent circle outline that encircles the bubbles when they're in the dismiss target. ---> -<shape - xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="oval"> - - <stroke - android:width="1dp" - android:color="#66FFFFFF" /> - - <solid android:color="#B3000000" /> -</shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml b/libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml deleted file mode 100644 index ff8feded11ab..000000000000 --- a/libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml +++ /dev/null @@ -1,26 +0,0 @@ -<!-- - ~ Copyright (C) 2020 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License. - --> -<!-- The 'X' bubble dismiss icon. This is just ic_close with a stroke. --> -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24.0dp" - android:height="24.0dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M19.000000,6.400000l-1.400000,-1.400000 -5.600000,5.600000 -5.600000,-5.600000 -1.400000,1.400000 5.600000,5.600000 -5.600000,5.600000 1.400000,1.400000 5.600000,-5.600000 5.600000,5.600000 1.400000,-1.400000 -5.600000,-5.600000z" - android:fillColor="#FFFFFFFF" - android:strokeColor="#FF000000"/> -</vector> diff --git a/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml b/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml index 7809c8398c2d..f7fda362d76c 100644 --- a/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml +++ b/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml @@ -20,9 +20,8 @@ android:shape="oval"> <stroke - android:width="1dp" - android:color="#AAFFFFFF" /> - - <solid android:color="#77000000" /> + android:width="2dp" + android:color="@android:color/system_accent1_600" /> + <solid android:color="@android:color/system_accent1_600" /> </shape>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml index 60456267afef..62285e62fbf5 100644 --- a/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml +++ b/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml @@ -21,5 +21,5 @@ android:viewportHeight="24.0"> <path android:pathData="M19.000000,6.400000l-1.400000,-1.400000 -5.600000,5.600000 -5.600000,-5.600000 -1.400000,1.400000 5.600000,5.600000 -5.600000,5.600000 1.400000,1.400000 5.600000,-5.600000 5.600000,5.600000 1.400000,-1.400000 -5.600000,-5.600000z" - android:fillColor="#FFFFFFFF"/> + android:fillColor="@android:color/system_neutral1_50"/> </vector> diff --git a/libs/WindowManager/Shell/res/layout/bubble_dismiss_target.xml b/libs/WindowManager/Shell/res/layout/bubble_dismiss_target.xml deleted file mode 100644 index f5cd727a6d03..000000000000 --- a/libs/WindowManager/Shell/res/layout/bubble_dismiss_target.xml +++ /dev/null @@ -1,49 +0,0 @@ -<!-- - ~ Copyright (C) 2019 The Android Open Source Project - ~ - ~ Licensed under the Apache License, Version 2.0 (the "License"); - ~ you may not use this file except in compliance with the License. - ~ You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, software - ~ distributed under the License is distributed on an "AS IS" BASIS, - ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ~ See the License for the specific language governing permissions and - ~ limitations under the License - --> -<!-- Bubble dismiss target consisting of an X icon and the text 'Dismiss'. --> -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="@dimen/floating_dismiss_gradient_height" - android:layout_gravity="bottom|center_horizontal"> - - <FrameLayout - android:id="@+id/bubble_dismiss_circle" - android:layout_width="@dimen/bubble_dismiss_encircle_size" - android:layout_height="@dimen/bubble_dismiss_encircle_size" - android:layout_gravity="center" - android:background="@drawable/bubble_dismiss_circle" /> - - <LinearLayout - android:id="@+id/bubble_dismiss_icon_container" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:gravity="center" - android:paddingBottom="@dimen/bubble_dismiss_target_padding_y" - android:paddingTop="@dimen/bubble_dismiss_target_padding_y" - android:paddingLeft="@dimen/bubble_dismiss_target_padding_x" - android:paddingRight="@dimen/bubble_dismiss_target_padding_x" - android:clipChildren="false" - android:clipToPadding="false" - android:orientation="horizontal"> - - <ImageView - android:id="@+id/bubble_dismiss_close_icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:src="@drawable/bubble_dismiss_icon" /> - </LinearLayout> -</FrameLayout>
\ No newline at end of file diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 3caff35c8a9d..dddf2c12ea2d 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -15,7 +15,8 @@ limitations under the License. --> <resources> - <dimen name="dismiss_circle_size">52dp</dimen> + <dimen name="dismiss_circle_size">96dp</dimen> + <dimen name="dismiss_circle_small">60dp</dimen> <!-- The height of the gradient indicating the dismiss edge when moving a PIP. --> <dimen name="floating_dismiss_gradient_height">250dp</dimen> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 7e48a7e13920..d821c6ff7cd1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -34,10 +34,7 @@ import android.content.Intent; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; import android.graphics.Outline; -import android.graphics.Paint; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; @@ -192,8 +189,7 @@ public class BubbleStackView extends FrameLayout private final BubbleController mBubbleController; private final BubbleData mBubbleData; - private final ValueAnimator mDesaturateAndDarkenAnimator; - private final Paint mDesaturateAndDarkenPaint = new Paint(); + private final ValueAnimator mDismissBubbleAnimator; private PhysicsAnimationLayout mBubbleContainer; private StackAnimationController mStackAnimationController; @@ -330,8 +326,8 @@ public class BubbleStackView extends FrameLayout private boolean mIsExpansionAnimating = false; private boolean mIsBubbleSwitchAnimating = false; - /** The view to desaturate/darken when magneted to the dismiss target. */ - @Nullable private View mDesaturateAndDarkenTargetView; + /** The view to shrink and apply alpha to when magneted to the dismiss target. */ + @Nullable private View mViewBeingDismissed; private Rect mTempRect = new Rect(); @@ -415,8 +411,7 @@ public class BubbleStackView extends FrameLayout if (mExpandedAnimationController.getDraggedOutBubble() == null) { return; } - - animateDesaturateAndDarken( + animateDismissBubble( mExpandedAnimationController.getDraggedOutBubble(), true); } @@ -426,8 +421,7 @@ public class BubbleStackView extends FrameLayout if (mExpandedAnimationController.getDraggedOutBubble() == null) { return; } - - animateDesaturateAndDarken( + animateDismissBubble( mExpandedAnimationController.getDraggedOutBubble(), false); if (wasFlungOut) { @@ -459,14 +453,13 @@ public class BubbleStackView extends FrameLayout @Override public void onStuckToTarget( @NonNull MagnetizedObject.MagneticTarget target) { - animateDesaturateAndDarken(mBubbleContainer, true); + animateDismissBubble(mBubbleContainer, true); } @Override public void onUnstuckFromTarget(@NonNull MagnetizedObject.MagneticTarget target, float velX, float velY, boolean wasFlungOut) { - animateDesaturateAndDarken(mBubbleContainer, false); - + animateDismissBubble(mBubbleContainer, false); if (wasFlungOut) { mStackAnimationController.flingStackThenSpringToEdge( mStackAnimationController.getStackPosition().x, velX, velY); @@ -481,11 +474,10 @@ public class BubbleStackView extends FrameLayout mStackAnimationController.animateStackDismissal( mDismissView.getHeight() /* translationYBy */, () -> { - resetDesaturationAndDarken(); + resetDismissAnimator(); dismissMagnetizedObject(); } ); - mDismissView.hide(); } }; @@ -836,17 +828,7 @@ public class BubbleStackView extends FrameLayout .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)); mFlyoutTransitionSpring.addEndListener(mAfterFlyoutTransitionSpring); - mDismissView = new DismissView(context); - addView(mDismissView); - - final ContentResolver contentResolver = getContext().getContentResolver(); - final int dismissRadius = Settings.Secure.getInt( - contentResolver, "bubble_dismiss_radius", mBubbleSize * 2 /* default */); - - // Save the MagneticTarget instance for the newly set up view - we'll add this to the - // MagnetizedObjects. - mMagneticTarget = new MagnetizedObject.MagneticTarget( - mDismissView.getCircle(), dismissRadius); + setUpDismissView(); setClipChildren(false); setFocusable(true); @@ -891,6 +873,7 @@ public class BubbleStackView extends FrameLayout mRelativeStackPositionBeforeRotation = null; } + setUpDismissView(); if (mIsExpanded) { // Re-draw bubble row and pointer for new orientation. beforeExpandedViewAnimation(); @@ -905,30 +888,23 @@ public class BubbleStackView extends FrameLayout } removeOnLayoutChangeListener(mOrientationChangedListener); }; - - final ColorMatrix animatedMatrix = new ColorMatrix(); - final ColorMatrix darkenMatrix = new ColorMatrix(); - - mDesaturateAndDarkenAnimator = ValueAnimator.ofFloat(1f, 0f); - mDesaturateAndDarkenAnimator.addUpdateListener(animation -> { + final float maxDismissSize = getResources().getDimensionPixelSize( + R.dimen.dismiss_circle_size); + final float minDismissSize = getResources().getDimensionPixelSize( + R.dimen.dismiss_circle_small); + final float sizePercent = minDismissSize / maxDismissSize; + mDismissBubbleAnimator = ValueAnimator.ofFloat(1f, 0f); + mDismissBubbleAnimator.addUpdateListener(animation -> { final float animatedValue = (float) animation.getAnimatedValue(); - animatedMatrix.setSaturation(animatedValue); - - final float animatedDarkenValue = (1f - animatedValue) * DARKEN_PERCENT; - darkenMatrix.setScale( - 1f - animatedDarkenValue /* red */, - 1f - animatedDarkenValue /* green */, - 1f - animatedDarkenValue /* blue */, - 1f /* alpha */); - - // Concat the matrices so that the animatedMatrix both desaturates and darkens. - animatedMatrix.postConcat(darkenMatrix); - - // Update the paint and apply it to the bubble container. - mDesaturateAndDarkenPaint.setColorFilter(new ColorMatrixColorFilter(animatedMatrix)); - - if (mDesaturateAndDarkenTargetView != null) { - mDesaturateAndDarkenTargetView.setLayerPaint(mDesaturateAndDarkenPaint); + if (mDismissView != null) { + mDismissView.setPivotX((mDismissView.getRight() - mDismissView.getLeft()) / 2f); + mDismissView.setPivotY((mDismissView.getBottom() - mDismissView.getTop()) / 2f); + final float scaleValue = Math.max(animatedValue, sizePercent); + mDismissView.getCircle().setScaleX(scaleValue); + mDismissView.getCircle().setScaleY(scaleValue); + } + if (mViewBeingDismissed != null) { + mViewBeingDismissed.setAlpha(Math.max(animatedValue, 0.7f)); } }); @@ -1048,6 +1024,23 @@ public class BubbleStackView extends FrameLayout } }; + private void setUpDismissView() { + if (mDismissView != null) { + removeView(mDismissView); + } + mDismissView = new DismissView(getContext()); + addView(mDismissView); + + final ContentResolver contentResolver = getContext().getContentResolver(); + final int dismissRadius = Settings.Secure.getInt( + contentResolver, "bubble_dismiss_radius", mBubbleSize * 2 /* default */); + + // Save the MagneticTarget instance for the newly set up view - we'll add this to the + // MagnetizedObjects. + mMagneticTarget = new MagnetizedObject.MagneticTarget( + mDismissView.getCircle(), dismissRadius); + } + // TODO: Create ManageMenuView and move setup / animations there private void setUpManageMenu() { if (mManageMenu != null) { @@ -1217,6 +1210,7 @@ public class BubbleStackView extends FrameLayout public void onThemeChanged() { setUpFlyout(); setUpManageMenu(); + setUpDismissView(); updateOverflow(); updateUserEdu(); updateExpandedViewTheme(); @@ -1256,6 +1250,7 @@ public class BubbleStackView extends FrameLayout updateOverflow(); setUpManageMenu(); setUpFlyout(); + setUpDismissView(); mBubbleSize = mPositioner.getBubbleSize(); for (Bubble b : mBubbleData.getBubbles()) { if (b.getIconView() == null) { @@ -2264,42 +2259,46 @@ public class BubbleStackView extends FrameLayout } } - /** Prepares and starts the desaturate/darken animation on the bubble stack. */ - private void animateDesaturateAndDarken(View targetView, boolean desaturateAndDarken) { - mDesaturateAndDarkenTargetView = targetView; + /** Prepares and starts the dismiss animation on the bubble stack. */ + private void animateDismissBubble(View targetView, boolean applyAlpha) { + mViewBeingDismissed = targetView; - if (mDesaturateAndDarkenTargetView == null) { + if (mViewBeingDismissed == null) { return; } - - if (desaturateAndDarken) { - // Use the animated paint for the bubbles. - mDesaturateAndDarkenTargetView.setLayerType( - View.LAYER_TYPE_HARDWARE, mDesaturateAndDarkenPaint); - mDesaturateAndDarkenAnimator.removeAllListeners(); - mDesaturateAndDarkenAnimator.start(); + if (applyAlpha) { + mDismissBubbleAnimator.removeAllListeners(); + mDismissBubbleAnimator.start(); } else { - mDesaturateAndDarkenAnimator.removeAllListeners(); - mDesaturateAndDarkenAnimator.addListener(new AnimatorListenerAdapter() { + mDismissBubbleAnimator.removeAllListeners(); + mDismissBubbleAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - // Stop using the animated paint. - resetDesaturationAndDarken(); + resetDismissAnimator(); + } + + @Override + public void onAnimationCancel(Animator animation) { + super.onAnimationCancel(animation); + resetDismissAnimator(); } }); - mDesaturateAndDarkenAnimator.reverse(); + mDismissBubbleAnimator.reverse(); } } - private void resetDesaturationAndDarken() { + private void resetDismissAnimator() { + mDismissBubbleAnimator.removeAllListeners(); + mDismissBubbleAnimator.cancel(); - mDesaturateAndDarkenAnimator.removeAllListeners(); - mDesaturateAndDarkenAnimator.cancel(); - - if (mDesaturateAndDarkenTargetView != null) { - mDesaturateAndDarkenTargetView.setLayerType(View.LAYER_TYPE_NONE, null); - mDesaturateAndDarkenTargetView = null; + if (mViewBeingDismissed != null) { + mViewBeingDismissed.setAlpha(1f); + mViewBeingDismissed = null; + } + if (mDismissView != null) { + mDismissView.getCircle().setScaleX(1f); + mDismissView.getCircle().setScaleY(1f); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt index 04b5ad6dddf9..0a1cd2246339 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt @@ -67,8 +67,6 @@ class DismissView(context: Context) : FrameLayout(context) { fun show() { if (isShowing) return isShowing = true - bringToFront() - setZ(Short.MAX_VALUE - 1f) setVisibility(View.VISIBLE) (getBackground() as TransitionDrawable).startTransition(DISMISS_SCRIM_FADE_MS) animator.cancel() diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 00494611420d..e1b198c4217a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -379,6 +379,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } + public SurfaceControl getSurfaceControl() { + return mLeash; + } + private void setBoundsStateForEntry(ComponentName componentName, PictureInPictureParams params, ActivityInfo activityInfo) { mPipBoundsState.setBoundsStateForEntry(componentName, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java index c26b686f91fb..1da9577fe49a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java @@ -26,8 +26,10 @@ import android.graphics.Rect; import android.graphics.drawable.TransitionDrawable; import android.view.Gravity; import android.view.MotionEvent; +import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.view.WindowManager; import android.widget.FrameLayout; @@ -47,7 +49,7 @@ import kotlin.Unit; /** * Handler of all Magnetized Object related code for PiP. */ -public class PipDismissTargetHandler { +public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListener { /* The multiplier to apply scale the target size by when applying the magnetic field radius */ private static final float MAGNETIC_FIELD_RADIUS_MULTIPLIER = 1.25f; @@ -92,6 +94,9 @@ public class PipDismissTargetHandler { private int mDismissAreaHeight; private float mMagneticFieldRadiusPercent = 1f; + private SurfaceControl mTaskLeash; + private boolean mHasDismissTargetSurface; + private final Context mContext; private final PipMotionHelper mMotionHelper; private final PipUiEventLogger mPipUiEventLogger; @@ -167,6 +172,14 @@ public class PipDismissTargetHandler { mMagneticTargetAnimator = PhysicsAnimator.getInstance(mTargetView); } + @Override + public boolean onPreDraw() { + mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this); + mHasDismissTargetSurface = true; + updateDismissTargetLayer(); + return true; + } + /** * Potentially start consuming future motion events if PiP is currently near the magnetized * object. @@ -207,12 +220,31 @@ public class PipDismissTargetHandler { * MAGNETIC_FIELD_RADIUS_MULTIPLIER)); } + public void setTaskLeash(SurfaceControl taskLeash) { + mTaskLeash = taskLeash; + } + + private void updateDismissTargetLayer() { + if (!mHasDismissTargetSurface || mTaskLeash == null) { + // No dismiss target surface, can just return + return; + } + + // Put the dismiss target behind the task + SurfaceControl.Transaction t = new SurfaceControl.Transaction(); + t.setRelativeLayer(mTargetViewContainer.getViewRootImpl().getSurfaceControl(), + mTaskLeash, -1); + t.apply(); + } + /** Adds the magnetic target view to the WindowManager so it's ready to be animated in. */ public void createOrUpdateDismissTarget() { if (!mTargetViewContainer.isAttachedToWindow()) { mMagneticTargetAnimator.cancel(); mTargetViewContainer.setVisibility(View.INVISIBLE); + mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this); + mHasDismissTargetSurface = false; try { mWindowManager.addView(mTargetViewContainer, getDismissTargetLayoutParams()); @@ -259,9 +291,9 @@ public class PipDismissTargetHandler { createOrUpdateDismissTarget(); if (mTargetViewContainer.getVisibility() != View.VISIBLE) { - mTargetView.setTranslationY(mTargetViewContainer.getHeight()); mTargetViewContainer.setVisibility(View.VISIBLE); + mTargetViewContainer.getViewTreeObserver().addOnPreDrawListener(this); // Cancel in case we were in the middle of animating it out. mMagneticTargetAnimator.cancel(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index 15e7f07a1f6c..604ebc08f42e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -40,6 +40,7 @@ import android.view.Choreographer; import androidx.dynamicanimation.animation.AnimationHandler; import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler; +import com.android.wm.shell.R; import com.android.wm.shell.animation.FloatProperties; import com.android.wm.shell.animation.PhysicsAnimator; import com.android.wm.shell.common.FloatingContentCoordinator; @@ -71,6 +72,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** Friction to use for PIP when it moves via physics fling animations. */ private static final float DEFAULT_FRICTION = 1.9f; + /** How much of the dismiss circle size to use when scaling down PIP. **/ + private static final float DISMISS_CIRCLE_PERCENT = 0.85f; private final Context mContext; private final PipTaskOrganizer mPipTaskOrganizer; @@ -296,9 +299,17 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, boolean flung, Function0<Unit> after) { final PointF targetCenter = target.getCenterOnScreen(); - final float desiredWidth = getBounds().width() / 2; - final float desiredHeight = getBounds().height() / 2; + // PIP should fit in the circle + final float dismissCircleSize = mContext.getResources().getDimensionPixelSize( + R.dimen.dismiss_circle_size); + final float width = getBounds().width(); + final float height = getBounds().height(); + final float ratio = width / height; + + // Width should be a little smaller than the circle size. + final float desiredWidth = dismissCircleSize * DISMISS_CIRCLE_PERCENT; + final float desiredHeight = desiredWidth / ratio; final float destinationX = targetCenter.x - (desiredWidth / 2f); final float destinationY = targetCenter.y - (desiredHeight / 2f); 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 f0ea4653c245..b1086c575f49 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 @@ -75,6 +75,7 @@ public class PipTouchHandler { private final @NonNull PipBoundsState mPipBoundsState; private final PipUiEventLogger mPipUiEventLogger; private final PipDismissTargetHandler mPipDismissTargetHandler; + private final PipTaskOrganizer mPipTaskOrganizer; private final ShellExecutor mMainExecutor; private PipResizeGestureHandler mPipResizeGestureHandler; @@ -173,6 +174,7 @@ public class PipTouchHandler { mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mPipBoundsAlgorithm = pipBoundsAlgorithm; mPipBoundsState = pipBoundsState; + mPipTaskOrganizer = pipTaskOrganizer; mMenuController = menuController; mPipUiEventLogger = pipUiEventLogger; mFloatingContentCoordinator = floatingContentCoordinator; @@ -799,6 +801,7 @@ public class PipTouchHandler { mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mPipBoundsState.getMovementBounds().bottom; mMotionHelper.setSpringingToTouch(false); + mPipDismissTargetHandler.setTaskLeash(mPipTaskOrganizer.getSurfaceControl()); // If the menu is still visible then just poke the menu // so that it will timeout after the user stops touching it @@ -847,6 +850,7 @@ public class PipTouchHandler { @Override public boolean onUp(PipTouchState touchState) { mPipDismissTargetHandler.hideDismissTargetMaybe(); + mPipDismissTargetHandler.setTaskLeash(null); if (!touchState.isUserInteracting()) { return false; |