From 4ac05e33d32397c4c019fa0623df02b076ea4748 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Wed, 11 Nov 2020 14:44:56 -0800 Subject: [PATCH] Bubbles taskbar broadcast * listen for broadcasts related to taskbar * update info in BubblePositioner based on that * show a scrim behind the bubbles when taskbar is on left / right so you don't see contents beneath Test: manual Bug: 173386799 Bug: 167413172 Change-Id: Id520718e779d3a45bcde447d7fcb0d2ba785c88e --- .../wm/shell/bubbles/BubbleController.java | 69 +++++++++++++++++++ .../wm/shell/bubbles/BubbleExpandedView.java | 2 +- .../wm/shell/bubbles/BubblePositioner.java | 51 +++++++++----- .../wm/shell/bubbles/BubbleStackView.java | 37 ++++++++-- .../com/android/wm/shell/bubbles/Bubbles.java | 7 ++ .../animation/StackAnimationController.java | 40 ----------- .../systemui/statusbar/phone/StatusBar.java | 12 ++++ 7 files changed, 156 insertions(+), 62 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index eb3a3a276727e..beac59b699fa8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -24,6 +24,10 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_BOTTOM; +import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_LEFT; +import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_NONE; +import static com.android.wm.shell.bubbles.BubblePositioner.TASKBAR_POSITION_RIGHT; import android.annotation.NonNull; import android.annotation.UserIdInt; @@ -38,7 +42,9 @@ import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.graphics.PixelFormat; +import android.graphics.PointF; import android.os.Binder; +import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; @@ -81,6 +87,18 @@ public class BubbleController implements Bubbles { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES; + // TODO(b/173386799) keep in sync with Launcher3 and also don't do a broadcast + public static final String TASKBAR_CHANGED_BROADCAST = "taskbarChanged"; + public static final String EXTRA_BUBBLE_OVERFLOW_OPENED = "bubbleOverflowOpened"; + public static final String EXTRA_TASKBAR_VISIBLE = "taskbarVisible"; + public static final String EXTRA_TASKBAR_POSITION = "taskbarPosition"; + public static final String EXTRA_TASKBAR_ICON_SIZE = "taskbarIconSize"; + public static final String EXTRA_TASKBAR_BUBBLE_XY = "taskbarBubbleXY"; + public static final String EXTRA_TASKBAR_SIZE = "taskbarSize"; + public static final String LEFT_POSITION = "Left"; + public static final String RIGHT_POSITION = "Right"; + public static final String BOTTOM_POSITION = "Bottom"; + private final Context mContext; private BubbleExpandListener mExpandListener; @Nullable private BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer; @@ -295,6 +313,57 @@ public class BubbleController implements Bubbles { } } + @Override + public void openBubbleOverflow() { + ensureStackViewCreated(); + mBubbleData.setShowingOverflow(true); + mBubbleData.setSelectedBubble(mBubbleData.getOverflow()); + mBubbleData.setExpanded(true); + } + + /** Called when any taskbar state changes (e.g. visibility, position, sizes). */ + @Override + public void onTaskbarChanged(Bundle b) { + if (b == null) { + return; + } + boolean isVisible = b.getBoolean(EXTRA_TASKBAR_VISIBLE, false /* default */); + String position = b.getString(EXTRA_TASKBAR_POSITION, RIGHT_POSITION /* default */); + @BubblePositioner.TaskbarPosition int taskbarPosition = TASKBAR_POSITION_NONE; + switch (position) { + case LEFT_POSITION: + taskbarPosition = TASKBAR_POSITION_LEFT; + break; + case RIGHT_POSITION: + taskbarPosition = TASKBAR_POSITION_RIGHT; + break; + case BOTTOM_POSITION: + taskbarPosition = TASKBAR_POSITION_BOTTOM; + break; + } + int[] itemPosition = b.getIntArray(EXTRA_TASKBAR_BUBBLE_XY); + int iconSize = b.getInt(EXTRA_TASKBAR_ICON_SIZE); + int taskbarSize = b.getInt(EXTRA_TASKBAR_SIZE); + Log.w(TAG, "onTaskbarChanged:" + + " isVisible: " + isVisible + + " position: " + position + + " itemPosition: " + itemPosition[0] + "," + itemPosition[1] + + " iconSize: " + iconSize); + PointF point = new PointF(itemPosition[0], itemPosition[1]); + mBubblePositioner.setPinnedLocation(point); + mBubblePositioner.updateForTaskbar(iconSize, taskbarPosition, isVisible, taskbarSize); + if (mStackView != null) { + if (isVisible) { + mStackView.updateStackPosition(); + } + mBubbleIconFactory = new BubbleIconFactory(mContext); + mStackView.onDisplaySizeChanged(); + } + if (b.getBoolean(EXTRA_BUBBLE_OVERFLOW_OPENED, false)) { + openBubbleOverflow(); + } + } + /** * Called when the status bar has become visible or invisible (either permanently or * temporarily). diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index 45ffe6b20984f..318a0bd42940e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -396,7 +396,7 @@ public class BubbleExpandedView extends LinearLayout { /** Return a GraphicBuffer with the contents of the task view surface. */ @Nullable SurfaceControl.ScreenshotHardwareBuffer snapshotActivitySurface() { - if (mTaskView == null) { + if (mTaskView == null || mTaskView.getSurfaceControl() == null) { return null; } return SurfaceControl.captureLayers( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java index 46e8e11610ac6..1562e4bf6fcc3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java @@ -48,8 +48,10 @@ public class BubblePositioner { : BubbleDebugConfig.TAG_BUBBLES; @Retention(SOURCE) - @IntDef({TASKBAR_POSITION_RIGHT, TASKBAR_POSITION_LEFT, TASKBAR_POSITION_BOTTOM}) + @IntDef({TASKBAR_POSITION_NONE, TASKBAR_POSITION_RIGHT, TASKBAR_POSITION_LEFT, + TASKBAR_POSITION_BOTTOM}) @interface TaskbarPosition {} + public static final int TASKBAR_POSITION_NONE = -1; public static final int TASKBAR_POSITION_RIGHT = 0; public static final int TASKBAR_POSITION_LEFT = 1; public static final int TASKBAR_POSITION_BOTTOM = 2; @@ -73,8 +75,9 @@ public class BubblePositioner { private PointF mRestingStackPosition; private boolean mShowingInTaskbar; - private @TaskbarPosition int mTaskbarPosition; + private @TaskbarPosition int mTaskbarPosition = TASKBAR_POSITION_NONE; private int mTaskbarIconSize; + private int mTaskbarSize; public BubblePositioner(Context context, WindowManager windowManager) { mContext = context; @@ -107,6 +110,21 @@ public class BubblePositioner { updateInternal(orientation, insets, windowMetrics.getBounds()); } + /** + * Updates position information to account for taskbar state. + * + * @param taskbarPosition which position the taskbar is displayed in. + * @param showingInTaskbar whether the taskbar is being shown. + */ + public void updateForTaskbar(int iconSize, + @TaskbarPosition int taskbarPosition, boolean showingInTaskbar, int taskbarSize) { + mShowingInTaskbar = showingInTaskbar; + mTaskbarIconSize = iconSize; + mTaskbarPosition = taskbarPosition; + mTaskbarSize = taskbarSize; + update(mOrientation); + } + @VisibleForTesting public void updateInternal(int orientation, Insets insets, Rect bounds) { mOrientation = orientation; @@ -121,21 +139,9 @@ public class BubblePositioner { Resources res = mContext.getResources(); mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size); - adjustForTaskbar(); - } - - /** - * Updates position information to account for taskbar state. - * - * @param taskbarPosition which position the taskbar is displayed in. - * @param showingInTaskbar whether the taskbar is being shown. - */ - public void updateForTaskbar(int iconSize, - @TaskbarPosition int taskbarPosition, boolean showingInTaskbar) { - mShowingInTaskbar = showingInTaskbar; - mTaskbarIconSize = iconSize; - mTaskbarPosition = taskbarPosition; - update(mOrientation); + if (mShowingInTaskbar) { + adjustForTaskbar(); + } } /** @@ -262,6 +268,17 @@ public class BubblePositioner { return mShowingInTaskbar; } + /** + * @return the taskbar position if set. + */ + public int getTaskbarPosition() { + return mTaskbarPosition; + } + + public int getTaskbarSize() { + return mTaskbarSize; + } + /** * In some situations bubbles will be pinned to a specific onscreen location. This sets the * location to anchor the stack to. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index cbe98458df86a..1e5e43a99b094 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -32,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.content.res.TypedArray; +import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Insets; @@ -194,6 +195,7 @@ public class BubbleStackView extends FrameLayout private StackAnimationController mStackAnimationController; private ExpandedAnimationController mExpandedAnimationController; + private View mTaskbarScrim; private FrameLayout mExpandedViewContainer; /** Matrix used to scale the expanded view container with a given pivot point. */ @@ -631,7 +633,9 @@ public class BubbleStackView extends FrameLayout public void onUp(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, float viewInitialY, float dx, float dy, float velX, float velY) { // If we're expanding or collapsing, ignore all touch events. - if (mIsExpansionAnimating) { + if (mIsExpansionAnimating + // Also ignore events if we shouldn't be draggable. + || (mPositioner.showingInTaskbar() && !mIsExpanded)) { return; } @@ -741,14 +745,13 @@ public class BubbleStackView extends FrameLayout mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); mBubbleTouchPadding = res.getDimensionPixelSize(R.dimen.bubble_touch_padding); mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height); - mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset); - mPositioner = mBubbleController.getPositioner(); - mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding); int elevation = res.getDimensionPixelSize(R.dimen.bubble_elevation); + mPositioner = mBubbleController.getPositioner(); + final TypedArray ta = mContext.obtainStyledAttributes( new int[] {android.R.attr.dialogCornerRadius}); mCornerRadius = ta.getDimensionPixelSize(0, 0); @@ -840,6 +843,12 @@ public class BubbleStackView extends FrameLayout mBubbleData.setExpanded(true); }); + mTaskbarScrim = new View(getContext()); + mTaskbarScrim.setBackgroundColor(Color.BLACK); + addView(mTaskbarScrim); + mTaskbarScrim.setAlpha(0f); + mTaskbarScrim.setVisibility(GONE); + setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> { mBubbleController.onImeVisibilityChanged( insets.getInsets(WindowInsets.Type.ime()).bottom > 0); @@ -1631,6 +1640,7 @@ public class BubbleStackView extends FrameLayout /** Set the stack position to whatever the positioner says. */ void updateStackPosition() { mStackAnimationController.setStackPosition(mPositioner.getRestingPosition()); + mDismissView.hide(); } private void beforeExpandedViewAnimation() { @@ -1664,6 +1674,17 @@ public class BubbleStackView extends FrameLayout } } /* after */); + if (mPositioner.showingInTaskbar() + // Don't need the scrim when the bar is at the bottom + && mPositioner.getTaskbarPosition() != BubblePositioner.TASKBAR_POSITION_BOTTOM) { + mTaskbarScrim.getLayoutParams().width = mPositioner.getTaskbarSize(); + mTaskbarScrim.setTranslationX(mStackOnLeftOrWillBe + ? 0f + : mPositioner.getAvailableRect().right - mPositioner.getTaskbarSize()); + mTaskbarScrim.setVisibility(VISIBLE); + mTaskbarScrim.animate().alpha(1f).start(); + } + mExpandedViewContainer.setTranslationX(0f); mExpandedViewContainer.setTranslationY(getExpandedViewY()); mExpandedViewContainer.setAlpha(1f); @@ -1781,6 +1802,10 @@ public class BubbleStackView extends FrameLayout /* 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(); @@ -1856,6 +1881,10 @@ public class BubbleStackView extends FrameLayout if (previouslySelected != null) { previouslySelected.setContentVisibility(false); } + + if (mPositioner.showingInTaskbar()) { + mTaskbarScrim.setVisibility(GONE); + } }) .start(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java index 79c42d83d7ead..92d15c5feaca9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java @@ -22,6 +22,7 @@ import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.SOURCE; import android.content.res.Configuration; +import android.os.Bundle; import android.service.notification.NotificationListenerService.RankingMap; import android.util.ArraySet; import android.view.View; @@ -104,6 +105,12 @@ public interface Bubbles { */ void expandStackAndSelectBubble(BubbleEntry entry); + /** Called for any taskbar changes. */ + void onTaskbarChanged(Bundle b); + + /** Open the overflow view. */ + void openBubbleOverflow(); + /** * We intercept notification entries (including group summaries) dismissed by the user when * there is an active bubble associated with it. We do this so that developers can still diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java index 24a8809d3f2b5..96398be42fb2c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java @@ -769,7 +769,6 @@ public class StackAnimationController extends if (getBubbleCount() > 0) { animationForChildAtIndex(0).translationX(mStackPosition.x).start(); } else { - // TODO: still needed with positioner? // When all children are removed ensure stack position is sane mPositioner.setRestingPosition(mPositioner.getRestingPosition()); @@ -939,45 +938,6 @@ public class StackAnimationController extends setStackPosition(position.getAbsolutePositionInRegion(getAllowableStackPositionRegion())); } - public BubbleStackView.RelativeStackPosition getRelativeStackPosition() { - return new BubbleStackView.RelativeStackPosition( - mStackPosition, getAllowableStackPositionRegion()); - } - - /** - * Sets the starting position for the stack, where it will be located when the first bubble is - * added. - */ - public void setStackStartPosition(BubbleStackView.RelativeStackPosition position) { - mStackStartPosition = position; - } - - /** - * Returns the starting stack position. If {@link #setStackStartPosition} was called, this will - * return that position - otherwise, a reasonable default will be returned. - */ - @Nullable public PointF getStartPosition() { - if (mLayout == null) { - return null; - } - - if (mStackStartPosition == null) { - // Start on the left if we're in LTR, right otherwise. - final boolean startOnLeft = - mLayout.getResources().getConfiguration().getLayoutDirection() - != View.LAYOUT_DIRECTION_RTL; - - final float startingVerticalOffset = mLayout.getResources().getDimensionPixelOffset( - R.dimen.bubble_stack_starting_offset_y); - - mStackStartPosition = new BubbleStackView.RelativeStackPosition( - startOnLeft, - startingVerticalOffset / getAllowableStackPositionRegion().height()); - } - - return mStackStartPosition.getAbsolutePositionInRegion(getAllowableStackPositionRegion()); - } - private boolean isStackPositionSet() { return mStackMovedToStartPosition; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 09de57509c2a5..5d8424592cd2a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -45,6 +45,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCE import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING; import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode; +import static com.android.wm.shell.bubbles.BubbleController.TASKBAR_CHANGED_BROADCAST; import android.annotation.NonNull; import android.annotation.Nullable; @@ -561,6 +562,15 @@ public class StatusBar extends SystemUI implements DemoMode, } }; + BroadcastReceiver mTaskbarChangeReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (mBubblesOptional.isPresent()) { + mBubblesOptional.get().onTaskbarChanged(intent.getExtras()); + } + } + }; + private Runnable mLaunchTransitionEndRunnable; private NotificationEntry mDraggedDownEntry; private boolean mLaunchCameraWhenFinishedWaking; @@ -844,6 +854,8 @@ public class StatusBar extends SystemUI implements DemoMode, mBypassHeadsUpNotifier.setUp(); if (mBubblesOptional.isPresent()) { mBubblesOptional.get().setExpandListener(mBubbleExpandListener); + IntentFilter filter = new IntentFilter(TASKBAR_CHANGED_BROADCAST); + mBroadcastDispatcher.registerReceiver(mTaskbarChangeReceiver, filter); } mColorExtractor.addOnColorsChangedListener(this);