diff options
| author | 2024-02-20 13:42:59 +0000 | |
|---|---|---|
| committer | 2024-02-20 13:42:59 +0000 | |
| commit | 351cdcd11f08ce6f4ceef29239fd2582b6cb6d1c (patch) | |
| tree | 2968a293815ccdd543aa9d338784c7acf4246d24 | |
| parent | 1944d090f6d3f1202e70aefd151175dbb77c73b9 (diff) | |
| parent | b25b66d9d60573ebcd12710d0ffcabd33f590e85 (diff) | |
Merge "Initial unit tests for BubbleStackView" into main
3 files changed, 218 insertions, 0 deletions
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index 310300d2f32a..d66c925de376 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -206,6 +206,8 @@ android_robolectric_test { srcs: [ "multivalentTests/src/**/*.kt", ], + // TODO(b/323188766): Include BubbleStackViewTest once the robolectric issue is fixed. + exclude_srcs: ["multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt"], static_libs: [ "junit", "androidx.test.runner", diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt new file mode 100644 index 000000000000..8989fc543044 --- /dev/null +++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt @@ -0,0 +1,215 @@ +/* + * 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.Intent +import android.graphics.Color +import android.graphics.drawable.Icon +import android.os.UserHandle +import android.view.IWindowManager +import android.view.WindowManager +import android.view.WindowManagerGlobal +import androidx.test.annotation.UiThreadTest +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.common.ProtoLog +import com.android.launcher3.icons.BubbleIconFactory +import com.android.wm.shell.R +import com.android.wm.shell.bubbles.Bubbles.SysuiProxy +import com.android.wm.shell.common.FloatingContentCoordinator +import com.android.wm.shell.common.ShellExecutor +import com.android.wm.shell.taskview.TaskView +import com.android.wm.shell.taskview.TaskViewTaskController +import com.google.common.truth.Truth.assertThat +import com.google.common.util.concurrent.MoreExecutors.directExecutor +import java.util.concurrent.Semaphore +import java.util.concurrent.TimeUnit +import java.util.function.Consumer +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock + +/** Unit tests for [BubbleStackView]. */ +@SmallTest +@RunWith(AndroidJUnit4::class) +class BubbleStackViewTest { + + private val context = ApplicationProvider.getApplicationContext<Context>() + private lateinit var positioner: BubblePositioner + private lateinit var iconFactory: BubbleIconFactory + private lateinit var expandedViewManager: FakeBubbleExpandedViewManager + private lateinit var bubbleStackView: BubbleStackView + private lateinit var shellExecutor: ShellExecutor + private lateinit var windowManager: IWindowManager + private lateinit var bubbleTaskViewFactory: BubbleTaskViewFactory + private lateinit var bubbleData: BubbleData + + @Before + fun setUp() { + // Disable protolog tool when running the tests from studio + ProtoLog.REQUIRE_PROTOLOGTOOL = false + windowManager = WindowManagerGlobal.getWindowManagerService()!! + shellExecutor = TestShellExecutor() + val windowManager = context.getSystemService(WindowManager::class.java) + iconFactory = + BubbleIconFactory( + context, + context.resources.getDimensionPixelSize(R.dimen.bubble_size), + context.resources.getDimensionPixelSize(R.dimen.bubble_badge_size), + Color.BLACK, + context.resources.getDimensionPixelSize( + com.android.internal.R.dimen.importance_ring_stroke_width + ) + ) + positioner = BubblePositioner(context, windowManager) + val bubbleStackViewManager = FakeBubbleStackViewManager() + bubbleData = + BubbleData( + context, + BubbleLogger(UiEventLoggerFake()), + positioner, + BubbleEducationController(context), + shellExecutor + ) + + val sysuiProxy = mock<SysuiProxy>() + expandedViewManager = FakeBubbleExpandedViewManager() + bubbleTaskViewFactory = FakeBubbleTaskViewFactory() + bubbleStackView = + BubbleStackView( + context, + bubbleStackViewManager, + positioner, + bubbleData, + null, + FloatingContentCoordinator(), + { sysuiProxy }, + shellExecutor + ) + } + + @UiThreadTest + @Test + fun addBubble() { + val bubble = createAndInflateBubble() + bubbleStackView.addBubble(bubble) + assertThat(bubbleStackView.bubbleCount).isEqualTo(1) + } + + @UiThreadTest + @Test + fun tapBubbleToExpand() { + val bubble = createAndInflateBubble() + bubbleStackView.addBubble(bubble) + assertThat(bubbleStackView.bubbleCount).isEqualTo(1) + + bubble.iconView!!.performClick() + // we're checking the expanded state in BubbleData because that's the source of truth. This + // will eventually propagate an update back to the stack view, but setting the entire + // pipeline is outside the scope of a unit test. + assertThat(bubbleData.isExpanded).isTrue() + } + + private fun createAndInflateBubble(): Bubble { + val intent = Intent(Intent.ACTION_VIEW).setPackage(context.packageName) + val icon = Icon.createWithResource(context.resources, R.drawable.bubble_ic_overflow_button) + val bubble = Bubble.createAppBubble(intent, UserHandle(1), icon, directExecutor()) + bubble.setInflateSynchronously(true) + bubbleData.notificationEntryUpdated(bubble, true, false) + + val semaphore = Semaphore(0) + val callback: BubbleViewInfoTask.Callback = + BubbleViewInfoTask.Callback { semaphore.release() } + bubble.inflate( + callback, + context, + expandedViewManager, + bubbleTaskViewFactory, + positioner, + bubbleStackView, + null, + iconFactory, + false + ) + + assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue() + assertThat(bubble.isInflated).isTrue() + return bubble + } + + private class FakeBubbleStackViewManager : BubbleStackViewManager { + + override fun onAllBubblesAnimatedOut() {} + + override fun updateWindowFlagsForBackpress(interceptBack: Boolean) {} + + override fun checkNotificationPanelExpandedState(callback: Consumer<Boolean>) {} + + override fun hideCurrentInputMethod() {} + } + + private class TestShellExecutor : ShellExecutor { + + override fun execute(runnable: Runnable) { + runnable.run() + } + + override fun executeDelayed(r: Runnable, delayMillis: Long) { + r.run() + } + + override fun removeCallbacks(r: Runnable) {} + + override fun hasCallback(r: Runnable): Boolean = false + } + + private inner class FakeBubbleTaskViewFactory : BubbleTaskViewFactory { + override fun create(): BubbleTaskView { + val taskViewTaskController = mock<TaskViewTaskController>() + val taskView = TaskView(context, taskViewTaskController) + return BubbleTaskView(taskView, shellExecutor) + } + } + + private inner class FakeBubbleExpandedViewManager : BubbleExpandedViewManager { + + override val overflowBubbles: List<Bubble> + get() = emptyList() + + override fun setOverflowListener(listener: BubbleData.Listener) {} + + override fun collapseStack() {} + + override fun updateWindowFlagsForBackpress(intercept: Boolean) {} + + override fun promoteBubbleFromOverflow(bubble: Bubble) {} + + override fun removeBubble(key: String, reason: Int) {} + + override fun dismissBubble(bubble: Bubble, reason: Int) {} + + override fun setAppBubbleTaskId(key: String, taskId: Int) {} + + override fun isStackExpanded(): Boolean = false + + override fun isShowingAsBubbleBar(): Boolean = false + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml index 47a116be1b66..2ef425cf3d41 100644 --- a/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml +++ b/libs/WindowManager/Shell/tests/unittest/AndroidManifest.xml @@ -21,6 +21,7 @@ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> <uses-permission android:name="android.permission.VIBRATE"/> + <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/> <application android:debuggable="true" android:largeHeap="true"> <uses-library android:name="android.test.mock" /> |