Merge changes from topic "floating_dismiss" into tm-dev

* changes:
  Update PIP dismiss to use DismissView
  Update dismiss to new spec
This commit is contained in:
Mady Mellor
2022-02-23 18:12:07 +00:00
committed by Android (Google) Code Review
3 changed files with 62 additions and 70 deletions

View File

@@ -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>

View File

@@ -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(

View File

@@ -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();
}
/**