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
This commit is contained in:
@@ -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).
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user