Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +9 −1 Original line number Diff line number Diff line Loading @@ -398,6 +398,14 @@ public class Bubble implements BubbleViewProvider { } } @Override public void setExpandedContentAlpha(float alpha) { if (mExpandedView != null) { mExpandedView.setAlpha(alpha); mExpandedView.setTaskViewAlpha(alpha); } } /** * Set visibility of bubble in the expanded state. * Loading @@ -407,7 +415,7 @@ public class Bubble implements BubbleViewProvider { * and setting {@code false} actually means rendering the expanded view in transparent. */ @Override public void setContentVisibility(boolean visibility) { public void setTaskViewVisibility(boolean visibility) { if (mExpandedView != null) { mExpandedView.setContentVisibility(visibility); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +41 −2 Original line number Diff line number Diff line Loading @@ -85,6 +85,19 @@ public class BubbleExpandedView extends LinearLayout { private boolean mImeVisible; private boolean mNeedsNewHeight; /** * Whether we want the TaskView's content to be visible (alpha = 1f). If * {@link #mIsAlphaAnimating} is true, this may not reflect the TaskView's actual alpha value * until the animation ends. */ private boolean mIsContentVisible = false; /** * Whether we're animating the TaskView's alpha value. If so, we will hold off on applying alpha * changes from {@link #setContentVisibility} until the animation ends. */ private boolean mIsAlphaAnimating = false; private int mMinHeight; private int mOverflowHeight; private int mSettingsIconHeight; Loading Loading @@ -464,6 +477,29 @@ public class BubbleExpandedView extends LinearLayout { } } /** * Whether we are currently animating the TaskView's alpha value. If this is set to true, calls * to {@link #setContentVisibility} will not be applied until this is set to false again. */ void setAlphaAnimating(boolean animating) { mIsAlphaAnimating = animating; // If we're done animating, apply the correct if (!animating) { setContentVisibility(mIsContentVisible); } } /** * Sets the alpha of the underlying TaskView, since changing the expanded view's alpha does not * affect the TaskView since it uses a Surface. */ void setTaskViewAlpha(float alpha) { if (mTaskView != null) { mTaskView.setAlpha(alpha); } } /** * Set visibility of contents in the expanded state. * Loading @@ -477,16 +513,19 @@ public class BubbleExpandedView extends LinearLayout { Log.d(TAG, "setContentVisibility: visibility=" + visibility + " bubble=" + getBubbleKey()); } mIsContentVisible = visibility; final float alpha = visibility ? 1f : 0f; mPointerView.setAlpha(alpha); if (mTaskView != null) { if (mTaskView != null && !mIsAlphaAnimating) { mTaskView.setAlpha(alpha); } } @Nullable View getTaskView() { TaskView getTaskView() { return mTaskView; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt +6 −2 Original line number Diff line number Diff line Loading @@ -167,8 +167,12 @@ class BubbleOverflow( return dotPath } override fun setContentVisibility(visible: Boolean) { expandedView?.setContentVisibility(visible) override fun setExpandedContentAlpha(alpha: Float) { expandedView?.alpha = alpha } override fun setTaskViewVisibility(visible: Boolean) { // Overflow does not have a TaskView. } override fun getIconView(): BadgedImageView? { Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +176 −59 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.os.Bundle; import android.os.Handler; import android.provider.Settings; import android.util.Log; import android.view.Choreographer; Loading Loading @@ -123,6 +122,10 @@ public class BubbleStackView extends FrameLayout @VisibleForTesting static final int FLYOUT_HIDE_AFTER = 5000; private static final float EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT = 0.1f; private static final int EXPANDED_VIEW_ALPHA_ANIMATION_DURATION = 150; /** * How long to wait to animate the stack temporarily invisible after a drag/flyout hide * animation ends, if we are in fact temporarily invisible. Loading @@ -142,7 +145,7 @@ public class BubbleStackView extends FrameLayout private final PhysicsAnimator.SpringConfig mTranslateSpringConfig = new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY); SpringForce.STIFFNESS_VERY_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY); /** * Handler to use for all delayed animations - this way, we can easily cancel them before Loading Loading @@ -211,6 +214,9 @@ public class BubbleStackView extends FrameLayout /** Container for the animating-out SurfaceView. */ private FrameLayout mAnimatingOutSurfaceContainer; /** Animator for animating the alpha value of the animating out SurfaceView. */ private final ValueAnimator mAnimatingOutSurfaceAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); /** * Buffer containing a screenshot of the animating-out bubble. This is drawn into the * SurfaceView during animations. Loading Loading @@ -261,6 +267,12 @@ public class BubbleStackView extends FrameLayout /** Whether we're in the middle of dragging the stack around by touch. */ private boolean mIsDraggingStack = false; /** Whether the expanded view has been hidden, because we are dragging out a bubble. */ private boolean mExpandedViewHidden = false; /** Animator for animating the expanded view's alpha (including the TaskView inside it). */ private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); /** * The pointer index of the ACTION_DOWN event we received prior to an ACTION_UP. We'll ignore * touches from other pointer indices. Loading Loading @@ -614,6 +626,12 @@ public class BubbleStackView extends FrameLayout // Show the dismiss target, if we haven't already. mDismissView.show(); if (mIsExpanded && mExpandedBubble != null && v.equals(mExpandedBubble.getIconView())) { // Hide the expanded view if we're dragging out the expanded bubble, and we haven't // already hidden it. hideExpandedViewIfNeeded(); } // First, see if the magnetized object consumes the event - if so, we shouldn't move the // bubble since it's stuck to the target. if (!passEventToMagnetizedObject(ev)) { Loading Loading @@ -645,6 +663,9 @@ public class BubbleStackView extends FrameLayout if (!passEventToMagnetizedObject(ev)) { if (mBubbleData.isExpanded()) { mExpandedAnimationController.snapBubbleBack(v, velX, velY); // Re-show the expanded view if we hid it. showExpandedViewIfNeeded(); } else { // Fling the stack to the edge, and save whether or not it's going to end up on // the left side of the screen. Loading Loading @@ -937,6 +958,46 @@ public class BubbleStackView extends FrameLayout animate() .setInterpolator(Interpolators.PANEL_CLOSE_ACCELERATED) .setDuration(FADE_IN_DURATION); mExpandedViewAlphaAnimator.setDuration(EXPANDED_VIEW_ALPHA_ANIMATION_DURATION); mExpandedViewAlphaAnimator.setInterpolator(Interpolators.PANEL_CLOSE_ACCELERATED); mExpandedViewAlphaAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { // We need to be Z ordered on top in order for alpha animations to work. mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(true); mExpandedBubble.getExpandedView().setAlphaAnimating(true); } } @Override public void onAnimationEnd(Animator animation) { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); mExpandedBubble.getExpandedView().setAlphaAnimating(false); } } }); mExpandedViewAlphaAnimator.addUpdateListener(valueAnimator -> { if (mExpandedBubble != null) { mExpandedBubble.setExpandedContentAlpha((float) valueAnimator.getAnimatedValue()); } }); mAnimatingOutSurfaceAlphaAnimator.setDuration(EXPANDED_VIEW_ALPHA_ANIMATION_DURATION); mAnimatingOutSurfaceAlphaAnimator.setInterpolator(Interpolators.PANEL_CLOSE_ACCELERATED); mAnimatingOutSurfaceAlphaAnimator.addUpdateListener(valueAnimator -> { if (!mExpandedViewHidden) { mAnimatingOutSurfaceView.setAlpha((float) valueAnimator.getAnimatedValue()); } }); mAnimatingOutSurfaceAlphaAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { releaseAnimatingOutBubbleBuffer(); } }); } /** Loading Loading @@ -1539,7 +1600,8 @@ public class BubbleStackView extends FrameLayout // If we're expanded, screenshot the currently expanded bubble (before expanding the newly // selected bubble) so we can animate it out. if (mIsExpanded && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { if (mIsExpanded && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null && !mExpandedViewHidden) { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { // Before screenshotting, have the real ActivityView show on top of other surfaces // so that the screenshot doesn't flicker on top of it. Loading Loading @@ -1575,7 +1637,7 @@ public class BubbleStackView extends FrameLayout mExpandedViewContainer.setAlpha(0.0f); mSurfaceSynchronizer.syncSurfaceAndRun(() -> { if (previouslySelected != null) { previouslySelected.setContentVisibility(false); previouslySelected.setTaskViewVisibility(false); } updateExpandedBubble(); Loading Loading @@ -1656,6 +1718,58 @@ public class BubbleStackView extends FrameLayout requestUpdate(); } /** Animate the expanded view hidden. This is done while we're dragging out a bubble. */ private void hideExpandedViewIfNeeded() { if (mExpandedViewHidden || mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) { return; } mExpandedViewHidden = true; // Scale down. PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .addUpdateListener((target, values) -> mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix)) .start(); // Animate alpha from 1f to 0f. mExpandedViewAlphaAnimator.reverse(); } /** * Animate the expanded view visible again. This is done when we're done dragging out a bubble. */ private void showExpandedViewIfNeeded() { if (!mExpandedViewHidden) { return; } mExpandedViewHidden = false; PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), mScaleOutSpringConfig) .addUpdateListener((target, values) -> mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix)) .start(); mExpandedViewAlphaAnimator.start(); } private void animateExpansion() { cancelDelayedExpandCollapseSwitchAnimations(); final boolean showVertically = mPositioner.showBubblesVertically(); Loading Loading @@ -1714,7 +1828,7 @@ public class BubbleStackView extends FrameLayout // Should not happen since we lay out before expanding, but just in case... if (getWidth() > 0) { startDelay = (long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 1.2f + (distanceAnimated / getWidth()) * 30); } Loading @@ -1728,20 +1842,29 @@ public class BubbleStackView extends FrameLayout pivotX = mPositioner.getAvailableRect().right - mBubbleSize - mExpandedViewPadding; } mExpandedViewContainerMatrix.setScale( 0f, 0f, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, pivotX, pivotY); } else { mExpandedViewContainerMatrix.setScale( 0f, 0f, bubbleWillBeAt + mBubbleSize / 2f, getExpandedViewY()); 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, bubbleWillBeAt + mBubbleSize / 2f, getExpandedViewY()); } mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); if (mExpandedBubble.getExpandedView() != null) { mExpandedBubble.setExpandedContentAlpha(0f); // We'll be starting the alpha animation after a slight delay, so set this flag early // here. mExpandedBubble.getExpandedView().setAlphaAnimating(true); } mDelayedAnimationExecutor.executeDelayed(() -> { mExpandedViewAlphaAnimator.start(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, Loading Loading @@ -1796,22 +1919,15 @@ public class BubbleStackView extends FrameLayout // since we're about to animate collapsed. mExpandedAnimationController.notifyPreparingToCollapse(); final long startDelay = (long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f); mDelayedAnimationExecutor.executeDelayed(() -> { mExpandedAnimationController.collapseBackToStack( mStackAnimationController.getStackPositionAlongNearestHorizontalEdge() /* collapseTo */, () -> mBubbleContainer.setActiveController(mStackAnimationController)); }, startDelay); if (mTaskbarScrim.getVisibility() == VISIBLE) { mTaskbarScrim.animate().alpha(0f).start(); } // We want to visually collapse into this bubble during the animation. final View expandingFromBubble = mExpandedBubble.getIconView(); int index; if (mExpandedBubble != null && BubbleOverflow.KEY.equals(mExpandedBubble.getKey())) { index = mBubbleData.getBubbles().size(); Loading Loading @@ -1840,31 +1956,25 @@ public class BubbleStackView extends FrameLayout getExpandedViewY()); } mExpandedViewAlphaAnimator.reverse(); // When the animation completes, we should no longer be showing the content. if (mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setContentVisibility(false); } PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, 0f, mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, 0f, mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .addUpdateListener((target, values) -> { if (expandingFromBubble != null) { // Follow the bubble as it translates! if (showVertically) { mExpandedViewContainerMatrix.postTranslate( 0f, expandingFromBubble.getTranslationY() - expandingFromBubbleAt); } else { mExpandedViewContainerMatrix.postTranslate( expandingFromBubble.getTranslationX() - expandingFromBubbleAt, 0f); } } mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); // Hide early so we don't have a tiny little expanded view still visible at the // end of the scale animation. if (mExpandedViewContainerMatrix.getScaleX() < 0.05f) { mExpandedViewContainer.setVisibility(View.INVISIBLE); } }) .withEndActions(() -> { final BubbleViewProvider previouslySelected = mExpandedBubble; Loading @@ -1882,7 +1992,7 @@ public class BubbleStackView extends FrameLayout updateBadgesAndZOrder(true /* setBadgeForCollapsedStack */); afterExpandedViewAnimation(); if (previouslySelected != null) { previouslySelected.setContentVisibility(false); previouslySelected.setTaskViewVisibility(false); } if (mPositioner.showingInTaskbar()) { Loading @@ -1903,22 +2013,21 @@ public class BubbleStackView extends FrameLayout // The surface contains a screenshot of the animating out bubble, so we just need to animate // it out (and then release the GraphicBuffer). PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel(); PhysicsAnimator animator = PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer) .spring(DynamicAnimation.SCALE_X, 0f, mScaleOutSpringConfig) .spring(DynamicAnimation.SCALE_Y, 0f, mScaleOutSpringConfig) .withEndActions(this::releaseAnimatingOutBubbleBuffer); mAnimatingOutSurfaceAlphaAnimator.reverse(); mExpandedViewAlphaAnimator.start(); if (mPositioner.showBubblesVertically()) { float translationX = mStackAnimationController.isStackOnLeftSide() ? mAnimatingOutSurfaceContainer.getTranslationX() + mBubbleSize * 2 : mAnimatingOutSurfaceContainer.getTranslationX(); animator.spring(DynamicAnimation.TRANSLATION_X, translationX, mTranslateSpringConfig) PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer) .spring(DynamicAnimation.TRANSLATION_X, translationX, mTranslateSpringConfig) .start(); } else { animator.spring(DynamicAnimation.TRANSLATION_Y, mAnimatingOutSurfaceContainer.getTranslationY() - mBubbleSize * 2, PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer) .spring(DynamicAnimation.TRANSLATION_Y, mAnimatingOutSurfaceContainer.getTranslationY() - mBubbleSize, mTranslateSpringConfig) .start(); } Loading Loading @@ -1947,7 +2056,8 @@ public class BubbleStackView extends FrameLayout pivotX, pivotY); } else { mExpandedViewContainerMatrix.setScale( 0f, 0f, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, expandingFromBubbleDestination + mBubbleSize / 2f, getExpandedViewY()); } Loading @@ -1972,10 +2082,7 @@ public class BubbleStackView extends FrameLayout mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); }) .withEndActions(() -> { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); } mExpandedViewHidden = false; mIsBubbleSwitchAnimating = false; }) .start(); Loading Loading @@ -2489,6 +2596,7 @@ public class BubbleStackView extends FrameLayout && mExpandedBubble.getExpandedView() != null) { BubbleExpandedView bev = mExpandedBubble.getExpandedView(); bev.setContentVisibility(false); bev.setAlphaAnimating(!mIsExpansionAnimating); mExpandedViewContainerMatrix.setScaleX(0f); mExpandedViewContainerMatrix.setScaleY(0f); mExpandedViewContainerMatrix.setTranslate(0f, 0f); Loading Loading @@ -2586,7 +2694,14 @@ public class BubbleStackView extends FrameLayout mAnimatingOutBubbleBuffer.getHardwareBuffer(), mAnimatingOutBubbleBuffer.getColorSpace()); mSurfaceSynchronizer.syncSurfaceAndRun(() -> post(() -> onComplete.accept(true))); mAnimatingOutSurfaceView.setAlpha(1f); mExpandedViewContainer.setVisibility(View.GONE); mSurfaceSynchronizer.syncSurfaceAndRun(() -> { post(() -> { onComplete.accept(true); }); }); }); } Loading Loading @@ -2618,7 +2733,9 @@ public class BubbleStackView extends FrameLayout } } mExpandedViewContainer.setPadding(leftPadding, 0, rightPadding, 0); if (mIsExpansionAnimating) { mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE); } if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedViewContainer.setTranslationY(getExpandedViewY()); mExpandedViewContainer.setTranslationX(0f); Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java +10 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,16 @@ import androidx.annotation.Nullable; public interface BubbleViewProvider { @Nullable BubbleExpandedView getExpandedView(); void setContentVisibility(boolean visible); /** * Sets the alpha of the expanded view content. This will be applied to both the expanded view * container itself (the manage button, etc.) as well as the TaskView within it. */ void setExpandedContentAlpha(float alpha); /** * Sets whether the contents of the bubble's TaskView should be visible. */ void setTaskViewVisibility(boolean visible); @Nullable View getIconView(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +9 −1 Original line number Diff line number Diff line Loading @@ -398,6 +398,14 @@ public class Bubble implements BubbleViewProvider { } } @Override public void setExpandedContentAlpha(float alpha) { if (mExpandedView != null) { mExpandedView.setAlpha(alpha); mExpandedView.setTaskViewAlpha(alpha); } } /** * Set visibility of bubble in the expanded state. * Loading @@ -407,7 +415,7 @@ public class Bubble implements BubbleViewProvider { * and setting {@code false} actually means rendering the expanded view in transparent. */ @Override public void setContentVisibility(boolean visibility) { public void setTaskViewVisibility(boolean visibility) { if (mExpandedView != null) { mExpandedView.setContentVisibility(visibility); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +41 −2 Original line number Diff line number Diff line Loading @@ -85,6 +85,19 @@ public class BubbleExpandedView extends LinearLayout { private boolean mImeVisible; private boolean mNeedsNewHeight; /** * Whether we want the TaskView's content to be visible (alpha = 1f). If * {@link #mIsAlphaAnimating} is true, this may not reflect the TaskView's actual alpha value * until the animation ends. */ private boolean mIsContentVisible = false; /** * Whether we're animating the TaskView's alpha value. If so, we will hold off on applying alpha * changes from {@link #setContentVisibility} until the animation ends. */ private boolean mIsAlphaAnimating = false; private int mMinHeight; private int mOverflowHeight; private int mSettingsIconHeight; Loading Loading @@ -464,6 +477,29 @@ public class BubbleExpandedView extends LinearLayout { } } /** * Whether we are currently animating the TaskView's alpha value. If this is set to true, calls * to {@link #setContentVisibility} will not be applied until this is set to false again. */ void setAlphaAnimating(boolean animating) { mIsAlphaAnimating = animating; // If we're done animating, apply the correct if (!animating) { setContentVisibility(mIsContentVisible); } } /** * Sets the alpha of the underlying TaskView, since changing the expanded view's alpha does not * affect the TaskView since it uses a Surface. */ void setTaskViewAlpha(float alpha) { if (mTaskView != null) { mTaskView.setAlpha(alpha); } } /** * Set visibility of contents in the expanded state. * Loading @@ -477,16 +513,19 @@ public class BubbleExpandedView extends LinearLayout { Log.d(TAG, "setContentVisibility: visibility=" + visibility + " bubble=" + getBubbleKey()); } mIsContentVisible = visibility; final float alpha = visibility ? 1f : 0f; mPointerView.setAlpha(alpha); if (mTaskView != null) { if (mTaskView != null && !mIsAlphaAnimating) { mTaskView.setAlpha(alpha); } } @Nullable View getTaskView() { TaskView getTaskView() { return mTaskView; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt +6 −2 Original line number Diff line number Diff line Loading @@ -167,8 +167,12 @@ class BubbleOverflow( return dotPath } override fun setContentVisibility(visible: Boolean) { expandedView?.setContentVisibility(visible) override fun setExpandedContentAlpha(alpha: Float) { expandedView?.alpha = alpha } override fun setTaskViewVisibility(visible: Boolean) { // Overflow does not have a TaskView. } override fun getIconView(): BadgedImageView? { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +176 −59 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.os.Bundle; import android.os.Handler; import android.provider.Settings; import android.util.Log; import android.view.Choreographer; Loading Loading @@ -123,6 +122,10 @@ public class BubbleStackView extends FrameLayout @VisibleForTesting static final int FLYOUT_HIDE_AFTER = 5000; private static final float EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT = 0.1f; private static final int EXPANDED_VIEW_ALPHA_ANIMATION_DURATION = 150; /** * How long to wait to animate the stack temporarily invisible after a drag/flyout hide * animation ends, if we are in fact temporarily invisible. Loading @@ -142,7 +145,7 @@ public class BubbleStackView extends FrameLayout private final PhysicsAnimator.SpringConfig mTranslateSpringConfig = new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY); SpringForce.STIFFNESS_VERY_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY); /** * Handler to use for all delayed animations - this way, we can easily cancel them before Loading Loading @@ -211,6 +214,9 @@ public class BubbleStackView extends FrameLayout /** Container for the animating-out SurfaceView. */ private FrameLayout mAnimatingOutSurfaceContainer; /** Animator for animating the alpha value of the animating out SurfaceView. */ private final ValueAnimator mAnimatingOutSurfaceAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); /** * Buffer containing a screenshot of the animating-out bubble. This is drawn into the * SurfaceView during animations. Loading Loading @@ -261,6 +267,12 @@ public class BubbleStackView extends FrameLayout /** Whether we're in the middle of dragging the stack around by touch. */ private boolean mIsDraggingStack = false; /** Whether the expanded view has been hidden, because we are dragging out a bubble. */ private boolean mExpandedViewHidden = false; /** Animator for animating the expanded view's alpha (including the TaskView inside it). */ private final ValueAnimator mExpandedViewAlphaAnimator = ValueAnimator.ofFloat(0f, 1f); /** * The pointer index of the ACTION_DOWN event we received prior to an ACTION_UP. We'll ignore * touches from other pointer indices. Loading Loading @@ -614,6 +626,12 @@ public class BubbleStackView extends FrameLayout // Show the dismiss target, if we haven't already. mDismissView.show(); if (mIsExpanded && mExpandedBubble != null && v.equals(mExpandedBubble.getIconView())) { // Hide the expanded view if we're dragging out the expanded bubble, and we haven't // already hidden it. hideExpandedViewIfNeeded(); } // First, see if the magnetized object consumes the event - if so, we shouldn't move the // bubble since it's stuck to the target. if (!passEventToMagnetizedObject(ev)) { Loading Loading @@ -645,6 +663,9 @@ public class BubbleStackView extends FrameLayout if (!passEventToMagnetizedObject(ev)) { if (mBubbleData.isExpanded()) { mExpandedAnimationController.snapBubbleBack(v, velX, velY); // Re-show the expanded view if we hid it. showExpandedViewIfNeeded(); } else { // Fling the stack to the edge, and save whether or not it's going to end up on // the left side of the screen. Loading Loading @@ -937,6 +958,46 @@ public class BubbleStackView extends FrameLayout animate() .setInterpolator(Interpolators.PANEL_CLOSE_ACCELERATED) .setDuration(FADE_IN_DURATION); mExpandedViewAlphaAnimator.setDuration(EXPANDED_VIEW_ALPHA_ANIMATION_DURATION); mExpandedViewAlphaAnimator.setInterpolator(Interpolators.PANEL_CLOSE_ACCELERATED); mExpandedViewAlphaAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { // We need to be Z ordered on top in order for alpha animations to work. mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(true); mExpandedBubble.getExpandedView().setAlphaAnimating(true); } } @Override public void onAnimationEnd(Animator animation) { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); mExpandedBubble.getExpandedView().setAlphaAnimating(false); } } }); mExpandedViewAlphaAnimator.addUpdateListener(valueAnimator -> { if (mExpandedBubble != null) { mExpandedBubble.setExpandedContentAlpha((float) valueAnimator.getAnimatedValue()); } }); mAnimatingOutSurfaceAlphaAnimator.setDuration(EXPANDED_VIEW_ALPHA_ANIMATION_DURATION); mAnimatingOutSurfaceAlphaAnimator.setInterpolator(Interpolators.PANEL_CLOSE_ACCELERATED); mAnimatingOutSurfaceAlphaAnimator.addUpdateListener(valueAnimator -> { if (!mExpandedViewHidden) { mAnimatingOutSurfaceView.setAlpha((float) valueAnimator.getAnimatedValue()); } }); mAnimatingOutSurfaceAlphaAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { releaseAnimatingOutBubbleBuffer(); } }); } /** Loading Loading @@ -1539,7 +1600,8 @@ public class BubbleStackView extends FrameLayout // If we're expanded, screenshot the currently expanded bubble (before expanding the newly // selected bubble) so we can animate it out. if (mIsExpanded && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { if (mIsExpanded && mExpandedBubble != null && mExpandedBubble.getExpandedView() != null && !mExpandedViewHidden) { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { // Before screenshotting, have the real ActivityView show on top of other surfaces // so that the screenshot doesn't flicker on top of it. Loading Loading @@ -1575,7 +1637,7 @@ public class BubbleStackView extends FrameLayout mExpandedViewContainer.setAlpha(0.0f); mSurfaceSynchronizer.syncSurfaceAndRun(() -> { if (previouslySelected != null) { previouslySelected.setContentVisibility(false); previouslySelected.setTaskViewVisibility(false); } updateExpandedBubble(); Loading Loading @@ -1656,6 +1718,58 @@ public class BubbleStackView extends FrameLayout requestUpdate(); } /** Animate the expanded view hidden. This is done while we're dragging out a bubble. */ private void hideExpandedViewIfNeeded() { if (mExpandedViewHidden || mExpandedBubble == null || mExpandedBubble.getExpandedView() == null) { return; } mExpandedViewHidden = true; // Scale down. PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .addUpdateListener((target, values) -> mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix)) .start(); // Animate alpha from 1f to 0f. mExpandedViewAlphaAnimator.reverse(); } /** * Animate the expanded view visible again. This is done when we're done dragging out a bubble. */ private void showExpandedViewIfNeeded() { if (!mExpandedViewHidden) { return; } mExpandedViewHidden = false; PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, AnimatableScaleMatrix.getAnimatableValueForScaleFactor(1f), mScaleOutSpringConfig) .addUpdateListener((target, values) -> mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix)) .start(); mExpandedViewAlphaAnimator.start(); } private void animateExpansion() { cancelDelayedExpandCollapseSwitchAnimations(); final boolean showVertically = mPositioner.showBubblesVertically(); Loading Loading @@ -1714,7 +1828,7 @@ public class BubbleStackView extends FrameLayout // Should not happen since we lay out before expanding, but just in case... if (getWidth() > 0) { startDelay = (long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 1.2f + (distanceAnimated / getWidth()) * 30); } Loading @@ -1728,20 +1842,29 @@ public class BubbleStackView extends FrameLayout pivotX = mPositioner.getAvailableRect().right - mBubbleSize - mExpandedViewPadding; } mExpandedViewContainerMatrix.setScale( 0f, 0f, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, pivotX, pivotY); } else { mExpandedViewContainerMatrix.setScale( 0f, 0f, bubbleWillBeAt + mBubbleSize / 2f, getExpandedViewY()); 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, bubbleWillBeAt + mBubbleSize / 2f, getExpandedViewY()); } mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); if (mExpandedBubble.getExpandedView() != null) { mExpandedBubble.setExpandedContentAlpha(0f); // We'll be starting the alpha animation after a slight delay, so set this flag early // here. mExpandedBubble.getExpandedView().setAlphaAnimating(true); } mDelayedAnimationExecutor.executeDelayed(() -> { mExpandedViewAlphaAnimator.start(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, Loading Loading @@ -1796,22 +1919,15 @@ public class BubbleStackView extends FrameLayout // since we're about to animate collapsed. mExpandedAnimationController.notifyPreparingToCollapse(); final long startDelay = (long) (ExpandedAnimationController.EXPAND_COLLAPSE_TARGET_ANIM_DURATION * 0.6f); mDelayedAnimationExecutor.executeDelayed(() -> { mExpandedAnimationController.collapseBackToStack( mStackAnimationController.getStackPositionAlongNearestHorizontalEdge() /* collapseTo */, () -> mBubbleContainer.setActiveController(mStackAnimationController)); }, startDelay); if (mTaskbarScrim.getVisibility() == VISIBLE) { mTaskbarScrim.animate().alpha(0f).start(); } // We want to visually collapse into this bubble during the animation. final View expandingFromBubble = mExpandedBubble.getIconView(); int index; if (mExpandedBubble != null && BubbleOverflow.KEY.equals(mExpandedBubble.getKey())) { index = mBubbleData.getBubbles().size(); Loading Loading @@ -1840,31 +1956,25 @@ public class BubbleStackView extends FrameLayout getExpandedViewY()); } mExpandedViewAlphaAnimator.reverse(); // When the animation completes, we should no longer be showing the content. if (mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setContentVisibility(false); } PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel(); PhysicsAnimator.getInstance(mExpandedViewContainerMatrix) .spring(AnimatableScaleMatrix.SCALE_X, 0f, mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, 0f, mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_X, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .spring(AnimatableScaleMatrix.SCALE_Y, AnimatableScaleMatrix.getAnimatableValueForScaleFactor( 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT), mScaleOutSpringConfig) .addUpdateListener((target, values) -> { if (expandingFromBubble != null) { // Follow the bubble as it translates! if (showVertically) { mExpandedViewContainerMatrix.postTranslate( 0f, expandingFromBubble.getTranslationY() - expandingFromBubbleAt); } else { mExpandedViewContainerMatrix.postTranslate( expandingFromBubble.getTranslationX() - expandingFromBubbleAt, 0f); } } mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); // Hide early so we don't have a tiny little expanded view still visible at the // end of the scale animation. if (mExpandedViewContainerMatrix.getScaleX() < 0.05f) { mExpandedViewContainer.setVisibility(View.INVISIBLE); } }) .withEndActions(() -> { final BubbleViewProvider previouslySelected = mExpandedBubble; Loading @@ -1882,7 +1992,7 @@ public class BubbleStackView extends FrameLayout updateBadgesAndZOrder(true /* setBadgeForCollapsedStack */); afterExpandedViewAnimation(); if (previouslySelected != null) { previouslySelected.setContentVisibility(false); previouslySelected.setTaskViewVisibility(false); } if (mPositioner.showingInTaskbar()) { Loading @@ -1903,22 +2013,21 @@ public class BubbleStackView extends FrameLayout // The surface contains a screenshot of the animating out bubble, so we just need to animate // it out (and then release the GraphicBuffer). PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer).cancel(); PhysicsAnimator animator = PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer) .spring(DynamicAnimation.SCALE_X, 0f, mScaleOutSpringConfig) .spring(DynamicAnimation.SCALE_Y, 0f, mScaleOutSpringConfig) .withEndActions(this::releaseAnimatingOutBubbleBuffer); mAnimatingOutSurfaceAlphaAnimator.reverse(); mExpandedViewAlphaAnimator.start(); if (mPositioner.showBubblesVertically()) { float translationX = mStackAnimationController.isStackOnLeftSide() ? mAnimatingOutSurfaceContainer.getTranslationX() + mBubbleSize * 2 : mAnimatingOutSurfaceContainer.getTranslationX(); animator.spring(DynamicAnimation.TRANSLATION_X, translationX, mTranslateSpringConfig) PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer) .spring(DynamicAnimation.TRANSLATION_X, translationX, mTranslateSpringConfig) .start(); } else { animator.spring(DynamicAnimation.TRANSLATION_Y, mAnimatingOutSurfaceContainer.getTranslationY() - mBubbleSize * 2, PhysicsAnimator.getInstance(mAnimatingOutSurfaceContainer) .spring(DynamicAnimation.TRANSLATION_Y, mAnimatingOutSurfaceContainer.getTranslationY() - mBubbleSize, mTranslateSpringConfig) .start(); } Loading Loading @@ -1947,7 +2056,8 @@ public class BubbleStackView extends FrameLayout pivotX, pivotY); } else { mExpandedViewContainerMatrix.setScale( 0f, 0f, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, expandingFromBubbleDestination + mBubbleSize / 2f, getExpandedViewY()); } Loading @@ -1972,10 +2082,7 @@ public class BubbleStackView extends FrameLayout mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); }) .withEndActions(() -> { if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedBubble.getExpandedView().setSurfaceZOrderedOnTop(false); } mExpandedViewHidden = false; mIsBubbleSwitchAnimating = false; }) .start(); Loading Loading @@ -2489,6 +2596,7 @@ public class BubbleStackView extends FrameLayout && mExpandedBubble.getExpandedView() != null) { BubbleExpandedView bev = mExpandedBubble.getExpandedView(); bev.setContentVisibility(false); bev.setAlphaAnimating(!mIsExpansionAnimating); mExpandedViewContainerMatrix.setScaleX(0f); mExpandedViewContainerMatrix.setScaleY(0f); mExpandedViewContainerMatrix.setTranslate(0f, 0f); Loading Loading @@ -2586,7 +2694,14 @@ public class BubbleStackView extends FrameLayout mAnimatingOutBubbleBuffer.getHardwareBuffer(), mAnimatingOutBubbleBuffer.getColorSpace()); mSurfaceSynchronizer.syncSurfaceAndRun(() -> post(() -> onComplete.accept(true))); mAnimatingOutSurfaceView.setAlpha(1f); mExpandedViewContainer.setVisibility(View.GONE); mSurfaceSynchronizer.syncSurfaceAndRun(() -> { post(() -> { onComplete.accept(true); }); }); }); } Loading Loading @@ -2618,7 +2733,9 @@ public class BubbleStackView extends FrameLayout } } mExpandedViewContainer.setPadding(leftPadding, 0, rightPadding, 0); if (mIsExpansionAnimating) { mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE); } if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { mExpandedViewContainer.setTranslationY(getExpandedViewY()); mExpandedViewContainer.setTranslationX(0f); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java +10 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,16 @@ import androidx.annotation.Nullable; public interface BubbleViewProvider { @Nullable BubbleExpandedView getExpandedView(); void setContentVisibility(boolean visible); /** * Sets the alpha of the expanded view content. This will be applied to both the expanded view * container itself (the manage button, etc.) as well as the TaskView within it. */ void setExpandedContentAlpha(float alpha); /** * Sets whether the contents of the bubble's TaskView should be visible. */ void setTaskViewVisibility(boolean visible); @Nullable View getIconView(); Loading