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

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

Merge changes I354d9199,I4b140876 into main

* changes:
  Fix an issue where onAllBubblesAnimatedOut could be called incorrectly
  Add visibility changes to the bubble view callback
parents 720941f3 3da70d55
Loading
Loading
Loading
Loading
+99 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.graphics.drawable.Icon
import android.os.Handler
import android.os.UserHandle
import android.os.UserManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import android.platform.test.flag.junit.SetFlagsRule
@@ -37,6 +38,7 @@ import android.view.IWindowManager
import android.view.InsetsSource
import android.view.InsetsState
import android.view.SurfaceControl
import android.view.View
import android.view.WindowInsets
import android.view.WindowManager
import android.view.WindowManager.TRANSIT_CHANGE
@@ -55,6 +57,7 @@ import com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE
import com.android.wm.shell.R
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.bubbles.Bubbles.BubbleExpandListener
import com.android.wm.shell.bubbles.Bubbles.DISMISS_USER_GESTURE
import com.android.wm.shell.bubbles.Bubbles.SysuiProxy
import com.android.wm.shell.bubbles.storage.BubblePersistentRepository
import com.android.wm.shell.common.DisplayController
@@ -710,6 +713,102 @@ class BubbleControllerTest(flags: FlagsParameterization) {
        assertThat(bubble.taskView.alpha).isEqualTo(0)
    }

    @DisableFlags(FLAG_ENABLE_BUBBLE_BAR)
    @Test
    fun onAllBubblesAnimatedOut_hasBubbles() {
        val bubble = createBubble("key")
        getInstrumentation().runOnMainSync {
            bubbleController.inflateAndAdd(
                bubble,
                /* suppressFlyout= */ true,
                /* showInShade= */ true
            )
        }
        assertThat(bubbleData.hasBubbles()).isTrue()

        getInstrumentation().runOnMainSync {
            bubbleController.onAllBubblesAnimatedOut()
        }
        assertThat(bubbleController.stackView!!.visibility).isEqualTo(View.VISIBLE)
    }

    @DisableFlags(FLAG_ENABLE_BUBBLE_BAR)
    @Test
    fun onAllBubblesAnimatedOut_noBubbles() {
        val bubble = createBubble("key")
        getInstrumentation().runOnMainSync {
            bubbleController.inflateAndAdd(
                bubble,
                /* suppressFlyout= */ true,
                /* showInShade= */ true
            )
        }
        getInstrumentation().runOnMainSync {
            bubbleController.dismissBubble("key", DISMISS_USER_GESTURE)
        }
        assertThat(bubbleData.hasBubbles()).isFalse()

        getInstrumentation().runOnMainSync {
            bubbleController.onAllBubblesAnimatedOut()
        }
        assertThat(bubbleController.stackView!!.visibility).isEqualTo(View.INVISIBLE)
    }

    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
    @Test
    fun onAllBubblesAnimatedOutBubbleBar_hasBubbles() {
        bubblePositioner.update(deviceConfigUnfolded)
        bubblePositioner.isShowingInBubbleBar = true
        getInstrumentation().runOnMainSync {
            bubbleController.setLauncherHasBubbleBar(true)
            bubbleController.registerBubbleStateListener(FakeBubblesStateListener())
        }

        val bubble = createBubble("key")
        getInstrumentation().runOnMainSync {
            bubbleController.inflateAndAdd(
                bubble,
                /* suppressFlyout= */ true,
                /* showInShade= */ true
            )
        }
        assertThat(bubbleData.hasBubbles()).isTrue()

        getInstrumentation().runOnMainSync {
            bubbleController.onAllBubblesAnimatedOut()
        }
        assertThat(bubbleController.layerView!!.visibility).isEqualTo(View.VISIBLE)
    }

    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)
    @Test
    fun onAllBubblesAnimatedOutBubbleBar_noBubbles() {
        bubblePositioner.update(deviceConfigUnfolded)
        bubblePositioner.isShowingInBubbleBar = true
        getInstrumentation().runOnMainSync {
            bubbleController.setLauncherHasBubbleBar(true)
            bubbleController.registerBubbleStateListener(FakeBubblesStateListener())
        }

        val bubble = createBubble("key")
        getInstrumentation().runOnMainSync {
            bubbleController.inflateAndAdd(
                bubble,
                /* suppressFlyout= */ true,
                /* showInShade= */ true
            )
        }
        getInstrumentation().runOnMainSync {
            bubbleController.dismissBubble("key", DISMISS_USER_GESTURE)
        }
        assertThat(bubbleData.hasBubbles()).isFalse()

        getInstrumentation().runOnMainSync {
            bubbleController.onAllBubblesAnimatedOut()
        }
        assertThat(bubbleController.layerView!!.visibility).isEqualTo(View.INVISIBLE)
    }

    private fun createBubble(key: String, taskId: Int = 0): Bubble {
        val icon = Icon.createWithResource(context.resources, R.drawable.bubble_ic_overflow_button)
        val shortcutInfo = ShortcutInfo.Builder(context, "fakeId").setIcon(icon).build()
+24 −20
Original line number Diff line number Diff line
@@ -204,6 +204,8 @@ public class BubbleController implements ConfigurationChangeListener,
        void bubbleOrderChanged(List<Bubble> bubbleOrder, boolean updatePointer);
        /** Called when the bubble overflow empty state changes, used to show/hide the overflow. */
        void bubbleOverflowChanged(boolean hasBubbles);
        /** Called when the visibility of bubble views should be updated. */
        void updateVisibility(boolean visible);
    }

    private final Context mContext;
