summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java76
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java46
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java6
5 files changed, 98 insertions, 50 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 c19da2ef0a02..eb3a3a276727 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
@@ -171,7 +171,7 @@ public class BubbleController implements Bubbles {
ShellTaskOrganizer organizer) {
BubbleLogger logger = new BubbleLogger(uiEventLogger);
BubblePositioner positioner = new BubblePositioner(context, windowManager);
- BubbleData data = new BubbleData(context, logger);
+ BubbleData data = new BubbleData(context, logger, positioner);
return new BubbleController(context, data, synchronizer, floatingContentCoordinator,
new BubbleDataRepository(context, launcherApps),
statusBarService, windowManager, windowManagerShellWrapper, launcherApps,
@@ -382,7 +382,6 @@ public class BubbleController implements Bubbles {
if (mStackView == null) {
mStackView = new BubbleStackView(
mContext, this, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator);
- mStackView.addView(mBubbleScrim);
mStackView.onOrientationChanged();
if (mExpandListener != null) {
mStackView.setExpandListener(mExpandListener);
@@ -422,6 +421,8 @@ public class BubbleController implements Bubbles {
try {
mAddedToWindowManager = true;
+ mBubbleData.getOverflow().initialize(this);
+ mStackView.addView(mBubbleScrim);
mWindowManager.addView(mStackView, mWmLayoutParams);
// Position info is dependent on us being attached to a window
mBubblePositioner.update(mOrientation);
@@ -446,7 +447,7 @@ public class BubbleController implements Bubbles {
if (mStackView != null) {
mWindowManager.removeView(mStackView);
mStackView.removeView(mBubbleScrim);
- mStackView = null;
+ mBubbleData.getOverflow().cleanUpExpandedState();
} else {
Log.w(TAG, "StackView added to WindowManager, but was null when removing!");
}
@@ -578,7 +579,7 @@ public class BubbleController implements Bubbles {
if (mStackView == null) {
return false;
}
- return mBubbleData.hasBubbles();
+ return mBubbleData.hasBubbles() || mBubbleData.isShowingOverflow();
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index b6a97e251009..e24ff063b661 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -69,7 +69,7 @@ public class BubbleData {
boolean selectionChanged;
boolean orderChanged;
boolean expanded;
- @Nullable Bubble selectedBubble;
+ @Nullable BubbleViewProvider selectedBubble;
@Nullable Bubble addedBubble;
@Nullable Bubble updatedBubble;
@Nullable Bubble addedOverflowBubble;
@@ -116,13 +116,15 @@ public class BubbleData {
}
private final Context mContext;
+ private final BubblePositioner mPositioner;
/** Bubbles that are actively in the stack. */
private final List<Bubble> mBubbles;
/** Bubbles that aged out to overflow. */
private final List<Bubble> mOverflowBubbles;
/** Bubbles that are being loaded but haven't been added to the stack just yet. */
private final HashMap<String, Bubble> mPendingBubbles;
- private Bubble mSelectedBubble;
+ private BubbleViewProvider mSelectedBubble;
+ private final BubbleOverflow mOverflow;
private boolean mShowingOverflow;
private boolean mExpanded;
private final int mMaxBubbles;
@@ -153,9 +155,11 @@ public class BubbleData {
*/
private HashMap<String, String> mSuppressedGroupKeys = new HashMap<>();
- public BubbleData(Context context, BubbleLogger bubbleLogger) {
+ public BubbleData(Context context, BubbleLogger bubbleLogger, BubblePositioner positioner) {
mContext = context;
mLogger = bubbleLogger;
+ mPositioner = positioner;
+ mOverflow = new BubbleOverflow(context, positioner);
mBubbles = new ArrayList<>();
mOverflowBubbles = new ArrayList<>();
mPendingBubbles = new HashMap<>();
@@ -178,6 +182,10 @@ public class BubbleData {
return !mBubbles.isEmpty();
}
+ public boolean hasOverflowBubbles() {
+ return !mOverflowBubbles.isEmpty();
+ }
+
public boolean isExpanded() {
return mExpanded;
}
@@ -195,10 +203,14 @@ public class BubbleData {
}
@Nullable
- public Bubble getSelectedBubble() {
+ public BubbleViewProvider getSelectedBubble() {
return mSelectedBubble;
}
+ public BubbleOverflow getOverflow() {
+ return mOverflow;
+ }
+
/** Return a read-only current active bubble lists. */
public List<Bubble> getActiveBubbles() {
return Collections.unmodifiableList(mBubbles);
@@ -212,7 +224,7 @@ public class BubbleData {
dispatchPendingChanges();
}
- public void setSelectedBubble(Bubble bubble) {
+ public void setSelectedBubble(BubbleViewProvider bubble) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "setSelectedBubble: " + bubble);
}
@@ -224,6 +236,10 @@ public class BubbleData {
mShowingOverflow = showingOverflow;
}
+ boolean isShowingOverflow() {
+ return mShowingOverflow && (isExpanded() || mPositioner.showingInTaskbar());
+ }
+
/**
* Constructs a new bubble or returns an existing one. Does not add new bubbles to
* bubble data, must go through {@link #notificationEntryUpdated(Bubble, boolean, boolean)}
@@ -264,8 +280,8 @@ public class BubbleData {
/**
* When this method is called it is expected that all info in the bubble has completed loading.
- * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context,
- * BubbleStackView, BubbleIconFactory, boolean).
+ * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleController, BubbleStackView,
+ * BubbleIconFactory, boolean)
*/
void notificationEntryUpdated(Bubble bubble, boolean suppressFlyout, boolean showInShade) {
if (DEBUG_BUBBLE_DATA) {
@@ -484,10 +500,17 @@ public class BubbleData {
Bubble bubbleToRemove = mBubbles.get(indexToRemove);
bubbleToRemove.stopInflation();
if (mBubbles.size() == 1) {
- // Going to become empty, handle specially.
- setExpandedInternal(false);
- // Don't use setSelectedBubbleInternal because we don't want to trigger an applyUpdate
- mSelectedBubble = null;
+ if (hasOverflowBubbles() && (mPositioner.showingInTaskbar() || isExpanded())) {
+ // No more active bubbles but we have stuff in the overflow -- select that view
+ // if we're already expanded or always showing.
+ setShowingOverflow(true);
+ setSelectedBubbleInternal(mOverflow);
+ } else {
+ setExpandedInternal(false);
+ // Don't use setSelectedBubbleInternal because we don't want to trigger an
+ // applyUpdate
+ mSelectedBubble = null;
+ }
}
if (indexToRemove < mBubbles.size() - 1) {
// Removing anything but the last bubble means positions will change.
@@ -505,7 +528,7 @@ public class BubbleData {
if (Objects.equals(mSelectedBubble, bubbleToRemove)) {
// Move selection to the new bubble at the same position.
int newIndex = Math.min(indexToRemove, mBubbles.size() - 1);
- Bubble newSelected = mBubbles.get(newIndex);
+ BubbleViewProvider newSelected = mBubbles.get(newIndex);
setSelectedBubbleInternal(newSelected);
}
maybeSendDeleteIntent(reason, bubbleToRemove);
@@ -564,7 +587,7 @@ public class BubbleData {
*
* @param bubble the new selected bubble
*/
- private void setSelectedBubbleInternal(@Nullable Bubble bubble) {
+ private void setSelectedBubbleInternal(@Nullable BubbleViewProvider bubble) {
if (DEBUG_BUBBLE_DATA) {
Log.d(TAG, "setSelectedBubbleInternal: " + bubble);
}
@@ -572,14 +595,17 @@ public class BubbleData {
return;
}
// Otherwise, if we are showing the overflow menu, return to the previously selected bubble.
-
- if (bubble != null && !mBubbles.contains(bubble) && !mOverflowBubbles.contains(bubble)) {
+ boolean isOverflow = bubble != null && BubbleOverflow.KEY.equals(bubble.getKey());
+ if (bubble != null
+ && !mBubbles.contains(bubble)
+ && !mOverflowBubbles.contains(bubble)
+ && !isOverflow) {
Log.e(TAG, "Cannot select bubble which doesn't exist!"
+ " (" + bubble + ") bubbles=" + mBubbles);
return;
}
- if (mExpanded && bubble != null) {
- bubble.markAsAccessedAt(mTimeSource.currentTimeMillis());
+ if (mExpanded && bubble != null && !isOverflow) {
+ ((Bubble) bubble).markAsAccessedAt(mTimeSource.currentTimeMillis());
}
mSelectedBubble = bubble;
mStateChange.selectedBubble = bubble;
@@ -629,7 +655,7 @@ public class BubbleData {
return;
}
if (shouldExpand) {
- if (mBubbles.isEmpty()) {
+ if (mBubbles.isEmpty() && !mShowingOverflow) {
Log.e(TAG, "Attempt to expand stack when empty!");
return;
}
@@ -637,7 +663,9 @@ public class BubbleData {
Log.e(TAG, "Attempt to expand stack without selected bubble!");
return;
}
- mSelectedBubble.markAsAccessedAt(mTimeSource.currentTimeMillis());
+ if (mSelectedBubble instanceof Bubble) {
+ ((Bubble) mSelectedBubble).markAsAccessedAt(mTimeSource.currentTimeMillis());
+ }
mStateChange.orderChanged |= repackAll();
} else if (!mBubbles.isEmpty()) {
// Apply ordering and grouping rules from expanded -> collapsed, then save
@@ -647,14 +675,18 @@ public class BubbleData {
if (mShowingOverflow) {
// Show previously selected bubble instead of overflow menu on next expansion.
- setSelectedBubbleInternal(mSelectedBubble);
+ if (!mSelectedBubble.getKey().equals(mOverflow.getKey())) {
+ setSelectedBubbleInternal(mSelectedBubble);
+ } else {
+ setSelectedBubbleInternal(mBubbles.get(0));
+ }
}
if (mBubbles.indexOf(mSelectedBubble) > 0) {
// Move the selected bubble to the top while collapsed.
int index = mBubbles.indexOf(mSelectedBubble);
if (index != 0) {
- mBubbles.remove(mSelectedBubble);
- mBubbles.add(0, mSelectedBubble);
+ mBubbles.remove((Bubble) mSelectedBubble);
+ mBubbles.add(0, (Bubble) mSelectedBubble);
mStateChange.orderChanged = true;
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index 95085d0f1a85..8ab2f6325d2b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -63,11 +63,17 @@ class BubbleOverflow(
overflowBtn = null
}
+ /** Call before use and again if cleanUpExpandedState was called. */
fun initialize(controller: BubbleController) {
getExpandedView()?.initialize(controller, controller.stackView)
getExpandedView()?.setOverflow(true)
}
+ fun cleanUpExpandedState() {
+ expandedView?.cleanUpExpandedState()
+ expandedView = null
+ }
+
fun update() {
updateResources()
getExpandedView()?.applyThemeAttrs()
@@ -132,11 +138,6 @@ class BubbleOverflow(
overflowBtn?.updateDotVisibility(true /* animate */)
}
- fun cleanUpExpandedState() {
- expandedView?.cleanUpExpandedState()
- expandedView = null
- }
-
override fun getExpandedView(): BubbleExpandedView? {
if (expandedView == null) {
expandedView = inflater.inflate(R.layout.bubble_expanded_view,
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 38fcd2f06003..cbe98458df86 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
@@ -227,7 +227,7 @@ public class BubbleStackView extends FrameLayout
* once it collapses.
*/
@Nullable
- private Bubble mBubbleToExpandAfterFlyoutCollapse = null;
+ private BubbleViewProvider mBubbleToExpandAfterFlyoutCollapse = null;
/** Layout change listener that moves the stack to the nearest valid position on rotation. */
private OnLayoutChangeListener mOrientationChangedListener;
@@ -571,6 +571,16 @@ public class BubbleStackView extends FrameLayout
mBubbleContainer.setActiveController(mStackAnimationController);
hideFlyoutImmediate();
+ if (!mPositioner.showingInTaskbar()) {
+ // Also, save the magnetized stack so we can dispatch touch events to it.
+ mMagnetizedObject = mStackAnimationController.getMagnetizedStack(
+ mMagneticTarget);
+ mMagnetizedObject.setMagnetListener(mStackMagnetListener);
+ } else {
+ // In taskbar, the stack isn't draggable so we shouldn't dispatch touch events.
+ mMagnetizedObject = null;
+ }
+
// Also, save the magnetized stack so we can dispatch touch events to it.
mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget);
mMagnetizedObject.setMagnetListener(mStackMagnetListener);
@@ -592,7 +602,9 @@ public class BubbleStackView extends FrameLayout
public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX,
float viewInitialY, float dx, float dy) {
// 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;
}
@@ -602,7 +614,7 @@ public class BubbleStackView extends FrameLayout
// 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)) {
- if (mBubbleData.isExpanded()) {
+ if (mBubbleData.isExpanded() || mPositioner.showingInTaskbar()) {
mExpandedAnimationController.dragBubbleOut(
v, viewInitialX + dx, viewInitialY + dy);
} else {
@@ -743,7 +755,7 @@ public class BubbleStackView extends FrameLayout
ta.recycle();
final Runnable onBubbleAnimatedOut = () -> {
- if (getBubbleCount() == 0) {
+ if (getBubbleCount() == 0 && !mBubbleData.isShowingOverflow()) {
mBubbleController.onAllBubblesAnimatedOut();
}
};
@@ -816,16 +828,16 @@ public class BubbleStackView extends FrameLayout
setFocusable(true);
mBubbleContainer.bringToFront();
- mBubbleOverflow = new BubbleOverflow(getContext(), mPositioner);
- mBubbleOverflow.initialize(mBubbleController);
+ mBubbleOverflow = mBubbleData.getOverflow();
mBubbleContainer.addView(mBubbleOverflow.getIconView(),
mBubbleContainer.getChildCount() /* index */,
new FrameLayout.LayoutParams(mPositioner.getBubbleSize(),
mPositioner.getBubbleSize()));
updateOverflow();
mBubbleOverflow.getIconView().setOnClickListener((View v) -> {
- setSelectedBubble(mBubbleOverflow);
- showManageMenu(false);
+ mBubbleData.setShowingOverflow(true);
+ mBubbleData.setSelectedBubble(mBubbleOverflow);
+ mBubbleData.setExpanded(true);
});
setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
@@ -996,11 +1008,12 @@ public class BubbleStackView extends FrameLayout
mManageMenu.findViewById(R.id.bubble_manage_menu_settings_container).setOnClickListener(
view -> {
showManageMenu(false /* show */);
- final Bubble bubble = mBubbleData.getSelectedBubble();
+ final BubbleViewProvider bubble = mBubbleData.getSelectedBubble();
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
- final Intent intent = bubble.getSettingsIntent(mContext);
+ // If it's in the stack it's a proper Bubble.
+ final Intent intent = ((Bubble) bubble).getSettingsIntent(mContext);
mBubbleData.setExpanded(false);
- mContext.startActivityAsUser(intent, bubble.getUser());
+ mContext.startActivityAsUser(intent, ((Bubble) bubble).getUser());
logBubbleEvent(bubble,
FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
}
@@ -1443,10 +1456,9 @@ public class BubbleStackView extends FrameLayout
}
private void updateOverflowVisibility() {
- if (mBubbleOverflow == null) {
- return;
- }
- mBubbleOverflow.setVisible(mIsExpanded ? VISIBLE : GONE);
+ mBubbleOverflow.setVisible((mIsExpanded || mBubbleData.isShowingOverflow())
+ ? VISIBLE
+ : GONE);
}
// via BubbleData.Listener
@@ -2128,7 +2140,7 @@ public class BubbleStackView extends FrameLayout
}
}
- private void dismissBubbleIfExists(@Nullable Bubble bubble) {
+ private void dismissBubbleIfExists(@Nullable BubbleViewProvider bubble) {
if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
mBubbleData.dismissBubbleWithKey(bubble.getKey(), Bubbles.DISMISS_USER_GESTURE);
}
@@ -2337,7 +2349,7 @@ public class BubbleStackView extends FrameLayout
}
if (!mIsExpanded) {
- if (getBubbleCount() > 0) {
+ if (getBubbleCount() > 0 || mBubbleData.isShowingOverflow()) {
mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect);
// Increase the touch target size of the bubble
outRect.top -= mBubbleTouchPadding;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 7adc4112fa90..7c9b9c37c2c4 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -35,6 +35,7 @@ import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
+import android.view.WindowManager;
import androidx.test.filters.SmallTest;
@@ -135,8 +136,9 @@ public class BubbleDataTest extends ShellTestCase {
mBubbleB2 = new Bubble(mEntryB2, mSuppressionListener, mPendingIntentCanceledListener);
mBubbleB3 = new Bubble(mEntryB3, mSuppressionListener, mPendingIntentCanceledListener);
mBubbleC1 = new Bubble(mEntryC1, mSuppressionListener, mPendingIntentCanceledListener);
-
- mBubbleData = new BubbleData(getContext(), mBubbleLogger);
+ TestableBubblePositioner positioner = new TestableBubblePositioner(mContext,
+ mock(WindowManager.class));
+ mBubbleData = new BubbleData(getContext(), mBubbleLogger, positioner);
// Used by BubbleData to set lastAccessedTime
when(mTimeSource.currentTimeMillis()).thenReturn(1000L);