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

Commit 08398904 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

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

If ChipsModernization flag is off, then call state is managed via
OngoingCallRepository. But if the flag is on, then call state is managed
via ActiveNotificationsInteractor. This CL adds some test helpers that
sets the right call state depending on the flag's status.

This CL only updates OngoingCallInteractorTest, other tests will be
updated in future CLs.

Bug: 372657935
Flag: com.android.systemui.status_bar_chips_modernization
Test: atest OngoingCallInteractorTest
Change-Id: I5ef2c458a867770126da2708c0d0c59d8350c2e8
parent 0c68fa23
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
}