Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 027b3b37 authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge "Modify the showAppBubble method to be showOrHideAppBubble" into tm-qpr-dev

parents 4813fb4a 64e7d5c1
Loading
Loading
Loading
Loading
+48 −10
Original line number Diff line number Diff line
@@ -973,22 +973,60 @@ 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 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);
        }
    }

    /**
     * Fills the overflow bubbles by loading them from disk.
@@ -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);
            });
        }

+20 −5
Original line number Diff line number Diff line
@@ -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.
+4 −2
Original line number Diff line number Diff line
@@ -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)
        }
    }

+9 −9
Original line number Diff line number Diff line
@@ -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

+62 −0
Original line number Diff line number Diff line
@@ -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);