summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mady Mellor <madym@google.com> 2021-06-04 19:29:15 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-06-04 19:29:15 +0000
commit73eb2771f80179a257b70551da4bf792f9b5a1a3 (patch)
tree98e84d6678a9443dc063825599aae7c36c1ac0f0
parente0fa7da5aaec2d3e11a07ceb8710d4e9f4e9a47c (diff)
parent1de4c3f418d3e075ffb8724479e724bcdbd1d871 (diff)
Merge changes I5c096c2b,If0d0d86b into sc-dev
* changes: PIP dismiss updates Bubble dismiss updates
-rw-r--r--libs/WindowManager/Shell/res/drawable/bubble_dismiss_circle.xml28
-rw-r--r--libs/WindowManager/Shell/res/drawable/bubble_dismiss_icon.xml26
-rw-r--r--libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml7
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml2
-rw-r--r--libs/WindowManager/Shell/res/layout/bubble_dismiss_target.xml49
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java145
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java4
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;