Merge "Helper to verify ui event has bubble info" into main
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/UiEventSubject.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/UiEventSubject.kt
new file mode 100644
index 0000000..2d6df43
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/UiEventSubject.kt
@@ -0,0 +1,40 @@
+/*
+ * 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 com.android.internal.logging.testing.UiEventLoggerFake.FakeUiEvent
+import com.google.common.truth.FailureMetadata
+import com.google.common.truth.Subject
+import com.google.common.truth.Truth
+
+/** Subclass of [Subject] to simplify verifying [FakeUiEvent] data */
+class UiEventSubject(metadata: FailureMetadata, private val actual: FakeUiEvent) :
+ Subject(metadata, actual) {
+
+ /** Check that [FakeUiEvent] contains the expected data from the [bubble] passed id */
+ fun hasBubbleInfo(bubble: Bubble) {
+ check("uid").that(actual.uid).isEqualTo(bubble.appUid)
+ check("packageName").that(actual.packageName).isEqualTo(bubble.packageName)
+ check("instanceId").that(actual.instanceId).isEqualTo(bubble.instanceId)
+ }
+
+ companion object {
+ @JvmStatic
+ fun assertThat(event: FakeUiEvent): UiEventSubject =
+ Truth.assertAbout(Factory(::UiEventSubject)).that(event)
+ }
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/UiEventSubjectTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/UiEventSubjectTest.kt
new file mode 100644
index 0000000..af238d0
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/UiEventSubjectTest.kt
@@ -0,0 +1,147 @@
+/*
+ * 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 androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.logging.testing.UiEventLoggerFake.FakeUiEvent
+import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat
+import com.google.common.truth.ExpectFailure.assertThat
+import com.google.common.truth.ExpectFailure.expectFailure
+import com.google.common.truth.Subject
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.whenever
+
+/** Test for [UiEventSubject] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class UiEventSubjectTest {
+
+ private val uiEventSubjectFactory =
+ Subject.Factory<UiEventSubject, FakeUiEvent> { metadata, actual ->
+ UiEventSubject(metadata, actual)
+ }
+
+ private lateinit var uiEventLoggerFake: UiEventLoggerFake
+
+ @Before
+ fun setUp() {
+ uiEventLoggerFake = UiEventLoggerFake()
+ }
+
+ @Test
+ fun test_bubbleLogEvent_hasBubbleInfo() {
+ val bubble =
+ createBubble(
+ appUid = 1,
+ packageName = "test",
+ instanceId = InstanceId.fakeInstanceId(2),
+ )
+ BubbleLogger(uiEventLoggerFake).log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_POSTED)
+ val uiEvent = uiEventLoggerFake.logs.first()
+
+ // Check that fields match the expected values
+ assertThat(uiEvent.uid).isEqualTo(1)
+ assertThat(uiEvent.packageName).isEqualTo("test")
+ assertThat(uiEvent.instanceId.id).isEqualTo(2)
+
+ // Check that hasBubbleInfo condition passes
+ assertThat(uiEvent).hasBubbleInfo(bubble)
+ }
+
+ @Test
+ fun test_bubbleLogEvent_uidMismatch() {
+ val bubble =
+ createBubble(
+ appUid = 1,
+ packageName = "test",
+ instanceId = InstanceId.fakeInstanceId(2),
+ )
+ BubbleLogger(uiEventLoggerFake).log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_POSTED)
+ val uiEvent = uiEventLoggerFake.logs.first()
+
+ // Change uid to have a mismatch
+ val otherBubble = bubble.copy(appUid = 99)
+
+ val failure = expectFailure { test ->
+ test.about(uiEventSubjectFactory).that(uiEvent).hasBubbleInfo(otherBubble)
+ }
+ assertThat(failure).factValue("value of").isEqualTo("uiEvent.uid")
+ }
+
+ @Test
+ fun test_bubbleLogEvent_packageNameMismatch() {
+ val bubble =
+ createBubble(
+ appUid = 1,
+ packageName = "test",
+ instanceId = InstanceId.fakeInstanceId(2),
+ )
+ BubbleLogger(uiEventLoggerFake).log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_POSTED)
+ val uiEvent = uiEventLoggerFake.logs.first()
+
+ // Change package name to have a mismatch
+ val otherBubble = bubble.copy(packageName = "somethingelse")
+
+ val failure = expectFailure { test ->
+ test.about(uiEventSubjectFactory).that(uiEvent).hasBubbleInfo(otherBubble)
+ }
+ assertThat(failure).factValue("value of").isEqualTo("uiEvent.packageName")
+ }
+
+ @Test
+ fun test_bubbleLogEvent_instanceIdMismatch() {
+ val bubble =
+ createBubble(
+ appUid = 1,
+ packageName = "test",
+ instanceId = InstanceId.fakeInstanceId(2),
+ )
+ BubbleLogger(uiEventLoggerFake).log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_POSTED)
+ val uiEvent = uiEventLoggerFake.logs.first()
+
+ // Change instance id to have a mismatch
+ val otherBubble = bubble.copy(instanceId = InstanceId.fakeInstanceId(99))
+
+ val failure = expectFailure { test ->
+ test.about(uiEventSubjectFactory).that(uiEvent).hasBubbleInfo(otherBubble)
+ }
+ assertThat(failure).factValue("value of").isEqualTo("uiEvent.instanceId")
+ }
+
+ private fun createBubble(appUid: Int, packageName: String, instanceId: InstanceId): Bubble {
+ return mock(Bubble::class.java).apply {
+ whenever(getAppUid()).thenReturn(appUid)
+ whenever(getPackageName()).thenReturn(packageName)
+ whenever(getInstanceId()).thenReturn(instanceId)
+ }
+ }
+
+ private fun Bubble.copy(
+ appUid: Int = this.appUid,
+ packageName: String = this.packageName,
+ instanceId: InstanceId = this.instanceId,
+ ): Bubble {
+ return createBubble(appUid, packageName, instanceId)
+ }
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
index fa9d2ba..08d647d 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewTest.kt
@@ -40,6 +40,7 @@
import com.android.wm.shell.bubbles.BubbleTaskViewFactory
import com.android.wm.shell.bubbles.DeviceConfig
import com.android.wm.shell.bubbles.RegionSamplingProvider
+import com.android.wm.shell.bubbles.UiEventSubject.Companion.assertThat
import com.android.wm.shell.common.ShellExecutor
import com.android.wm.shell.shared.bubbles.BubbleBarLocation
import com.android.wm.shell.shared.handles.RegionSamplingHelper
@@ -47,16 +48,14 @@
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.Collections
+import java.util.concurrent.Executor
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-import java.util.Collections
-import java.util.concurrent.Executor
/** Tests for [BubbleBarExpandedViewTest] */
@SmallTest
@@ -82,7 +81,7 @@
private var testableRegionSamplingHelper: TestableRegionSamplingHelper? = null
private var regionSamplingProvider: TestRegionSamplingProvider? = null
- private val bubbleLogger = spy(BubbleLogger(UiEventLoggerFake()))
+ private val uiEventLoggerFake = UiEventLoggerFake()
@Before
fun setUp() {
@@ -116,7 +115,7 @@
bubbleExpandedView.initialize(
expandedViewManager,
positioner,
- bubbleLogger,
+ BubbleLogger(uiEventLoggerFake),
false /* isOverflow */,
bubbleTaskView,
mainExecutor,
@@ -223,7 +222,10 @@
bubbleExpandedView.findViewWithTag<View>(BubbleBarMenuView.DISMISS_ACTION_TAG)
assertThat(dismissMenuItem).isNotNull()
getInstrumentation().runOnMainSync { dismissMenuItem.performClick() }
- verify(bubbleLogger).log(bubble, BubbleLogger.Event.BUBBLE_BAR_BUBBLE_DISMISSED_APP_MENU)
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+ assertThat(uiEventLoggerFake.logs[0].eventId)
+ .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_BUBBLE_DISMISSED_APP_MENU.id)
+ assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
}
private inner class FakeBubbleTaskViewFactory : BubbleTaskViewFactory {