• 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.model
18 
19 import android.os.PersistableBundle
20 import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL
21 import android.telephony.CarrierConfigManager.KEY_SHOW_5G_SLICE_ICON_BOOL
22 import android.telephony.CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL
23 import androidx.annotation.VisibleForTesting
24 import kotlinx.coroutines.flow.MutableStateFlow
25 import kotlinx.coroutines.flow.StateFlow
26 import kotlinx.coroutines.flow.asStateFlow
27 
28 /**
29  * Represents, for a given subscription ID, the set of keys about which SystemUI cares.
30  *
31  * Upon first creation, this config represents only the default configuration (see
32  * [android.telephony.CarrierConfigManager.getDefaultConfig]).
33  *
34  * Upon request (see
35  * [com.android.systemui.statusbar.pipeline.mobile.data.repository.CarrierConfigRepository]), an
36  * instance of this class may be created for a given subscription Id, and will default to
37  * representing the default carrier configuration. However, once a carrier config is received for
38  * this [subId], all fields will reflect those in the received config, using [PersistableBundle]'s
39  * default of false for any config that is not present in the override.
40  *
41  * To keep things relatively simple, this class defines a wrapper around each config key which
42  * exposes a StateFlow<Boolean> for each config we care about. It also tracks whether or not it is
43  * using the default config for logging purposes.
44  *
45  * NOTE to add new keys to be tracked:
46  * 1. Define a new `private val` wrapping the key using [BooleanCarrierConfig]
47  * 2. Define a public `val` exposing the wrapped flow using [BooleanCarrierConfig.config]
48  * 3. Add the new [BooleanCarrierConfig] to the list of tracked configs, so they are properly
49  *    updated when a new carrier config comes down
50  */
51 class SystemUiCarrierConfig constructor(val subId: Int, defaultConfig: PersistableBundle) {
52     @VisibleForTesting
53     var isUsingDefault = true
54         private set
55 
56     private val inflateSignalStrength =
57         BooleanCarrierConfig(KEY_INFLATE_SIGNAL_STRENGTH_BOOL, defaultConfig)
58     /** Flow tracking the [KEY_INFLATE_SIGNAL_STRENGTH_BOOL] carrier config */
59     val shouldInflateSignalStrength: StateFlow<Boolean> = inflateSignalStrength.config
60 
61     private val showOperatorName =
62         BooleanCarrierConfig(KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL, defaultConfig)
63     /** Flow tracking the [KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL] config */
64     val showOperatorNameInStatusBar: StateFlow<Boolean> = showOperatorName.config
65 
66     private val showNetworkSlice = BooleanCarrierConfig(KEY_SHOW_5G_SLICE_ICON_BOOL, defaultConfig)
67     /** Flow tracking the [KEY_SHOW_5G_SLICE_ICON_BOOL] config */
68     val allowNetworkSliceIndicator: StateFlow<Boolean> = showNetworkSlice.config
69 
70     private val trackedConfigs = listOf(inflateSignalStrength, showOperatorName, showNetworkSlice)
71 
72     /** Ingest a new carrier config, and switch all of the tracked keys over to the new values */
processNewCarrierConfignull73     fun processNewCarrierConfig(config: PersistableBundle) {
74         isUsingDefault = false
75         trackedConfigs.forEach { it.update(config) }
76     }
77 
78     /** For dumpsys, shortcut if we haven't overridden any keys */
toStringConsideringDefaultsnull79     fun toStringConsideringDefaults(): String {
80         return if (isUsingDefault) {
81             "using defaults"
82         } else {
83             trackedConfigs.joinToString { it.toString() }
84         }
85     }
86 
<lambda>null87     override fun toString(): String = trackedConfigs.joinToString { it.toString() }
88 }
89 
90 /** Extracts [key] from the carrier config, and stores it in a flow */
91 private class BooleanCarrierConfig(val key: String, defaultConfig: PersistableBundle) {
92     private val _configValue = MutableStateFlow(defaultConfig.getBoolean(key))
93     val config = _configValue.asStateFlow()
94 
updatenull95     fun update(config: PersistableBundle) {
96         _configValue.value = config.getBoolean(key)
97     }
98 
toStringnull99     override fun toString(): String {
100         return "$key=${config.value}"
101     }
102 }
103