1 /*
2  * Copyright (C) 2021 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.util;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.os.PersistableBundle;
24 import android.telephony.CarrierConfigManager;
25 import android.telephony.SubscriptionManager;
26 import android.util.ArraySet;
27 import android.util.SparseBooleanArray;
28 
29 import androidx.annotation.NonNull;
30 
31 import com.android.internal.telephony.TelephonyIntents;
32 import com.android.systemui.broadcast.BroadcastDispatcher;
33 import com.android.systemui.dagger.SysUISingleton;
34 import com.android.systemui.statusbar.policy.CallbackController;
35 
36 import java.util.Set;
37 
38 import javax.inject.Inject;
39 
40 /**
41  * Tracks CarrierConfigs for each subId, as well as the default configuration. CarrierConfigurations
42  * do not trigger a device configuration event, so any UI that relies on carrier configurations must
43  * register with the tracker to get proper updates.
44  *
45  * The tracker also listens for `TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED`
46  *
47  * @see CarrierConfigChangedListener to listen for updates
48  */
49 @SysUISingleton
50 public class CarrierConfigTracker
51         extends BroadcastReceiver
52         implements CallbackController<CarrierConfigTracker.CarrierConfigChangedListener> {
53     private final SparseBooleanArray mCallStrengthConfigs = new SparseBooleanArray();
54     private final SparseBooleanArray mNoCallingConfigs = new SparseBooleanArray();
55     private final SparseBooleanArray mCarrierProvisionsWifiMergedNetworks =
56             new SparseBooleanArray();
57     private final SparseBooleanArray mShowOperatorNameConfigs = new SparseBooleanArray();
58     private final CarrierConfigManager mCarrierConfigManager;
59     private final Set<CarrierConfigChangedListener> mListeners = new ArraySet<>();
60     private final Set<DefaultDataSubscriptionChangedListener> mDataListeners =
61             new ArraySet<>();
62     private boolean mDefaultCallStrengthConfigLoaded;
63     private boolean mDefaultCallStrengthConfig;
64     private boolean mDefaultNoCallingConfigLoaded;
65     private boolean mDefaultNoCallingConfig;
66     private boolean mDefaultCarrierProvisionsWifiMergedNetworksLoaded;
67     private boolean mDefaultCarrierProvisionsWifiMergedNetworks;
68     private boolean mDefaultShowOperatorNameConfigLoaded;
69     private boolean mDefaultShowOperatorNameConfig;
70     private boolean mDefaultAlwaysShowPrimarySignalBarInOpportunisticNetworkConfigLoaded;
71     private boolean mDefaultAlwaysShowPrimarySignalBarInOpportunisticNetworkConfig;
72 
73     @Inject
CarrierConfigTracker( CarrierConfigManager carrierConfigManager, BroadcastDispatcher broadcastDispatcher)74     public CarrierConfigTracker(
75             CarrierConfigManager carrierConfigManager,
76             BroadcastDispatcher broadcastDispatcher) {
77         mCarrierConfigManager = carrierConfigManager;
78         IntentFilter filter = new IntentFilter();
79         filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
80         filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
81         broadcastDispatcher.registerReceiver(this, filter);
82     }
83 
84     @Override
onReceive(Context context, Intent intent)85     public void onReceive(Context context, Intent intent) {
86         String action = intent.getAction();
87         if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
88             updateFromNewCarrierConfig(intent);
89         } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
90             updateDefaultDataSubscription(intent);
91         }
92     }
93 
updateFromNewCarrierConfig(Intent intent)94     private void updateFromNewCarrierConfig(Intent intent) {
95         final int subId = intent.getIntExtra(
96                 CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
97                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
98         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
99             return;
100         }
101 
102         final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
103         if (config == null) {
104             return;
105         }
106 
107         synchronized (mCallStrengthConfigs) {
108             mCallStrengthConfigs.put(subId, config.getBoolean(
109                     CarrierConfigManager.KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL));
110         }
111         synchronized (mNoCallingConfigs) {
112             mNoCallingConfigs.put(subId, config.getBoolean(
113                     CarrierConfigManager.KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL));
114         }
115         synchronized (mCarrierProvisionsWifiMergedNetworks) {
116             mCarrierProvisionsWifiMergedNetworks.put(subId, config.getBoolean(
117                     CarrierConfigManager.KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL));
118         }
119         synchronized (mShowOperatorNameConfigs) {
120             mShowOperatorNameConfigs.put(subId, config.getBoolean(
121                     CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL));
122         }
123 
124         notifyCarrierConfigChanged();
125     }
126 
updateDefaultDataSubscription(Intent intent)127     private void updateDefaultDataSubscription(Intent intent) {
128         int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, -1);
129         notifyDefaultDataSubscriptionChanged(subId);
130     }
131 
notifyCarrierConfigChanged()132     private void notifyCarrierConfigChanged() {
133         for (CarrierConfigChangedListener l : mListeners) {
134             l.onCarrierConfigChanged();
135         }
136     }
137 
notifyDefaultDataSubscriptionChanged(int subId)138     private void notifyDefaultDataSubscriptionChanged(int subId) {
139         for (DefaultDataSubscriptionChangedListener l : mDataListeners) {
140             l.onDefaultSubscriptionChanged(subId);
141         }
142     }
143 
144     /**
145      * Returns the KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL value for the given subId.
146      */
getCallStrengthConfig(int subId)147     public boolean getCallStrengthConfig(int subId) {
148         synchronized (mCallStrengthConfigs) {
149             if (mCallStrengthConfigs.indexOfKey(subId) >= 0) {
150                 return mCallStrengthConfigs.get(subId);
151             }
152         }
153         if (!mDefaultCallStrengthConfigLoaded) {
154             mDefaultCallStrengthConfig =
155                     CarrierConfigManager.getDefaultConfig().getBoolean(
156                             CarrierConfigManager.KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL);
157             mDefaultCallStrengthConfigLoaded = true;
158         }
159         return mDefaultCallStrengthConfig;
160     }
161 
162     /**
163      * Returns the KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL value for the given subId.
164      */
getNoCallingConfig(int subId)165     public boolean getNoCallingConfig(int subId) {
166         synchronized (mNoCallingConfigs) {
167             if (mNoCallingConfigs.indexOfKey(subId) >= 0) {
168                 return mNoCallingConfigs.get(subId);
169             }
170         }
171         if (!mDefaultNoCallingConfigLoaded) {
172             mDefaultNoCallingConfig =
173                     CarrierConfigManager.getDefaultConfig().getBoolean(
174                             CarrierConfigManager.KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL);
175             mDefaultNoCallingConfigLoaded = true;
176         }
177         return mDefaultNoCallingConfig;
178     }
179 
180     /**
181      * Returns the KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL value for the given subId.
182      */
getCarrierProvisionsWifiMergedNetworksBool(int subId)183     public boolean getCarrierProvisionsWifiMergedNetworksBool(int subId) {
184         synchronized (mCarrierProvisionsWifiMergedNetworks) {
185             if (mCarrierProvisionsWifiMergedNetworks.indexOfKey(subId) >= 0) {
186                 return mCarrierProvisionsWifiMergedNetworks.get(subId);
187             }
188         }
189         if (!mDefaultCarrierProvisionsWifiMergedNetworksLoaded) {
190             mDefaultCarrierProvisionsWifiMergedNetworks =
191                     CarrierConfigManager.getDefaultConfig().getBoolean(
192                             CarrierConfigManager.KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL);
193             mDefaultCarrierProvisionsWifiMergedNetworksLoaded = true;
194         }
195         return mDefaultCarrierProvisionsWifiMergedNetworks;
196     }
197 
198     /**
199      * Returns the KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL value for the default config
200      */
getShowOperatorNameInStatusBarConfigDefault()201     public boolean getShowOperatorNameInStatusBarConfigDefault() {
202         if (!mDefaultShowOperatorNameConfigLoaded) {
203             mDefaultShowOperatorNameConfig = CarrierConfigManager.getDefaultConfig().getBoolean(
204                     CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL);
205             mDefaultShowOperatorNameConfigLoaded = true;
206         }
207 
208         return mDefaultShowOperatorNameConfig;
209     }
210 
211     /**
212      * Returns KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN value for
213      * the default carrier config.
214      */
getAlwaysShowPrimarySignalBarInOpportunisticNetworkDefault()215     public boolean getAlwaysShowPrimarySignalBarInOpportunisticNetworkDefault() {
216         if (!mDefaultAlwaysShowPrimarySignalBarInOpportunisticNetworkConfigLoaded) {
217             mDefaultAlwaysShowPrimarySignalBarInOpportunisticNetworkConfig = CarrierConfigManager
218                     .getDefaultConfig().getBoolean(CarrierConfigManager
219                             .KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN
220                     );
221             mDefaultAlwaysShowPrimarySignalBarInOpportunisticNetworkConfigLoaded = true;
222         }
223 
224         return mDefaultAlwaysShowPrimarySignalBarInOpportunisticNetworkConfig;
225     }
226 
227     /**
228      * Returns the KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL value for the given subId, or the
229      * default value if no override exists
230      *
231      * @param subId the subscription id for which to query the config
232      */
getShowOperatorNameInStatusBarConfig(int subId)233     public boolean getShowOperatorNameInStatusBarConfig(int subId) {
234         if (mShowOperatorNameConfigs.indexOfKey(subId) >= 0) {
235             return mShowOperatorNameConfigs.get(subId);
236         } else {
237             return getShowOperatorNameInStatusBarConfigDefault();
238         }
239     }
240 
241     @Override
addCallback(@onNull CarrierConfigChangedListener listener)242     public void addCallback(@NonNull CarrierConfigChangedListener listener) {
243         mListeners.add(listener);
244     }
245 
246     @Override
removeCallback(@onNull CarrierConfigChangedListener listener)247     public void removeCallback(@NonNull CarrierConfigChangedListener listener) {
248         mListeners.remove(listener);
249     }
250 
251     /** */
addDefaultDataSubscriptionChangedListener( @onNull DefaultDataSubscriptionChangedListener listener)252     public void addDefaultDataSubscriptionChangedListener(
253             @NonNull DefaultDataSubscriptionChangedListener listener) {
254         mDataListeners.add(listener);
255     }
256 
257     /** */
removeDataSubscriptionChangedListener( DefaultDataSubscriptionChangedListener listener)258     public void removeDataSubscriptionChangedListener(
259             DefaultDataSubscriptionChangedListener listener) {
260         mDataListeners.remove(listener);
261     }
262 
263     /**
264      * Called when carrier config changes
265      */
266     public interface CarrierConfigChangedListener {
267         /** */
onCarrierConfigChanged()268         void onCarrierConfigChanged();
269     }
270 
271     /**
272      * Called when the default data subscription changes. Listeners may want to query
273      * subId-dependent configuration values when this event happens
274      */
275     public interface DefaultDataSubscriptionChangedListener {
276         /**
277          * @param subId the new default data subscription id per
278          * {@link SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX}
279          */
onDefaultSubscriptionChanged(int subId)280         void onDefaultSubscriptionChanged(int subId);
281     }
282 }
283