Pin bubbles to the bottom right on tablets for the prototype

- Remove some old code around bubbles in taskbar that is not currently
  relevant
- Update some of that code to work for the prototype, namely set
  a pinned location while the prototype is running and modify touch
  handling behavior so that the stack remains pinned

Test: manual - turn on the flag and add a bubble on tablet
             => bubble is above the taskbar on the bottom right
             => dragging and releasing the bubble returns it back
                to the same position
             => you can drag to dismiss when collapsed or expanded
Bug: 253318833
Bug: 173386799
Change-Id: I1a9530f98d908e19c5e65ffee9a87459a3e51c8c
This commit is contained in:
Mady Mellor
2022-10-14 13:09:17 -07:00
parent a6729cea41
commit a8057d4751
5 changed files with 41 additions and 97 deletions

View File

@@ -28,10 +28,6 @@ import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTRO
import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_GESTURE;
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 static com.android.wm.shell.bubbles.Bubbles.DISMISS_BLOCKED;
import static com.android.wm.shell.bubbles.Bubbles.DISMISS_GROUP_CANCELLED;
import static com.android.wm.shell.bubbles.Bubbles.DISMISS_INVALID_INTENT;
@@ -41,6 +37,7 @@ import static com.android.wm.shell.bubbles.Bubbles.DISMISS_NO_LONGER_BUBBLE;
import static com.android.wm.shell.bubbles.Bubbles.DISMISS_PACKAGE_REMOVED;
import static com.android.wm.shell.bubbles.Bubbles.DISMISS_SHORTCUT_REMOVED;
import static com.android.wm.shell.bubbles.Bubbles.DISMISS_USER_CHANGED;
import static com.android.wm.shell.floating.FloatingTasksController.SHOW_FLOATING_TASKS_AS_BUBBLES;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -59,10 +56,8 @@ import android.content.pm.ShortcutInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -126,18 +121,6 @@ public class BubbleController implements ConfigurationChangeListener {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
// TODO(b/173386799) keep in sync with Launcher3, not hooked up to anything
public static final String EXTRA_TASKBAR_CREATED = "taskbarCreated";
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";
// Should match with PhoneWindowManager
private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
@@ -470,52 +453,6 @@ public class BubbleController implements ConfigurationChangeListener {
mBubbleData.setExpanded(true);
}
/** Called when any taskbar state changes (e.g. visibility, position, sizes). */
private 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(isVisible ? point : null);
mBubblePositioner.updateForTaskbar(iconSize, taskbarPosition, isVisible, taskbarSize);
if (mStackView != null) {
if (isVisible && b.getBoolean(EXTRA_TASKBAR_CREATED, false /* default */)) {
// If taskbar was created, add and remove the window so that bubbles display on top
removeFromWindowManagerMaybe();
addToWindowManagerMaybe();
}
mStackView.updateStackPosition();
mBubbleIconFactory = new BubbleIconFactory(mContext);
mBubbleBadgeIconFactory = new BubbleBadgeIconFactory(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).
@@ -654,6 +591,11 @@ public class BubbleController implements ConfigurationChangeListener {
}
mStackView.setUnbubbleConversationCallback(mSysuiProxy::onUnbubbleConversation);
}
if (SHOW_FLOATING_TASKS_AS_BUBBLES && mBubblePositioner.isLargeScreen()) {
mBubblePositioner.setUsePinnedLocation(true);
} else {
mBubblePositioner.setUsePinnedLocation(false);
}
addToWindowManagerMaybe();
}
@@ -1731,13 +1673,6 @@ public class BubbleController implements ConfigurationChangeListener {
});
}
@Override
public void onTaskbarChanged(Bundle b) {
mMainExecutor.execute(() -> {
BubbleController.this.onTaskbarChanged(b);
});
}
@Override
public boolean handleDismissalInterception(BubbleEntry entry,
@Nullable List<BubbleEntry> children, IntConsumer removeCallback,

View File

@@ -713,6 +713,9 @@ public class BubblePositioner {
* is being shown.
*/
public PointF getDefaultStartPosition() {
if (mPinLocation != null) {
return mPinLocation;
}
// Start on the left if we're in LTR, right otherwise.
final boolean startOnLeft =
mContext.getResources().getConfiguration().getLayoutDirection()
@@ -766,11 +769,18 @@ public class BubblePositioner {
}
/**
* In some situations bubbles will be pinned to a specific onscreen location. This sets the
* location to anchor the stack to.
* In some situations bubbles will be pinned to a specific onscreen location. This sets whether
* bubbles should be pinned or not.
*/
public void setPinnedLocation(PointF point) {
mPinLocation = point;
public void setUsePinnedLocation(boolean usePinnedLocation) {
if (usePinnedLocation) {
mShowingInTaskbar = true;
mPinLocation = new PointF(mPositionRect.right - mBubbleSize,
mPositionRect.bottom - mBubbleSize);
} else {
mPinLocation = null;
mShowingInTaskbar = false;
}
}
/**

View File

@@ -613,16 +613,11 @@ public class BubbleStackView extends FrameLayout
mBubbleContainer.setActiveController(mStackAnimationController);
hideFlyoutImmediate();
if (mPositioner.showingInTaskbar()) {
// In taskbar, the stack isn't draggable so we shouldn't dispatch touch events.
mMagnetizedObject = null;
} else {
// Save the magnetized stack so we can dispatch touch events to it.
mMagnetizedObject = mStackAnimationController.getMagnetizedStack();
mMagnetizedObject.clearAllTargets();
mMagnetizedObject.addTarget(mMagneticTarget);
mMagnetizedObject.setMagnetListener(mStackMagnetListener);
}
// Save the magnetized stack so we can dispatch touch events to it.
mMagnetizedObject = mStackAnimationController.getMagnetizedStack();
mMagnetizedObject.clearAllTargets();
mMagnetizedObject.addTarget(mMagneticTarget);
mMagnetizedObject.setMagnetListener(mStackMagnetListener);
mIsDraggingStack = true;
@@ -641,10 +636,7 @@ 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
// Also ignore events if we shouldn't be draggable.
|| (mPositioner.showingInTaskbar() && !mIsExpanded)
|| mShowedUserEducationInTouchListenerActive) {
if (mIsExpansionAnimating || mShowedUserEducationInTouchListenerActive) {
return;
}
@@ -661,7 +653,7 @@ public class BubbleStackView extends FrameLayout
// bubble since it's stuck to the target.
if (!passEventToMagnetizedObject(ev)) {
updateBubbleShadows(true /* showForAllBubbles */);
if (mBubbleData.isExpanded() || mPositioner.showingInTaskbar()) {
if (mBubbleData.isExpanded()) {
mExpandedAnimationController.dragBubbleOut(
v, viewInitialX + dx, viewInitialY + dy);
} else {
@@ -678,9 +670,7 @@ 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
// Also ignore events if we shouldn't be draggable.
|| (mPositioner.showingInTaskbar() && !mIsExpanded)) {
if (mIsExpansionAnimating) {
return;
}
if (mShowedUserEducationInTouchListenerActive) {
@@ -696,6 +686,8 @@ public class BubbleStackView extends FrameLayout
// Re-show the expanded view if we hid it.
showExpandedViewIfNeeded();
} else if (mPositioner.showingInTaskbar()) {
mStackAnimationController.snapStackBack();
} 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.

View File

@@ -23,7 +23,6 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.app.NotificationChannel;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.RankingMap;
@@ -114,9 +113,6 @@ public interface Bubbles {
@Nullable
Bubble getBubbleWithShortcutId(String shortcutId);
/** Called for any taskbar changes. */
void onTaskbarChanged(Bundle b);
/**
* 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

View File

@@ -416,6 +416,17 @@ public class StackAnimationController extends
return destinationRelativeX;
}
/**
* Snaps the stack back to the previous resting position.
*/
public void snapStackBack() {
if (mLayout == null) {
return;
}
PointF p = getStackPositionAlongNearestHorizontalEdge();
springStackAfterFling(p.x, p.y);
}
/**
* Where the stack would be if it were snapped to the nearest horizontal edge (left or right).
*/