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

Commit e020101a authored by Olivier St-Onge's avatar Olivier St-Onge
Browse files

Add mobile context needed for RAT icon in dual-sim icon

Flag: com.android.settingslib.flags.new_status_bar_icons
Flag: com.android.systemui.status_bar_root_modernization
Test: manually with demo mode
Test: StackedMobileIconViewModelTest
Fixes: 410697005
Change-Id: I3239c8dec5cc336fd5601fbc91cc29c63e201638
parent 3bdf59de
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel

import android.content.Context
import android.platform.test.annotations.EnableFlags
import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -28,6 +29,7 @@ import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.statusbar.connectivity.ui.mobileContextProvider
import com.android.systemui.statusbar.core.NewStatusBarIcons
import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
@@ -38,6 +40,10 @@ 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.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -53,6 +59,7 @@ class StackedMobileIconViewModelTest : SysuiTestCase() {
        kosmos.run {
            // Set prerequisites for the stacked icon
            fakeMobileIconsInteractor.isStackable.value = true
            whenever(mobileContextProvider.getMobileContextForSub(any(), any())).thenReturn(context)
            underTest.activateIn(testScope)
        }

@@ -177,6 +184,35 @@ class StackedMobileIconViewModelTest : SysuiTestCase() {
            assertThat(underTest.contentDescription).isNull()
        }

    @Test
    @EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
    fun mobileContext_tracksConnections() =
        kosmos.runTest {
            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf()
            assertThat(underTest.mobileContext).isNull()

            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
            assertThat(underTest.mobileContext).isNotNull()
        }

    @Test
    @EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
    fun mobileContext_tracksPrimaryConnection() =
        kosmos.runTest {
            val contextSub1 = mock(Context::class.java)
            val contextSub2 = mock(Context::class.java)
            whenever(mobileContextProvider.getMobileContextForSub(eq(SUB_1.subscriptionId), any()))
                .thenReturn(contextSub1)
            whenever(mobileContextProvider.getMobileContextForSub(eq(SUB_2.subscriptionId), any()))
                .thenReturn(contextSub2)

            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
            assertThat(underTest.mobileContext).isEqualTo(contextSub1)

            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_2, SUB_1)
            assertThat(underTest.mobileContext).isEqualTo(contextSub2)
        }

    private fun setIconLevel(subId: Int, level: Int) {
        with(kosmos.fakeMobileIconsInteractor.getInteractorForSubId(subId)!!) {
            signalLevelIcon.value =
+19 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider
import com.android.systemui.statusbar.pipeline.dagger.StackedMobileIconTableLog
import com.android.systemui.statusbar.pipeline.mobile.ui.model.DualSim
import com.android.systemui.statusbar.pipeline.mobile.ui.model.logDualSimDiff
@@ -42,6 +43,8 @@ interface StackedMobileIconViewModel {
    val dualSim: DualSim?
    val contentDescription: String?
    val networkTypeIcon: Icon.Resource?
    /** [Context] to use when loading the [networkTypeIcon] */
    val mobileContext: Context?
    val isIconVisible: Boolean
}

@@ -52,6 +55,7 @@ constructor(
    mobileIconsViewModel: MobileIconsViewModel,
    @StackedMobileIconTableLog private val tableLogger: TableLogBuffer,
    @ShadeDisplayAware private val context: Context,
    private val mobileContextProvider: MobileContextProvider,
) : ExclusiveActivatable(), StackedMobileIconViewModel {
    private val hydrator = Hydrator("StackedMobileIconViewModel")

@@ -128,6 +132,21 @@ constructor(
            initialValue = null,
        )

    override val mobileContext: Context? by
        hydrator.hydratedStateOf(
            traceName = "mobileContext",
            source =
                flowIfIconIsVisible(
                    iconViewModelFlow.map { viewModels ->
                        // Get mobile context of primary connection
                        viewModels.firstOrNull()?.let {
                            mobileContextProvider.getMobileContextForSub(it.subscriptionId, context)
                        }
                    }
                ),
            initialValue = null,
        )

    override val isIconVisible: Boolean by
        hydrator.hydratedStateOf(
            traceName = "isIconVisible",
+13 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.android.systemui.kairos.map
import com.android.systemui.kairos.stateOf
import com.android.systemui.kairosBuilder
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider
import com.android.systemui.statusbar.pipeline.mobile.ui.model.DualSim
import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
import com.android.systemui.statusbar.pipeline.mobile.ui.model.tryParseDualSim
@@ -41,6 +42,7 @@ class StackedMobileIconViewModelKairos
constructor(
    mobileIcons: MobileIconsViewModelKairos,
    @ShadeDisplayAware private val context: Context,
    private val mobileContextProvider: MobileContextProvider,
) : KairosBuilder by kairosBuilder(), StackedMobileIconViewModel {

    private val isStackable: Boolean by
@@ -89,6 +91,17 @@ constructor(
            initialValue = null,
        )

    override val mobileContext: Context? by
        hydratedComposeStateOf(
            "StackedMobileIconViewModelKairos.mobileContext",
            iconList.map { icons ->
                icons.firstOrNull()?.let {
                    mobileContextProvider.getMobileContextForSub(it.subscriptionId, context)
                }
            },
            initialValue = null,
        )

    override val isIconVisible: Boolean
        get() = isStackable && dualSim != null

+8 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
@@ -33,6 +34,7 @@ import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
@@ -78,9 +80,13 @@ fun StackedMobileIcon(viewModel: StackedMobileIconViewModel, modifier: Modifier
        modifier = modifier.padding(horizontal = padding),
    ) {
        viewModel.networkTypeIcon?.let {
            // Provide the RAT context needed for the resource overlays
            val ratContext = viewModel.mobileContext ?: LocalContext.current
            CompositionLocalProvider(LocalContext provides ratContext) {
                val height = with(LocalDensity.current) { IconHeightSp.toDp() }
                Icon(it, tint = contentColor, modifier = Modifier.height(height).wrapContentWidth())
            }
        }

        StackedMobileIcon(
            viewModel = dualSim,
+6 −1
Original line number Diff line number Diff line
@@ -20,8 +20,13 @@ import android.content.testableContext
import com.android.systemui.kairos.ActivatedKairosFixture
import com.android.systemui.kairos.ExperimentalKairosApi
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.statusbar.connectivity.ui.mobileContextProvider

@ExperimentalKairosApi
val Kosmos.stackedMobileIconViewModelKairos by ActivatedKairosFixture {
    StackedMobileIconViewModelKairos(mobileIconsViewModelKairos, testableContext)
    StackedMobileIconViewModelKairos(
        mobileIconsViewModelKairos,
        testableContext,
        mobileContextProvider,
    )
}
Loading