@@ -1295,17 +1297,15 @@ public class BubbleController implements ConfigurationChangeListener,
    };

    /**
     * Called by the BubbleStackView and whenever all bubbles have animated out, and none have been
     * added in the meantime.
     * Called by the view displaying bubbles once all bubbles have finished animating out.
     */
    public void onAllBubblesAnimatedOut() {
        if (mStackView != null) {
            mStackView.setVisibility(INVISIBLE);
            removeFromWindowManagerMaybe();
        } else if (mLayerView != null) {
            mLayerView.setVisibility(INVISIBLE);
            removeFromWindowManagerMaybe();
        if (hasBubbles()) {
            // Bubbles could've been added in the time it takes to animate out the bubbles.
            return;
        }
        mBubbleViewCallback.updateVisibility(false /* visible */);
        removeFromWindowManagerMaybe();
    }

    /**
@@ -2492,6 +2492,13 @@ public class BubbleController implements ConfigurationChangeListener,
                }
            }
        }

        @Override
        public void updateVisibility(boolean visible) {
            if (mStackView != null) {
                mStackView.setVisibility(visible ? VISIBLE : INVISIBLE);
            }
        }
    };

    /** When bubbles are in the bubble bar, this will be used to notify bubble bar views. */
@@ -2571,6 +2578,13 @@ public class BubbleController implements ConfigurationChangeListener,
                }
            }
        }

        @Override
        public void updateVisibility(boolean visible) {
            if (mLayerView != null) {
                mLayerView.setVisibility(visible ? VISIBLE : INVISIBLE);
            }
        }
    };

    @SuppressWarnings("FieldCanBeLocal")
@@ -2832,22 +2846,12 @@ public class BubbleController implements ConfigurationChangeListener,
                mIsStatusBarShade, hasBubbles());
        if (!mIsStatusBarShade) {
            // Bubbles don't appear when the device is locked.
            if (mStackView != null) {
                mStackView.setVisibility(INVISIBLE);
            }
            if (mLayerView != null) {
                mLayerView.setVisibility(INVISIBLE);
            }
            mBubbleViewCallback.updateVisibility(false /* visible */);
        } else if (hasBubbles()) {
            // If we're unlocked, show the stack if we have bubbles. If we don't have bubbles, the
            // stack will be set to INVISIBLE in onAllBubblesAnimatedOut after the bubbles animate
            // out.
            if (mStackView != null) {
                mStackView.setVisibility(VISIBLE);
            }
            if (mLayerView != null) {
                mLayerView.setVisibility(VISIBLE);
            }
            mBubbleViewCallback.updateVisibility(true /* visible */);
        }

        if (mStackView != null) {