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