summaryrefslogtreecommitdiff
path: root/libs/WindowManager/Shell
diff options
context:
space:
mode:
author Mady Mellor <madym@google.com> 2022-02-23 18:12:07 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-02-23 18:12:07 +0000
commitba688138fb83874114c9ea8a5737182cb1bf37ec (patch)
treef0c315bc9e3ab77d23605259d53dfea40a11423e /libs/WindowManager/Shell
parent014c25967bd16c352ca213e117c3427cde0392ac (diff)
parenta62aa184f7226411182434413805878d839f292f (diff)
Merge changes from topic "floating_dismiss" into tm-dev
* changes: Update PIP dismiss to use DismissView Update dismiss to new spec
Diffstat (limited to 'libs/WindowManager/Shell')
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt58
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java70
3 files changed, 62 insertions, 70 deletions
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 3852c69b4325..bb8a43d87cb8 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -18,8 +18,8 @@
<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>
+ <!-- The height of the gradient indicating the dismiss edge when moving a PIP or bubble. -->
+ <dimen name="floating_dismiss_gradient_height">548dp</dimen>
<!-- The padding around a PiP actions. -->
<dimen name="pip_action_padding">16dp</dimen>
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 74672a336161..063dac3d4109 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
@@ -16,11 +16,16 @@
package com.android.wm.shell.bubbles
+import android.animation.ObjectAnimator
import android.content.Context
-import android.graphics.drawable.TransitionDrawable
+import android.graphics.Color
+import android.graphics.drawable.GradientDrawable
+import android.util.IntProperty
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
+import android.view.WindowManager
+import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY
@@ -28,8 +33,6 @@ import androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW
import com.android.wm.shell.R
import com.android.wm.shell.animation.PhysicsAnimator
import com.android.wm.shell.common.DismissCircleView
-import android.view.WindowInsets
-import android.view.WindowManager
/*
* View that handles interactions between DismissCircleView and BubbleStackView.
@@ -41,9 +44,21 @@ class DismissView(context: Context) : FrameLayout(context) {
private val animator = PhysicsAnimator.getInstance(circle)
private val spring = PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_LOW_BOUNCY)
- private val DISMISS_SCRIM_FADE_MS = 200
+ private val DISMISS_SCRIM_FADE_MS = 200L
private var wm: WindowManager =
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ private var gradientDrawable = createGradient()
+
+ private val GRADIENT_ALPHA: IntProperty<GradientDrawable> =
+ object : IntProperty<GradientDrawable>("alpha") {
+ override fun setValue(d: GradientDrawable, percent: Int) {
+ d.alpha = percent
+ }
+ override fun get(d: GradientDrawable): Int {
+ return d.alpha
+ }
+ }
+
init {
setLayoutParams(LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -53,8 +68,7 @@ class DismissView(context: Context) : FrameLayout(context) {
setClipToPadding(false)
setClipChildren(false)
setVisibility(View.INVISIBLE)
- setBackgroundResource(
- R.drawable.floating_dismiss_gradient_transition)
+ setBackgroundDrawable(gradientDrawable)
val targetSize: Int = resources.getDimensionPixelSize(R.dimen.dismiss_circle_size)
addView(circle, LayoutParams(targetSize, targetSize,
@@ -71,7 +85,11 @@ class DismissView(context: Context) : FrameLayout(context) {
if (isShowing) return
isShowing = true
setVisibility(View.VISIBLE)
- (getBackground() as TransitionDrawable).startTransition(DISMISS_SCRIM_FADE_MS)
+ val alphaAnim = ObjectAnimator.ofInt(gradientDrawable, GRADIENT_ALPHA,
+ gradientDrawable.alpha, 255)
+ alphaAnim.setDuration(DISMISS_SCRIM_FADE_MS)
+ alphaAnim.start()
+
animator.cancel()
animator
.spring(DynamicAnimation.TRANSLATION_Y, 0f, spring)
@@ -85,7 +103,10 @@ class DismissView(context: Context) : FrameLayout(context) {
fun hide() {
if (!isShowing) return
isShowing = false
- (getBackground() as TransitionDrawable).reverseTransition(DISMISS_SCRIM_FADE_MS)
+ val alphaAnim = ObjectAnimator.ofInt(gradientDrawable, GRADIENT_ALPHA,
+ gradientDrawable.alpha, 0)
+ alphaAnim.setDuration(DISMISS_SCRIM_FADE_MS)
+ alphaAnim.start()
animator
.spring(DynamicAnimation.TRANSLATION_Y, height.toFloat(),
spring)
@@ -93,6 +114,13 @@ class DismissView(context: Context) : FrameLayout(context) {
.start()
}
+ /**
+ * Cancels the animator for the dismiss target.
+ */
+ fun cancelAnimators() {
+ animator.cancel()
+ }
+
fun updateResources() {
updatePadding()
layoutParams.height = resources.getDimensionPixelSize(
@@ -104,6 +132,20 @@ class DismissView(context: Context) : FrameLayout(context) {
circle.requestLayout()
}
+ private fun createGradient(): GradientDrawable {
+ val gradientColor = context.resources.getColor(android.R.color.system_neutral1_900)
+ val alpha = 0.7f * 255
+ val gradientColorWithAlpha = Color.argb(alpha.toInt(),
+ Color.red(gradientColor),
+ Color.green(gradientColor),
+ Color.blue(gradientColor))
+ val gd = GradientDrawable(
+ GradientDrawable.Orientation.BOTTOM_TOP,
+ intArrayOf(gradientColorWithAlpha, Color.TRANSPARENT))
+ gd.setAlpha(0)
+ return gd
+ }
+
private fun updatePadding() {
val insets: WindowInsets = wm.getCurrentWindowMetrics().getWindowInsets()
val navInset = insets.getInsetsIgnoringVisibility(
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 915c5939c34b..3115f8afde3b 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
@@ -20,27 +20,20 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
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.WindowInsets;
import android.view.WindowManager;
-import android.widget.FrameLayout;
import androidx.annotation.NonNull;
-import androidx.dynamicanimation.animation.DynamicAnimation;
-import androidx.dynamicanimation.animation.SpringForce;
import com.android.wm.shell.R;
-import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.DismissView;
import com.android.wm.shell.common.DismissCircleView;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
@@ -56,9 +49,6 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
/* 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;
- /** Duration of the dismiss scrim fading in/out. */
- private static final int DISMISS_TRANSITION_DURATION_MS = 200;
-
/**
* MagnetizedObject wrapper for PIP. This allows the magnetic target library to locate and move
* PIP.
@@ -69,7 +59,7 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
* Container for the dismiss circle, so that it can be animated within the container via
* translation rather than within the WindowManager via slow layout animations.
*/
- private ViewGroup mTargetViewContainer;
+ private DismissView mTargetViewContainer;
/** Circle view used to render the dismiss target. */
private DismissCircleView mTargetView;
@@ -79,16 +69,6 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
*/
private MagnetizedObject.MagneticTarget mMagneticTarget;
- /**
- * PhysicsAnimator instance for animating the dismiss target in/out.
- */
- private PhysicsAnimator<View> mMagneticTargetAnimator;
-
- /** Default configuration to use for springing the dismiss target in/out. */
- private final PhysicsAnimator.SpringConfig mTargetSpringConfig =
- new PhysicsAnimator.SpringConfig(
- SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
-
// Allow dragging the PIP to a location to close it
private boolean mEnableDismissDragToEdge;
@@ -125,12 +105,8 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
cleanUpDismissTarget();
}
- mTargetView = new DismissCircleView(mContext);
- mTargetViewContainer = new FrameLayout(mContext);
- mTargetViewContainer.setBackgroundDrawable(
- mContext.getDrawable(R.drawable.floating_dismiss_gradient_transition));
- mTargetViewContainer.setClipChildren(false);
- mTargetViewContainer.addView(mTargetView);
+ mTargetViewContainer = new DismissView(mContext);
+ mTargetView = mTargetViewContainer.getCircle();
mTargetViewContainer.setOnApplyWindowInsetsListener((view, windowInsets) -> {
if (!windowInsets.equals(mWindowInsets)) {
mWindowInsets = windowInsets;
@@ -187,7 +163,6 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
}
});
- mMagneticTargetAnimator = PhysicsAnimator.getInstance(mTargetView);
}
@Override
@@ -213,19 +188,13 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
if (mTargetView == null) {
return;
}
+ if (mTargetViewContainer != null) {
+ mTargetViewContainer.updateResources();
+ }
final Resources res = mContext.getResources();
mTargetSize = res.getDimensionPixelSize(R.dimen.dismiss_circle_size);
mDismissAreaHeight = res.getDimensionPixelSize(R.dimen.floating_dismiss_gradient_height);
- final WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
- final Insets navInset = insets.getInsetsIgnoringVisibility(
- WindowInsets.Type.navigationBars());
- final FrameLayout.LayoutParams newParams =
- new FrameLayout.LayoutParams(mTargetSize, mTargetSize);
- newParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- newParams.bottomMargin = navInset.bottom + mContext.getResources().getDimensionPixelSize(
- R.dimen.floating_dismiss_bottom_margin);
- mTargetView.setLayoutParams(newParams);
// Set the magnetic field radius equal to the target size from the center of the target
setMagneticFieldRadiusPercent(mMagneticFieldRadiusPercent);
@@ -261,7 +230,7 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
/** 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.cancelAnimators();
mTargetViewContainer.setVisibility(View.INVISIBLE);
mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this);
@@ -312,18 +281,8 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
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();
- mMagneticTargetAnimator
- .spring(DynamicAnimation.TRANSLATION_Y, 0f, mTargetSpringConfig)
- .start();
-
- ((TransitionDrawable) mTargetViewContainer.getBackground()).startTransition(
- DISMISS_TRANSITION_DURATION_MS);
+ mTargetViewContainer.show();
}
}
@@ -332,16 +291,7 @@ public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListen
if (!mEnableDismissDragToEdge) {
return;
}
-
- mMagneticTargetAnimator
- .spring(DynamicAnimation.TRANSLATION_Y,
- mTargetViewContainer.getHeight(),
- mTargetSpringConfig)
- .withEndActions(() -> mTargetViewContainer.setVisibility(View.GONE))
- .start();
-
- ((TransitionDrawable) mTargetViewContainer.getBackground()).reverseTransition(
- DISMISS_TRANSITION_DURATION_MS);
+ mTargetViewContainer.hide();
}
/**