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