• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.demo
18 
19 import android.telephony.CellSignalStrength
20 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
21 import android.telephony.TelephonyManager
22 import com.android.systemui.log.table.TableLogBuffer
23 import com.android.systemui.log.table.logDiffsForTable
24 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
25 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
26 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
27 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
28 import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
29 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CARRIER_ID
30 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CARRIER_NETWORK_CHANGE
31 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_CDMA_LEVEL
32 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_EMERGENCY
33 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_IS_GSM
34 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_IS_IN_SERVICE
35 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_OPERATOR
36 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_PRIMARY_LEVEL
37 import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Companion.COL_ROAMING
38 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
39 import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
40 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
41 import kotlinx.coroutines.CoroutineScope
42 import kotlinx.coroutines.flow.MutableStateFlow
43 import kotlinx.coroutines.flow.SharingStarted
44 import kotlinx.coroutines.flow.stateIn
45 
46 /**
47  * Demo version of [MobileConnectionRepository]. Note that this class shares all of its flows using
48  * [SharingStarted.WhileSubscribed()] to give the same semantics as using a regular
49  * [MutableStateFlow] while still logging all of the inputs in the same manor as the production
50  * repos.
51  */
52 class DemoMobileConnectionRepository(
53     override val subId: Int,
54     override val tableLogBuffer: TableLogBuffer,
55     val scope: CoroutineScope,
56 ) : MobileConnectionRepository {
57     private val _carrierId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
58     override val carrierId =
59         _carrierId
60             .logDiffsForTable(
61                 tableLogBuffer,
62                 columnPrefix = "",
63                 columnName = COL_CARRIER_ID,
64                 _carrierId.value,
65             )
66             .stateIn(scope, SharingStarted.WhileSubscribed(), _carrierId.value)
67 
68     private val _isEmergencyOnly = MutableStateFlow(false)
69     override val isEmergencyOnly =
70         _isEmergencyOnly
71             .logDiffsForTable(
72                 tableLogBuffer,
73                 columnPrefix = "",
74                 columnName = COL_EMERGENCY,
75                 _isEmergencyOnly.value
76             )
77             .stateIn(scope, SharingStarted.WhileSubscribed(), _isEmergencyOnly.value)
78 
79     private val _isRoaming = MutableStateFlow(false)
80     override val isRoaming =
81         _isRoaming
82             .logDiffsForTable(
83                 tableLogBuffer,
84                 columnPrefix = "",
85                 columnName = COL_ROAMING,
86                 _isRoaming.value
87             )
88             .stateIn(scope, SharingStarted.WhileSubscribed(), _isRoaming.value)
89 
90     private val _operatorAlphaShort: MutableStateFlow<String?> = MutableStateFlow(null)
91     override val operatorAlphaShort =
92         _operatorAlphaShort
93             .logDiffsForTable(
94                 tableLogBuffer,
95                 columnPrefix = "",
96                 columnName = COL_OPERATOR,
97                 _operatorAlphaShort.value
98             )
99             .stateIn(scope, SharingStarted.WhileSubscribed(), _operatorAlphaShort.value)
100 
101     private val _isInService = MutableStateFlow(false)
102     override val isInService =
103         _isInService
104             .logDiffsForTable(
105                 tableLogBuffer,
106                 columnPrefix = "",
107                 columnName = COL_IS_IN_SERVICE,
108                 _isInService.value
109             )
110             .stateIn(scope, SharingStarted.WhileSubscribed(), _isInService.value)
111 
112     private val _isGsm = MutableStateFlow(false)
113     override val isGsm =
114         _isGsm
115             .logDiffsForTable(
116                 tableLogBuffer,
117                 columnPrefix = "",
118                 columnName = COL_IS_GSM,
119                 _isGsm.value
120             )
121             .stateIn(scope, SharingStarted.WhileSubscribed(), _isGsm.value)
122 
123     private val _cdmaLevel = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
124     override val cdmaLevel =
125         _cdmaLevel
126             .logDiffsForTable(
127                 tableLogBuffer,
128                 columnPrefix = "",
129                 columnName = COL_CDMA_LEVEL,
130                 _cdmaLevel.value
131             )
132             .stateIn(scope, SharingStarted.WhileSubscribed(), _cdmaLevel.value)
133 
134     private val _primaryLevel = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
135     override val primaryLevel =
136         _primaryLevel
137             .logDiffsForTable(
138                 tableLogBuffer,
139                 columnPrefix = "",
140                 columnName = COL_PRIMARY_LEVEL,
141                 _primaryLevel.value
142             )
143             .stateIn(scope, SharingStarted.WhileSubscribed(), _primaryLevel.value)
144 
145     private val _dataConnectionState = MutableStateFlow(DataConnectionState.Disconnected)
146     override val dataConnectionState =
147         _dataConnectionState
148             .logDiffsForTable(tableLogBuffer, columnPrefix = "", _dataConnectionState.value)
149             .stateIn(scope, SharingStarted.WhileSubscribed(), _dataConnectionState.value)
150 
151     private val _dataActivityDirection =
152         MutableStateFlow(
153             DataActivityModel(
154                 hasActivityIn = false,
155                 hasActivityOut = false,
156             )
157         )
158     override val dataActivityDirection =
159         _dataActivityDirection
160             .logDiffsForTable(tableLogBuffer, columnPrefix = "", _dataActivityDirection.value)
161             .stateIn(scope, SharingStarted.WhileSubscribed(), _dataActivityDirection.value)
162 
163     private val _carrierNetworkChangeActive = MutableStateFlow(false)
164     override val carrierNetworkChangeActive =
165         _carrierNetworkChangeActive
166             .logDiffsForTable(
167                 tableLogBuffer,
168                 columnPrefix = "",
169                 columnName = COL_CARRIER_NETWORK_CHANGE,
170                 _carrierNetworkChangeActive.value
171             )
172             .stateIn(scope, SharingStarted.WhileSubscribed(), _carrierNetworkChangeActive.value)
173 
174     private val _resolvedNetworkType: MutableStateFlow<ResolvedNetworkType> =
175         MutableStateFlow(ResolvedNetworkType.UnknownNetworkType)
176     override val resolvedNetworkType =
177         _resolvedNetworkType
178             .logDiffsForTable(tableLogBuffer, columnPrefix = "", _resolvedNetworkType.value)
179             .stateIn(scope, SharingStarted.WhileSubscribed(), _resolvedNetworkType.value)
180 
181     override val numberOfLevels = MutableStateFlow(MobileConnectionRepository.DEFAULT_NUM_LEVELS)
182 
183     override val dataEnabled = MutableStateFlow(true)
184 
185     override val cdmaRoaming = MutableStateFlow(false)
186 
187     override val networkName = MutableStateFlow(NetworkNameModel.IntentDerived(DEMO_CARRIER_NAME))
188 
189     override val carrierName =
190         MutableStateFlow(NetworkNameModel.SubscriptionDerived(DEMO_CARRIER_NAME))
191 
192     override val isAllowedDuringAirplaneMode = MutableStateFlow(false)
193 
194     /**
195      * Process a new demo mobile event. Note that [resolvedNetworkType] must be passed in separately
196      * from the event, due to the requirement to reverse the mobile mappings lookup in the top-level
197      * repository.
198      */
processDemoMobileEventnull199     fun processDemoMobileEvent(
200         event: FakeNetworkEventModel.Mobile,
201         resolvedNetworkType: ResolvedNetworkType,
202     ) {
203         // This is always true here, because we split out disabled states at the data-source level
204         dataEnabled.value = true
205         networkName.value = NetworkNameModel.IntentDerived(event.name)
206         carrierName.value = NetworkNameModel.SubscriptionDerived("${event.name} ${event.subId}")
207 
208         _carrierId.value = event.carrierId ?: INVALID_SUBSCRIPTION_ID
209 
210         cdmaRoaming.value = event.roaming
211         _isRoaming.value = event.roaming
212         // TODO(b/261029387): not yet supported
213         _isEmergencyOnly.value = false
214         _operatorAlphaShort.value = event.name
215         _isInService.value = (event.level ?: 0) > 0
216         // TODO(b/261029387): not yet supported
217         _isGsm.value = false
218         _cdmaLevel.value = event.level ?: 0
219         _primaryLevel.value = event.level ?: 0
220         // TODO(b/261029387): not yet supported
221         _dataConnectionState.value = DataConnectionState.Connected
222         _dataActivityDirection.value =
223             (event.activity ?: TelephonyManager.DATA_ACTIVITY_NONE).toMobileDataActivityModel()
224         _carrierNetworkChangeActive.value = event.carrierNetworkChange
225         _resolvedNetworkType.value = resolvedNetworkType
226 
227         isAllowedDuringAirplaneMode.value = false
228     }
229 
processCarrierMergedEventnull230     fun processCarrierMergedEvent(event: FakeWifiEventModel.CarrierMerged) {
231         // This is always true here, because we split out disabled states at the data-source level
232         dataEnabled.value = true
233         networkName.value = NetworkNameModel.IntentDerived(CARRIER_MERGED_NAME)
234         carrierName.value = NetworkNameModel.SubscriptionDerived(CARRIER_MERGED_NAME)
235         // TODO(b/276943904): is carrierId a thing with carrier merged networks?
236         _carrierId.value = INVALID_SUBSCRIPTION_ID
237         numberOfLevels.value = event.numberOfLevels
238         cdmaRoaming.value = false
239         _primaryLevel.value = event.level
240         _cdmaLevel.value = event.level
241         _dataActivityDirection.value = event.activity.toMobileDataActivityModel()
242 
243         // These fields are always the same for carrier-merged networks
244         _resolvedNetworkType.value = ResolvedNetworkType.CarrierMergedNetworkType
245         _dataConnectionState.value = DataConnectionState.Connected
246         _isRoaming.value = false
247         _isEmergencyOnly.value = false
248         _operatorAlphaShort.value = null
249         _isInService.value = true
250         _isGsm.value = false
251         _carrierNetworkChangeActive.value = false
252         isAllowedDuringAirplaneMode.value = true
253     }
254 
255     companion object {
256         private const val DEMO_CARRIER_NAME = "Demo Carrier"
257         private const val CARRIER_MERGED_NAME = "Carrier Merged Network"
258     }
259 }
260