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

Commit 2d3be8d4 authored by Ats Jenk's avatar Ats Jenk Committed by Android (Google) Code Review
Browse files

Merge "Helper to verify ui event has bubble info" into main

parents b0c55e8d ccedde80
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
/*
 * 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)
    }
}
+147 −0
Original line number Diff line number Diff line
/*
 * 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)
    }
}
+9 −7
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.wm.shell.bubbles.BubbleTaskView
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.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.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 @@ class BubbleBarExpandedViewTest {
    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 @@ class BubbleBarExpandedViewTest {
        bubbleExpandedView.initialize(
            expandedViewManager,
            positioner,
            bubbleLogger,
            BubbleLogger(uiEventLoggerFake),
            false /* isOverflow */,
            bubbleTaskView,
            mainExecutor,
@@ -223,7 +222,10 @@ class BubbleBarExpandedViewTest {
            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 {