diff options
| author | 2024-11-22 01:16:30 +0000 | |
|---|---|---|
| committer | 2024-11-22 01:16:30 +0000 | |
| commit | 00821838b95c4c04cd7b898f94cd75d24f430d6f (patch) | |
| tree | deee032170b19b39c3248c38fd540205668d8cb7 | |
| parent | 3ea15a0ed3e5e4a97628e32efc64a9c745e56f60 (diff) | |
| parent | d2c7543e70bbb22ee0c93c9ddd4ce7ae14d41dea (diff) | |
Merge "BubbleController test for logging drag events" into main
5 files changed, 332 insertions, 78 deletions
| diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt new file mode 100644 index 000000000000..f535fbd653c5 --- /dev/null +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleControllerBubbleBarTest.kt @@ -0,0 +1,320 @@ +/* + * 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.bubbles + +import android.content.Context +import android.content.pm.LauncherApps +import android.graphics.Insets +import android.graphics.Rect +import android.os.Handler +import android.os.UserManager +import android.platform.test.annotations.EnableFlags +import android.platform.test.flag.junit.SetFlagsRule +import android.view.IWindowManager +import android.view.WindowManager +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.internal.logging.testing.UiEventLoggerFake +import com.android.internal.protolog.ProtoLog +import com.android.internal.statusbar.IStatusBarService +import com.android.wm.shell.Flags +import com.android.wm.shell.ShellTaskOrganizer +import com.android.wm.shell.WindowManagerShellWrapper +import com.android.wm.shell.bubbles.Bubbles.SysuiProxy +import com.android.wm.shell.bubbles.properties.ProdBubbleProperties +import com.android.wm.shell.bubbles.storage.BubblePersistentRepository +import com.android.wm.shell.common.DisplayController +import com.android.wm.shell.common.DisplayInsetsController +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.draganddrop.DragAndDropController +import com.android.wm.shell.shared.TransactionPool +import com.android.wm.shell.shared.bubbles.BubbleBarLocation +import com.android.wm.shell.shared.bubbles.BubbleBarUpdate +import com.android.wm.shell.sysui.ShellCommandHandler +import com.android.wm.shell.sysui.ShellController +import com.android.wm.shell.sysui.ShellInit +import com.android.wm.shell.taskview.TaskViewTransitions +import com.android.wm.shell.transition.Transitions +import com.google.common.truth.Truth.assertThat +import com.google.common.util.concurrent.MoreExecutors.directExecutor +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import java.util.Optional + +/** Tests for [BubbleController] when using bubble bar */ +@SmallTest +@EnableFlags(Flags.FLAG_ENABLE_BUBBLE_BAR) +@RunWith(AndroidJUnit4::class) +class BubbleControllerBubbleBarTest { + +    companion object { +        private const val SCREEN_WIDTH = 2000 +        private const val SCREEN_HEIGHT = 1000 +    } + +    @get:Rule val setFlagsRule = SetFlagsRule() + +    private val context = ApplicationProvider.getApplicationContext<Context>() + +    private lateinit var bubbleController: BubbleController +    private lateinit var uiEventLoggerFake: UiEventLoggerFake +    private lateinit var bubblePositioner: BubblePositioner +    private lateinit var bubbleData: BubbleData +    private lateinit var mainExecutor: TestExecutor +    private lateinit var bgExecutor: TestExecutor + +    @Before +    fun setUp() { +        ProtoLog.REQUIRE_PROTOLOGTOOL = false +        ProtoLog.init() + +        mainExecutor = TestExecutor() +        bgExecutor = TestExecutor() + +        uiEventLoggerFake = UiEventLoggerFake() +        val bubbleLogger = BubbleLogger(uiEventLoggerFake) + +        val deviceConfig = +            DeviceConfig( +                windowBounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), +                isLargeScreen = true, +                isSmallTablet = false, +                isLandscape = true, +                isRtl = false, +                insets = Insets.of(10, 20, 30, 40), +            ) + +        bubblePositioner = BubblePositioner(context, deviceConfig) +        bubblePositioner.isShowingInBubbleBar = true + +        bubbleData = +            BubbleData( +                context, +                bubbleLogger, +                bubblePositioner, +                BubbleEducationController(context), +                mainExecutor, +                bgExecutor, +            ) + +        val shellInit = ShellInit(mainExecutor) + +        bubbleController = +            createBubbleController( +                shellInit, +                bubbleData, +                bubbleLogger, +                bubblePositioner, +                mainExecutor, +                bgExecutor, +            ) +        bubbleController.asBubbles().setSysuiProxy(Mockito.mock(SysuiProxy::class.java)) + +        shellInit.init() + +        mainExecutor.flushAll() +        bgExecutor.flushAll() + +        bubbleController.registerBubbleStateListener(FakeBubblesStateListener()) +    } + +    @After +    fun tearDown() { +        mainExecutor.flushAll() +        bgExecutor.flushAll() +    } + +    @Test +    fun testEventLogging_bubbleBar_dragBarLeft() { +        addBubble() + +        bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT + +        bubbleController.setBubbleBarLocation( +            BubbleBarLocation.LEFT, +            BubbleBarLocation.UpdateSource.DRAG_BAR, +        ) + +        // 2 events: add bubble + drag event +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2) +        assertThat(uiEventLoggerFake.eventId(1)) +            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BAR.id) +    } + +    @Test +    fun testEventLogging_bubbleBar_dragBarRight() { +        addBubble() + +        bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT + +        bubbleController.setBubbleBarLocation( +            BubbleBarLocation.RIGHT, +            BubbleBarLocation.UpdateSource.DRAG_BAR, +        ) + +        // 2 events: add bubble + drag event +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2) +        assertThat(uiEventLoggerFake.eventId(1)) +            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BAR.id) +    } + +    @Test +    fun testEventLogging_bubbleBar_dragBubbleLeft() { +        addBubble() + +        bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT + +        bubbleController.setBubbleBarLocation( +            BubbleBarLocation.LEFT, +            BubbleBarLocation.UpdateSource.DRAG_BUBBLE, +        ) + +        // 2 events: add bubble + drag event +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2) +        assertThat(uiEventLoggerFake.eventId(1)) +            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BUBBLE.id) +    } + +    @Test +    fun testEventLogging_bubbleBar_dragBubbleRight() { +        addBubble() + +        bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT + +        bubbleController.setBubbleBarLocation( +            BubbleBarLocation.RIGHT, +            BubbleBarLocation.UpdateSource.DRAG_BUBBLE, +        ) + +        // 2 events: add bubble + drag event +        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2) +        assertThat(uiEventLoggerFake.eventId(1)) +            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BUBBLE.id) +    } + +    private fun addBubble(): Bubble { +        val bubble = FakeBubbleFactory.createChatBubble(context) +        bubble.setInflateSynchronously(true) +        bubbleData.notificationEntryUpdated( +            bubble, +            /* suppressFlyout= */ true, +            /* showInShade= */ true, +        ) +        return bubble +    } + +    private fun createBubbleController( +        shellInit: ShellInit, +        bubbleData: BubbleData, +        bubbleLogger: BubbleLogger, +        bubblePositioner: BubblePositioner, +        mainExecutor: TestExecutor, +        bgExecutor: TestExecutor, +    ): BubbleController { +        val shellCommandHandler = ShellCommandHandler() +        val shellController = +            ShellController( +                context, +                shellInit, +                shellCommandHandler, +                mock<DisplayInsetsController>(), +                mainExecutor, +            ) +        val surfaceSynchronizer = { obj: Runnable -> obj.run() } + +        val bubbleDataRepository = +            BubbleDataRepository( +                mock<LauncherApps>(), +                mainExecutor, +                bgExecutor, +                BubblePersistentRepository(context), +            ) + +        val shellTaskOrganizer = mock<ShellTaskOrganizer>() +        whenever(shellTaskOrganizer.executor).thenReturn(directExecutor()) + +        return BubbleController( +            context, +            shellInit, +            shellCommandHandler, +            shellController, +            bubbleData, +            surfaceSynchronizer, +            FloatingContentCoordinator(), +            bubbleDataRepository, +            mock<IStatusBarService>(), +            mock<WindowManager>(), +            WindowManagerShellWrapper(mainExecutor), +            mock<UserManager>(), +            mock<LauncherApps>(), +            bubbleLogger, +            mock<TaskStackListenerImpl>(), +            shellTaskOrganizer, +            bubblePositioner, +            mock<DisplayController>(), +            /* oneHandedOptional= */ Optional.empty(), +            mock<DragAndDropController>(), +            mainExecutor, +            mock<Handler>(), +            bgExecutor, +            mock<TaskViewTransitions>(), +            mock<Transitions>(), +            SyncTransactionQueue(TransactionPool(), mainExecutor), +            mock<IWindowManager>(), +            ProdBubbleProperties, +        ) +    } + +    private class TestExecutor : ShellExecutor { + +        private val runnables: MutableList<Runnable> = mutableListOf() + +        override fun execute(runnable: Runnable) { +            runnables.add(runnable) +        } + +        override fun executeDelayed(runnable: Runnable, delayMillis: Long) { +            execute(runnable) +        } + +        override fun removeCallbacks(runnable: Runnable?) {} + +        override fun hasCallback(runnable: Runnable?): Boolean = false + +        fun flushAll() { +            while (runnables.isNotEmpty()) { +                runnables.removeAt(0).run() +            } +        } +    } + +    private class FakeBubblesStateListener : Bubbles.BubbleStateListener { +        override fun onBubbleStateChange(update: BubbleBarUpdate?) {} + +        override fun animateBubbleBarLocation(location: BubbleBarLocation?) {} +    } +} diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt index cb6fb62bf89b..3279d561d4f1 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/FakeBubbleFactory.kt @@ -32,10 +32,10 @@ class FakeBubbleFactory {              return BubbleViewInfo().apply { bubbleBarExpandedView = bubbleExpandedView }          } -        fun createChatBubbleWithViewInfo( +        fun createChatBubble(              context: Context,              key: String = "key", -            viewInfo: BubbleViewInfo, +            viewInfo: BubbleViewInfo? = null,          ): Bubble {              val bubble =                  Bubble( @@ -50,7 +50,9 @@ class FakeBubbleFactory {                      directExecutor(),                      directExecutor(),                  ) {} -            bubble.setViewInfo(viewInfo) +            if (viewInfo != null) { +                bubble.setViewInfo(viewInfo) +            }              return bubble          }      } diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt index 3d34cbaeaf08..7280f8aa07a6 100644 --- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt @@ -165,7 +165,7 @@ class BubbleBarLayerViewTest {                  }          val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView) -        bubble = FakeBubbleFactory.createChatBubbleWithViewInfo(context, viewInfo = viewInfo) +        bubble = FakeBubbleFactory.createChatBubble(context, viewInfo = viewInfo)      }      @After 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 068b2d246500..0fd4206c0545 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 @@ -101,9 +101,13 @@ public class BubblePositioner {      private int mBubbleBarTopOnScreen;      public BubblePositioner(Context context, WindowManager windowManager) { +        this(context, DeviceConfig.create(context, windowManager)); +    } + +    public BubblePositioner(Context context, DeviceConfig deviceConfig) {          mContext = context; -        mDeviceConfig = DeviceConfig.create(context, windowManager); -        update(mDeviceConfig); +        mDeviceConfig = deviceConfig; +        update(deviceConfig);      }      /** 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 aad8b4ba1191..5d4d9e698161 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -2575,78 +2575,6 @@ public class BubblesTest extends SysuiTestCase {      @EnableFlags(FLAG_ENABLE_BUBBLE_BAR)      @Test -    public void testEventLogging_bubbleBar_dragBarLeft() { -        mBubbleProperties.mIsBubbleBarEnabled = true; -        mPositioner.setIsLargeScreen(true); -        mPositioner.setBubbleBarLocation(BubbleBarLocation.RIGHT); -        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); -        mBubbleController.registerBubbleStateListener(bubbleStateListener); - -        mEntryListener.onEntryAdded(mRow); -        assertBarMode(); - -        mBubbleController.setBubbleBarLocation(BubbleBarLocation.LEFT, -                BubbleBarLocation.UpdateSource.DRAG_BAR); - -        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BAR); -    } - -    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) -    @Test -    public void testEventLogging_bubbleBar_dragBarRight() { -        mBubbleProperties.mIsBubbleBarEnabled = true; -        mPositioner.setIsLargeScreen(true); -        mPositioner.setBubbleBarLocation(BubbleBarLocation.LEFT); -        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); -        mBubbleController.registerBubbleStateListener(bubbleStateListener); - -        mEntryListener.onEntryAdded(mRow); -        assertBarMode(); - -        mBubbleController.setBubbleBarLocation(BubbleBarLocation.RIGHT, -                BubbleBarLocation.UpdateSource.DRAG_BAR); - -        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BAR); -    } - -    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) -    @Test -    public void testEventLogging_bubbleBar_dragBubbleLeft() { -        mBubbleProperties.mIsBubbleBarEnabled = true; -        mPositioner.setIsLargeScreen(true); -        mPositioner.setBubbleBarLocation(BubbleBarLocation.RIGHT); -        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); -        mBubbleController.registerBubbleStateListener(bubbleStateListener); - -        mEntryListener.onEntryAdded(mRow); -        assertBarMode(); - -        mBubbleController.setBubbleBarLocation(BubbleBarLocation.LEFT, -                BubbleBarLocation.UpdateSource.DRAG_BUBBLE); - -        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_BUBBLE); -    } - -    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) -    @Test -    public void testEventLogging_bubbleBar_dragBubbleRight() { -        mBubbleProperties.mIsBubbleBarEnabled = true; -        mPositioner.setIsLargeScreen(true); -        mPositioner.setBubbleBarLocation(BubbleBarLocation.LEFT); -        FakeBubbleStateListener bubbleStateListener = new FakeBubbleStateListener(); -        mBubbleController.registerBubbleStateListener(bubbleStateListener); - -        mEntryListener.onEntryAdded(mRow); -        assertBarMode(); - -        mBubbleController.setBubbleBarLocation(BubbleBarLocation.RIGHT, -                BubbleBarLocation.UpdateSource.DRAG_BUBBLE); - -        verify(mBubbleLogger).log(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_BUBBLE); -    } - -    @EnableFlags(FLAG_ENABLE_BUBBLE_BAR) -    @Test      public void testEventLogging_bubbleBar_expandAndCollapse() {          mBubbleProperties.mIsBubbleBarEnabled = true;          mPositioner.setIsLargeScreen(true); |