• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
18 
19 import androidx.test.ext.junit.runners.AndroidJUnit4
20 import androidx.test.filters.SmallTest
21 import com.android.settingslib.SignalIcon
22 import com.android.settingslib.mobile.MobileIconCarrierIdOverrides
23 import com.android.systemui.activated
24 import com.android.systemui.kairos.BuildScope
25 import com.android.systemui.kairos.ExperimentalKairosApi
26 import com.android.systemui.kairos.Incremental
27 import com.android.systemui.kairos.State
28 import com.android.systemui.kairos.asIncremental
29 import com.android.systemui.kairos.buildSpec
30 import com.android.systemui.kairos.combine
31 import com.android.systemui.kairos.launchKairosNetwork
32 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
33 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairosAdapterTest.Companion.wrapRepo
34 import com.android.systemui.util.mockito.mock
35 import kotlinx.coroutines.ExperimentalCoroutinesApi
36 import kotlinx.coroutines.Job
37 import kotlinx.coroutines.launch
38 import kotlinx.coroutines.test.runCurrent
39 import org.junit.runner.RunWith
40 
41 @OptIn(ExperimentalKairosApi::class, ExperimentalCoroutinesApi::class)
42 @SmallTest
43 @RunWith(AndroidJUnit4::class)
44 class MobileIconInteractorKairosAdapterTest : MobileIconInteractorTestBase() {
45 
46     var job: Job? = null
47     val kairosNetwork = testScope.backgroundScope.launchKairosNetwork()
48 
49     override fun createInteractor(overrides: MobileIconCarrierIdOverrides): MobileIconInteractor {
50         lateinit var result: MobileIconInteractor
51         job?.cancel()
52         job =
53             testScope.backgroundScope.launch {
54                 kairosNetwork.activateSpec {
55                     val wrapped = wrap(mobileIconsInteractor)
56                     result =
57                         MobileIconInteractorKairosAdapter(
58                             kairosImpl =
59                                 activated {
60                                     MobileIconInteractorKairosImpl(
61                                         defaultSubscriptionHasDataEnabled =
62                                             wrapped.activeDataConnectionHasDataEnabled,
63                                         alwaysShowDataRatIcon = wrapped.alwaysShowDataRatIcon,
64                                         alwaysUseCdmaLevel = wrapped.alwaysUseCdmaLevel,
65                                         isSingleCarrier = wrapped.isSingleCarrier,
66                                         mobileIsDefault = wrapped.mobileIsDefault,
67                                         defaultMobileIconMapping = wrapped.defaultMobileIconMapping,
68                                         defaultMobileIconGroup = wrapped.defaultMobileIconGroup,
69                                         isDefaultConnectionFailed =
70                                             wrapped.isDefaultConnectionFailed,
71                                         isForceHidden = wrapped.isForceHidden,
72                                         connectionRepository = wrapRepo(connectionRepository),
73                                         context = context,
74                                         carrierIdOverrides = overrides,
75                                     )
76                                 }
77                         )
78                     Unit
79                 }
80             }
81         testScope.runCurrent() // ensure the lateinit is set
82         return result
83     }
84 
85     /** Allows us to wrap a (likely fake) MobileIconsInteractor into a Kairos version. */
86     private fun BuildScope.wrap(interactor: MobileIconsInteractor): MobileIconsInteractorKairos {
87         val filteredSubscriptions = interactor.filteredSubscriptions.toState(emptyList())
88         val icons = interactor.icons.toState()
89         return InteractorWrapper(
90             mobileIsDefault = interactor.mobileIsDefault.toState(),
91             filteredSubscriptions = filteredSubscriptions,
92             icons =
93                 combine(filteredSubscriptions, icons) { subs, icons ->
94                         subs.zip(icons).associate { (subModel, icon) ->
95                             subModel.subscriptionId to buildSpec { wrap(icon) }
96                         }
97                     }
98                     .asIncremental()
99                     .applyLatestSpecForKey(),
100             isStackable = interactor.isStackable.toState(false),
101             activeDataConnectionHasDataEnabled =
102                 interactor.activeDataConnectionHasDataEnabled.toState(),
103             activeDataIconInteractor =
104                 interactor.activeDataIconInteractor.toState().mapLatestBuild {
105                     it?.let { wrap(it) }
106                 },
107             alwaysShowDataRatIcon = interactor.alwaysShowDataRatIcon.toState(),
108             alwaysUseCdmaLevel = interactor.alwaysUseCdmaLevel.toState(),
109             isSingleCarrier = interactor.isSingleCarrier.toState(),
110             defaultMobileIconMapping = interactor.defaultMobileIconMapping.toState(),
111             defaultMobileIconGroup = interactor.defaultMobileIconGroup.toState(),
112             isDefaultConnectionFailed = interactor.isDefaultConnectionFailed.toState(),
113             isUserSetUp = interactor.isUserSetUp.toState(),
114             isForceHidden = interactor.isForceHidden.toState(false),
115             isDeviceInEmergencyCallsOnlyMode =
116                 interactor.isDeviceInEmergencyCallsOnlyMode.toState(false),
117         )
118     }
119 
120     private fun BuildScope.wrap(interactor: MobileIconInteractor): MobileIconInteractorKairos =
121         // unused in tests
122         mock()
123 
124     private class InteractorWrapper(
125         override val mobileIsDefault: State<Boolean>,
126         override val filteredSubscriptions: State<List<SubscriptionModel>>,
127         override val icons: Incremental<Int, MobileIconInteractorKairos>,
128         override val isStackable: State<Boolean>,
129         override val activeDataConnectionHasDataEnabled: State<Boolean>,
130         override val activeDataIconInteractor: State<MobileIconInteractorKairos?>,
131         override val alwaysShowDataRatIcon: State<Boolean>,
132         override val alwaysUseCdmaLevel: State<Boolean>,
133         override val isSingleCarrier: State<Boolean>,
134         override val defaultMobileIconMapping: State<Map<String, SignalIcon.MobileIconGroup>>,
135         override val defaultMobileIconGroup: State<SignalIcon.MobileIconGroup>,
136         override val isDefaultConnectionFailed: State<Boolean>,
137         override val isUserSetUp: State<Boolean>,
138         override val isForceHidden: State<Boolean>,
139         override val isDeviceInEmergencyCallsOnlyMode: State<Boolean>,
140     ) : MobileIconsInteractorKairos
141 }
142