From 953a9e14c74282cc7a3aaa5e56667e92e1336dc4 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Fri, 18 Feb 2022 11:58:43 -0800 Subject: Update dismiss to new spec 1 - larger gradient (same for both phone & tablet) 2 - gradient is now based on theme color Test: manual - have a bubble, drag to dismiss it, observe the gradient Bug: 217211205 Change-Id: Ibef23992089f0ae33dd93f9528a3ea2887aae465 --- libs/WindowManager/Shell/res/values/dimen.xml | 4 +- .../com/android/wm/shell/bubbles/DismissView.kt | 51 ++++++++++++++++++---- 2 files changed, 45 insertions(+), 10 deletions(-) (limited to 'libs/WindowManager/Shell') diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 8a8231d00195..c534c5390e17 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -18,8 +18,8 @@ 96dp 60dp - - 250dp + + 548dp 16dp 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..d3355545a4b9 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 = + object : IntProperty("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) @@ -104,6 +125,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( -- cgit v1.2.3-59-g8ed1b From a62aa184f7226411182434413805878d839f292f Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Fri, 18 Feb 2022 12:05:42 -0800 Subject: Update PIP dismiss to use DismissView All the values / things being done in PIP are exactly the same as what DismissView does. This change updates PIP to use DismissView directly so PIP will always pick up visual changes to dismiss without having to copy them over manually. Test: manual - have a PIP, drag it around and observe dismiss, drag PIP to dismiss, observe Bug: 217211205 Change-Id: I430df28bdb7980ff5a0316c4aab728fe54e95e6b --- .../com/android/wm/shell/bubbles/DismissView.kt | 7 +++ .../shell/pip/phone/PipDismissTargetHandler.java | 70 ++++------------------ 2 files changed, 17 insertions(+), 60 deletions(-) (limited to 'libs/WindowManager/Shell') 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 d3355545a4b9..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 @@ -114,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( 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 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(); } /** -- cgit v1.2.3-59-g8ed1b