Loading libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java +13 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,19 @@ public class Interpolators { */ public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f); /** * The accelerated emphasized interpolator. Used for hero / emphasized movement of content that * is disappearing e.g. when moving off screen. */ public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator( 0.3f, 0f, 0.8f, 0.15f); /** * The decelerating emphasized interpolator. Used for hero / emphasized movement of content that * is appearing e.g. when coming from off screen */ public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( 0.05f, 0.7f, 0.1f, 1f); /** * Interpolator to be used when animating a move based on a click. Pair with enough duration. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +1 −1 Original line number Diff line number Diff line Loading @@ -1512,7 +1512,7 @@ public class BubbleController { public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { mBubblePositioner.setImeVisible(imeVisible, imeHeight); if (mStackView != null) { mStackView.animateForIme(imeVisible); mStackView.setImeVisible(imeVisible); } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java +3 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ public class BubbleDebugConfig { static final boolean DEBUG_OVERFLOW = false; static final boolean DEBUG_USER_EDUCATION = false; static final boolean DEBUG_POSITIONER = false; public static final boolean DEBUG_COLLAPSE_ANIMATOR = false; static final boolean DEBUG_BUBBLE_GESTURE = false; public static boolean DEBUG_EXPANDED_VIEW_DRAGGING = false; private static final boolean FORCE_SHOW_USER_EDUCATION = false; private static final String FORCE_SHOW_USER_EDUCATION_SETTING = Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +248 −28 Original line number Diff line number Diff line Loading @@ -43,10 +43,13 @@ import android.graphics.CornerPathEffect; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.ShapeDrawable; import android.os.RemoteException; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.IntProperty; import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; Loading Loading @@ -75,6 +78,48 @@ import java.io.PrintWriter; public class BubbleExpandedView extends LinearLayout { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleExpandedView" : TAG_BUBBLES; /** {@link IntProperty} for updating bottom clip */ public static final IntProperty<BubbleExpandedView> BOTTOM_CLIP_PROPERTY = new IntProperty<BubbleExpandedView>("bottomClip") { @Override public void setValue(BubbleExpandedView expandedView, int value) { expandedView.setBottomClip(value); } @Override public Integer get(BubbleExpandedView expandedView) { return expandedView.mBottomClip; } }; /** {@link FloatProperty} for updating taskView or overflow alpha */ public static final FloatProperty<BubbleExpandedView> CONTENT_ALPHA = new FloatProperty<BubbleExpandedView>("contentAlpha") { @Override public void setValue(BubbleExpandedView expandedView, float value) { expandedView.setContentAlpha(value); } @Override public Float get(BubbleExpandedView expandedView) { return expandedView.getContentAlpha(); } }; /** {@link FloatProperty} for updating manage button alpha */ public static final FloatProperty<BubbleExpandedView> MANAGE_BUTTON_ALPHA = new FloatProperty<BubbleExpandedView>("manageButtonAlpha") { @Override public void setValue(BubbleExpandedView expandedView, float value) { expandedView.mManageButton.setAlpha(value); } @Override public Float get(BubbleExpandedView expandedView) { return expandedView.mManageButton.getAlpha(); } }; // The triangle pointing to the expanded view private View mPointerView; @Nullable private int[] mExpandedViewContainerLocation; Loading @@ -90,7 +135,7 @@ public class BubbleExpandedView extends LinearLayout { /** * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If * {@link #mIsAlphaAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha * {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha * value until the animation ends. */ private boolean mIsContentVisible = false; Loading @@ -99,12 +144,13 @@ public class BubbleExpandedView extends LinearLayout { * Whether we're animating the {@code 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 boolean mIsAnimating = false; private int mPointerWidth; private int mPointerHeight; private float mPointerRadius; private float mPointerOverlap; private final PointF mPointerPos = new PointF(); private CornerPathEffect mPointerEffect; private ShapeDrawable mCurrentPointer; private ShapeDrawable mTopPointer; Loading @@ -113,11 +159,13 @@ public class BubbleExpandedView extends LinearLayout { private float mCornerRadius = 0f; private int mBackgroundColorFloating; private boolean mUsingMaxHeight; private int mTopClip = 0; private int mBottomClip = 0; @Nullable private Bubble mBubble; private PendingIntent mPendingIntent; // TODO(b/170891664): Don't use a flag, set the BubbleOverflow object instead private boolean mIsOverflow; private boolean mIsClipping; private BubbleController mController; private BubbleStackView mStackView; Loading Loading @@ -268,7 +316,8 @@ public class BubbleExpandedView extends LinearLayout { mExpandedViewContainer.setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCornerRadius); Rect clip = new Rect(0, mTopClip, view.getWidth(), view.getHeight() - mBottomClip); outline.setRoundRect(clip, mCornerRadius); } }); mExpandedViewContainer.setClipToOutline(true); Loading Loading @@ -429,7 +478,7 @@ public class BubbleExpandedView extends LinearLayout { * ordering surfaces during animations. When content is drawn on top of the app (e.g. bubble * being dragged out, the manage menu) this is set to false, otherwise it should be true. */ void setSurfaceZOrderedOnTop(boolean onTop) { public void setSurfaceZOrderedOnTop(boolean onTop) { if (mTaskView == null) { return; } Loading Loading @@ -510,12 +559,12 @@ public class BubbleExpandedView extends LinearLayout { } /** * Whether we are currently animating the {@code TaskView}'s alpha value. If this is set to * Whether we are currently animating the {@code TaskView}. 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; public void setAnimating(boolean animating) { mIsAnimating = animating; // If we're done animating, apply the correct if (!animating) { Loading @@ -524,15 +573,128 @@ public class BubbleExpandedView extends LinearLayout { } /** * Sets the alpha of the underlying {@code TaskView}, since changing the expanded view's alpha * does not affect the {@code TaskView} since it uses a Surface. * Get alpha from underlying {@code TaskView} if this view is for a bubble. * Or get alpha for the overflow view if this view is for overflow. * * @return alpha for the content being shown */ void setTaskViewAlpha(float alpha) { public float getContentAlpha() { if (mIsOverflow) { return mOverflowView.getAlpha(); } if (mTaskView != null) { return mTaskView.getAlpha(); } return 1f; } /** * Set alpha of the underlying {@code TaskView} if this view is for a bubble. * Or set alpha for the overflow view if this view is for overflow. * * Changing expanded view's alpha does not affect the {@code TaskView} since it uses a Surface. */ public void setContentAlpha(float alpha) { if (mIsOverflow) { mOverflowView.setAlpha(alpha); } else if (mTaskView != null) { mTaskView.setAlpha(alpha); } mPointerView.setAlpha(alpha); setAlpha(alpha); } /** * Set translation Y for the expanded view content. * Excludes manage button and pointer. */ public void setContentTranslationY(float translationY) { mExpandedViewContainer.setTranslationY(translationY); // Left or right pointer can become detached when moving the view up if (translationY <= 0 && (isShowingLeftPointer() || isShowingRightPointer())) { // Y coordinate where the pointer would start to get detached from the expanded view. // Takes into account bottom clipping and rounded corners float detachPoint = mExpandedViewContainer.getBottom() - mBottomClip - mCornerRadius + translationY; float pointerBottom = mPointerPos.y + mPointerHeight; // If pointer bottom is past detach point, move it in by that many pixels float horizontalShift = 0; if (pointerBottom > detachPoint) { horizontalShift = pointerBottom - detachPoint; } if (isShowingLeftPointer()) { // Move left pointer right movePointerBy(horizontalShift, 0); } else { // Move right pointer left movePointerBy(-horizontalShift, 0); } // Hide pointer if it is moved by entire width mPointerView.setVisibility( horizontalShift > mPointerWidth ? View.INVISIBLE : View.VISIBLE); } } /** * Update alpha value for the manage button */ public void setManageButtonAlpha(float alpha) { mManageButton.setAlpha(alpha); } /** * Set {@link #setTranslationY(float) translationY} for the manage button */ public void setManageButtonTranslationY(float translationY) { mManageButton.setTranslationY(translationY); } /** * Set top clipping for the view */ public void setTopClip(int clip) { mTopClip = clip; onContainerClipUpdate(); } /** * Set bottom clipping for the view */ public void setBottomClip(int clip) { mBottomClip = clip; onContainerClipUpdate(); } private void onContainerClipUpdate() { if (mTopClip == 0 && mBottomClip == 0) { if (mIsClipping) { mIsClipping = false; if (mTaskView != null) { mTaskView.setClipBounds(null); mTaskView.setEnableSurfaceClipping(false); } mExpandedViewContainer.invalidateOutline(); } } else { if (!mIsClipping) { mIsClipping = true; if (mTaskView != null) { mTaskView.setEnableSurfaceClipping(true); } } mExpandedViewContainer.invalidateOutline(); if (mTaskView != null) { mTaskView.setClipBounds(new Rect(0, mTopClip, mTaskView.getWidth(), mTaskView.getHeight() - mBottomClip)); } } } /** * Move pointer from base position */ public void movePointerBy(float x, float y) { mPointerView.setTranslationX(mPointerPos.x + x); mPointerView.setTranslationY(mPointerPos.y + y); } /** Loading @@ -543,13 +705,13 @@ public class BubbleExpandedView extends LinearLayout { * Note that this contents visibility doesn't affect visibility at {@link android.view.View}, * and setting {@code false} actually means rendering the contents in transparent. */ void setContentVisibility(boolean visibility) { public void setContentVisibility(boolean visibility) { if (DEBUG_BUBBLE_EXPANDED_VIEW) { Log.d(TAG, "setContentVisibility: visibility=" + visibility + " bubble=" + getBubbleKey()); } mIsContentVisible = visibility; if (mTaskView != null && !mIsAlphaAnimating) { if (mTaskView != null && !mIsAnimating) { mTaskView.setAlpha(visibility ? 1f : 0f); mPointerView.setAlpha(visibility ? 1f : 0f); } Loading @@ -560,6 +722,44 @@ public class BubbleExpandedView extends LinearLayout { return mTaskView; } @VisibleForTesting public BubbleOverflowContainerView getOverflow() { return mOverflowView; } /** * Return content height: taskView or overflow. * Takes into account clippings set by {@link #setTopClip(int)} and {@link #setBottomClip(int)} * * @return if bubble is for overflow, return overflow height, otherwise return taskView height */ public int getContentHeight() { if (mIsOverflow) { return mOverflowView.getHeight() - mTopClip - mBottomClip; } if (mTaskView != null) { return mTaskView.getHeight() - mTopClip - mBottomClip; } return 0; } /** * Return bottom position of the content on screen * * @return if bubble is for overflow, return value for overflow, otherwise taskView */ public int getContentBottomOnScreen() { Rect out = new Rect(); if (mIsOverflow) { mOverflowView.getBoundsOnScreen(out); } if (mTaskView != null) { mTaskView.getBoundsOnScreen(out); } return out.bottom; } int getTaskId() { return mTaskId; } Loading Loading @@ -728,27 +928,47 @@ public class BubbleExpandedView extends LinearLayout { post(() -> { mCurrentPointer = showVertically ? onLeft ? mLeftPointer : mRightPointer : mTopPointer; updatePointerView(); float pointerY; float pointerX; if (showVertically) { pointerY = bubbleCenter - (mPointerWidth / 2f); pointerX = onLeft mPointerPos.y = bubbleCenter - (mPointerWidth / 2f); mPointerPos.x = onLeft ? -mPointerHeight + mPointerOverlap : getWidth() - mPaddingRight - mPointerOverlap; } else { pointerY = mPointerOverlap; pointerX = bubbleCenter - (mPointerWidth / 2f); mPointerPos.y = mPointerOverlap; mPointerPos.x = bubbleCenter - (mPointerWidth / 2f); } if (animate) { mPointerView.animate().translationX(pointerX).translationY(pointerY).start(); mPointerView.animate().translationX(mPointerPos.x).translationY( mPointerPos.y).start(); } else { mPointerView.setTranslationY(pointerY); mPointerView.setTranslationX(pointerX); mPointerView.setTranslationY(mPointerPos.y); mPointerView.setTranslationX(mPointerPos.x); mPointerView.setVisibility(VISIBLE); } }); } /** * Return true if pointer is shown on the left */ public boolean isShowingLeftPointer() { return mCurrentPointer == mLeftPointer; } /** * Return true if pointer is shown on the right */ public boolean isShowingRightPointer() { return mCurrentPointer == mRightPointer; } /** * Return width of the current pointer */ public int getPointerWidth() { return mPointerWidth; } /** * Position of the manage button displayed in the expanded view. Used for placing user * education about the manage button. Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +25 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,14 @@ public class BubblePositioner { return mImeVisible ? mImeHeight : 0; } /** Return top position of the IME if it's visible */ public int getImeTop() { if (mImeVisible) { return getScreenRect().bottom - getImeHeight() - getInsets().bottom; } return 0; } /** Sets whether the IME is visible. **/ public void setImeVisible(boolean visible, int height) { mImeVisible = visible; Loading Loading @@ -706,4 +714,21 @@ public class BubblePositioner { public void setPinnedLocation(PointF point) { mPinLocation = point; } /** * Navigation bar has an area where system gestures can be started from. * * @return {@link Rect} for system navigation bar gesture zone */ public Rect getNavBarGestureZone() { // Gesture zone height from the bottom int gestureZoneHeight = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_gesture_height); Rect screen = getScreenRect(); return new Rect( screen.left, screen.bottom - gestureZoneHeight, screen.right, screen.bottom); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java +13 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,19 @@ public class Interpolators { */ public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f); /** * The accelerated emphasized interpolator. Used for hero / emphasized movement of content that * is disappearing e.g. when moving off screen. */ public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator( 0.3f, 0f, 0.8f, 0.15f); /** * The decelerating emphasized interpolator. Used for hero / emphasized movement of content that * is appearing e.g. when coming from off screen */ public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator( 0.05f, 0.7f, 0.1f, 1f); /** * Interpolator to be used when animating a move based on a click. Pair with enough duration. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +1 −1 Original line number Diff line number Diff line Loading @@ -1512,7 +1512,7 @@ public class BubbleController { public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { mBubblePositioner.setImeVisible(imeVisible, imeHeight); if (mStackView != null) { mStackView.animateForIme(imeVisible); mStackView.setImeVisible(imeVisible); } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDebugConfig.java +3 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ public class BubbleDebugConfig { static final boolean DEBUG_OVERFLOW = false; static final boolean DEBUG_USER_EDUCATION = false; static final boolean DEBUG_POSITIONER = false; public static final boolean DEBUG_COLLAPSE_ANIMATOR = false; static final boolean DEBUG_BUBBLE_GESTURE = false; public static boolean DEBUG_EXPANDED_VIEW_DRAGGING = false; private static final boolean FORCE_SHOW_USER_EDUCATION = false; private static final String FORCE_SHOW_USER_EDUCATION_SETTING = Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +248 −28 Original line number Diff line number Diff line Loading @@ -43,10 +43,13 @@ import android.graphics.CornerPathEffect; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.ShapeDrawable; import android.os.RemoteException; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.IntProperty; import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; Loading Loading @@ -75,6 +78,48 @@ import java.io.PrintWriter; public class BubbleExpandedView extends LinearLayout { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleExpandedView" : TAG_BUBBLES; /** {@link IntProperty} for updating bottom clip */ public static final IntProperty<BubbleExpandedView> BOTTOM_CLIP_PROPERTY = new IntProperty<BubbleExpandedView>("bottomClip") { @Override public void setValue(BubbleExpandedView expandedView, int value) { expandedView.setBottomClip(value); } @Override public Integer get(BubbleExpandedView expandedView) { return expandedView.mBottomClip; } }; /** {@link FloatProperty} for updating taskView or overflow alpha */ public static final FloatProperty<BubbleExpandedView> CONTENT_ALPHA = new FloatProperty<BubbleExpandedView>("contentAlpha") { @Override public void setValue(BubbleExpandedView expandedView, float value) { expandedView.setContentAlpha(value); } @Override public Float get(BubbleExpandedView expandedView) { return expandedView.getContentAlpha(); } }; /** {@link FloatProperty} for updating manage button alpha */ public static final FloatProperty<BubbleExpandedView> MANAGE_BUTTON_ALPHA = new FloatProperty<BubbleExpandedView>("manageButtonAlpha") { @Override public void setValue(BubbleExpandedView expandedView, float value) { expandedView.mManageButton.setAlpha(value); } @Override public Float get(BubbleExpandedView expandedView) { return expandedView.mManageButton.getAlpha(); } }; // The triangle pointing to the expanded view private View mPointerView; @Nullable private int[] mExpandedViewContainerLocation; Loading @@ -90,7 +135,7 @@ public class BubbleExpandedView extends LinearLayout { /** * Whether we want the {@code TaskView}'s content to be visible (alpha = 1f). If * {@link #mIsAlphaAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha * {@link #mIsAnimating} is true, this may not reflect the {@code TaskView}'s actual alpha * value until the animation ends. */ private boolean mIsContentVisible = false; Loading @@ -99,12 +144,13 @@ public class BubbleExpandedView extends LinearLayout { * Whether we're animating the {@code 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 boolean mIsAnimating = false; private int mPointerWidth; private int mPointerHeight; private float mPointerRadius; private float mPointerOverlap; private final PointF mPointerPos = new PointF(); private CornerPathEffect mPointerEffect; private ShapeDrawable mCurrentPointer; private ShapeDrawable mTopPointer; Loading @@ -113,11 +159,13 @@ public class BubbleExpandedView extends LinearLayout { private float mCornerRadius = 0f; private int mBackgroundColorFloating; private boolean mUsingMaxHeight; private int mTopClip = 0; private int mBottomClip = 0; @Nullable private Bubble mBubble; private PendingIntent mPendingIntent; // TODO(b/170891664): Don't use a flag, set the BubbleOverflow object instead private boolean mIsOverflow; private boolean mIsClipping; private BubbleController mController; private BubbleStackView mStackView; Loading Loading @@ -268,7 +316,8 @@ public class BubbleExpandedView extends LinearLayout { mExpandedViewContainer.setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), mCornerRadius); Rect clip = new Rect(0, mTopClip, view.getWidth(), view.getHeight() - mBottomClip); outline.setRoundRect(clip, mCornerRadius); } }); mExpandedViewContainer.setClipToOutline(true); Loading Loading @@ -429,7 +478,7 @@ public class BubbleExpandedView extends LinearLayout { * ordering surfaces during animations. When content is drawn on top of the app (e.g. bubble * being dragged out, the manage menu) this is set to false, otherwise it should be true. */ void setSurfaceZOrderedOnTop(boolean onTop) { public void setSurfaceZOrderedOnTop(boolean onTop) { if (mTaskView == null) { return; } Loading Loading @@ -510,12 +559,12 @@ public class BubbleExpandedView extends LinearLayout { } /** * Whether we are currently animating the {@code TaskView}'s alpha value. If this is set to * Whether we are currently animating the {@code TaskView}. 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; public void setAnimating(boolean animating) { mIsAnimating = animating; // If we're done animating, apply the correct if (!animating) { Loading @@ -524,15 +573,128 @@ public class BubbleExpandedView extends LinearLayout { } /** * Sets the alpha of the underlying {@code TaskView}, since changing the expanded view's alpha * does not affect the {@code TaskView} since it uses a Surface. * Get alpha from underlying {@code TaskView} if this view is for a bubble. * Or get alpha for the overflow view if this view is for overflow. * * @return alpha for the content being shown */ void setTaskViewAlpha(float alpha) { public float getContentAlpha() { if (mIsOverflow) { return mOverflowView.getAlpha(); } if (mTaskView != null) { return mTaskView.getAlpha(); } return 1f; } /** * Set alpha of the underlying {@code TaskView} if this view is for a bubble. * Or set alpha for the overflow view if this view is for overflow. * * Changing expanded view's alpha does not affect the {@code TaskView} since it uses a Surface. */ public void setContentAlpha(float alpha) { if (mIsOverflow) { mOverflowView.setAlpha(alpha); } else if (mTaskView != null) { mTaskView.setAlpha(alpha); } mPointerView.setAlpha(alpha); setAlpha(alpha); } /** * Set translation Y for the expanded view content. * Excludes manage button and pointer. */ public void setContentTranslationY(float translationY) { mExpandedViewContainer.setTranslationY(translationY); // Left or right pointer can become detached when moving the view up if (translationY <= 0 && (isShowingLeftPointer() || isShowingRightPointer())) { // Y coordinate where the pointer would start to get detached from the expanded view. // Takes into account bottom clipping and rounded corners float detachPoint = mExpandedViewContainer.getBottom() - mBottomClip - mCornerRadius + translationY; float pointerBottom = mPointerPos.y + mPointerHeight; // If pointer bottom is past detach point, move it in by that many pixels float horizontalShift = 0; if (pointerBottom > detachPoint) { horizontalShift = pointerBottom - detachPoint; } if (isShowingLeftPointer()) { // Move left pointer right movePointerBy(horizontalShift, 0); } else { // Move right pointer left movePointerBy(-horizontalShift, 0); } // Hide pointer if it is moved by entire width mPointerView.setVisibility( horizontalShift > mPointerWidth ? View.INVISIBLE : View.VISIBLE); } } /** * Update alpha value for the manage button */ public void setManageButtonAlpha(float alpha) { mManageButton.setAlpha(alpha); } /** * Set {@link #setTranslationY(float) translationY} for the manage button */ public void setManageButtonTranslationY(float translationY) { mManageButton.setTranslationY(translationY); } /** * Set top clipping for the view */ public void setTopClip(int clip) { mTopClip = clip; onContainerClipUpdate(); } /** * Set bottom clipping for the view */ public void setBottomClip(int clip) { mBottomClip = clip; onContainerClipUpdate(); } private void onContainerClipUpdate() { if (mTopClip == 0 && mBottomClip == 0) { if (mIsClipping) { mIsClipping = false; if (mTaskView != null) { mTaskView.setClipBounds(null); mTaskView.setEnableSurfaceClipping(false); } mExpandedViewContainer.invalidateOutline(); } } else { if (!mIsClipping) { mIsClipping = true; if (mTaskView != null) { mTaskView.setEnableSurfaceClipping(true); } } mExpandedViewContainer.invalidateOutline(); if (mTaskView != null) { mTaskView.setClipBounds(new Rect(0, mTopClip, mTaskView.getWidth(), mTaskView.getHeight() - mBottomClip)); } } } /** * Move pointer from base position */ public void movePointerBy(float x, float y) { mPointerView.setTranslationX(mPointerPos.x + x); mPointerView.setTranslationY(mPointerPos.y + y); } /** Loading @@ -543,13 +705,13 @@ public class BubbleExpandedView extends LinearLayout { * Note that this contents visibility doesn't affect visibility at {@link android.view.View}, * and setting {@code false} actually means rendering the contents in transparent. */ void setContentVisibility(boolean visibility) { public void setContentVisibility(boolean visibility) { if (DEBUG_BUBBLE_EXPANDED_VIEW) { Log.d(TAG, "setContentVisibility: visibility=" + visibility + " bubble=" + getBubbleKey()); } mIsContentVisible = visibility; if (mTaskView != null && !mIsAlphaAnimating) { if (mTaskView != null && !mIsAnimating) { mTaskView.setAlpha(visibility ? 1f : 0f); mPointerView.setAlpha(visibility ? 1f : 0f); } Loading @@ -560,6 +722,44 @@ public class BubbleExpandedView extends LinearLayout { return mTaskView; } @VisibleForTesting public BubbleOverflowContainerView getOverflow() { return mOverflowView; } /** * Return content height: taskView or overflow. * Takes into account clippings set by {@link #setTopClip(int)} and {@link #setBottomClip(int)} * * @return if bubble is for overflow, return overflow height, otherwise return taskView height */ public int getContentHeight() { if (mIsOverflow) { return mOverflowView.getHeight() - mTopClip - mBottomClip; } if (mTaskView != null) { return mTaskView.getHeight() - mTopClip - mBottomClip; } return 0; } /** * Return bottom position of the content on screen * * @return if bubble is for overflow, return value for overflow, otherwise taskView */ public int getContentBottomOnScreen() { Rect out = new Rect(); if (mIsOverflow) { mOverflowView.getBoundsOnScreen(out); } if (mTaskView != null) { mTaskView.getBoundsOnScreen(out); } return out.bottom; } int getTaskId() { return mTaskId; } Loading Loading @@ -728,27 +928,47 @@ public class BubbleExpandedView extends LinearLayout { post(() -> { mCurrentPointer = showVertically ? onLeft ? mLeftPointer : mRightPointer : mTopPointer; updatePointerView(); float pointerY; float pointerX; if (showVertically) { pointerY = bubbleCenter - (mPointerWidth / 2f); pointerX = onLeft mPointerPos.y = bubbleCenter - (mPointerWidth / 2f); mPointerPos.x = onLeft ? -mPointerHeight + mPointerOverlap : getWidth() - mPaddingRight - mPointerOverlap; } else { pointerY = mPointerOverlap; pointerX = bubbleCenter - (mPointerWidth / 2f); mPointerPos.y = mPointerOverlap; mPointerPos.x = bubbleCenter - (mPointerWidth / 2f); } if (animate) { mPointerView.animate().translationX(pointerX).translationY(pointerY).start(); mPointerView.animate().translationX(mPointerPos.x).translationY( mPointerPos.y).start(); } else { mPointerView.setTranslationY(pointerY); mPointerView.setTranslationX(pointerX); mPointerView.setTranslationY(mPointerPos.y); mPointerView.setTranslationX(mPointerPos.x); mPointerView.setVisibility(VISIBLE); } }); } /** * Return true if pointer is shown on the left */ public boolean isShowingLeftPointer() { return mCurrentPointer == mLeftPointer; } /** * Return true if pointer is shown on the right */ public boolean isShowingRightPointer() { return mCurrentPointer == mRightPointer; } /** * Return width of the current pointer */ public int getPointerWidth() { return mPointerWidth; } /** * Position of the manage button displayed in the expanded view. Used for placing user * education about the manage button. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +25 −0 Original line number Diff line number Diff line Loading @@ -344,6 +344,14 @@ public class BubblePositioner { return mImeVisible ? mImeHeight : 0; } /** Return top position of the IME if it's visible */ public int getImeTop() { if (mImeVisible) { return getScreenRect().bottom - getImeHeight() - getInsets().bottom; } return 0; } /** Sets whether the IME is visible. **/ public void setImeVisible(boolean visible, int height) { mImeVisible = visible; Loading Loading @@ -706,4 +714,21 @@ public class BubblePositioner { public void setPinnedLocation(PointF point) { mPinLocation = point; } /** * Navigation bar has an area where system gestures can be started from. * * @return {@link Rect} for system navigation bar gesture zone */ public Rect getNavBarGestureZone() { // Gesture zone height from the bottom int gestureZoneHeight = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.navigation_bar_gesture_height); Rect screen = getScreenRect(); return new Rect( screen.left, screen.bottom - gestureZoneHeight, screen.right, screen.bottom); } }