Loading libs/WindowManager/Shell/res/values/dimen.xml +4 −0 Original line number Diff line number Diff line Loading @@ -266,6 +266,10 @@ <dimen name="bubble_bar_manage_menu_item_height">52dp</dimen> <!-- Size of the icons in the bubble bar manage menu. --> <dimen name="bubble_bar_manage_menu_item_icon_size">20dp</dimen> <!-- Corner radius for expanded view when bubble bar is used --> <dimen name="bubble_bar_expanded_view_corner_radius">16dp</dimen> <!-- Corner radius for expanded view while it is being dragged --> <dimen name="bubble_bar_expanded_view_corner_radius_dragged">28dp</dimen> <!-- Bottom and end margin for compat buttons. --> <dimen name="compat_button_margin">24dp</dimen> Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java +138 −68 Original line number Diff line number Diff line Loading @@ -15,17 +15,28 @@ */ package com.android.wm.shell.bubbles.bar; import static android.view.View.SCALE_X; import static android.view.View.SCALE_Y; import static android.view.View.TRANSLATION_X; import static android.view.View.TRANSLATION_Y; import static android.view.View.VISIBLE; import static android.view.View.X; import static android.view.View.Y; import static com.android.wm.shell.animation.Interpolators.EMPHASIZED; import static com.android.wm.shell.animation.Interpolators.EMPHASIZED_DECELERATE; import static com.android.wm.shell.bubbles.bar.BubbleBarExpandedView.CORNER_RADIUS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.util.Log; import android.util.Size; import android.view.View; import android.widget.FrameLayout; import androidx.annotation.Nullable; Loading @@ -48,15 +59,16 @@ public class BubbleBarAnimationHelper { private static final float EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT = 0.1f; private static final float EXPANDED_VIEW_ANIMATE_OUT_SCALE_AMOUNT = .75f; private static final int EXPANDED_VIEW_ALPHA_ANIMATION_DURATION = 150; private static final int EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION = 100; private static final int EXPANDED_VIEW_ANIMATE_POSITION_DURATION = 300; private static final int EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION = 400; private static final int EXPANDED_VIEW_ANIMATE_TO_REST_DURATION = 400; private static final int EXPANDED_VIEW_DISMISS_DURATION = 250; private static final int EXPANDED_VIEW_DRAG_ANIMATION_DURATION = 150; private static final int EXPANDED_VIEW_DRAG_ANIMATION_DURATION = 400; /** * Additional scale applied to expanded view when it is positioned inside a magnetic target. */ private static final float EXPANDED_VIEW_IN_TARGET_SCALE = 0.6f; private static final float EXPANDED_VIEW_DRAG_SCALE = 0.5f; private static final float EXPANDED_VIEW_IN_TARGET_SCALE = 0.2f; private static final float EXPANDED_VIEW_DRAG_SCALE = 0.4f; private static final float DISMISS_VIEW_SCALE = 1.25f; /** Spring config for the expanded view scale-in animation. */ private final PhysicsAnimator.SpringConfig mScaleInSpringConfig = Loading @@ -72,6 +84,9 @@ public class BubbleBarAnimationHelper { /** Animator for animating the expanded view's alpha (including the TaskView inside it). */ private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); @Nullable private Animator mRunningDragAnimator; private final Context mContext; private final BubbleBarLayerView mLayerView; private final BubblePositioner mPositioner; Loading Loading @@ -232,14 +247,18 @@ public class BubbleBarAnimationHelper { Log.w(TAG, "Trying to animate start drag without a bubble"); return; } bbev.setPivotX(bbev.getWidth() / 2f); bbev.setPivotY(0f); bbev.animate() .scaleX(EXPANDED_VIEW_DRAG_SCALE) .scaleY(EXPANDED_VIEW_DRAG_SCALE) .setInterpolator(Interpolators.EMPHASIZED) .setDuration(EXPANDED_VIEW_DRAG_ANIMATION_DURATION) .start(); setDragPivot(bbev); AnimatorSet animatorSet = new AnimatorSet(); // Corner radius gets scaled, apply the reverse scale to ensure we have the desired radius final float cornerRadius = bbev.getDraggedCornerRadius() / EXPANDED_VIEW_DRAG_SCALE; animatorSet.playTogether( ObjectAnimator.ofFloat(bbev, SCALE_X, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, SCALE_Y, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, cornerRadius) ); animatorSet.setDuration(EXPANDED_VIEW_DRAG_ANIMATION_DURATION).setInterpolator(EMPHASIZED); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev)); startNewDragAnimation(animatorSet); } /** Loading @@ -258,6 +277,7 @@ public class BubbleBarAnimationHelper { int[] location = bbev.getLocationOnScreen(); int diffFromBottom = mPositioner.getScreenRect().bottom - location[1]; cancelAnimations(); bbev.animate() // 2x distance from bottom so the view flies out .translationYBy(diffFromBottom * 2) Loading @@ -276,19 +296,24 @@ public class BubbleBarAnimationHelper { return; } Point restPoint = getExpandedViewRestPosition(getExpandedViewSize()); bbev.animate() .x(restPoint.x) .y(restPoint.y) .scaleX(1f) .scaleY(1f) .setDuration(EXPANDED_VIEW_ANIMATE_POSITION_DURATION) .setInterpolator(Interpolators.EMPHASIZED_DECELERATE) .withStartAction(() -> bbev.setAnimating(true)) .withEndAction(() -> { bbev.setAnimating(false); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( ObjectAnimator.ofFloat(bbev, X, restPoint.x), ObjectAnimator.ofFloat(bbev, Y, restPoint.y), ObjectAnimator.ofFloat(bbev, SCALE_X, 1f), ObjectAnimator.ofFloat(bbev, SCALE_Y, 1f), ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, bbev.getRestingCornerRadius()) ); animatorSet.setDuration(EXPANDED_VIEW_ANIMATE_TO_REST_DURATION).setInterpolator(EMPHASIZED); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev) { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); bbev.resetPivot(); }) .start(); } }); startNewDragAnimation(animatorSet); } /** Loading @@ -304,17 +329,7 @@ public class BubbleBarAnimationHelper { return; } // Calculate scale of expanded view so it fits inside the magnetic target float bbevMaxSide = Math.max(bbev.getWidth(), bbev.getHeight()); View targetView = target.getTargetView(); float targetMaxSide = Math.max(targetView.getWidth(), targetView.getHeight()); // Reduce target size to have some padding between the target and expanded view targetMaxSide *= EXPANDED_VIEW_IN_TARGET_SCALE; float scaleInTarget = targetMaxSide / bbevMaxSide; // Scale around the top center of the expanded view. Same as when dragging. bbev.setPivotX(bbev.getWidth() / 2f); bbev.setPivotY(0); setDragPivot(bbev); // When the view animates into the target, it is scaled down with the pivot at center top. // Find the point on the view that would be the center of the view at its final scale. Loading @@ -330,13 +345,13 @@ public class BubbleBarAnimationHelper { // Get scaled width of the view and adjust mTmpLocation so that point on x-axis is at the // center of the view at its current size. float currentWidth = bbev.getWidth() * bbev.getScaleX(); mTmpLocation[0] += currentWidth / 2; mTmpLocation[0] += (int) (currentWidth / 2f); // Since pivotY is at the top of the view, at final scale, top coordinate of the view // remains the same. // Get height of the view at final scale and adjust mTmpLocation so that point on y-axis is // moved down by half of the height at final scale. float targetHeight = bbev.getHeight() * scaleInTarget; mTmpLocation[1] += targetHeight / 2; float targetHeight = bbev.getHeight() * EXPANDED_VIEW_IN_TARGET_SCALE; mTmpLocation[1] += (int) (targetHeight / 2f); // mTmpLocation is now set to the point on the view that will be the center of the view once // scale is applied. Loading @@ -344,41 +359,61 @@ public class BubbleBarAnimationHelper { float xDiff = target.getCenterOnScreen().x - mTmpLocation[0]; float yDiff = target.getCenterOnScreen().y - mTmpLocation[1]; bbev.animate() .translationX(bbev.getTranslationX() + xDiff) .translationY(bbev.getTranslationY() + yDiff) .scaleX(scaleInTarget) .scaleY(scaleInTarget) .setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION) .setInterpolator(Interpolators.EMPHASIZED) .withStartAction(() -> bbev.setAnimating(true)) .withEndAction(() -> { bbev.setAnimating(false); // Corner radius gets scaled, apply the reverse scale to ensure we have the desired radius final float cornerRadius = bbev.getDraggedCornerRadius() / EXPANDED_VIEW_IN_TARGET_SCALE; AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( // Move expanded view to the center of dismiss view ObjectAnimator.ofFloat(bbev, TRANSLATION_X, bbev.getTranslationX() + xDiff), ObjectAnimator.ofFloat(bbev, TRANSLATION_Y, bbev.getTranslationY() + yDiff), // Scale expanded view down ObjectAnimator.ofFloat(bbev, SCALE_X, EXPANDED_VIEW_IN_TARGET_SCALE), ObjectAnimator.ofFloat(bbev, SCALE_Y, EXPANDED_VIEW_IN_TARGET_SCALE), // Update corner radius for expanded view ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, cornerRadius), // Scale dismiss view up ObjectAnimator.ofFloat(target.getTargetView(), SCALE_X, DISMISS_VIEW_SCALE), ObjectAnimator.ofFloat(target.getTargetView(), SCALE_Y, DISMISS_VIEW_SCALE) ); animatorSet.setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION).setInterpolator( EMPHASIZED_DECELERATE); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev) { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (endRunnable != null) { endRunnable.run(); } }) .start(); } }); startNewDragAnimation(animatorSet); } /** * Animate currently expanded view when it is released from dismiss view */ public void animateUnstuckFromDismissView() { BubbleBarExpandedView expandedView = getExpandedView(); if (expandedView == null) { public void animateUnstuckFromDismissView(MagneticTarget target) { BubbleBarExpandedView bbev = getExpandedView(); if (bbev == null) { Log.w(TAG, "Trying to unsnap the expanded view from dismiss without a bubble"); return; } expandedView .animate() .scaleX(EXPANDED_VIEW_DRAG_SCALE) .scaleY(EXPANDED_VIEW_DRAG_SCALE) .setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION) .setInterpolator(Interpolators.EMPHASIZED) .withStartAction(() -> expandedView.setAnimating(true)) .withEndAction(() -> expandedView.setAnimating(false)) .start(); setDragPivot(bbev); // Corner radius gets scaled, apply the reverse scale to ensure we have the desired radius final float cornerRadius = bbev.getDraggedCornerRadius() / EXPANDED_VIEW_DRAG_SCALE; AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( ObjectAnimator.ofFloat(bbev, SCALE_X, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, SCALE_Y, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, cornerRadius), ObjectAnimator.ofFloat(target.getTargetView(), SCALE_X, 1f), ObjectAnimator.ofFloat(target.getTargetView(), SCALE_Y, 1f) ); animatorSet.setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION).setInterpolator( EMPHASIZED_DECELERATE); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev)); startNewDragAnimation(animatorSet); } /** Loading @@ -391,6 +426,10 @@ public class BubbleBarAnimationHelper { if (bbev != null) { bbev.animate().cancel(); } if (mRunningDragAnimator != null) { mRunningDragAnimator.cancel(); mRunningDragAnimator = null; } } private @Nullable BubbleBarExpandedView getExpandedView() { Loading Loading @@ -438,4 +477,35 @@ public class BubbleBarAnimationHelper { final int height = mPositioner.getExpandedViewHeightForBubbleBar(isOverflowExpanded); return new Size(width, height); } private void startNewDragAnimation(Animator animator) { cancelAnimations(); mRunningDragAnimator = animator; animator.start(); } private static void setDragPivot(BubbleBarExpandedView bbev) { bbev.setPivotX(bbev.getWidth() / 2f); bbev.setPivotY(0f); } private class DragAnimatorListenerAdapter extends AnimatorListenerAdapter { private final BubbleBarExpandedView mBubbleBarExpandedView; DragAnimatorListenerAdapter(BubbleBarExpandedView bbev) { mBubbleBarExpandedView = bbev; } @Override public void onAnimationStart(Animator animation) { mBubbleBarExpandedView.setAnimating(true); } @Override public void onAnimationEnd(Animator animation) { mBubbleBarExpandedView.setAnimating(false); mRunningDragAnimator = null; } } } libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +63 −13 Original line number Diff line number Diff line Loading @@ -27,13 +27,13 @@ import android.graphics.Insets; import android.graphics.Outline; import android.graphics.Rect; import android.util.AttributeSet; import android.util.FloatProperty; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.widget.FrameLayout; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubble; import com.android.wm.shell.bubbles.BubbleExpandedViewManager; Loading Loading @@ -61,6 +61,23 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView void onBackPressed(); } /** * A property wrapper around corner radius for the expanded view, handled by * {@link #setCornerRadius(float)} and {@link #getCornerRadius()} methods. */ public static final FloatProperty<BubbleBarExpandedView> CORNER_RADIUS = new FloatProperty<>( "cornerRadius") { @Override public void setValue(BubbleBarExpandedView bbev, float radius) { bbev.setCornerRadius(radius); } @Override public Float get(BubbleBarExpandedView bbev) { return bbev.getCornerRadius(); } }; private static final String TAG = BubbleBarExpandedView.class.getSimpleName(); private static final int INVALID_TASK_ID = -1; Loading @@ -78,7 +95,12 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView private int mCaptionHeight; private int mBackgroundColor; private float mCornerRadius = 0f; /** Corner radius used when view is resting */ private float mRestingCornerRadius = 0f; /** Corner radius applied while dragging */ private float mDraggedCornerRadius = 0f; /** Current corner radius */ private float mCurrentCornerRadius = 0f; /** * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If Loading Loading @@ -118,7 +140,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCornerRadius); outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCurrentCornerRadius); } }); } Loading Loading @@ -155,7 +177,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); addView(mTaskView, lp); mTaskView.setEnableSurfaceClipping(true); mTaskView.setCornerRadius(mCornerRadius); mTaskView.setCornerRadius(mCurrentCornerRadius); mTaskView.setVisibility(VISIBLE); // Handle view needs to draw on top of task view. Loading Loading @@ -198,22 +220,24 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView // TODO (b/275087636): call this when theme/config changes /** Updates the view based on the current theme. */ public void applyThemeAttrs() { boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows( mContext.getResources()); mRestingCornerRadius = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_corner_radius ); mDraggedCornerRadius = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_corner_radius_dragged ); mCurrentCornerRadius = mRestingCornerRadius; final TypedArray ta = mContext.obtainStyledAttributes(new int[]{ android.R.attr.dialogCornerRadius, android.R.attr.colorBackgroundFloating}); mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0; mCornerRadius = mCornerRadius / 2f; mBackgroundColor = ta.getColor(1, Color.WHITE); mBackgroundColor = ta.getColor(0, Color.WHITE); ta.recycle(); mCaptionHeight = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_caption_height); if (mTaskView != null) { mTaskView.setCornerRadius(mCornerRadius); mTaskView.setCornerRadius(mCurrentCornerRadius); updateHandleColor(true /* animated */); } } Loading Loading @@ -396,4 +420,30 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView public boolean isAnimating() { return mIsAnimating; } /** @return corner radius that should be applied while view is in rest */ public float getRestingCornerRadius() { return mRestingCornerRadius; } /** @return corner radius that should be applied while view is being dragged */ public float getDraggedCornerRadius() { return mDraggedCornerRadius; } /** @return current corner radius */ public float getCornerRadius() { return mCurrentCornerRadius; } /** Update corner radius */ public void setCornerRadius(float cornerRadius) { if (mCurrentCornerRadius != cornerRadius) { mCurrentCornerRadius = cornerRadius; if (mTaskView != null) { mTaskView.setCornerRadius(cornerRadius); } invalidateOutline(); } } } libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt +1 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,7 @@ class BubbleBarExpandedViewDragController( wasFlungOut: Boolean ) { isStuckToDismiss = false animationHelper.animateUnstuckFromDismissView() animationHelper.animateUnstuckFromDismissView(target) } override fun onReleasedInTarget( Loading Loading
libs/WindowManager/Shell/res/values/dimen.xml +4 −0 Original line number Diff line number Diff line Loading @@ -266,6 +266,10 @@ <dimen name="bubble_bar_manage_menu_item_height">52dp</dimen> <!-- Size of the icons in the bubble bar manage menu. --> <dimen name="bubble_bar_manage_menu_item_icon_size">20dp</dimen> <!-- Corner radius for expanded view when bubble bar is used --> <dimen name="bubble_bar_expanded_view_corner_radius">16dp</dimen> <!-- Corner radius for expanded view while it is being dragged --> <dimen name="bubble_bar_expanded_view_corner_radius_dragged">28dp</dimen> <!-- Bottom and end margin for compat buttons. --> <dimen name="compat_button_margin">24dp</dimen> Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java +138 −68 Original line number Diff line number Diff line Loading @@ -15,17 +15,28 @@ */ package com.android.wm.shell.bubbles.bar; import static android.view.View.SCALE_X; import static android.view.View.SCALE_Y; import static android.view.View.TRANSLATION_X; import static android.view.View.TRANSLATION_Y; import static android.view.View.VISIBLE; import static android.view.View.X; import static android.view.View.Y; import static com.android.wm.shell.animation.Interpolators.EMPHASIZED; import static com.android.wm.shell.animation.Interpolators.EMPHASIZED_DECELERATE; import static com.android.wm.shell.bubbles.bar.BubbleBarExpandedView.CORNER_RADIUS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.util.Log; import android.util.Size; import android.view.View; import android.widget.FrameLayout; import androidx.annotation.Nullable; Loading @@ -48,15 +59,16 @@ public class BubbleBarAnimationHelper { private static final float EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT = 0.1f; private static final float EXPANDED_VIEW_ANIMATE_OUT_SCALE_AMOUNT = .75f; private static final int EXPANDED_VIEW_ALPHA_ANIMATION_DURATION = 150; private static final int EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION = 100; private static final int EXPANDED_VIEW_ANIMATE_POSITION_DURATION = 300; private static final int EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION = 400; private static final int EXPANDED_VIEW_ANIMATE_TO_REST_DURATION = 400; private static final int EXPANDED_VIEW_DISMISS_DURATION = 250; private static final int EXPANDED_VIEW_DRAG_ANIMATION_DURATION = 150; private static final int EXPANDED_VIEW_DRAG_ANIMATION_DURATION = 400; /** * Additional scale applied to expanded view when it is positioned inside a magnetic target. */ private static final float EXPANDED_VIEW_IN_TARGET_SCALE = 0.6f; private static final float EXPANDED_VIEW_DRAG_SCALE = 0.5f; private static final float EXPANDED_VIEW_IN_TARGET_SCALE = 0.2f; private static final float EXPANDED_VIEW_DRAG_SCALE = 0.4f; private static final float DISMISS_VIEW_SCALE = 1.25f; /** Spring config for the expanded view scale-in animation. */ private final PhysicsAnimator.SpringConfig mScaleInSpringConfig = Loading @@ -72,6 +84,9 @@ public class BubbleBarAnimationHelper { /** Animator for animating the expanded view's alpha (including the TaskView inside it). */ private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); @Nullable private Animator mRunningDragAnimator; private final Context mContext; private final BubbleBarLayerView mLayerView; private final BubblePositioner mPositioner; Loading Loading @@ -232,14 +247,18 @@ public class BubbleBarAnimationHelper { Log.w(TAG, "Trying to animate start drag without a bubble"); return; } bbev.setPivotX(bbev.getWidth() / 2f); bbev.setPivotY(0f); bbev.animate() .scaleX(EXPANDED_VIEW_DRAG_SCALE) .scaleY(EXPANDED_VIEW_DRAG_SCALE) .setInterpolator(Interpolators.EMPHASIZED) .setDuration(EXPANDED_VIEW_DRAG_ANIMATION_DURATION) .start(); setDragPivot(bbev); AnimatorSet animatorSet = new AnimatorSet(); // Corner radius gets scaled, apply the reverse scale to ensure we have the desired radius final float cornerRadius = bbev.getDraggedCornerRadius() / EXPANDED_VIEW_DRAG_SCALE; animatorSet.playTogether( ObjectAnimator.ofFloat(bbev, SCALE_X, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, SCALE_Y, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, cornerRadius) ); animatorSet.setDuration(EXPANDED_VIEW_DRAG_ANIMATION_DURATION).setInterpolator(EMPHASIZED); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev)); startNewDragAnimation(animatorSet); } /** Loading @@ -258,6 +277,7 @@ public class BubbleBarAnimationHelper { int[] location = bbev.getLocationOnScreen(); int diffFromBottom = mPositioner.getScreenRect().bottom - location[1]; cancelAnimations(); bbev.animate() // 2x distance from bottom so the view flies out .translationYBy(diffFromBottom * 2) Loading @@ -276,19 +296,24 @@ public class BubbleBarAnimationHelper { return; } Point restPoint = getExpandedViewRestPosition(getExpandedViewSize()); bbev.animate() .x(restPoint.x) .y(restPoint.y) .scaleX(1f) .scaleY(1f) .setDuration(EXPANDED_VIEW_ANIMATE_POSITION_DURATION) .setInterpolator(Interpolators.EMPHASIZED_DECELERATE) .withStartAction(() -> bbev.setAnimating(true)) .withEndAction(() -> { bbev.setAnimating(false); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( ObjectAnimator.ofFloat(bbev, X, restPoint.x), ObjectAnimator.ofFloat(bbev, Y, restPoint.y), ObjectAnimator.ofFloat(bbev, SCALE_X, 1f), ObjectAnimator.ofFloat(bbev, SCALE_Y, 1f), ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, bbev.getRestingCornerRadius()) ); animatorSet.setDuration(EXPANDED_VIEW_ANIMATE_TO_REST_DURATION).setInterpolator(EMPHASIZED); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev) { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); bbev.resetPivot(); }) .start(); } }); startNewDragAnimation(animatorSet); } /** Loading @@ -304,17 +329,7 @@ public class BubbleBarAnimationHelper { return; } // Calculate scale of expanded view so it fits inside the magnetic target float bbevMaxSide = Math.max(bbev.getWidth(), bbev.getHeight()); View targetView = target.getTargetView(); float targetMaxSide = Math.max(targetView.getWidth(), targetView.getHeight()); // Reduce target size to have some padding between the target and expanded view targetMaxSide *= EXPANDED_VIEW_IN_TARGET_SCALE; float scaleInTarget = targetMaxSide / bbevMaxSide; // Scale around the top center of the expanded view. Same as when dragging. bbev.setPivotX(bbev.getWidth() / 2f); bbev.setPivotY(0); setDragPivot(bbev); // When the view animates into the target, it is scaled down with the pivot at center top. // Find the point on the view that would be the center of the view at its final scale. Loading @@ -330,13 +345,13 @@ public class BubbleBarAnimationHelper { // Get scaled width of the view and adjust mTmpLocation so that point on x-axis is at the // center of the view at its current size. float currentWidth = bbev.getWidth() * bbev.getScaleX(); mTmpLocation[0] += currentWidth / 2; mTmpLocation[0] += (int) (currentWidth / 2f); // Since pivotY is at the top of the view, at final scale, top coordinate of the view // remains the same. // Get height of the view at final scale and adjust mTmpLocation so that point on y-axis is // moved down by half of the height at final scale. float targetHeight = bbev.getHeight() * scaleInTarget; mTmpLocation[1] += targetHeight / 2; float targetHeight = bbev.getHeight() * EXPANDED_VIEW_IN_TARGET_SCALE; mTmpLocation[1] += (int) (targetHeight / 2f); // mTmpLocation is now set to the point on the view that will be the center of the view once // scale is applied. Loading @@ -344,41 +359,61 @@ public class BubbleBarAnimationHelper { float xDiff = target.getCenterOnScreen().x - mTmpLocation[0]; float yDiff = target.getCenterOnScreen().y - mTmpLocation[1]; bbev.animate() .translationX(bbev.getTranslationX() + xDiff) .translationY(bbev.getTranslationY() + yDiff) .scaleX(scaleInTarget) .scaleY(scaleInTarget) .setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION) .setInterpolator(Interpolators.EMPHASIZED) .withStartAction(() -> bbev.setAnimating(true)) .withEndAction(() -> { bbev.setAnimating(false); // Corner radius gets scaled, apply the reverse scale to ensure we have the desired radius final float cornerRadius = bbev.getDraggedCornerRadius() / EXPANDED_VIEW_IN_TARGET_SCALE; AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( // Move expanded view to the center of dismiss view ObjectAnimator.ofFloat(bbev, TRANSLATION_X, bbev.getTranslationX() + xDiff), ObjectAnimator.ofFloat(bbev, TRANSLATION_Y, bbev.getTranslationY() + yDiff), // Scale expanded view down ObjectAnimator.ofFloat(bbev, SCALE_X, EXPANDED_VIEW_IN_TARGET_SCALE), ObjectAnimator.ofFloat(bbev, SCALE_Y, EXPANDED_VIEW_IN_TARGET_SCALE), // Update corner radius for expanded view ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, cornerRadius), // Scale dismiss view up ObjectAnimator.ofFloat(target.getTargetView(), SCALE_X, DISMISS_VIEW_SCALE), ObjectAnimator.ofFloat(target.getTargetView(), SCALE_Y, DISMISS_VIEW_SCALE) ); animatorSet.setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION).setInterpolator( EMPHASIZED_DECELERATE); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev) { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (endRunnable != null) { endRunnable.run(); } }) .start(); } }); startNewDragAnimation(animatorSet); } /** * Animate currently expanded view when it is released from dismiss view */ public void animateUnstuckFromDismissView() { BubbleBarExpandedView expandedView = getExpandedView(); if (expandedView == null) { public void animateUnstuckFromDismissView(MagneticTarget target) { BubbleBarExpandedView bbev = getExpandedView(); if (bbev == null) { Log.w(TAG, "Trying to unsnap the expanded view from dismiss without a bubble"); return; } expandedView .animate() .scaleX(EXPANDED_VIEW_DRAG_SCALE) .scaleY(EXPANDED_VIEW_DRAG_SCALE) .setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION) .setInterpolator(Interpolators.EMPHASIZED) .withStartAction(() -> expandedView.setAnimating(true)) .withEndAction(() -> expandedView.setAnimating(false)) .start(); setDragPivot(bbev); // Corner radius gets scaled, apply the reverse scale to ensure we have the desired radius final float cornerRadius = bbev.getDraggedCornerRadius() / EXPANDED_VIEW_DRAG_SCALE; AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( ObjectAnimator.ofFloat(bbev, SCALE_X, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, SCALE_Y, EXPANDED_VIEW_DRAG_SCALE), ObjectAnimator.ofFloat(bbev, CORNER_RADIUS, cornerRadius), ObjectAnimator.ofFloat(target.getTargetView(), SCALE_X, 1f), ObjectAnimator.ofFloat(target.getTargetView(), SCALE_Y, 1f) ); animatorSet.setDuration(EXPANDED_VIEW_SNAP_TO_DISMISS_DURATION).setInterpolator( EMPHASIZED_DECELERATE); animatorSet.addListener(new DragAnimatorListenerAdapter(bbev)); startNewDragAnimation(animatorSet); } /** Loading @@ -391,6 +426,10 @@ public class BubbleBarAnimationHelper { if (bbev != null) { bbev.animate().cancel(); } if (mRunningDragAnimator != null) { mRunningDragAnimator.cancel(); mRunningDragAnimator = null; } } private @Nullable BubbleBarExpandedView getExpandedView() { Loading Loading @@ -438,4 +477,35 @@ public class BubbleBarAnimationHelper { final int height = mPositioner.getExpandedViewHeightForBubbleBar(isOverflowExpanded); return new Size(width, height); } private void startNewDragAnimation(Animator animator) { cancelAnimations(); mRunningDragAnimator = animator; animator.start(); } private static void setDragPivot(BubbleBarExpandedView bbev) { bbev.setPivotX(bbev.getWidth() / 2f); bbev.setPivotY(0f); } private class DragAnimatorListenerAdapter extends AnimatorListenerAdapter { private final BubbleBarExpandedView mBubbleBarExpandedView; DragAnimatorListenerAdapter(BubbleBarExpandedView bbev) { mBubbleBarExpandedView = bbev; } @Override public void onAnimationStart(Animator animation) { mBubbleBarExpandedView.setAnimating(true); } @Override public void onAnimationEnd(Animator animation) { mBubbleBarExpandedView.setAnimating(false); mRunningDragAnimator = null; } } }
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedView.java +63 −13 Original line number Diff line number Diff line Loading @@ -27,13 +27,13 @@ import android.graphics.Insets; import android.graphics.Outline; import android.graphics.Rect; import android.util.AttributeSet; import android.util.FloatProperty; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.widget.FrameLayout; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubble; import com.android.wm.shell.bubbles.BubbleExpandedViewManager; Loading Loading @@ -61,6 +61,23 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView void onBackPressed(); } /** * A property wrapper around corner radius for the expanded view, handled by * {@link #setCornerRadius(float)} and {@link #getCornerRadius()} methods. */ public static final FloatProperty<BubbleBarExpandedView> CORNER_RADIUS = new FloatProperty<>( "cornerRadius") { @Override public void setValue(BubbleBarExpandedView bbev, float radius) { bbev.setCornerRadius(radius); } @Override public Float get(BubbleBarExpandedView bbev) { return bbev.getCornerRadius(); } }; private static final String TAG = BubbleBarExpandedView.class.getSimpleName(); private static final int INVALID_TASK_ID = -1; Loading @@ -78,7 +95,12 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView private int mCaptionHeight; private int mBackgroundColor; private float mCornerRadius = 0f; /** Corner radius used when view is resting */ private float mRestingCornerRadius = 0f; /** Corner radius applied while dragging */ private float mDraggedCornerRadius = 0f; /** Current corner radius */ private float mCurrentCornerRadius = 0f; /** * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If Loading Loading @@ -118,7 +140,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCornerRadius); outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCurrentCornerRadius); } }); } Loading Loading @@ -155,7 +177,7 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); addView(mTaskView, lp); mTaskView.setEnableSurfaceClipping(true); mTaskView.setCornerRadius(mCornerRadius); mTaskView.setCornerRadius(mCurrentCornerRadius); mTaskView.setVisibility(VISIBLE); // Handle view needs to draw on top of task view. Loading Loading @@ -198,22 +220,24 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView // TODO (b/275087636): call this when theme/config changes /** Updates the view based on the current theme. */ public void applyThemeAttrs() { boolean supportsRoundedCorners = ScreenDecorationsUtils.supportsRoundedCornersOnWindows( mContext.getResources()); mRestingCornerRadius = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_corner_radius ); mDraggedCornerRadius = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_corner_radius_dragged ); mCurrentCornerRadius = mRestingCornerRadius; final TypedArray ta = mContext.obtainStyledAttributes(new int[]{ android.R.attr.dialogCornerRadius, android.R.attr.colorBackgroundFloating}); mCornerRadius = supportsRoundedCorners ? ta.getDimensionPixelSize(0, 0) : 0; mCornerRadius = mCornerRadius / 2f; mBackgroundColor = ta.getColor(1, Color.WHITE); mBackgroundColor = ta.getColor(0, Color.WHITE); ta.recycle(); mCaptionHeight = getResources().getDimensionPixelSize( R.dimen.bubble_bar_expanded_view_caption_height); if (mTaskView != null) { mTaskView.setCornerRadius(mCornerRadius); mTaskView.setCornerRadius(mCurrentCornerRadius); updateHandleColor(true /* animated */); } } Loading Loading @@ -396,4 +420,30 @@ public class BubbleBarExpandedView extends FrameLayout implements BubbleTaskView public boolean isAnimating() { return mIsAnimating; } /** @return corner radius that should be applied while view is in rest */ public float getRestingCornerRadius() { return mRestingCornerRadius; } /** @return corner radius that should be applied while view is being dragged */ public float getDraggedCornerRadius() { return mDraggedCornerRadius; } /** @return current corner radius */ public float getCornerRadius() { return mCurrentCornerRadius; } /** Update corner radius */ public void setCornerRadius(float cornerRadius) { if (mCurrentCornerRadius != cornerRadius) { mCurrentCornerRadius = cornerRadius; if (mTaskView != null) { mTaskView.setCornerRadius(cornerRadius); } invalidateOutline(); } } }
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt +1 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,7 @@ class BubbleBarExpandedViewDragController( wasFlungOut: Boolean ) { isStuckToDismiss = false animationHelper.animateUnstuckFromDismissView() animationHelper.animateUnstuckFromDismissView(target) } override fun onReleasedInTarget( Loading