• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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.data.repository
18 
19 import android.content.Context
20 import com.android.settingslib.SignalIcon
21 import com.android.settingslib.mobile.MobileMappings
22 import com.android.systemui.Flags
23 import com.android.systemui.KairosActivatable
24 import com.android.systemui.KairosBuilder
25 import com.android.systemui.dagger.SysUISingleton
26 import com.android.systemui.dagger.qualifiers.Application
27 import com.android.systemui.kairos.ExperimentalKairosApi
28 import com.android.systemui.kairos.KairosNetwork
29 import com.android.systemui.kairos.buildSpec
30 import com.android.systemui.kairos.combine
31 import com.android.systemui.kairos.map
32 import com.android.systemui.kairos.mapValues
33 import com.android.systemui.kairos.toColdConflatedFlow
34 import com.android.systemui.kairosBuilder
35 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
36 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileConnectionRepositoryKairosAdapter
37 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
38 import dagger.Provides
39 import dagger.multibindings.ElementsIntoSet
40 import javax.inject.Inject
41 import javax.inject.Provider
42 import kotlinx.coroutines.CoroutineScope
43 import kotlinx.coroutines.flow.Flow
44 import kotlinx.coroutines.flow.SharingStarted
45 import kotlinx.coroutines.flow.StateFlow
46 import kotlinx.coroutines.flow.stateIn
47 
48 @ExperimentalKairosApi
49 @SysUISingleton
50 class MobileConnectionsRepositoryKairosAdapter
51 @Inject
52 constructor(
53     private val kairosRepo: MobileConnectionsRepositoryKairos,
54     private val kairosNetwork: KairosNetwork,
55     @Application scope: CoroutineScope,
56     connectivityRepository: ConnectivityRepository,
57     context: Context,
58     carrierConfigRepo: CarrierConfigRepository,
59 ) : MobileConnectionsRepository, KairosBuilder by kairosBuilder() {
60     override val subscriptions: StateFlow<List<SubscriptionModel>> =
61         kairosRepo.subscriptions
62             .map { it.toList() }
63             .toColdConflatedFlow(kairosNetwork)
64             .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
65 
66     override val activeMobileDataSubscriptionId: StateFlow<Int?> =
67         kairosRepo.activeMobileDataSubscriptionId
68             .toColdConflatedFlow(kairosNetwork)
69             .stateIn(scope, SharingStarted.WhileSubscribed(), null)
70 
71     private val reposBySubIdK = buildIncremental {
72         kairosRepo.mobileConnectionsBySubId
73             .mapValues { (subId, repo) ->
74                 buildSpec {
75                     MobileConnectionRepositoryKairosAdapter(
76                         kairosRepo = repo,
77                         carrierConfig = carrierConfigRepo.getOrCreateConfigForSubId(subId),
78                     )
79                 }
80             }
81             .applyLatestSpecForKey()
82     }
83 
84     private val reposBySubId =
85         reposBySubIdK
86             .toColdConflatedFlow(kairosNetwork)
87             .stateIn(scope, SharingStarted.Eagerly, emptyMap())
88 
89     override val activeMobileDataRepository: StateFlow<MobileConnectionRepository?> =
90         combine(kairosRepo.activeMobileDataSubscriptionId, reposBySubIdK) { id, repos -> repos[id] }
91             .toColdConflatedFlow(kairosNetwork)
92             .stateIn(scope, SharingStarted.WhileSubscribed(), null)
93 
94     override val activeSubChangedInGroupEvent: Flow<Unit> =
95         kairosRepo.activeSubChangedInGroupEvent.toColdConflatedFlow(kairosNetwork)
96 
97     override val defaultDataSubId: StateFlow<Int?> =
98         kairosRepo.defaultDataSubId
99             .toColdConflatedFlow(kairosNetwork)
100             .stateIn(scope, SharingStarted.WhileSubscribed(), null)
101 
102     override val mobileIsDefault: StateFlow<Boolean> =
103         kairosRepo.mobileIsDefault
104             .toColdConflatedFlow(kairosNetwork)
105             .stateIn(
106                 scope,
107                 SharingStarted.WhileSubscribed(),
108                 connectivityRepository.defaultConnections.value.mobile.isDefault,
109             )
110 
111     override val hasCarrierMergedConnection: Flow<Boolean> =
112         kairosRepo.hasCarrierMergedConnection.toColdConflatedFlow(kairosNetwork)
113 
114     override val defaultConnectionIsValidated: StateFlow<Boolean> =
115         kairosRepo.defaultConnectionIsValidated
116             .toColdConflatedFlow(kairosNetwork)
117             .stateIn(
118                 scope,
119                 SharingStarted.WhileSubscribed(),
120                 connectivityRepository.defaultConnections.value.isValidated,
121             )
122 
123     override fun getRepoForSubId(subId: Int): MobileConnectionRepository =
124         reposBySubId.value[subId] ?: error("Unknown subscription id: $subId")
125 
126     override val defaultDataSubRatConfig: StateFlow<MobileMappings.Config> =
127         kairosRepo.defaultDataSubRatConfig
128             .toColdConflatedFlow(kairosNetwork)
129             .stateIn(
130                 scope,
131                 SharingStarted.WhileSubscribed(),
132                 MobileMappings.Config.readConfig(context),
133             )
134 
135     override val defaultMobileIconMapping: Flow<Map<String, SignalIcon.MobileIconGroup>> =
136         kairosRepo.defaultMobileIconMapping.toColdConflatedFlow(kairosNetwork)
137 
138     override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
139         kairosRepo.defaultMobileIconGroup.toColdConflatedFlow(kairosNetwork)
140 
141     override val isDeviceEmergencyCallCapable: StateFlow<Boolean> =
142         kairosRepo.isDeviceEmergencyCallCapable
143             .toColdConflatedFlow(kairosNetwork)
144             .stateIn(scope, SharingStarted.Eagerly, false)
145 
146     override val isAnySimSecure: StateFlow<Boolean> =
147         kairosRepo.isAnySimSecure
148             .toColdConflatedFlow(kairosNetwork)
149             .stateIn(scope, SharingStarted.Eagerly, false)
150 
151     override fun getIsAnySimSecure(): Boolean = isAnySimSecure.value
152 
153     override suspend fun isInEcmMode(): Boolean =
154         kairosNetwork.transact { kairosRepo.isInEcmMode.sample() }
155 
156     @dagger.Module
157     object Module {
158         @Provides
159         @ElementsIntoSet
160         fun kairosActivatable(
161             impl: Provider<MobileConnectionsRepositoryKairosAdapter>
162         ): Set<@JvmSuppressWildcards KairosActivatable> =
163             if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
164     }
165 }
166