Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba688138 authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge changes from topic "floating_dismiss" into tm-dev

* changes:
  Update PIP dismiss to use DismissView
  Update dismiss to new spec
parents 014c2596 a62aa184
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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>
+50 −8
Original line number Diff line number Diff line
@@ -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(
+10 −60
Original line number Diff line number Diff line
@@ -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();
    }

    /**