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

Commit 9a72466a authored by Caitlin Shkuratov's avatar Caitlin Shkuratov Committed by Android (Google) Code Review
Browse files

Merge "[SB][Call] Add test helpers for setting call state based on chips flag." into main

parents ea543ddb 08398904
Loading
Loading
Loading
Loading
+27 −116
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone.ongoingcall.domain.interactor

import android.app.PendingIntent
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -30,12 +31,12 @@ import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.data.repository.fakeStatusBarModeRepository
import com.android.systemui.statusbar.gesture.swipeStatusBarAwayGestureHandler
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.CallType
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.setNoCallState
import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.setOngoingCallState
import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -50,6 +51,7 @@ import org.mockito.kotlin.verify

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableFlags(StatusBarChipsModernization.FLAG_NAME)
class OngoingCallInteractorTest : SysuiTestCase() {
    private val kosmos = Kosmos().useUnconfinedTestDispatcher()
    private val repository = kosmos.activeNotificationListRepository
@@ -76,21 +78,14 @@ class OngoingCallInteractorTest : SysuiTestCase() {
            val testIntent: PendingIntent = mock()
            val testPromotedContent =
                PromotedNotificationContentModel.Builder("promotedCall").build()
            repository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
            setOngoingCallState(
                kosmos = this,
                key = "promotedCall",
                                whenTime = 1000L,
                                callType = CallType.Ongoing,
                                statusBarChipIcon = testIconView,
                startTimeMs = 1000L,
                statusBarChipIconView = testIconView,
                contentIntent = testIntent,
                promotedContent = testPromotedContent,
            )
                        )
                    }
                    .build()

            // Verify model is InCall and has the correct icon, intent, and promoted content.
            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
@@ -100,46 +95,14 @@ class OngoingCallInteractorTest : SysuiTestCase() {
            assertThat(model.promotedContent).isSameInstanceAs(testPromotedContent)
        }

    @Test
    fun ongoingCallNotification_emitsInCall() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingCallState)

            repository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = "notif1",
                                whenTime = 1000L,
                                callType = CallType.Ongoing,
                            )
                        )
                    }
                    .build()

            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
        }

    @Test
    fun notificationRemoved_emitsNoCall() =
        kosmos.runTest {
            val latest by collectLastValue(underTest.ongoingCallState)

            repository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = "notif1",
                                whenTime = 1000L,
                                callType = CallType.Ongoing,
                            )
                        )
                    }
                    .build()
            setOngoingCallState(kosmos = this)
            setNoCallState(kosmos = this)

            repository.activeNotifications.value = ActiveNotificationsStore()
            assertThat(latest).isInstanceOf(OngoingCallModel.NoCall::class.java)
        }

@@ -149,19 +112,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {
            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = true
            val latest by collectLastValue(underTest.ongoingCallState)

            repository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = "notif1",
                                whenTime = 1000L,
                                callType = CallType.Ongoing,
                                uid = UID,
                            )
                        )
                    }
                    .build()
            setOngoingCallState(kosmos = this, uid = UID)

            assertThat(latest).isInstanceOf(OngoingCallModel.InCallWithVisibleApp::class.java)
        }
@@ -172,19 +123,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {
            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = false
            val latest by collectLastValue(underTest.ongoingCallState)

            repository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = "notif1",
                                whenTime = 1000L,
                                callType = CallType.Ongoing,
                                uid = UID,
                            )
                        )
                    }
                    .build()
            setOngoingCallState(kosmos = this, uid = UID)

            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)
        }
@@ -196,19 +135,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {

            // Start with notification and app not visible
            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = false
            repository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = "notif1",
                                whenTime = 1000L,
                                callType = CallType.Ongoing,
                                uid = UID,
                            )
                        )
                    }
                    .build()
            setOngoingCallState(kosmos = this, uid = UID)
            assertThat(latest).isInstanceOf(OngoingCallModel.InCall::class.java)

            // App becomes visible
@@ -234,7 +161,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {
                    kosmos.fakeStatusBarWindowControllerStore.defaultDisplay
                        .ongoingProcessRequiresStatusBarVisible
                )
            postOngoingCallNotification()
            setOngoingCallState(kosmos = this)

            assertThat(isStatusBarRequired).isTrue()
            assertThat(requiresStatusBarVisibleInRepository).isTrue()
@@ -256,9 +183,9 @@ class OngoingCallInteractorTest : SysuiTestCase() {
                        .ongoingProcessRequiresStatusBarVisible
                )

            postOngoingCallNotification()
            setOngoingCallState(kosmos = this)

            repository.activeNotifications.value = ActiveNotificationsStore()
            setNoCallState(kosmos = this)

            assertThat(isStatusBarRequired).isFalse()
            assertThat(requiresStatusBarVisibleInRepository).isFalse()
