diff options
author | 2024-03-07 19:42:18 +0000 | |
---|---|---|
committer | 2024-03-07 19:42:18 +0000 | |
commit | a0d8e5fb48383cefd514acad6249514f70aff489 (patch) | |
tree | 8f159d718dc0e1a2dab8106bdf08ebe265cfe930 | |
parent | 9fe5e6f2da1a2c45845dcc00a9f5a9d0269955c6 (diff) | |
parent | a340394365bc5d9a29eb9116a7d106de1c2aee94 (diff) |
Merge changes from topic "bubble-bar-drag" into main
* changes:
Support expanded view drag to left or right
Introduce BubbleBarLocation to define bubble bar location
12 files changed, 344 insertions, 44 deletions
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt index 9cd14fca6a9d..e422198c40c5 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt @@ -28,6 +28,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.wm.shell.R import com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT +import com.android.wm.shell.common.bubbles.BubbleBarLocation import com.google.common.truth.Truth.assertThat import com.google.common.util.concurrent.MoreExecutors.directExecutor import org.junit.Before @@ -486,6 +487,32 @@ class BubblePositionerTest { positioner.screenRect.width() - paddings[0] - paddings[2]) } + @Test + fun testIsBubbleBarOnLeft_defaultsToRight() { + positioner.bubbleBarLocation = BubbleBarLocation.DEFAULT + assertThat(positioner.isBubbleBarOnLeft).isFalse() + + // Check that left and right return expected position + positioner.bubbleBarLocation = BubbleBarLocation.LEFT + assertThat(positioner.isBubbleBarOnLeft).isTrue() + positioner.bubbleBarLocation = BubbleBarLocation.RIGHT + assertThat(positioner.isBubbleBarOnLeft).isFalse() + } + + @Test + fun testIsBubbleBarOnLeft_rtlEnabled_defaultsToLeft() { + positioner.update(defaultDeviceConfig.copy(isRtl = true)) + + positioner.bubbleBarLocation = BubbleBarLocation.DEFAULT + assertThat(positioner.isBubbleBarOnLeft).isTrue() + + // Check that left and right return expected position + positioner.bubbleBarLocation = BubbleBarLocation.LEFT + assertThat(positioner.isBubbleBarOnLeft).isTrue() + positioner.bubbleBarLocation = BubbleBarLocation.RIGHT + assertThat(positioner.isBubbleBarOnLeft).isFalse() + } + private val defaultYPosition: Float /** * Calculates the Y position bubbles should be placed based on the config. Based on the 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 96aaf02cb5e3..9585842a2014 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 @@ -103,6 +103,7 @@ import com.android.wm.shell.common.TaskStackListenerCallback; import com.android.wm.shell.common.TaskStackListenerImpl; import com.android.wm.shell.common.annotations.ShellBackgroundThread; import com.android.wm.shell.common.annotations.ShellMainThread; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; import com.android.wm.shell.common.bubbles.BubbleBarUpdate; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHandedController; @@ -708,6 +709,30 @@ public class BubbleController implements ConfigurationChangeListener, return mBubbleProperties.isBubbleBarEnabled() && mBubblePositioner.isLargeScreen(); } + /** + * Returns current {@link BubbleBarLocation} if bubble bar is being used. + * Otherwise returns <code>null</code> + */ + @Nullable + public BubbleBarLocation getBubbleBarLocation() { + if (canShowAsBubbleBar()) { + return mBubblePositioner.getBubbleBarLocation(); + } + return null; + } + + /** + * Update bubble bar location and trigger and update to listeners + */ + public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) { + if (canShowAsBubbleBar()) { + mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); + BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate(); + bubbleBarUpdate.bubbleBarLocation = bubbleBarLocation; + mBubbleStateListener.onBubbleStateChange(bubbleBarUpdate); + } + } + /** Whether this userId belongs to the current user. */ private boolean isCurrentProfile(int userId) { return userId == UserHandle.USER_ALL @@ -1179,7 +1204,7 @@ public class BubbleController implements ConfigurationChangeListener, */ @VisibleForTesting public void expandStackAndSelectBubbleFromLauncher(String key, Rect bubbleBarBounds) { - mBubblePositioner.setBubbleBarPosition(bubbleBarBounds); + mBubblePositioner.setBubbleBarBounds(bubbleBarBounds); if (BubbleOverflow.KEY.equals(key)) { mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow()); 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 6c2f925119f3..61f0ed22b537 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 @@ -165,7 +165,7 @@ public class BubbleData { * used when {@link BubbleController#isShowingAsBubbleBar()} is true. */ BubbleBarUpdate getInitialState() { - BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate(); + BubbleBarUpdate bubbleBarUpdate = BubbleBarUpdate.createInitialState(); bubbleBarUpdate.shouldShowEducation = shouldShowEducation; for (int i = 0; i < bubbles.size(); i++) { bubbleBarUpdate.currentBubbleList.add(bubbles.get(i).asBubbleBarBubble()); @@ -255,7 +255,9 @@ public class BubbleData { * Returns a bubble bar update populated with the current list of active bubbles. */ public BubbleBarUpdate getInitialStateForBubbleBar() { - return mStateChange.getInitialState(); + BubbleBarUpdate initialState = mStateChange.getInitialState(); + initialState.bubbleBarLocation = mPositioner.getBubbleBarLocation(); + return initialState; } public void setSuppressionChangedListener(Bubbles.BubbleMetadataFlagListener listener) { 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 a5853d621cb5..b215b616dcce 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 @@ -32,6 +32,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.launcher3.icons.IconNormalizer; import com.android.wm.shell.R; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; /** * Keeps track of display size, configuration, and specific bubble sizes. One place for all @@ -95,6 +96,7 @@ public class BubblePositioner { private PointF mRestingStackPosition; private boolean mShowingInBubbleBar; + private BubbleBarLocation mBubbleBarLocation = BubbleBarLocation.DEFAULT; private final Rect mBubbleBarBounds = new Rect(); public BubblePositioner(Context context, WindowManager windowManager) { @@ -797,14 +799,36 @@ public class BubblePositioner { mShowingInBubbleBar = showingInBubbleBar; } + public void setBubbleBarLocation(BubbleBarLocation location) { + mBubbleBarLocation = location; + } + + public BubbleBarLocation getBubbleBarLocation() { + return mBubbleBarLocation; + } + + /** + * @return <code>true</code> when bubble bar is on the left and <code>false</code> when on right + */ + public boolean isBubbleBarOnLeft() { + return mBubbleBarLocation.isOnLeft(mDeviceConfig.isRtl()); + } + /** * Sets the position of the bubble bar in display coordinates. */ - public void setBubbleBarPosition(Rect bubbleBarBounds) { + public void setBubbleBarBounds(Rect bubbleBarBounds) { mBubbleBarBounds.set(bubbleBarBounds); } /** + * Returns the display coordinates of the bubble bar. + */ + public Rect getBubbleBarBounds() { + return mBubbleBarBounds; + } + + /** * How wide the expanded view should be when showing from the bubble bar. */ public int getExpandedViewWidthForBubbleBar(boolean isOverflow) { @@ -831,11 +855,4 @@ public class BubblePositioner { public int getBubbleBarExpandedViewPadding() { return mExpandedViewPadding; } - - /** - * Returns the display coordinates of the bubble bar. - */ - public Rect getBubbleBarBounds() { - return mBubbleBarBounds; - } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java index 8946f41e96a7..9eb963237115 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java @@ -477,7 +477,7 @@ public class BubbleBarAnimationHelper { private Point getExpandedViewRestPosition(Size size) { final int padding = mPositioner.getBubbleBarExpandedViewPadding(); Point point = new Point(); - if (mLayerView.isOnLeft()) { + if (mPositioner.isBubbleBarOnLeft()) { point.x = mPositioner.getInsets().left + padding; } else { point.x = mPositioner.getAvailableRect().width() - size.getWidth() - padding; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt index 7d37d6068dfb..056598b86d58 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt @@ -19,6 +19,8 @@ package com.android.wm.shell.bubbles.bar import android.annotation.SuppressLint import android.view.MotionEvent import android.view.View +import com.android.wm.shell.bubbles.BubblePositioner +import com.android.wm.shell.common.bubbles.BubbleBarLocation import com.android.wm.shell.common.bubbles.DismissView import com.android.wm.shell.common.bubbles.RelativeTouchListener import com.android.wm.shell.common.magnetictarget.MagnetizedObject @@ -29,7 +31,8 @@ class BubbleBarExpandedViewDragController( private val expandedView: BubbleBarExpandedView, private val dismissView: DismissView, private val animationHelper: BubbleBarAnimationHelper, - private val onDismissed: () -> Unit + private val bubblePositioner: BubblePositioner, + private val dragListener: DragListener ) { var isStuckToDismiss: Boolean = false @@ -45,11 +48,11 @@ class BubbleBarExpandedViewDragController( magnetizedExpandedView.magnetListener = MagnetListener() magnetizedExpandedView.animateStuckToTarget = { - target: MagnetizedObject.MagneticTarget, - _: Float, - _: Float, - _: Boolean, - after: (() -> Unit)? -> + target: MagnetizedObject.MagneticTarget, + _: Float, + _: Float, + _: Boolean, + after: (() -> Unit)? -> animationHelper.animateIntoTarget(target, after) } @@ -73,13 +76,34 @@ class BubbleBarExpandedViewDragController( } } + /** Listener to receive callback about dragging events */ + interface DragListener { + /** + * Bubble bar [BubbleBarLocation] has changed as a result of dragging the expanded view. + * + * Triggered when drag gesture passes the middle of the screen and before touch up. + * Can be triggered multiple times per gesture. + * + * @param location new location of the bubble bar as a result of the ongoing drag operation + */ + fun onLocationChanged(location: BubbleBarLocation) + + /** Expanded view has been released in the dismiss target */ + fun onReleasedInDismiss() + } + private inner class HandleDragListener : RelativeTouchListener() { private var isMoving = false + private var screenCenterX: Int = -1 + private var isOnLeft = false override fun onDown(v: View, ev: MotionEvent): Boolean { // While animating, don't allow new touch events - return !expandedView.isAnimating + if (expandedView.isAnimating) return false + screenCenterX = bubblePositioner.screenRect.centerX() + isOnLeft = bubblePositioner.isBubbleBarOnLeft + return true } override fun onMove( @@ -97,6 +121,14 @@ class BubbleBarExpandedViewDragController( expandedView.translationX = expandedViewInitialTranslationX + dx expandedView.translationY = expandedViewInitialTranslationY + dy dismissView.show() + + if (isOnLeft && ev.rawX > screenCenterX) { + isOnLeft = false + dragListener.onLocationChanged(BubbleBarLocation.RIGHT) + } else if (!isOnLeft && ev.rawX < screenCenterX) { + isOnLeft = true + dragListener.onLocationChanged(BubbleBarLocation.LEFT) + } } override fun onUp( @@ -113,6 +145,7 @@ class BubbleBarExpandedViewDragController( } override fun onCancel(v: View, ev: MotionEvent, viewInitialX: Float, viewInitialY: Float) { + isStuckToDismiss = false finishDrag() } @@ -127,30 +160,29 @@ class BubbleBarExpandedViewDragController( private inner class MagnetListener : MagnetizedObject.MagnetListener { override fun onStuckToTarget( - target: MagnetizedObject.MagneticTarget, - draggedObject: MagnetizedObject<*> + target: MagnetizedObject.MagneticTarget, + draggedObject: MagnetizedObject<*> ) { isStuckToDismiss = true } override fun onUnstuckFromTarget( - target: MagnetizedObject.MagneticTarget, - draggedObject: MagnetizedObject<*>, - velX: Float, - velY: Float, - wasFlungOut: Boolean + target: MagnetizedObject.MagneticTarget, + draggedObject: MagnetizedObject<*>, + velX: Float, + velY: Float, + wasFlungOut: Boolean ) { isStuckToDismiss = false animationHelper.animateUnstuckFromDismissView(target) } override fun onReleasedInTarget( - target: MagnetizedObject.MagneticTarget, - draggedObject: MagnetizedObject<*> + target: MagnetizedObject.MagneticTarget, + draggedObject: MagnetizedObject<*> ) { - onDismissed() + dragListener.onReleasedInDismiss() dismissView.hide() } } } - diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java index 42799d975e1b..3fb9f63c0506 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java @@ -33,6 +33,8 @@ import android.view.ViewTreeObserver; import android.view.WindowManager; import android.widget.FrameLayout; +import androidx.annotation.NonNull; + import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubble; import com.android.wm.shell.bubbles.BubbleController; @@ -42,6 +44,8 @@ import com.android.wm.shell.bubbles.BubblePositioner; import com.android.wm.shell.bubbles.BubbleViewProvider; import com.android.wm.shell.bubbles.DeviceConfig; import com.android.wm.shell.bubbles.DismissViewUtils; +import com.android.wm.shell.bubbles.bar.BubbleBarExpandedViewDragController.DragListener; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; import com.android.wm.shell.common.bubbles.DismissView; import kotlin.Unit; @@ -155,12 +159,6 @@ public class BubbleBarLayerView extends FrameLayout return mIsExpanded; } - // TODO(b/313661121) - when dragging is implemented, check user setting first - /** Whether the expanded view is positioned on the left or right side of the screen. */ - public boolean isOnLeft() { - return getLayoutDirection() == LAYOUT_DIRECTION_RTL; - } - /** Shows the expanded view of the provided bubble. */ public void showExpandedView(BubbleViewProvider b) { BubbleBarExpandedView expandedView = b.getBubbleBarExpandedView(); @@ -207,15 +205,23 @@ public class BubbleBarLayerView extends FrameLayout } }); + DragListener dragListener = new DragListener() { + @Override + public void onLocationChanged(@NonNull BubbleBarLocation location) { + mBubbleController.setBubbleBarLocation(location); + } + + @Override + public void onReleasedInDismiss() { + mBubbleController.dismissBubble(mExpandedBubble.getKey(), DISMISS_USER_GESTURE); + } + }; mDragController = new BubbleBarExpandedViewDragController( mExpandedView, mDismissView, mAnimationHelper, - () -> { - mBubbleController.dismissBubble(mExpandedBubble.getKey(), - DISMISS_USER_GESTURE); - return Unit.INSTANCE; - }); + mPositioner, + dragListener); addView(mExpandedView, new LayoutParams(width, height, Gravity.LEFT)); } @@ -352,7 +358,7 @@ public class BubbleBarLayerView extends FrameLayout lp.width = width; lp.height = height; mExpandedView.setLayoutParams(lp); - if (isOnLeft()) { + if (mPositioner.isBubbleBarOnLeft()) { mExpandedView.setX(mPositioner.getInsets().left + padding); } else { mExpandedView.setX(mPositioner.getAvailableRect().width() - width - padding); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.kt new file mode 100644 index 000000000000..f0bdfdef1073 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.kt @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.common.bubbles + +import android.os.Parcel +import android.os.Parcelable + +/** + * The location of the bubble bar. + */ +enum class BubbleBarLocation : Parcelable { + /** + * Place bubble bar at the default location for the chosen system language. + * If an RTL language is used, it is on the left. Otherwise on the right. + */ + DEFAULT, + /** Default bubble bar location is overridden. Place bubble bar on the left. */ + LEFT, + /** Default bubble bar location is overridden. Place bubble bar on the right. */ + RIGHT; + + /** + * Returns whether bubble bar is pinned to the left edge or right edge. + */ + fun isOnLeft(isRtl: Boolean): Boolean { + if (this == DEFAULT) { + return isRtl + } + return this == LEFT + } + + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeString(name) + } + + companion object { + @JvmField + val CREATOR = object : Parcelable.Creator<BubbleBarLocation> { + override fun createFromParcel(parcel: Parcel): BubbleBarLocation { + return parcel.readString()?.let { valueOf(it) } ?: DEFAULT + } + + override fun newArray(size: Int) = arrayOfNulls<BubbleBarLocation>(size) + } + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java index fc627a8dcb36..e5f6c370da84 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarUpdate.java @@ -33,6 +33,7 @@ public class BubbleBarUpdate implements Parcelable { public static final String BUNDLE_KEY = "update"; + public final boolean initialState; public boolean expandedChanged; public boolean expanded; public boolean shouldShowEducation; @@ -46,6 +47,8 @@ public class BubbleBarUpdate implements Parcelable { public String suppressedBubbleKey; @Nullable public String unsupressedBubbleKey; + @Nullable + public BubbleBarLocation bubbleBarLocation; // This is only populated if bubbles have been removed. public List<RemovedBubble> removedBubbles = new ArrayList<>(); @@ -56,10 +59,17 @@ public class BubbleBarUpdate implements Parcelable { // This is only populated the first time a listener is connected so it gets the current state. public List<BubbleInfo> currentBubbleList = new ArrayList<>(); + public BubbleBarUpdate() { + this(false); + } + + private BubbleBarUpdate(boolean initialState) { + this.initialState = initialState; } public BubbleBarUpdate(Parcel parcel) { + initialState = parcel.readBoolean(); expandedChanged = parcel.readBoolean(); expanded = parcel.readBoolean(); shouldShowEducation = parcel.readBoolean(); @@ -75,6 +85,8 @@ public class BubbleBarUpdate implements Parcelable { parcel.readStringList(bubbleKeysInOrder); currentBubbleList = parcel.readParcelableList(new ArrayList<>(), BubbleInfo.class.getClassLoader()); + bubbleBarLocation = parcel.readParcelable(BubbleBarLocation.class.getClassLoader(), + BubbleBarLocation.class); } /** @@ -89,12 +101,15 @@ public class BubbleBarUpdate implements Parcelable { || !bubbleKeysInOrder.isEmpty() || suppressedBubbleKey != null || unsupressedBubbleKey != null - || !currentBubbleList.isEmpty(); + || !currentBubbleList.isEmpty() + || bubbleBarLocation != null; } @Override public String toString() { - return "BubbleBarUpdate{ expandedChanged=" + expandedChanged + return "BubbleBarUpdate{" + + " initialState=" + initialState + + " expandedChanged=" + expandedChanged + " expanded=" + expanded + " selectedBubbleKey=" + selectedBubbleKey + " shouldShowEducation=" + shouldShowEducation @@ -105,6 +120,7 @@ public class BubbleBarUpdate implements Parcelable { + " removedBubbles=" + removedBubbles + " bubbles=" + bubbleKeysInOrder + " currentBubbleList=" + currentBubbleList + + " bubbleBarLocation=" + bubbleBarLocation + " }"; } @@ -115,6 +131,7 @@ public class BubbleBarUpdate implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { + parcel.writeBoolean(initialState); parcel.writeBoolean(expandedChanged); parcel.writeBoolean(expanded); parcel.writeBoolean(shouldShowEducation); @@ -126,6 +143,16 @@ public class BubbleBarUpdate implements Parcelable { parcel.writeParcelableList(removedBubbles, flags); parcel.writeStringList(bubbleKeysInOrder); parcel.writeParcelableList(currentBubbleList, flags); + parcel.writeParcelable(bubbleBarLocation, flags); + } + + /** + * Create update for initial set of values. + * <p> + * Used when bubble bar is newly created. + */ + public static BubbleBarUpdate createInitialState() { + return new BubbleBarUpdate(true); } @NonNull 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 fa0aba5a6ee9..48e396a4817f 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 @@ -49,6 +49,8 @@ import androidx.test.filters.SmallTest; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.bubbles.BubbleData.TimeSource; import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; +import com.android.wm.shell.common.bubbles.BubbleBarUpdate; import com.google.common.collect.ImmutableList; @@ -1207,6 +1209,19 @@ public class BubbleDataTest extends ShellTestCase { assertOverflowChangedTo(ImmutableList.of()); } + @Test + public void test_getInitialStateForBubbleBar_includesInitialBubblesAndPosition() { + sendUpdatedEntryAtTime(mEntryA1, 1000); + sendUpdatedEntryAtTime(mEntryA2, 2000); + mPositioner.setBubbleBarLocation(BubbleBarLocation.LEFT); + + BubbleBarUpdate update = mBubbleData.getInitialStateForBubbleBar(); + assertThat(update.currentBubbleList).hasSize(2); + assertThat(update.currentBubbleList.get(0).getKey()).isEqualTo(mEntryA2.getKey()); + assertThat(update.currentBubbleList.get(1).getKey()).isEqualTo(mEntryA1.getKey()); + assertThat(update.bubbleBarLocation).isEqualTo(BubbleBarLocation.LEFT); + } + private void verifyUpdateReceived() { verify(mListener).applyUpdate(mUpdateCaptor.capture()); reset(mListener); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleBarLocationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleBarLocationTest.kt new file mode 100644 index 000000000000..27e0b196f0be --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/bubbles/BubbleBarLocationTest.kt @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.wm.shell.common.bubbles + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.common.bubbles.BubbleBarLocation.DEFAULT +import com.android.wm.shell.common.bubbles.BubbleBarLocation.LEFT +import com.android.wm.shell.common.bubbles.BubbleBarLocation.RIGHT +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class BubbleBarLocationTest : ShellTestCase() { + + @Test + fun isOnLeft_rtlEnabled_defaultsToLeft() { + assertThat(DEFAULT.isOnLeft(isRtl = true)).isTrue() + } + + @Test + fun isOnLeft_rtlDisabled_defaultsToRight() { + assertThat(DEFAULT.isOnLeft(isRtl = false)).isFalse() + } + + @Test + fun isOnLeft_left_trueForAllLanguageDirections() { + assertThat(LEFT.isOnLeft(isRtl = false)).isTrue() + assertThat(LEFT.isOnLeft(isRtl = true)).isTrue() + } + + @Test + fun isOnLeft_right_falseForAllLanguageDirections() { + assertThat(RIGHT.isOnLeft(isRtl = false)).isFalse() + assertThat(RIGHT.isOnLeft(isRtl = true)).isFalse() + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index fbefb0eedfa8..c0d3d27e94a3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -90,6 +90,7 @@ import android.view.View; import android.view.ViewTreeObserver; import android.view.WindowManager; +import androidx.annotation.Nullable; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor; @@ -196,6 +197,7 @@ import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.TaskStackListenerImpl; +import com.android.wm.shell.common.bubbles.BubbleBarLocation; import com.android.wm.shell.common.bubbles.BubbleBarUpdate; import com.android.wm.shell.draganddrop.DragAndDropController; import com.android.wm.shell.onehanded.OneHandedController; @@ -2251,6 +2253,30 @@ public class BubblesTest extends SysuiTestCase { verify(mBubbleController).onSensitiveNotificationProtectionStateChanged(false); } + @Test + public void setBubbleBarLocation_listenerNotified() { + mBubbleProperties.mIsBubbleBarEnabled = true; + mPositioner.setIsLargeScreen(true); + + FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); + mBubbleController.registerBubbleStateListener(bubbleStateListener); + mBubbleController.setBubbleBarLocation(BubbleBarLocation.LEFT); + assertThat(bubbleStateListener.mLastUpdate).isNotNull(); + assertThat(bubbleStateListener.mLastUpdate.bubbleBarLocation).isEqualTo( + BubbleBarLocation.LEFT); + } + + @Test + public void setBubbleBarLocation_barDisabled_shouldBeIgnored() { + mBubbleProperties.mIsBubbleBarEnabled = false; + mPositioner.setIsLargeScreen(true); + + FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); + mBubbleController.registerBubbleStateListener(bubbleStateListener); + mBubbleController.setBubbleBarLocation(BubbleBarLocation.LEFT); + assertThat(bubbleStateListener.mStateChangeCalls).isEqualTo(0); + } + /** Creates a bubble using the userId and package. */ private Bubble createBubble(int userId, String pkg) { final UserHandle userHandle = new UserHandle(userId); @@ -2436,8 +2462,15 @@ public class BubblesTest extends SysuiTestCase { } private static class FakeBubbleStateListener implements Bubbles.BubbleStateListener { + + int mStateChangeCalls = 0; + @Nullable + BubbleBarUpdate mLastUpdate; + @Override public void onBubbleStateChange(BubbleBarUpdate update) { + mStateChangeCalls++; + mLastUpdate = update; } } |