Merge "Modify the showAppBubble method to be showOrHideAppBubble" into tm-qpr-dev am: 027b3b377f
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20873919 Change-Id: I7b164ba6e4b1719d0b07e21d43c7229d6902c0c2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -973,21 +973,59 @@ public class BubbleController implements ConfigurationChangeListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds and expands bubble for a specific intent. These bubbles are <b>not</b> backed by a n
|
||||
* otification and remain until the user dismisses the bubble or bubble stack. Only one intent
|
||||
* bubble is supported at a time.
|
||||
* This method has different behavior depending on:
|
||||
* - if an app bubble exists
|
||||
* - if an app bubble is expanded
|
||||
*
|
||||
* If no app bubble exists, this will add and expand a bubble with the provided intent. The
|
||||
* intent must be explicit (i.e. include a package name or fully qualified component class name)
|
||||
* and the activity for it should be resizable.
|
||||
*
|
||||
* If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
|
||||
* expanded, calling this method will collapse it. If the app bubble is not expanded, calling
|
||||
* this method will expand it.
|
||||
*
|
||||
* These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
|
||||
* the bubble or bubble stack.
|
||||
*
|
||||
* Some notes:
|
||||
* - Only one app bubble is supported at a time
|
||||
* - Calling this method with a different intent than the existing app bubble will do nothing
|
||||
*
|
||||
* @param intent the intent to display in the bubble expanded view.
|
||||
*/
|
||||
public void showAppBubble(Intent intent) {
|
||||
if (intent == null || intent.getPackage() == null) return;
|
||||
public void showOrHideAppBubble(Intent intent) {
|
||||
if (intent == null || intent.getPackage() == null) {
|
||||
Log.w(TAG, "App bubble failed to show, invalid intent: " + intent
|
||||
+ ((intent != null) ? " with package: " + intent.getPackage() : " "));
|
||||
return;
|
||||
}
|
||||
|
||||
PackageManager packageManager = getPackageManagerForUser(mContext, mCurrentUserId);
|
||||
if (!isResizableActivity(intent, packageManager, KEY_APP_BUBBLE)) return;
|
||||
|
||||
Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
|
||||
b.setShouldAutoExpand(true);
|
||||
inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
|
||||
Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE);
|
||||
if (existingAppBubble != null) {
|
||||
BubbleViewProvider selectedBubble = mBubbleData.getSelectedBubble();
|
||||
if (isStackExpanded()) {
|
||||
if (selectedBubble != null && KEY_APP_BUBBLE.equals(selectedBubble.getKey())) {
|
||||
// App bubble is expanded, lets collapse
|
||||
collapseStack();
|
||||
} else {
|
||||
// App bubble is not selected, select it
|
||||
mBubbleData.setSelectedBubble(existingAppBubble);
|
||||
}
|
||||
} else {
|
||||
// App bubble is not selected, select it & expand
|
||||
mBubbleData.setSelectedBubble(existingAppBubble);
|
||||
mBubbleData.setExpanded(true);
|
||||
}
|
||||
} else {
|
||||
// App bubble does not exist, lets add and expand it
|
||||
Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
|
||||
b.setShouldAutoExpand(true);
|
||||
inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1697,9 +1735,9 @@ public class BubbleController implements ConfigurationChangeListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showAppBubble(Intent intent) {
|
||||
public void showOrHideAppBubble(Intent intent) {
|
||||
mMainExecutor.execute(() -> {
|
||||
BubbleController.this.showAppBubble(intent);
|
||||
BubbleController.this.showOrHideAppBubble(intent);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -109,13 +109,28 @@ public interface Bubbles {
|
||||
void expandStackAndSelectBubble(Bubble bubble);
|
||||
|
||||
/**
|
||||
* Adds and expands bubble that is not notification based, but instead based on an intent from
|
||||
* the app. The intent must be explicit (i.e. include a package name or fully qualified
|
||||
* component class name) and the activity for it should be resizable.
|
||||
* This method has different behavior depending on:
|
||||
* - if an app bubble exists
|
||||
* - if an app bubble is expanded
|
||||
*
|
||||
* @param intent the intent to populate the bubble.
|
||||
* If no app bubble exists, this will add and expand a bubble with the provided intent. The
|
||||
* intent must be explicit (i.e. include a package name or fully qualified component class name)
|
||||
* and the activity for it should be resizable.
|
||||
*
|
||||
* If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
|
||||
* expanded, calling this method will collapse it. If the app bubble is not expanded, calling
|
||||
* this method will expand it.
|
||||
*
|
||||
* These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
|
||||
* the bubble or bubble stack.
|
||||
*
|
||||
* Some notes:
|
||||
* - Only one app bubble is supported at a time
|
||||
* - Calling this method with a different intent than the existing app bubble will do nothing
|
||||
*
|
||||
* @param intent the intent to display in the bubble expanded view.
|
||||
*/
|
||||
void showAppBubble(Intent intent);
|
||||
void showOrHideAppBubble(Intent intent);
|
||||
|
||||
/**
|
||||
* @return a bubble that matches the provided shortcutId, if one exists.
|
||||
|
||||
@@ -57,7 +57,9 @@ constructor(
|
||||
* If the keyguard is locked, notes will open as a full screen experience. A locked device has
|
||||
* no contextual information which let us use the whole screen space available.
|
||||
*
|
||||
* If no in multi-window or the keyguard is unlocked, notes will open as a floating experience.
|
||||
* If no in multi-window or the keyguard is unlocked, notes will open as a bubble OR it will be
|
||||
* collapsed if the notes bubble is already opened.
|
||||
*
|
||||
* That will let users open other apps in full screen, and take contextual notes.
|
||||
*/
|
||||
fun showNoteTask(isInMultiWindowMode: Boolean = false) {
|
||||
@@ -75,7 +77,7 @@ constructor(
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
// TODO(b/254606432): Should include Intent.EXTRA_FLOATING_WINDOW_MODE parameter.
|
||||
bubbles.showAppBubble(intent)
|
||||
bubbles.showOrHideAppBubble(intent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(context).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,7 +102,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(bubbles).showAppBubble(notesIntent)
|
||||
verify(bubbles).showOrHideAppBubble(notesIntent)
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = true)
|
||||
|
||||
verify(context).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -123,7 +123,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -133,7 +133,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,7 +143,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,7 +153,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,7 +161,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController(isEnabled = false).showNoteTask()
|
||||
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -171,7 +171,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||
createNoteTaskController().showNoteTask(isInMultiWindowMode = false)
|
||||
|
||||
verify(context, never()).startActivity(notesIntent)
|
||||
verify(bubbles, never()).showAppBubble(notesIntent)
|
||||
verify(bubbles, never()).showOrHideAppBubble(notesIntent)
|
||||
}
|
||||
// endregion
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.service.notification.NotificationListenerService.REASON_AP
|
||||
import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||
import static com.android.wm.shell.bubbles.Bubble.KEY_APP_BUBBLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -228,6 +229,8 @@ public class BubblesTest extends SysuiTestCase {
|
||||
private BubbleEntry mBubbleEntryUser11;
|
||||
private BubbleEntry mBubbleEntry2User11;
|
||||
|
||||
private Intent mAppBubbleIntent;
|
||||
|
||||
@Mock
|
||||
private ShellInit mShellInit;
|
||||
@Mock
|
||||
@@ -323,6 +326,9 @@ public class BubblesTest extends SysuiTestCase {
|
||||
mBubbleEntry2User11 = BubblesManager.notifToBubbleEntry(
|
||||
mNotificationTestHelper.createBubble(handle));
|
||||
|
||||
mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
|
||||
mAppBubbleIntent.setPackage(mContext.getPackageName());
|
||||
|
||||
mZenModeConfig.suppressedVisualEffects = 0;
|
||||
when(mZenModeController.getConfig()).thenReturn(mZenModeConfig);
|
||||
|
||||
@@ -1630,6 +1636,62 @@ public class BubblesTest extends SysuiTestCase {
|
||||
any(Bubble.class), anyBoolean(), anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowOrHideAppBubble_addsAndExpand() {
|
||||
assertThat(mBubbleController.isStackExpanded()).isFalse();
|
||||
assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
|
||||
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
|
||||
verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true),
|
||||
/* showInShade= */ eq(false));
|
||||
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
|
||||
assertThat(mBubbleController.isStackExpanded()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowOrHideAppBubble_expandIfCollapsed() {
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
mBubbleController.updateBubble(mBubbleEntry);
|
||||
mBubbleController.collapseStack();
|
||||
assertThat(mBubbleController.isStackExpanded()).isFalse();
|
||||
|
||||
// Calling this while collapsed will expand the app bubble
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
|
||||
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
|
||||
assertThat(mBubbleController.isStackExpanded()).isTrue();
|
||||
assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowOrHideAppBubble_collapseIfSelected() {
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
|
||||
assertThat(mBubbleController.isStackExpanded()).isTrue();
|
||||
|
||||
// Calling this while the app bubble is expanded should collapse the stack
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
|
||||
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
|
||||
assertThat(mBubbleController.isStackExpanded()).isFalse();
|
||||
assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowOrHideAppBubble_selectIfNotSelected() {
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
mBubbleController.updateBubble(mBubbleEntry);
|
||||
mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
|
||||
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey());
|
||||
assertThat(mBubbleController.isStackExpanded()).isTrue();
|
||||
|
||||
mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
|
||||
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
|
||||
assertThat(mBubbleController.isStackExpanded()).isTrue();
|
||||
assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
/** Creates a bubble using the userId and package. */
|
||||
private Bubble createBubble(int userId, String pkg) {
|
||||
final UserHandle userHandle = new UserHandle(userId);
|
||||
|
||||
Reference in New Issue
Block a user