@@ -283,7 +210,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {

            kosmos.activityManagerRepository.fake.startingIsAppVisibleValue = false

            postOngoingCallNotification()
            setOngoingCallState(kosmos = this, uid = UID)

            assertThat(ongoingCallState).isInstanceOf(OngoingCallModel.InCall::class.java)
            assertThat(requiresStatusBarVisibleInRepository).isTrue()
@@ -305,7 +232,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {
            clearInvocations(kosmos.swipeStatusBarAwayGestureHandler)
            // Set up notification but not in fullscreen
            kosmos.fakeStatusBarModeRepository.defaultDisplay.isInFullscreenMode.value = false
            postOngoingCallNotification()
            setOngoingCallState(kosmos = this)

            assertThat(ongoingCallState).isInstanceOf(OngoingCallModel.InCall::class.java)
            verify(kosmos.swipeStatusBarAwayGestureHandler, never())
@@ -319,7 +246,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {

            // Set up notification and fullscreen mode
            kosmos.fakeStatusBarModeRepository.defaultDisplay.isInFullscreenMode.value = true
            postOngoingCallNotification()
            setOngoingCallState(kosmos = this)

            assertThat(isGestureListeningEnabled).isTrue()
            verify(kosmos.swipeStatusBarAwayGestureHandler)
@@ -333,7 +260,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {

            // Set up notification and fullscreen mode
            kosmos.fakeStatusBarModeRepository.defaultDisplay.isInFullscreenMode.value = true
            postOngoingCallNotification()
            setOngoingCallState(kosmos = this)

            clearInvocations(kosmos.swipeStatusBarAwayGestureHandler)

@@ -360,7 +287,7 @@ class OngoingCallInteractorTest : SysuiTestCase() {
                )

            // Start with an ongoing call (which should set status bar required)
            postOngoingCallNotification()
            setOngoingCallState(kosmos = this)

            assertThat(isStatusBarRequiredForOngoingCall).isTrue()
            assertThat(requiresStatusBarVisibleInRepository).isTrue()
@@ -374,22 +301,6 @@ class OngoingCallInteractorTest : SysuiTestCase() {
            assertThat(requiresStatusBarVisibleInWindowController).isFalse()
        }

    private fun postOngoingCallNotification() {
        repository.activeNotifications.value =
            ActiveNotificationsStore.Builder()
                .apply {
                    addIndividualNotif(
                        activeNotificationModel(
                            key = "notif1",
                            whenTime = 1000L,
                            callType = CallType.Ongoing,
                            uid = UID,
                        )
                    )
                }
                .build()
    }

    companion object {
        private const val UID = 885
    }
+0 −39
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.systemui.statusbar.phone.ongoingcall.shared.model

import android.app.PendingIntent
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel

/** Helper for building [OngoingCallModel.InCall] instances in tests. */
fun inCallModel(
    startTimeMs: Long,
    notificationIcon: StatusBarIconView? = null,
    intent: PendingIntent? = null,
    notificationKey: String = "test",
    appName: String = "",
    promotedContent: PromotedNotificationContentModel? = null,
) =
    OngoingCallModel.InCall(
        startTimeMs,
        notificationIcon,
        intent,
        notificationKey,
        appName,
        promotedContent,
    )
+116 −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.systemui.statusbar.phone.ongoingcall.shared.model

import android.app.PendingIntent
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
import com.android.systemui.statusbar.notification.promoted.shared.model.PromotedNotificationContentModel
import com.android.systemui.statusbar.notification.shared.CallType
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import org.mockito.kotlin.mock

/** Helper for building [OngoingCallModel.InCall] instances in tests. */
fun inCallModel(
    startTimeMs: Long,
    notificationIcon: StatusBarIconView? = null,
    intent: PendingIntent? = null,
    notificationKey: String = "test",
    appName: String = "",
    promotedContent: PromotedNotificationContentModel? = null,
) =
    OngoingCallModel.InCall(
        startTimeMs,
        notificationIcon,
        intent,
        notificationKey,
        appName,
        promotedContent,
    )

object OngoingCallTestHelper {
    /**
     * Sets the call state to be no call, and does it correctly based on whether
     * [StatusBarChipsModernization] is enabled or not.
     */
    fun setNoCallState(kosmos: Kosmos) {
        if (StatusBarChipsModernization.isEnabled) {
            // TODO(b/372657935): Maybe don't clear *all* notifications
            kosmos.activeNotificationListRepository.activeNotifications.value =
                ActiveNotificationsStore()
        } else {
            kosmos.ongoingCallRepository.setOngoingCallState(OngoingCallModel.NoCall)
        }
    }

    /**
     * Sets the ongoing call state correctly based on whether [StatusBarChipsModernization] is
     * enabled or not.
     */
    fun setOngoingCallState(
        kosmos: Kosmos,
        startTimeMs: Long = 1000L,
        key: String = "notif",
        statusBarChipIconView: StatusBarIconView? = createStatusBarIconViewOrNull(),
        promotedContent: PromotedNotificationContentModel? = null,
        contentIntent: PendingIntent? = null,
        uid: Int = DEFAULT_UID,
    ) {
        if (StatusBarChipsModernization.isEnabled) {
            kosmos.activeNotificationListRepository.activeNotifications.value =
                ActiveNotificationsStore.Builder()
                    .apply {
                        addIndividualNotif(
                            activeNotificationModel(
                                key = key,
                                whenTime = startTimeMs,
                                callType = CallType.Ongoing,
                                statusBarChipIcon = statusBarChipIconView,
                                contentIntent = contentIntent,
                                promotedContent = promotedContent,
                                uid = uid,
                            )
                        )
                    }
                    .build()
        } else {
            kosmos.ongoingCallRepository.setOngoingCallState(
                inCallModel(
                    startTimeMs = startTimeMs,
                    notificationIcon = statusBarChipIconView,
                    intent = contentIntent,
                    notificationKey = key,
                    promotedContent = promotedContent,
                )
            )
        }
    }

    private fun createStatusBarIconViewOrNull(): StatusBarIconView? =
        if (StatusBarConnectedDisplays.isEnabled) {
            null
        } else {
            mock<StatusBarIconView>()
        }

    private const val DEFAULT_UID = 886
}