Merge "App Bubble custom icon support" into udc-dev

This commit is contained in:
Ivan Tkachenko
2023-03-20 17:42:35 +00:00
committed by Android (Google) Code Review
7 changed files with 37 additions and 23 deletions

View File

@@ -206,12 +206,14 @@ public class Bubble implements BubbleViewProvider {
public Bubble(Intent intent,
UserHandle user,
@Nullable Icon icon,
Executor mainExecutor) {
mKey = KEY_APP_BUBBLE;
mGroupKey = null;
mLocusId = null;
mFlags = 0;
mUser = user;
mIcon = icon;
mShowBubbleUpdateDot = false;
mMainExecutor = mainExecutor;
mTaskId = INVALID_TASK_ID;

View File

@@ -57,6 +57,7 @@ import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
@@ -1034,8 +1035,9 @@ public class BubbleController implements ConfigurationChangeListener {
*
* @param intent the intent to display in the bubble expanded view.
* @param user the {@link UserHandle} of the user to start this activity for.
* @param icon the {@link Icon} to use for the bubble view.
*/
public void showOrHideAppBubble(Intent intent, UserHandle user) {
public void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
if (intent == null || intent.getPackage() == null) {
Log.w(TAG, "App bubble failed to show, invalid intent: " + intent
+ ((intent != null) ? " with package: " + intent.getPackage() : " "));
@@ -1063,7 +1065,7 @@ public class BubbleController implements ConfigurationChangeListener {
}
} else {
// App bubble does not exist, lets add and expand it
Bubble b = new Bubble(intent, user, mMainExecutor);
Bubble b = new Bubble(intent, user, icon, mMainExecutor);
b.setShouldAutoExpand(true);
inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
}
@@ -1871,9 +1873,9 @@ public class BubbleController implements ConfigurationChangeListener {
}
@Override
public void showOrHideAppBubble(Intent intent, UserHandle user) {
public void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
mMainExecutor.execute(
() -> BubbleController.this.showOrHideAppBubble(intent, user));
() -> BubbleController.this.showOrHideAppBubble(intent, user, icon));
}
@Override

View File

@@ -26,6 +26,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.app.NotificationChannel;
import android.content.Intent;
import android.content.pm.UserInfo;
import android.graphics.drawable.Icon;
import android.hardware.HardwareBuffer;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
@@ -135,8 +136,9 @@ public interface Bubbles {
*
* @param intent the intent to display in the bubble expanded view.
* @param user the {@link UserHandle} of the user to start this activity for.
* @param icon the {@link Icon} to use for the bubble view.
*/
void showOrHideAppBubble(Intent intent, UserHandle user);
void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon);
/** @return true if the specified {@code taskId} corresponds to app bubble's taskId. */
boolean isAppBubbleTaskId(int taskId);

View File

@@ -185,7 +185,8 @@ public class BubbleDataTest extends ShellTestCase {
Intent appBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
appBubbleIntent.setPackage(mContext.getPackageName());
mAppBubble = new Bubble(appBubbleIntent, new UserHandle(1), mMainExecutor);
mAppBubble = new Bubble(appBubbleIntent, new UserHandle(1), mock(Icon.class),
mMainExecutor);
mPositioner = new TestableBubblePositioner(mContext,
mock(WindowManager.class));

View File

@@ -138,7 +138,8 @@ constructor(
logDebug { "onShowNoteTask - start: $info on user#${user.identifier}" }
when (info.launchMode) {
is NoteTaskLaunchMode.AppBubble -> {
bubbles.showOrHideAppBubble(intent, userTracker.userHandle)
// TODO: provide app bubble icon
bubbles.showOrHideAppBubble(intent, userTracker.userHandle, null /* icon */)
// App bubble logging happens on `onBubbleExpandChanged`.
logDebug { "onShowNoteTask - opened as app bubble: $info" }
}

View File

@@ -46,6 +46,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.isNull
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@@ -267,7 +268,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
verifyZeroInteractions(context)
val intentCaptor = argumentCaptor<Intent>()
verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle))
verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -401,7 +403,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
val intentCaptor = argumentCaptor<Intent>()
verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle))
verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -424,7 +427,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
val intentCaptor = argumentCaptor<Intent>()
verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle))
verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)

View File

@@ -284,6 +284,8 @@ public class BubblesTest extends SysuiTestCase {
private ShadeWindowLogger mShadeWindowLogger;
@Mock
private NotifPipelineFlags mNotifPipelineFlags;
@Mock
private Icon mAppBubbleIcon;
private TestableBubblePositioner mPositioner;
@@ -303,7 +305,7 @@ public class BubblesTest extends SysuiTestCase {
// For the purposes of this test, just run everything synchronously
ShellExecutor syncExecutor = new SyncExecutor();
mUser0 = createUserHande(/* userId= */ 0);
mUser0 = createUserHandle(/* userId= */ 0);
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
when(mNotificationShadeWindowView.getViewTreeObserver())
@@ -1250,7 +1252,7 @@ public class BubblesTest extends SysuiTestCase {
@Test
public void testShowManageMenuChangesSysuiState_appBubble() {
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertTrue(mBubbleController.hasBubbles());
// Expand the stack
@@ -1671,7 +1673,7 @@ public class BubblesTest extends SysuiTestCase {
assertThat(mBubbleController.isStackExpanded()).isFalse();
assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true),
/* showInShade= */ eq(false));
@@ -1681,13 +1683,13 @@ public class BubblesTest extends SysuiTestCase {
@Test
public void testShowOrHideAppBubble_expandIfCollapsed() {
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleController.collapseStack();
assertThat(mBubbleController.isStackExpanded()).isFalse();
// Calling this while collapsed will expand the app bubble
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isTrue();
@@ -1696,12 +1698,12 @@ public class BubblesTest extends SysuiTestCase {
@Test
public void testShowOrHideAppBubble_collapseIfSelected() {
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
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, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isFalse();
@@ -1711,15 +1713,15 @@ public class BubblesTest extends SysuiTestCase {
@Test
public void testShowOrHideAppBubbleWithNonPrimaryUser_bubbleCollapsedWithExpectedUser() {
UserHandle user10 = createUserHande(/* userId = */ 10);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10);
UserHandle user10 = createUserHandle(/* userId = */ 10);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isTrue();
assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(user10);
// Calling this while the app bubble is expanded should collapse the stack
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isFalse();
@@ -1729,13 +1731,13 @@ public class BubblesTest extends SysuiTestCase {
@Test
public void testShowOrHideAppBubble_selectIfNotSelected() {
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey());
assertThat(mBubbleController.isStackExpanded()).isTrue();
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0);
mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isTrue();
assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
@@ -1870,7 +1872,7 @@ public class BubblesTest extends SysuiTestCase {
mBubbleController.onUserChanged(userId);
}
private UserHandle createUserHande(int userId) {
private UserHandle createUserHandle(int userId) {
UserHandle user = mock(UserHandle.class);
when(user.getIdentifier()).thenReturn(userId);
return user;