blob: 051bd29bc32347dc526d8c3ddd89eb01c0798264 [file] [log] [blame]
John Spurlockaf8d6c42014-05-07 17:49:08 -04001/*
2 * Copyright (C) 2010 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
17package com.android.systemui.statusbar.policy;
18
Roshan Pius80fb1372018-07-16 15:43:03 -070019import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
Malcolm Chen0c63c4d2020-02-25 18:13:40 -080020import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
Roshan Pius80fb1372018-07-16 15:43:03 -070021import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN;
22import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
23import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE;
24import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT;
Malcolm Chen50ba9632019-02-26 16:49:56 -080025import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
Jason Monk196d6392018-12-20 13:25:34 -050026
John Spurlockaf8d6c42014-05-07 17:49:08 -040027import android.content.BroadcastReceiver;
28import android.content.Context;
29import android.content.Intent;
30import android.content.IntentFilter;
Jason Monk9c7844c2017-01-18 15:21:53 -050031import android.content.res.Configuration;
John Spurlockaf8d6c42014-05-07 17:49:08 -040032import android.content.res.Resources;
33import android.net.ConnectivityManager;
Anarghya Mitra678722f2018-05-11 14:29:54 -070034import android.net.Network;
Lorenzo Colitti403aa262014-11-28 11:21:30 +090035import android.net.NetworkCapabilities;
Fabian Kozynski57ba5192020-04-01 15:24:12 -040036import android.net.NetworkScoreManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -040037import android.net.wifi.WifiManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -040038import android.os.AsyncTask;
39import android.os.Bundle;
Jason Monk07b75fe2015-05-14 16:47:03 -040040import android.os.Handler;
Jason Monk30d80042015-05-08 16:54:18 -040041import android.os.Looper;
Wenting Xiong63364fe2017-02-07 19:12:27 +080042import android.os.PersistableBundle;
John Spurlockaf8d6c42014-05-07 17:49:08 -040043import android.provider.Settings;
Wenting Xiong63364fe2017-02-07 19:12:27 +080044import android.telephony.CarrierConfigManager;
Amit Mahajan75eab472020-01-29 10:47:48 -080045import android.telephony.CellSignalStrength;
Malcolm Chen50ba9632019-02-26 16:49:56 -080046import android.telephony.PhoneStateListener;
Jason Monkb0808aa2015-07-22 16:34:36 -040047import android.telephony.ServiceState;
Jason Monkb5746272014-11-12 16:50:31 -050048import android.telephony.SubscriptionInfo;
49import android.telephony.SubscriptionManager;
50import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
John Spurlockaf8d6c42014-05-07 17:49:08 -040051import android.telephony.TelephonyManager;
Jason Monkb5746272014-11-12 16:50:31 -050052import android.text.TextUtils;
John Spurlockaf8d6c42014-05-07 17:49:08 -040053import android.util.Log;
John Spurlockcf053c12015-05-14 16:33:59 -040054import android.util.MathUtils;
Jason Monk8996b942017-03-02 13:58:19 -050055import android.util.SparseArray;
Winsonc0d70582016-01-29 10:24:39 -080056
Evan Laird470ae842019-04-09 16:24:27 -040057import com.android.internal.annotations.GuardedBy;
Jason Monke0cdb602014-11-05 12:39:45 -050058import com.android.internal.annotations.VisibleForTesting;
Jason Monkf668d7c2016-01-14 10:38:41 -050059import com.android.settingslib.net.DataUsageController;
John Spurlockaf8d6c42014-05-07 17:49:08 -040060import com.android.systemui.DemoMode;
Jason Monk9c7844c2017-01-18 15:21:53 -050061import com.android.systemui.Dumpable;
John Spurlockaf8d6c42014-05-07 17:49:08 -040062import com.android.systemui.R;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000063import com.android.systemui.broadcast.BroadcastDispatcher;
Dave Mankoff00e8a2f2019-12-18 16:59:49 -050064import com.android.systemui.dagger.qualifiers.Background;
Jason Monk9c7844c2017-01-18 15:21:53 -050065import com.android.systemui.settings.CurrentUserTracker;
66import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
John Spurlockaf8d6c42014-05-07 17:49:08 -040067
68import java.io.FileDescriptor;
69import java.io.PrintWriter;
70import java.util.ArrayList;
Lorenzo Colitti403aa262014-11-28 11:21:30 +090071import java.util.BitSet;
Jason Monkb5746272014-11-12 16:50:31 -050072import java.util.Collections;
73import java.util.Comparator;
John Spurlockaf8d6c42014-05-07 17:49:08 -040074import java.util.List;
75import java.util.Locale;
76
Jason Monk196d6392018-12-20 13:25:34 -050077import javax.inject.Inject;
Jason Monk196d6392018-12-20 13:25:34 -050078import javax.inject.Singleton;
79
John Spurlockaf8d6c42014-05-07 17:49:08 -040080/** Platform implementation of the network controller. **/
Jason Monk196d6392018-12-20 13:25:34 -050081@Singleton
John Spurlockaf8d6c42014-05-07 17:49:08 -040082public class NetworkControllerImpl extends BroadcastReceiver
Dave Mankoffbba732d2019-11-20 13:04:54 -050083 implements NetworkController, DemoMode, DataUsageController.NetworkNameProvider, Dumpable {
John Spurlockaf8d6c42014-05-07 17:49:08 -040084 // debug
Jason Monkd2263cd2014-11-10 14:22:56 -050085 static final String TAG = "NetworkController";
86 static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
87 // additional diagnostics, but not logspew
Jason Monk07b75fe2015-05-14 16:47:03 -040088 static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG);
John Spurlockaf8d6c42014-05-07 17:49:08 -040089
Jason Monk66845a32015-08-03 11:09:41 -040090 private static final int EMERGENCY_NO_CONTROLLERS = 0;
91 private static final int EMERGENCY_FIRST_CONTROLLER = 100;
92 private static final int EMERGENCY_VOICE_CONTROLLER = 200;
93 private static final int EMERGENCY_NO_SUB = 300;
Jason Monk8996b942017-03-02 13:58:19 -050094 private static final int EMERGENCY_ASSUMED_VOICE_CONTROLLER = 400;
Jason Monk66845a32015-08-03 11:09:41 -040095
Jason Monkd2263cd2014-11-10 14:22:56 -050096 private final Context mContext;
97 private final TelephonyManager mPhone;
98 private final WifiManager mWifiManager;
99 private final ConnectivityManager mConnectivityManager;
Jason Monkb5746272014-11-12 16:50:31 -0500100 private final SubscriptionManager mSubscriptionManager;
Jason Monkd2263cd2014-11-10 14:22:56 -0500101 private final boolean mHasMobileDataFeature;
Jason Monkc6cc6262015-06-11 11:10:15 -0400102 private final SubscriptionDefaults mSubDefaults;
Jason Monk9a4ce132016-01-21 15:27:17 -0500103 private final DataSaverController mDataSaverController;
Jason Monk9c7844c2017-01-18 15:21:53 -0500104 private final CurrentUserTracker mUserTracker;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000105 private final BroadcastDispatcher mBroadcastDispatcher;
Evan Laird470ae842019-04-09 16:24:27 -0400106 private final Object mLock = new Object();
Jason Monk3aaabd72014-12-12 11:11:44 -0500107 private Config mConfig;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400108
Evan Laird470ae842019-04-09 16:24:27 -0400109 private PhoneStateListener mPhoneStateListener;
Malcolm Chen50ba9632019-02-26 16:49:56 -0800110 private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
111
Jason Monkd2263cd2014-11-10 14:22:56 -0500112 // Subcontrollers.
113 @VisibleForTesting
114 final WifiSignalController mWifiSignalController;
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900115
116 @VisibleForTesting
117 final EthernetSignalController mEthernetSignalController;
118
Jason Monkd2263cd2014-11-10 14:22:56 -0500119 @VisibleForTesting
Jason Monk8996b942017-03-02 13:58:19 -0500120 final SparseArray<MobileSignalController> mMobileSignalControllers = new SparseArray<>();
Jason Monkb5746272014-11-12 16:50:31 -0500121 // When no SIMs are around at setup, and one is added later, it seems to default to the first
122 // SIM for most actions. This may be null if there aren't any SIMs around.
123 private MobileSignalController mDefaultSignalController;
Jason Monk0e2400f2014-11-21 11:08:55 -0500124 private final AccessPointControllerImpl mAccessPoints;
Jason Monkf668d7c2016-01-14 10:38:41 -0500125 private final DataUsageController mDataUsageController;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400126
Jason Monkd2263cd2014-11-10 14:22:56 -0500127 private boolean mInetCondition; // Used for Logging and demo.
Lorenzo Colitti23dd1762014-09-10 22:58:54 +0900128
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900129 // BitSets indicating which network transport types (e.g., TRANSPORT_WIFI, TRANSPORT_MOBILE) are
130 // connected and validated, respectively.
131 private final BitSet mConnectedTransports = new BitSet();
132 private final BitSet mValidatedTransports = new BitSet();
133
Jason Monkd2263cd2014-11-10 14:22:56 -0500134 // States that don't belong to a subcontroller.
John Spurlockaf8d6c42014-05-07 17:49:08 -0400135 private boolean mAirplaneMode = false;
Jason Monk1ff77662017-09-29 11:17:05 -0400136 private boolean mHasNoSubs;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400137 private Locale mLocale = null;
Jason Monkb5746272014-11-12 16:50:31 -0500138 // This list holds our ordering.
John Spurlockcf053c12015-05-14 16:33:59 -0400139 private List<SubscriptionInfo> mCurrentSubscriptions = new ArrayList<>();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400140
Jason Monkc014dec2014-12-12 11:49:55 -0500141 @VisibleForTesting
142 boolean mListening;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400143
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900144 // The current user ID.
145 private int mCurrentUserId;
146
Jason Monk8fcab352015-06-29 10:57:00 -0400147 private OnSubscriptionsChangedListener mSubscriptionListener;
148
Jason Monk07b75fe2015-05-14 16:47:03 -0400149 // Handler that all broadcasts are received on.
150 private final Handler mReceiverHandler;
151 // Handler that all callbacks are made on.
152 private final CallbackHandler mCallbackHandler;
153
Jason Monk66845a32015-08-03 11:09:41 -0400154 private int mEmergencySource;
155 private boolean mIsEmergency;
156
Jason Monkb0808aa2015-07-22 16:34:36 -0400157 @VisibleForTesting
158 ServiceState mLastServiceState;
Jason Monkfd57ea72016-04-29 13:37:58 -0400159 private boolean mUserSetup;
Jason Monk1ff77662017-09-29 11:17:05 -0400160 private boolean mSimDetected;
Malcolm Chen0c63c4d2020-02-25 18:13:40 -0800161 private boolean mForceCellularValidated;
Jason Monkb0808aa2015-07-22 16:34:36 -0400162
Dave Mankoffbba732d2019-11-20 13:04:54 -0500163 private ConfigurationController.ConfigurationListener mConfigurationListener =
164 new ConfigurationController.ConfigurationListener() {
165 @Override
166 public void onConfigChanged(Configuration newConfig) {
167 mConfig = Config.readConfig(mContext);
168 mReceiverHandler.post(() -> handleConfigurationChanged());
169 }
170 };
John Spurlockaf8d6c42014-05-07 17:49:08 -0400171 /**
172 * Construct this controller object and register for updates.
173 */
Jason Monk196d6392018-12-20 13:25:34 -0500174 @Inject
Dave Mankoff00e8a2f2019-12-18 16:59:49 -0500175 public NetworkControllerImpl(Context context, @Background Looper bgLooper,
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000176 DeviceProvisionedController deviceProvisionedController,
Fabian Kozynski57ba5192020-04-01 15:24:12 -0400177 BroadcastDispatcher broadcastDispatcher, ConnectivityManager connectivityManager,
178 TelephonyManager telephonyManager, WifiManager wifiManager,
179 NetworkScoreManager networkScoreManager) {
180 this(context, connectivityManager,
181 telephonyManager,
182 wifiManager,
183 networkScoreManager,
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +0000184 SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
Jason Monk07b75fe2015-05-14 16:47:03 -0400185 new CallbackHandler(),
Tony Mantler0edf09b2017-09-28 15:03:37 -0700186 new AccessPointControllerImpl(context),
Jason Monkf668d7c2016-01-14 10:38:41 -0500187 new DataUsageController(context),
Jason Monk9c7844c2017-01-18 15:21:53 -0500188 new SubscriptionDefaults(),
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000189 deviceProvisionedController,
190 broadcastDispatcher);
Jason Monk07b75fe2015-05-14 16:47:03 -0400191 mReceiverHandler.post(mRegisterListeners);
Jason Monkf13b4b32014-11-07 16:39:34 -0500192 }
193
194 @VisibleForTesting
195 NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +0000196 TelephonyManager telephonyManager, WifiManager wifiManager,
Fabian Kozynski57ba5192020-04-01 15:24:12 -0400197 NetworkScoreManager networkScoreManager,
Sundeep Ghuman9d10a3c2017-06-16 00:05:16 +0000198 SubscriptionManager subManager, Config config, Looper bgLooper,
Jason Monk07b75fe2015-05-14 16:47:03 -0400199 CallbackHandler callbackHandler,
Jason Monkd2263cd2014-11-10 14:22:56 -0500200 AccessPointControllerImpl accessPointController,
Jason Monkf668d7c2016-01-14 10:38:41 -0500201 DataUsageController dataUsageController,
Jason Monk9c7844c2017-01-18 15:21:53 -0500202 SubscriptionDefaults defaultsHandler,
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000203 DeviceProvisionedController deviceProvisionedController,
204 BroadcastDispatcher broadcastDispatcher) {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400205 mContext = context;
Jason Monkb5746272014-11-12 16:50:31 -0500206 mConfig = config;
Jason Monk07b75fe2015-05-14 16:47:03 -0400207 mReceiverHandler = new Handler(bgLooper);
208 mCallbackHandler = callbackHandler;
Jason Monk9abca5e2016-11-11 16:18:14 -0500209 mDataSaverController = new DataSaverControllerImpl(context);
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000210 mBroadcastDispatcher = broadcastDispatcher;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400211
Jason Monkb5746272014-11-12 16:50:31 -0500212 mSubscriptionManager = subManager;
Jason Monkc6cc6262015-06-11 11:10:15 -0400213 mSubDefaults = defaultsHandler;
Jason Monkf13b4b32014-11-07 16:39:34 -0500214 mConnectivityManager = connectivityManager;
215 mHasMobileDataFeature =
216 mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400217
John Spurlockaf8d6c42014-05-07 17:49:08 -0400218 // telephony
Jason Monk07b75fe2015-05-14 16:47:03 -0400219 mPhone = telephonyManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400220
221 // wifi
Jason Monkf13b4b32014-11-07 16:39:34 -0500222 mWifiManager = wifiManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400223
Jason Monkd2263cd2014-11-10 14:22:56 -0500224 mLocale = mContext.getResources().getConfiguration().locale;
Jason Monk29f7a7b2014-11-17 14:40:56 -0500225 mAccessPoints = accessPointController;
Jason Monkf668d7c2016-01-14 10:38:41 -0500226 mDataUsageController = dataUsageController;
227 mDataUsageController.setNetworkController(this);
228 // TODO: Find a way to move this into DataUsageController.
229 mDataUsageController.setCallback(new DataUsageController.Callback() {
Jason Monke0cdb602014-11-05 12:39:45 -0500230 @Override
231 public void onMobileDataEnabled(boolean enabled) {
Jason Monk07b75fe2015-05-14 16:47:03 -0400232 mCallbackHandler.setMobileDataEnabled(enabled);
Evan Laird2ea99c12019-09-19 16:52:58 -0400233 notifyControllersMobileDataChanged();
Jason Monke0cdb602014-11-05 12:39:45 -0500234 }
235 });
Jason Monkd2263cd2014-11-10 14:22:56 -0500236 mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
Fabian Kozynski57ba5192020-04-01 15:24:12 -0400237 mCallbackHandler, this, mWifiManager, mConnectivityManager, networkScoreManager);
Jason Monkd2263cd2014-11-10 14:22:56 -0500238
Jason Monk07b75fe2015-05-14 16:47:03 -0400239 mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900240
Jason Monkd2263cd2014-11-10 14:22:56 -0500241 // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
Jason Monkb5746272014-11-12 16:50:31 -0500242 updateAirplaneMode(true /* force callback */);
Fabian Kozynski5ca7a512019-10-16 19:56:11 +0000243 mUserTracker = new CurrentUserTracker(broadcastDispatcher) {
Jason Monk9c7844c2017-01-18 15:21:53 -0500244 @Override
245 public void onUserSwitched(int newUserId) {
246 NetworkControllerImpl.this.onUserSwitched(newUserId);
247 }
248 };
249 mUserTracker.startTracking();
250 deviceProvisionedController.addCallback(new DeviceProvisionedListener() {
251 @Override
252 public void onUserSetupChanged() {
253 setUserSetupComplete(deviceProvisionedController.isUserSetup(
254 deviceProvisionedController.getCurrentUser()));
255 }
256 });
Anarghya Mitra678722f2018-05-11 14:29:54 -0700257
258 ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback(){
259 private Network mLastNetwork;
260 private NetworkCapabilities mLastNetworkCapabilities;
261
262 @Override
263 public void onCapabilitiesChanged(
264 Network network, NetworkCapabilities networkCapabilities) {
265 boolean lastValidated = (mLastNetworkCapabilities != null) &&
266 mLastNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
267 boolean validated =
268 networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED);
269
270 // This callback is invoked a lot (i.e. when RSSI changes), so avoid updating
271 // icons when connectivity state has remained the same.
272 if (network.equals(mLastNetwork) &&
273 networkCapabilities.equalsTransportTypes(mLastNetworkCapabilities) &&
274 validated == lastValidated) {
275 return;
276 }
277 mLastNetwork = network;
278 mLastNetworkCapabilities = networkCapabilities;
279 updateConnectivity();
280 }
281 };
282 // Even though this callback runs on the receiver handler thread which also processes the
283 // CONNECTIVITY_ACTION broadcasts, the broadcast and callback might come in at different
284 // times. This is safe since updateConnectivity() builds the list of transports from
285 // scratch.
286 // TODO: Move off of the deprecated CONNECTIVITY_ACTION broadcast and rely on callbacks
287 // exclusively for status bar icons.
288 mConnectivityManager.registerDefaultNetworkCallback(callback, mReceiverHandler);
Evan Laird470ae842019-04-09 16:24:27 -0400289 // Register the listener on our bg looper
Jayachandran Cff50c8e2019-10-30 16:41:59 -0700290 mPhoneStateListener = new PhoneStateListener(mReceiverHandler::post) {
Evan Laird470ae842019-04-09 16:24:27 -0400291 @Override
292 public void onActiveDataSubscriptionIdChanged(int subId) {
Malcolm Chen0c63c4d2020-02-25 18:13:40 -0800293 // For data switching from A to B, we assume B is validated for up to 2 seconds iff:
294 // 1) A and B are in the same subscription group e.g. CBRS data switch. And
295 // 2) A was validated before the switch.
296 // This is to provide smooth transition for UI without showing cross during data
297 // switch.
298 if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) {
299 if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true.");
300 mForceCellularValidated = true;
301 mReceiverHandler.removeCallbacks(mClearForceValidated);
302 mReceiverHandler.postDelayed(mClearForceValidated, 2000);
303 }
Evan Laird470ae842019-04-09 16:24:27 -0400304 mActiveMobileDataSubscription = subId;
305 doUpdateMobileControllers();
306 }
307 };
Jason Monke0cdb602014-11-05 12:39:45 -0500308 }
309
Malcolm Chen0c63c4d2020-02-25 18:13:40 -0800310 private final Runnable mClearForceValidated = () -> {
311 if (DEBUG) Log.d(TAG, ": mClearForceValidated");
312 mForceCellularValidated = false;
313 updateConnectivity();
314 };
315
316 boolean isInGroupDataSwitch(int subId1, int subId2) {
317 SubscriptionInfo info1 = mSubscriptionManager.getActiveSubscriptionInfo(subId1);
318 SubscriptionInfo info2 = mSubscriptionManager.getActiveSubscriptionInfo(subId2);
319 return (info1 != null && info2 != null && info1.getGroupUuid() != null
320 && info1.getGroupUuid().equals(info2.getGroupUuid()));
321 }
322
323 boolean keepCellularValidationBitInSwitch(int sourceSubId, int destSubId) {
324 return mValidatedTransports.get(TRANSPORT_CELLULAR)
325 && isInGroupDataSwitch(sourceSubId, destSubId);
326 }
327
Jason Monk9a4ce132016-01-21 15:27:17 -0500328 public DataSaverController getDataSaverController() {
329 return mDataSaverController;
330 }
331
Jason Monkf13b4b32014-11-07 16:39:34 -0500332 private void registerListeners() {
Jason Monk8996b942017-03-02 13:58:19 -0500333 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
334 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500335 mobileSignalController.registerListener();
336 }
Jason Monk8fcab352015-06-29 10:57:00 -0400337 if (mSubscriptionListener == null) {
338 mSubscriptionListener = new SubListener();
339 }
Wink Saville071743f2015-01-12 17:11:04 -0800340 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Malcolm Chen50ba9632019-02-26 16:49:56 -0800341 mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
Jason Monke0cdb602014-11-05 12:39:45 -0500342
John Spurlockaf8d6c42014-05-07 17:49:08 -0400343 // broadcasts
344 IntentFilter filter = new IntentFilter();
345 filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
346 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
347 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
Daniel Bright350f7f92020-01-22 14:24:11 -0800348 filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
Jayachandran C041e7692019-12-20 16:20:02 -0800349 filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
350 filter.addAction(TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
351 filter.addAction(Intent.ACTION_SERVICE_STATE);
Meng Wang57f56552020-01-17 16:58:40 -0800352 filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);
Erik Kline32830cc2015-04-21 13:09:15 +0900353 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400354 filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400355 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
Wenting Xiong63364fe2017-02-07 19:12:27 +0800356 filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
Fabian Kozynski5e92c6f2020-01-03 13:56:17 -0500357 mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler);
Jason Monkb5746272014-11-12 16:50:31 -0500358 mListening = true;
359
360 updateMobileControllers();
John Spurlockb98f7472014-07-08 17:09:42 -0400361 }
362
Jason Monkd2263cd2014-11-10 14:22:56 -0500363 private void unregisterListeners() {
Jason Monkb5746272014-11-12 16:50:31 -0500364 mListening = false;
Jason Monk8996b942017-03-02 13:58:19 -0500365 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
366 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500367 mobileSignalController.unregisterListener();
368 }
Wink Saville071743f2015-01-12 17:11:04 -0800369 mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
Evan Lairdb7f2c692020-04-14 16:55:49 -0400370 mBroadcastDispatcher.unregisterReceiver(this);
Jason Monk5d325072014-10-27 11:38:47 -0400371 }
372
Jason Monk0e2400f2014-11-21 11:08:55 -0500373 public int getConnectedWifiLevel() {
374 return mWifiSignalController.getState().level;
375 }
376
Jason Monk5d325072014-10-27 11:38:47 -0400377 @Override
Jason Monkd2263cd2014-11-10 14:22:56 -0500378 public AccessPointController getAccessPointController() {
379 return mAccessPoints;
380 }
381
382 @Override
Jason Monkf668d7c2016-01-14 10:38:41 -0500383 public DataUsageController getMobileDataController() {
384 return mDataUsageController;
Jason Monkd2263cd2014-11-10 14:22:56 -0500385 }
386
387 public void addEmergencyListener(EmergencyListener listener) {
Jason Monk07b75fe2015-05-14 16:47:03 -0400388 mCallbackHandler.setListening(listener, true);
389 mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
John Spurlockaf8d6c42014-05-07 17:49:08 -0400390 }
391
Jason Monk46dbfb42016-02-25 14:59:20 -0500392 public void removeEmergencyListener(EmergencyListener listener) {
393 mCallbackHandler.setListening(listener, false);
394 }
395
John Spurlockaf8d6c42014-05-07 17:49:08 -0400396 public boolean hasMobileDataFeature() {
397 return mHasMobileDataFeature;
398 }
399
400 public boolean hasVoiceCallingFeature() {
401 return mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
402 }
403
Jason Monkb5746272014-11-12 16:50:31 -0500404 private MobileSignalController getDataController() {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400405 int dataSubId = mSubDefaults.getActiveDataSubId();
Wink Savillea54bf652014-12-11 13:37:50 -0800406 if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
Jason Monkb5746272014-11-12 16:50:31 -0500407 if (DEBUG) Log.e(TAG, "No data sim selected");
408 return mDefaultSignalController;
409 }
Jason Monk8996b942017-03-02 13:58:19 -0500410 if (mMobileSignalControllers.indexOfKey(dataSubId) >= 0) {
Jason Monkb5746272014-11-12 16:50:31 -0500411 return mMobileSignalControllers.get(dataSubId);
412 }
Dan Sandlerc8466322014-12-08 15:42:52 -0500413 if (DEBUG) Log.e(TAG, "Cannot find controller for data sub: " + dataSubId);
Jason Monkb5746272014-11-12 16:50:31 -0500414 return mDefaultSignalController;
415 }
416
Amin Shaikh329c8282018-03-09 14:50:59 -0500417 @Override
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700418 public String getMobileDataNetworkName() {
Jason Monkb5746272014-11-12 16:50:31 -0500419 MobileSignalController controller = getDataController();
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700420 return controller != null ? controller.getState().networkNameData : "";
Jason Monkd2263cd2014-11-10 14:22:56 -0500421 }
422
Fabian Kozynskif1c32a02019-03-22 15:09:30 -0400423 @Override
424 public int getNumberSubscriptions() {
425 return mMobileSignalControllers.size();
426 }
427
Evan Laird2ea99c12019-09-19 16:52:58 -0400428 boolean isDataControllerDisabled() {
429 MobileSignalController dataController = getDataController();
430 if (dataController == null) {
431 return false;
432 }
433
434 return dataController.isDataDisabled();
435 }
436
437 private void notifyControllersMobileDataChanged() {
438 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
439 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
440 mobileSignalController.onMobileDataChanged();
441 }
442 }
443
John Spurlockaf8d6c42014-05-07 17:49:08 -0400444 public boolean isEmergencyOnly() {
Jason Monkb0808aa2015-07-22 16:34:36 -0400445 if (mMobileSignalControllers.size() == 0) {
446 // When there are no active subscriptions, determine emengency state from last
447 // broadcast.
Jason Monk66845a32015-08-03 11:09:41 -0400448 mEmergencySource = EMERGENCY_NO_CONTROLLERS;
Jason Monkb0808aa2015-07-22 16:34:36 -0400449 return mLastServiceState != null && mLastServiceState.isEmergencyOnly();
450 }
Jason Monkc6cc6262015-06-11 11:10:15 -0400451 int voiceSubId = mSubDefaults.getDefaultVoiceSubId();
Wink Savillea54bf652014-12-11 13:37:50 -0800452 if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) {
Jason Monk8996b942017-03-02 13:58:19 -0500453 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
454 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monkc6cc6262015-06-11 11:10:15 -0400455 if (!mobileSignalController.getState().isEmergency) {
Jason Monk66845a32015-08-03 11:09:41 -0400456 mEmergencySource = EMERGENCY_FIRST_CONTROLLER
457 + mobileSignalController.mSubscriptionInfo.getSubscriptionId();
Jason Monkc6cc6262015-06-11 11:10:15 -0400458 if (DEBUG) Log.d(TAG, "Found emergency " + mobileSignalController.mTag);
Jason Monkb5746272014-11-12 16:50:31 -0500459 return false;
460 }
461 }
462 }
Jason Monk8996b942017-03-02 13:58:19 -0500463 if (mMobileSignalControllers.indexOfKey(voiceSubId) >= 0) {
Jason Monk66845a32015-08-03 11:09:41 -0400464 mEmergencySource = EMERGENCY_VOICE_CONTROLLER + voiceSubId;
Jason Monkc6cc6262015-06-11 11:10:15 -0400465 if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId);
466 return mMobileSignalControllers.get(voiceSubId).getState().isEmergency;
Jason Monkb5746272014-11-12 16:50:31 -0500467 }
Jason Monk8996b942017-03-02 13:58:19 -0500468 // If we have the wrong subId but there is only one sim anyway, assume it should be the
469 // default.
470 if (mMobileSignalControllers.size() == 1) {
471 mEmergencySource = EMERGENCY_ASSUMED_VOICE_CONTROLLER
472 + mMobileSignalControllers.keyAt(0);
473 if (DEBUG) Log.d(TAG, "Getting assumed emergency from "
474 + mMobileSignalControllers.keyAt(0));
475 return mMobileSignalControllers.valueAt(0).getState().isEmergency;
476 }
Dan Sandlerc8466322014-12-08 15:42:52 -0500477 if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
Jason Monk66845a32015-08-03 11:09:41 -0400478 mEmergencySource = EMERGENCY_NO_SUB + voiceSubId;
Jason Monkb5746272014-11-12 16:50:31 -0500479 // Something is wrong, better assume we can't make calls...
480 return true;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400481 }
482
Jason Monkd2263cd2014-11-10 14:22:56 -0500483 /**
484 * Emergency status may have changed (triggered by MobileSignalController),
485 * so we should recheck and send out the state to listeners.
486 */
487 void recalculateEmergency() {
Jason Monk66845a32015-08-03 11:09:41 -0400488 mIsEmergency = isEmergencyOnly();
489 mCallbackHandler.setEmergencyCallsOnly(mIsEmergency);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400490 }
491
Jason Monk88529052016-11-04 13:29:58 -0400492 public void addCallback(SignalCallback cb) {
Jason Monke06b0652016-03-02 16:35:27 -0500493 cb.setSubs(mCurrentSubscriptions);
494 cb.setIsAirplaneMode(new IconState(mAirplaneMode,
Jason Monk07b75fe2015-05-14 16:47:03 -0400495 TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
Jason Monk1ff77662017-09-29 11:17:05 -0400496 cb.setNoSims(mHasNoSubs, mSimDetected);
Jason Monke06b0652016-03-02 16:35:27 -0500497 mWifiSignalController.notifyListeners(cb);
498 mEthernetSignalController.notifyListeners(cb);
Jason Monk8996b942017-03-02 13:58:19 -0500499 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
500 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monke06b0652016-03-02 16:35:27 -0500501 mobileSignalController.notifyListeners(cb);
Jason Monkb5746272014-11-12 16:50:31 -0500502 }
Jason Monke06b0652016-03-02 16:35:27 -0500503 mCallbackHandler.setListening(cb, true);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400504 }
505
Jason Monk07b75fe2015-05-14 16:47:03 -0400506 @Override
Jason Monk88529052016-11-04 13:29:58 -0400507 public void removeCallback(SignalCallback cb) {
Jason Monk07b75fe2015-05-14 16:47:03 -0400508 mCallbackHandler.setListening(cb, false);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400509 }
510
511 @Override
512 public void setWifiEnabled(final boolean enabled) {
513 new AsyncTask<Void, Void, Void>() {
514 @Override
515 protected Void doInBackground(Void... args) {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400516 mWifiManager.setWifiEnabled(enabled);
517 return null;
518 }
519 }.execute();
520 }
521
Jason Monk9c7844c2017-01-18 15:21:53 -0500522 private void onUserSwitched(int newUserId) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900523 mCurrentUserId = newUserId;
524 mAccessPoints.onUserSwitched(newUserId);
525 updateConnectivity();
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900526 }
527
528 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400529 public void onReceive(Context context, Intent intent) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500530 if (CHATTY) {
531 Log.d(TAG, "onReceive: intent=" + intent);
532 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400533 final String action = intent.getAction();
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800534 switch (action) {
535 case ConnectivityManager.CONNECTIVITY_ACTION:
536 case ConnectivityManager.INET_CONDITION_ACTION:
537 updateConnectivity();
538 break;
539 case Intent.ACTION_AIRPLANE_MODE_CHANGED:
540 refreshLocale();
541 updateAirplaneMode(false);
542 break;
Jayachandran C041e7692019-12-20 16:20:02 -0800543 case TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED:
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800544 // We are using different subs now, we might be able to make calls.
Jason Monkb0808aa2015-07-22 16:34:36 -0400545 recalculateEmergency();
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800546 break;
Jayachandran C041e7692019-12-20 16:20:02 -0800547 case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800548 // Notify every MobileSignalController so they can know whether they are the
549 // data sim or not.
550 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
551 MobileSignalController controller = mMobileSignalControllers.valueAt(i);
552 controller.handleBroadcast(intent);
Wenting Xiong63364fe2017-02-07 19:12:27 +0800553 }
Niklas Lindgrena02964d2018-09-21 14:01:57 +0200554 mConfig = Config.readConfig(mContext);
555 mReceiverHandler.post(this::handleConfigurationChanged);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800556 break;
Daniel Bright350f7f92020-01-22 14:24:11 -0800557 case Intent.ACTION_SIM_STATE_CHANGED:
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800558 // Avoid rebroadcast because SysUI is direct boot aware.
Meng Wang0e8d91a2020-01-17 14:58:01 -0800559 if (intent.getBooleanExtra(Intent.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800560 break;
561 }
562 // Might have different subscriptions now.
563 updateMobileControllers();
564 break;
Jayachandran C041e7692019-12-20 16:20:02 -0800565 case Intent.ACTION_SERVICE_STATE:
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800566 mLastServiceState = ServiceState.newFromBundle(intent.getExtras());
567 if (mMobileSignalControllers.size() == 0) {
568 // If none of the subscriptions are active, we might need to recalculate
569 // emergency state.
570 recalculateEmergency();
571 }
572 break;
573 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
574 mConfig = Config.readConfig(mContext);
575 mReceiverHandler.post(this::handleConfigurationChanged);
576 break;
577 default:
Daniel Bright63514be2020-01-15 12:10:53 -0800578 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800579 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
580 if (SubscriptionManager.isValidSubscriptionId(subId)) {
581 if (mMobileSignalControllers.indexOfKey(subId) >= 0) {
582 mMobileSignalControllers.get(subId).handleBroadcast(intent);
583 } else {
584 // Can't find this subscription... We must be out of date.
585 updateMobileControllers();
586 }
Jason Monkb5746272014-11-12 16:50:31 -0500587 } else {
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800588 // No sub id, must be for the wifi.
589 mWifiSignalController.handleBroadcast(intent);
Jason Monkb5746272014-11-12 16:50:31 -0500590 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800591 break;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400592 }
Jason Monkb5746272014-11-12 16:50:31 -0500593 }
594
Jason Monk1c040db2015-07-20 09:45:54 -0400595 @VisibleForTesting
596 void handleConfigurationChanged() {
Malcolm Chen50ba9632019-02-26 16:49:56 -0800597 updateMobileControllers();
Jason Monk8996b942017-03-02 13:58:19 -0500598 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
599 MobileSignalController controller = mMobileSignalControllers.valueAt(i);
600 controller.setConfiguration(mConfig);
Jason Monk3aaabd72014-12-12 11:11:44 -0500601 }
602 refreshLocale();
Jason Monk3aaabd72014-12-12 11:11:44 -0500603 }
604
Jason Monkb5746272014-11-12 16:50:31 -0500605 private void updateMobileControllers() {
606 if (!mListening) {
607 return;
608 }
Jason Monkc6cc6262015-06-11 11:10:15 -0400609 doUpdateMobileControllers();
610 }
611
Malcolm Chen50ba9632019-02-26 16:49:56 -0800612 private void filterMobileSubscriptionInSameGroup(List<SubscriptionInfo> subscriptions) {
Malcolm Chene6befe22020-02-25 13:34:09 -0800613 if (subscriptions.size() == 2) {
Malcolm Chen50ba9632019-02-26 16:49:56 -0800614 SubscriptionInfo info1 = subscriptions.get(0);
615 SubscriptionInfo info2 = subscriptions.get(1);
616 if (info1.getGroupUuid() != null && info1.getGroupUuid().equals(info2.getGroupUuid())) {
617 // If both subscriptions are primary, show both.
618 if (!info1.isOpportunistic() && !info2.isOpportunistic()) return;
619
620 // If carrier required, always show signal bar of primary subscription.
621 // Otherwise, show whichever subscription is currently active for Internet.
622 boolean alwaysShowPrimary = CarrierConfigManager.getDefaultConfig()
623 .getBoolean(CarrierConfigManager
624 .KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN);
625 if (alwaysShowPrimary) {
626 subscriptions.remove(info1.isOpportunistic() ? info1 : info2);
627 } else {
628 subscriptions.remove(info1.getSubscriptionId() == mActiveMobileDataSubscription
629 ? info2 : info1);
630 }
631 }
632 }
633 }
634
Jason Monkc6cc6262015-06-11 11:10:15 -0400635 @VisibleForTesting
636 void doUpdateMobileControllers() {
Malcolm Chend2d400cb2018-12-21 17:11:10 -0800637 List<SubscriptionInfo> subscriptions = mSubscriptionManager
Sooraj Sasindran40468062020-01-06 19:10:50 -0800638 .getCompleteActiveSubscriptionInfoList();
Jason Monkc9f05712014-12-15 12:24:10 -0500639 if (subscriptions == null) {
640 subscriptions = Collections.emptyList();
641 }
Malcolm Chen50ba9632019-02-26 16:49:56 -0800642
643 filterMobileSubscriptionInSameGroup(subscriptions);
644
Jason Monkb5746272014-11-12 16:50:31 -0500645 // If there have been no relevant changes to any of the subscriptions, we can leave as is.
646 if (hasCorrectMobileControllers(subscriptions)) {
647 // Even if the controllers are correct, make sure we have the right no sims state.
648 // Such as on boot, don't need any controllers, because there are no sims,
649 // but we still need to update the no sim state.
650 updateNoSims();
651 return;
652 }
Evan Laird470ae842019-04-09 16:24:27 -0400653 synchronized (mLock) {
654 setCurrentSubscriptionsLocked(subscriptions);
655 }
Jason Monkb5746272014-11-12 16:50:31 -0500656 updateNoSims();
Jason Monkc6cc6262015-06-11 11:10:15 -0400657 recalculateEmergency();
Jason Monkb5746272014-11-12 16:50:31 -0500658 }
659
Jason Monk21d05a02014-12-02 12:46:58 -0500660 @VisibleForTesting
661 protected void updateNoSims() {
Jason Monk1ff77662017-09-29 11:17:05 -0400662 boolean hasNoSubs = mHasMobileDataFeature && mMobileSignalControllers.size() == 0;
663 boolean simDetected = hasAnySim();
664 if (hasNoSubs != mHasNoSubs || simDetected != mSimDetected) {
665 mHasNoSubs = hasNoSubs;
666 mSimDetected = simDetected;
667 mCallbackHandler.setNoSims(mHasNoSubs, mSimDetected);
Jason Monkb5746272014-11-12 16:50:31 -0500668 }
669 }
670
Jason Monk1ff77662017-09-29 11:17:05 -0400671 private boolean hasAnySim() {
Jayachandran Ca43d0a72019-11-01 17:39:38 -0700672 int simCount = mPhone.getActiveModemCount();
Jason Monk1ff77662017-09-29 11:17:05 -0400673 for (int i = 0; i < simCount; i++) {
674 int state = mPhone.getSimState(i);
675 if (state != TelephonyManager.SIM_STATE_ABSENT
676 && state != TelephonyManager.SIM_STATE_UNKNOWN) {
677 return true;
678 }
679 }
680 return false;
681 }
682
Evan Laird470ae842019-04-09 16:24:27 -0400683 @GuardedBy("mLock")
Jason Monkb5746272014-11-12 16:50:31 -0500684 @VisibleForTesting
Evan Laird470ae842019-04-09 16:24:27 -0400685 public void setCurrentSubscriptionsLocked(List<SubscriptionInfo> subscriptions) {
Jason Monkb5746272014-11-12 16:50:31 -0500686 Collections.sort(subscriptions, new Comparator<SubscriptionInfo>() {
687 @Override
688 public int compare(SubscriptionInfo lhs, SubscriptionInfo rhs) {
689 return lhs.getSimSlotIndex() == rhs.getSimSlotIndex()
690 ? lhs.getSubscriptionId() - rhs.getSubscriptionId()
691 : lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
692 }
693 });
Jason Monkb5746272014-11-12 16:50:31 -0500694 mCurrentSubscriptions = subscriptions;
695
Jason Monk8996b942017-03-02 13:58:19 -0500696 SparseArray<MobileSignalController> cachedControllers =
697 new SparseArray<MobileSignalController>();
698 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
699 cachedControllers.put(mMobileSignalControllers.keyAt(i),
700 mMobileSignalControllers.valueAt(i));
701 }
Jason Monkb5746272014-11-12 16:50:31 -0500702 mMobileSignalControllers.clear();
703 final int num = subscriptions.size();
704 for (int i = 0; i < num; i++) {
705 int subId = subscriptions.get(i).getSubscriptionId();
706 // If we have a copy of this controller already reuse it, otherwise make a new one.
Jason Monk8996b942017-03-02 13:58:19 -0500707 if (cachedControllers.indexOfKey(subId) >= 0) {
708 mMobileSignalControllers.put(subId, cachedControllers.get(subId));
709 cachedControllers.remove(subId);
Jason Monkb5746272014-11-12 16:50:31 -0500710 } else {
711 MobileSignalController controller = new MobileSignalController(mContext, mConfig,
chen xu84a90872019-03-28 15:44:12 -0700712 mHasMobileDataFeature, mPhone.createForSubscriptionId(subId),
713 mCallbackHandler, this, subscriptions.get(i),
714 mSubDefaults, mReceiverHandler.getLooper());
Jason Monkfd57ea72016-04-29 13:37:58 -0400715 controller.setUserSetupComplete(mUserSetup);
Jason Monkb5746272014-11-12 16:50:31 -0500716 mMobileSignalControllers.put(subId, controller);
717 if (subscriptions.get(i).getSimSlotIndex() == 0) {
718 mDefaultSignalController = controller;
719 }
720 if (mListening) {
721 controller.registerListener();
722 }
723 }
724 }
725 if (mListening) {
Jason Monk8996b942017-03-02 13:58:19 -0500726 for (int i = 0; i < cachedControllers.size(); i++) {
727 int key = cachedControllers.keyAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500728 if (cachedControllers.get(key) == mDefaultSignalController) {
729 mDefaultSignalController = null;
730 }
731 cachedControllers.get(key).unregisterListener();
732 }
733 }
Jason Monk8fcab352015-06-29 10:57:00 -0400734 mCallbackHandler.setSubs(subscriptions);
735 notifyAllListeners();
736
Jason Monk25d8a482014-12-09 12:27:24 -0500737 // There may be new MobileSignalControllers around, make sure they get the current
738 // inet condition and airplane mode.
739 pushConnectivityToSignals();
740 updateAirplaneMode(true /* force */);
Jason Monkb5746272014-11-12 16:50:31 -0500741 }
742
Jason Monk0288de02017-02-23 14:48:05 -0500743 private void setUserSetupComplete(final boolean userSetup) {
744 mReceiverHandler.post(() -> handleSetUserSetupComplete(userSetup));
Jason Monkfd57ea72016-04-29 13:37:58 -0400745 }
746
Jason Monk0288de02017-02-23 14:48:05 -0500747 private void handleSetUserSetupComplete(boolean userSetup) {
Jason Monkfd57ea72016-04-29 13:37:58 -0400748 mUserSetup = userSetup;
Jason Monk8996b942017-03-02 13:58:19 -0500749 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
750 MobileSignalController controller = mMobileSignalControllers.valueAt(i);
Jason Monkfd57ea72016-04-29 13:37:58 -0400751 controller.setUserSetupComplete(mUserSetup);
752 }
753 }
754
Jason Monkc014dec2014-12-12 11:49:55 -0500755 @VisibleForTesting
756 boolean hasCorrectMobileControllers(List<SubscriptionInfo> allSubscriptions) {
Jason Monkc9f05712014-12-15 12:24:10 -0500757 if (allSubscriptions.size() != mMobileSignalControllers.size()) {
758 return false;
Jason Monkb5746272014-11-12 16:50:31 -0500759 }
760 for (SubscriptionInfo info : allSubscriptions) {
Jason Monk8996b942017-03-02 13:58:19 -0500761 if (mMobileSignalControllers.indexOfKey(info.getSubscriptionId()) < 0) {
Jason Monkb5746272014-11-12 16:50:31 -0500762 return false;
763 }
764 }
765 return true;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400766 }
767
Jason Monkd2263cd2014-11-10 14:22:56 -0500768 private void updateAirplaneMode(boolean force) {
769 boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
770 Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
771 if (airplaneMode != mAirplaneMode || force) {
772 mAirplaneMode = airplaneMode;
Jason Monk8996b942017-03-02 13:58:19 -0500773 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
774 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500775 mobileSignalController.setAirplaneMode(mAirplaneMode);
776 }
777 notifyListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400778 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400779 }
780
781 private void refreshLocale() {
Jason Monkd2263cd2014-11-10 14:22:56 -0500782 Locale current = mContext.getResources().getConfiguration().locale;
Jason Monkb5746272014-11-12 16:50:31 -0500783 if (!current.equals(mLocale)) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500784 mLocale = current;
Fabian Kozynskid9cb3842018-09-28 13:34:14 -0400785 mWifiSignalController.refreshLocale();
Jason Monkd2263cd2014-11-10 14:22:56 -0500786 notifyAllListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400787 }
788 }
789
Jason Monkd2263cd2014-11-10 14:22:56 -0500790 /**
Jason Monkb5746272014-11-12 16:50:31 -0500791 * Forces update of all callbacks on both SignalClusters and
792 * NetworkSignalChangedCallbacks.
793 */
Jason Monkd2263cd2014-11-10 14:22:56 -0500794 private void notifyAllListeners() {
Jason Monkb5746272014-11-12 16:50:31 -0500795 notifyListeners();
Jason Monk8996b942017-03-02 13:58:19 -0500796 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
797 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500798 mobileSignalController.notifyListeners();
799 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500800 mWifiSignalController.notifyListeners();
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900801 mEthernetSignalController.notifyListeners();
Jason Monkd2263cd2014-11-10 14:22:56 -0500802 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400803
Jason Monkb5746272014-11-12 16:50:31 -0500804 /**
805 * Notifies listeners of changes in state of to the NetworkController, but
806 * does not notify for any info on SignalControllers, for that call
807 * notifyAllListeners.
808 */
809 private void notifyListeners() {
Jason Monk07b75fe2015-05-14 16:47:03 -0400810 mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode,
811 TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
Jason Monk1ff77662017-09-29 11:17:05 -0400812 mCallbackHandler.setNoSims(mHasNoSubs, mSimDetected);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400813 }
814
Jason Monkd2263cd2014-11-10 14:22:56 -0500815 /**
816 * Update the Inet conditions and what network we are connected to.
817 */
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900818 private void updateConnectivity() {
819 mConnectedTransports.clear();
820 mValidatedTransports.clear();
821 for (NetworkCapabilities nc :
822 mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) {
823 for (int transportType : nc.getTransportTypes()) {
824 mConnectedTransports.set(transportType);
825 if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
826 mValidatedTransports.set(transportType);
827 }
828 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400829 }
830
Malcolm Chen0c63c4d2020-02-25 18:13:40 -0800831 if (mForceCellularValidated) mValidatedTransports.set(TRANSPORT_CELLULAR);
832
John Spurlockaf8d6c42014-05-07 17:49:08 -0400833 if (CHATTY) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900834 Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports);
835 Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400836 }
837
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900838 mInetCondition = !mValidatedTransports.isEmpty();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400839
Jason Monk25d8a482014-12-09 12:27:24 -0500840 pushConnectivityToSignals();
841 }
842
843 /**
844 * Pushes the current connectivity state to all SignalControllers.
845 */
846 private void pushConnectivityToSignals() {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400847 // We want to update all the icons, all at once, for any condition change
Jason Monk8996b942017-03-02 13:58:19 -0500848 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
849 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monk33f8ae72015-05-08 10:45:15 -0400850 mobileSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
Jason Monkb5746272014-11-12 16:50:31 -0500851 }
Jason Monk33f8ae72015-05-08 10:45:15 -0400852 mWifiSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
853 mEthernetSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400854 }
855
John Spurlockaf8d6c42014-05-07 17:49:08 -0400856 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
857 pw.println("NetworkController state:");
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900858
John Spurlockaf8d6c42014-05-07 17:49:08 -0400859 pw.println(" - telephony ------");
860 pw.print(" hasVoiceCallingFeature()=");
861 pw.println(hasVoiceCallingFeature());
Evan Lairdb7f2c692020-04-14 16:55:49 -0400862 pw.println(" mListening=" + mListening);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400863
John Spurlockaf8d6c42014-05-07 17:49:08 -0400864 pw.println(" - connectivity ------");
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900865 pw.print(" mConnectedTransports=");
866 pw.println(mConnectedTransports);
867 pw.print(" mValidatedTransports=");
868 pw.println(mValidatedTransports);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400869 pw.print(" mInetCondition=");
870 pw.println(mInetCondition);
Jason Monkd2263cd2014-11-10 14:22:56 -0500871 pw.print(" mAirplaneMode=");
872 pw.println(mAirplaneMode);
873 pw.print(" mLocale=");
874 pw.println(mLocale);
Jason Monkb0808aa2015-07-22 16:34:36 -0400875 pw.print(" mLastServiceState=");
876 pw.println(mLastServiceState);
Jason Monk66845a32015-08-03 11:09:41 -0400877 pw.print(" mIsEmergency=");
878 pw.println(mIsEmergency);
879 pw.print(" mEmergencySource=");
880 pw.println(emergencyToString(mEmergencySource));
John Spurlockaf8d6c42014-05-07 17:49:08 -0400881
Bill Lin767c0db2019-08-15 20:42:06 +0800882 pw.println(" - config ------");
Jason Monk8996b942017-03-02 13:58:19 -0500883 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
884 MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500885 mobileSignalController.dump(pw);
886 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500887 mWifiSignalController.dump(pw);
Jason Monkd52356a2015-01-28 10:40:41 -0500888
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900889 mEthernetSignalController.dump(pw);
890
Jason Monkd52356a2015-01-28 10:40:41 -0500891 mAccessPoints.dump(pw);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400892 }
893
Jason Monk66845a32015-08-03 11:09:41 -0400894 private static final String emergencyToString(int emergencySource) {
895 if (emergencySource > EMERGENCY_NO_SUB) {
Jason Monk8996b942017-03-02 13:58:19 -0500896 return "ASSUMED_VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER)
897 + ")";
898 } else if (emergencySource > EMERGENCY_NO_SUB) {
Jason Monk66845a32015-08-03 11:09:41 -0400899 return "NO_SUB(" + (emergencySource - EMERGENCY_NO_SUB) + ")";
900 } else if (emergencySource > EMERGENCY_VOICE_CONTROLLER) {
901 return "VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER) + ")";
902 } else if (emergencySource > EMERGENCY_FIRST_CONTROLLER) {
903 return "FIRST_CONTROLLER(" + (emergencySource - EMERGENCY_FIRST_CONTROLLER) + ")";
904 } else if (emergencySource == EMERGENCY_NO_CONTROLLERS) {
905 return "NO_CONTROLLERS";
906 }
907 return "UNKNOWN_SOURCE";
908 }
909
John Spurlockaf8d6c42014-05-07 17:49:08 -0400910 private boolean mDemoMode;
Jason Monk33f8ae72015-05-08 10:45:15 -0400911 private boolean mDemoInetCondition;
Jason Monkd2263cd2014-11-10 14:22:56 -0500912 private WifiSignalController.WifiState mDemoWifiState;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400913
914 @Override
915 public void dispatchDemoCommand(String command, Bundle args) {
916 if (!mDemoMode && command.equals(COMMAND_ENTER)) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500917 if (DEBUG) Log.d(TAG, "Entering demo mode");
918 unregisterListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400919 mDemoMode = true;
Jason Monk33f8ae72015-05-08 10:45:15 -0400920 mDemoInetCondition = mInetCondition;
Jason Monkd2263cd2014-11-10 14:22:56 -0500921 mDemoWifiState = mWifiSignalController.getState();
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100922 mDemoWifiState.ssid = "DemoMode";
John Spurlockaf8d6c42014-05-07 17:49:08 -0400923 } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500924 if (DEBUG) Log.d(TAG, "Exiting demo mode");
John Spurlockaf8d6c42014-05-07 17:49:08 -0400925 mDemoMode = false;
Jason Monkb5746272014-11-12 16:50:31 -0500926 // Update what MobileSignalControllers, because they may change
927 // to set the number of sim slots.
928 updateMobileControllers();
Jason Monk8996b942017-03-02 13:58:19 -0500929 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
930 MobileSignalController controller = mMobileSignalControllers.valueAt(i);
Jason Monkb5746272014-11-12 16:50:31 -0500931 controller.resetLastState();
932 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500933 mWifiSignalController.resetLastState();
Jason Monk07b75fe2015-05-14 16:47:03 -0400934 mReceiverHandler.post(mRegisterListeners);
Jason Monkd2263cd2014-11-10 14:22:56 -0500935 notifyAllListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400936 } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
937 String airplane = args.getString("airplane");
938 if (airplane != null) {
939 boolean show = airplane.equals("show");
Jason Monk07b75fe2015-05-14 16:47:03 -0400940 mCallbackHandler.setIsAirplaneMode(new IconState(show,
941 TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode,
942 mContext));
John Spurlockaf8d6c42014-05-07 17:49:08 -0400943 }
944 String fully = args.getString("fully");
945 if (fully != null) {
Jason Monk33f8ae72015-05-08 10:45:15 -0400946 mDemoInetCondition = Boolean.parseBoolean(fully);
947 BitSet connected = new BitSet();
948
949 if (mDemoInetCondition) {
950 connected.set(mWifiSignalController.mTransportType);
951 }
952 mWifiSignalController.updateConnectivity(connected, connected);
Jason Monk8996b942017-03-02 13:58:19 -0500953 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
954 MobileSignalController controller = mMobileSignalControllers.valueAt(i);
Jason Monk33f8ae72015-05-08 10:45:15 -0400955 if (mDemoInetCondition) {
956 connected.set(controller.mTransportType);
957 }
958 controller.updateConnectivity(connected, connected);
Jason Monkb5746272014-11-12 16:50:31 -0500959 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400960 }
961 String wifi = args.getString("wifi");
962 if (wifi != null) {
963 boolean show = wifi.equals("show");
964 String level = args.getString("level");
965 if (level != null) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500966 mDemoWifiState.level = level.equals("null") ? -1
John Spurlockaf8d6c42014-05-07 17:49:08 -0400967 : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
Jason Monkd2263cd2014-11-10 14:22:56 -0500968 mDemoWifiState.connected = mDemoWifiState.level >= 0;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400969 }
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100970 String activity = args.getString("activity");
971 if (activity != null) {
972 switch (activity) {
973 case "inout":
Roshan Pius80fb1372018-07-16 15:43:03 -0700974 mWifiSignalController.setActivity(DATA_ACTIVITY_INOUT);
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100975 break;
976 case "in":
Roshan Pius80fb1372018-07-16 15:43:03 -0700977 mWifiSignalController.setActivity(DATA_ACTIVITY_IN);
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100978 break;
979 case "out":
Roshan Pius80fb1372018-07-16 15:43:03 -0700980 mWifiSignalController.setActivity(DATA_ACTIVITY_OUT);
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100981 break;
982 default:
Roshan Pius80fb1372018-07-16 15:43:03 -0700983 mWifiSignalController.setActivity(DATA_ACTIVITY_NONE);
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100984 break;
985 }
986 } else {
Roshan Pius80fb1372018-07-16 15:43:03 -0700987 mWifiSignalController.setActivity(DATA_ACTIVITY_NONE);
Kenneth Westin5c88ffb2013-11-28 16:29:40 +0100988 }
Evan Laird27a99572017-09-27 14:09:30 -0400989 String ssid = args.getString("ssid");
990 if (ssid != null) {
991 mDemoWifiState.ssid = ssid;
992 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500993 mDemoWifiState.enabled = show;
994 mWifiSignalController.notifyListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400995 }
Jason Monkb5746272014-11-12 16:50:31 -0500996 String sims = args.getString("sims");
997 if (sims != null) {
John Spurlockcf053c12015-05-14 16:33:59 -0400998 int num = MathUtils.constrain(Integer.parseInt(sims), 1, 8);
999 List<SubscriptionInfo> subs = new ArrayList<>();
Jason Monkb5746272014-11-12 16:50:31 -05001000 if (num != mMobileSignalControllers.size()) {
1001 mMobileSignalControllers.clear();
1002 int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
1003 for (int i = start /* get out of normal index range */; i < start + num; i++) {
John Spurlockcf053c12015-05-14 16:33:59 -04001004 subs.add(addSignalController(i, i));
Jason Monkb5746272014-11-12 16:50:31 -05001005 }
Jason Monk33b60bb2015-07-13 10:42:23 -04001006 mCallbackHandler.setSubs(subs);
Evan Lairde1d13c92018-03-20 16:58:01 -04001007 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
1008 int key = mMobileSignalControllers.keyAt(i);
1009 MobileSignalController controller = mMobileSignalControllers.get(key);
1010 controller.notifyListeners();
1011 }
Jason Monkb5746272014-11-12 16:50:31 -05001012 }
Jason Monkb5746272014-11-12 16:50:31 -05001013 }
1014 String nosim = args.getString("nosim");
1015 if (nosim != null) {
Jason Monk1ff77662017-09-29 11:17:05 -04001016 mHasNoSubs = nosim.equals("show");
1017 mCallbackHandler.setNoSims(mHasNoSubs, mSimDetected);
Jason Monkb5746272014-11-12 16:50:31 -05001018 }
John Spurlockaf8d6c42014-05-07 17:49:08 -04001019 String mobile = args.getString("mobile");
1020 if (mobile != null) {
1021 boolean show = mobile.equals("show");
1022 String datatype = args.getString("datatype");
Jason Monkb5746272014-11-12 16:50:31 -05001023 String slotString = args.getString("slot");
1024 int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString);
John Spurlockcf053c12015-05-14 16:33:59 -04001025 slot = MathUtils.constrain(slot, 0, 8);
1026 // Ensure we have enough sim slots
1027 List<SubscriptionInfo> subs = new ArrayList<>();
1028 while (mMobileSignalControllers.size() <= slot) {
1029 int nextSlot = mMobileSignalControllers.size();
1030 subs.add(addSignalController(nextSlot, nextSlot));
1031 }
1032 if (!subs.isEmpty()) {
Jason Monk07b75fe2015-05-14 16:47:03 -04001033 mCallbackHandler.setSubs(subs);
John Spurlockcf053c12015-05-14 16:33:59 -04001034 }
Jason Monkb5746272014-11-12 16:50:31 -05001035 // Hack to index linearly for easy use.
Jason Monk8996b942017-03-02 13:58:19 -05001036 MobileSignalController controller = mMobileSignalControllers.valueAt(slot);
Jason Monkb5746272014-11-12 16:50:31 -05001037 controller.getState().dataSim = datatype != null;
Jason Monkb5950982017-01-24 15:53:53 -05001038 controller.getState().isDefault = datatype != null;
1039 controller.getState().dataConnected = datatype != null;
John Spurlockaf8d6c42014-05-07 17:49:08 -04001040 if (datatype != null) {
Jason Monkb5746272014-11-12 16:50:31 -05001041 controller.getState().iconGroup =
Jason Monkd2263cd2014-11-10 14:22:56 -05001042 datatype.equals("1x") ? TelephonyIcons.ONE_X :
1043 datatype.equals("3g") ? TelephonyIcons.THREE_G :
1044 datatype.equals("4g") ? TelephonyIcons.FOUR_G :
Ajay Nambi7965fa42015-05-14 18:48:33 -07001045 datatype.equals("4g+") ? TelephonyIcons.FOUR_G_PLUS :
Bill Lin767c0db2019-08-15 20:42:06 +08001046 datatype.equals("5g") ? TelephonyIcons.NR_5G :
Evan Laird5784a6b2019-09-24 19:14:05 -04001047 datatype.equals("5ge") ? TelephonyIcons.LTE_CA_5G_E :
Bill Lin767c0db2019-08-15 20:42:06 +08001048 datatype.equals("5g+") ? TelephonyIcons.NR_5G_PLUS :
Jason Monkd2263cd2014-11-10 14:22:56 -05001049 datatype.equals("e") ? TelephonyIcons.E :
1050 datatype.equals("g") ? TelephonyIcons.G :
1051 datatype.equals("h") ? TelephonyIcons.H :
Amin Shaikhf5830ca2018-03-09 14:06:50 -05001052 datatype.equals("h+") ? TelephonyIcons.H_PLUS :
Jason Monkd2263cd2014-11-10 14:22:56 -05001053 datatype.equals("lte") ? TelephonyIcons.LTE :
Jason Monkaa730be2016-07-13 14:22:52 -04001054 datatype.equals("lte+") ? TelephonyIcons.LTE_PLUS :
Jason Monk7e6c83c2017-04-26 14:35:24 -04001055 datatype.equals("dis") ? TelephonyIcons.DATA_DISABLED :
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -04001056 datatype.equals("not") ? TelephonyIcons.NOT_DEFAULT_DATA :
Jason Monkd2263cd2014-11-10 14:22:56 -05001057 TelephonyIcons.UNKNOWN;
John Spurlockaf8d6c42014-05-07 17:49:08 -04001058 }
Jason Monk0f0de132016-12-19 15:36:13 -05001059 if (args.containsKey("roam")) {
1060 controller.getState().roaming = "show".equals(args.getString("roam"));
1061 }
John Spurlockaf8d6c42014-05-07 17:49:08 -04001062 String level = args.getString("level");
1063 if (level != null) {
Jason Monkb5746272014-11-12 16:50:31 -05001064 controller.getState().level = level.equals("null") ? -1
Jason Monk48edc0c2017-04-10 15:01:27 -04001065 : Math.min(Integer.parseInt(level),
Amit Mahajan75eab472020-01-29 10:47:48 -08001066 CellSignalStrength.getNumSignalStrengthLevels());
Jason Monkb5746272014-11-12 16:50:31 -05001067 controller.getState().connected = controller.getState().level >= 0;
John Spurlockaf8d6c42014-05-07 17:49:08 -04001068 }
Amin Shaikh0ad7e512019-04-29 07:36:34 -04001069 if (args.containsKey("inflate")) {
1070 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
1071 mMobileSignalControllers.valueAt(i).mInflateSignalStrengths =
1072 "true".equals(args.getString("inflate"));
1073 }
1074 }
Jason Monk0f0de132016-12-19 15:36:13 -05001075 String activity = args.getString("activity");
1076 if (activity != null) {
Kenneth Westin5c88ffb2013-11-28 16:29:40 +01001077 controller.getState().dataConnected = true;
1078 switch (activity) {
1079 case "inout":
1080 controller.setActivity(TelephonyManager.DATA_ACTIVITY_INOUT);
1081 break;
1082 case "in":
1083 controller.setActivity(TelephonyManager.DATA_ACTIVITY_IN);
1084 break;
1085 case "out":
1086 controller.setActivity(TelephonyManager.DATA_ACTIVITY_OUT);
1087 break;
1088 default:
1089 controller.setActivity(TelephonyManager.DATA_ACTIVITY_NONE);
1090 break;
1091 }
1092 } else {
1093 controller.setActivity(TelephonyManager.DATA_ACTIVITY_NONE);
Jason Monk0f0de132016-12-19 15:36:13 -05001094 }
Jason Monkb5746272014-11-12 16:50:31 -05001095 controller.getState().enabled = show;
1096 controller.notifyListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -04001097 }
Andrew Flynna478d702015-04-14 23:33:45 -04001098 String carrierNetworkChange = args.getString("carriernetworkchange");
1099 if (carrierNetworkChange != null) {
1100 boolean show = carrierNetworkChange.equals("show");
Jason Monk8996b942017-03-02 13:58:19 -05001101 for (int i = 0; i < mMobileSignalControllers.size(); i++) {
1102 MobileSignalController controller = mMobileSignalControllers.valueAt(i);
Andrew Flynna478d702015-04-14 23:33:45 -04001103 controller.setCarrierNetworkChangeMode(show);
1104 }
1105 }
Jason Monkd2263cd2014-11-10 14:22:56 -05001106 }
1107 }
1108
John Spurlockcf053c12015-05-14 16:33:59 -04001109 private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
1110 SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
Malcolm Chene89e0ce2018-08-09 17:01:35 -07001111 null, null, null, "", false, null, null);
Jason Monkb5950982017-01-24 15:53:53 -05001112 MobileSignalController controller = new MobileSignalController(mContext,
chen xu84a90872019-03-28 15:44:12 -07001113 mConfig, mHasMobileDataFeature,
1114 mPhone.createForSubscriptionId(info.getSubscriptionId()), mCallbackHandler, this, info,
Jason Monkb5950982017-01-24 15:53:53 -05001115 mSubDefaults, mReceiverHandler.getLooper());
1116 mMobileSignalControllers.put(id, controller);
1117 controller.getState().userSetup = true;
John Spurlockcf053c12015-05-14 16:33:59 -04001118 return info;
1119 }
1120
Adrian Roos316bf542016-08-23 17:53:07 +02001121 public boolean hasEmergencyCryptKeeperText() {
1122 return EncryptionHelper.IS_DATA_ENCRYPTED;
1123 }
1124
1125 public boolean isRadioOn() {
1126 return !mAirplaneMode;
1127 }
1128
Jason Monk8fcab352015-06-29 10:57:00 -04001129 private class SubListener extends OnSubscriptionsChangedListener {
Jason Monkc9f05712014-12-15 12:24:10 -05001130 @Override
1131 public void onSubscriptionsChanged() {
Jason Monkb5746272014-11-12 16:50:31 -05001132 updateMobileControllers();
Jason Monk8fcab352015-06-29 10:57:00 -04001133 }
1134 }
Jason Monkb5746272014-11-12 16:50:31 -05001135
Jason Monk07b75fe2015-05-14 16:47:03 -04001136 /**
1137 * Used to register listeners from the BG Looper, this way the PhoneStateListeners that
1138 * get created will also run on the BG Looper.
1139 */
1140 private final Runnable mRegisterListeners = new Runnable() {
1141 @Override
1142 public void run() {
1143 registerListeners();
1144 }
1145 };
Jason Monkd2263cd2014-11-10 14:22:56 -05001146
Jason Monkc6cc6262015-06-11 11:10:15 -04001147 public static class SubscriptionDefaults {
1148 public int getDefaultVoiceSubId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001149 return SubscriptionManager.getDefaultVoiceSubscriptionId();
Jason Monkc6cc6262015-06-11 11:10:15 -04001150 }
1151
1152 public int getDefaultDataSubId() {
Shishir Agrawal7ea3e8b2016-01-25 13:03:07 -08001153 return SubscriptionManager.getDefaultDataSubscriptionId();
Jason Monkc6cc6262015-06-11 11:10:15 -04001154 }
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001155
1156 public int getActiveDataSubId() {
1157 return SubscriptionManager.getActiveDataSubscriptionId();
1158 }
Jason Monkc6cc6262015-06-11 11:10:15 -04001159 }
1160
Jason Monkd2263cd2014-11-10 14:22:56 -05001161 @VisibleForTesting
1162 static class Config {
Jason Monkb5746272014-11-12 16:50:31 -05001163 boolean showAtLeast3G = false;
vagdevi3f2b9a52019-08-09 09:45:14 -07001164 boolean show4gFor3g = false;
Jason Monkd2263cd2014-11-10 14:22:56 -05001165 boolean alwaysShowCdmaRssi = false;
1166 boolean show4gForLte = false;
Robert Greenwalt37d34ba2016-07-27 14:54:34 -07001167 boolean hideLtePlus = false;
Jason Monkd2263cd2014-11-10 14:22:56 -05001168 boolean hspaDataDistinguishable;
Jason Monk43c14d12017-06-22 11:20:04 -04001169 boolean inflateSignalStrengths = false;
Wenting Xiong63364fe2017-02-07 19:12:27 +08001170 boolean alwaysShowDataRatIcon = false;
Pengquan Menga62d32b2018-12-06 17:38:38 -08001171
Jason Monkd2263cd2014-11-10 14:22:56 -05001172 static Config readConfig(Context context) {
1173 Config config = new Config();
1174 Resources res = context.getResources();
1175
Jason Monkb5746272014-11-12 16:50:31 -05001176 config.showAtLeast3G = res.getBoolean(R.bool.config_showMin3G);
Jason Monkd2263cd2014-11-10 14:22:56 -05001177 config.alwaysShowCdmaRssi =
1178 res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
Jason Monkd2263cd2014-11-10 14:22:56 -05001179 config.hspaDataDistinguishable =
1180 res.getBoolean(R.bool.config_hspa_data_distinguishable);
Antony Sargentc026de32019-05-21 16:29:04 -07001181 config.inflateSignalStrengths = res.getBoolean(
1182 com.android.internal.R.bool.config_inflateSignalStrength);
Wenting Xiong63364fe2017-02-07 19:12:27 +08001183
1184 CarrierConfigManager configMgr = (CarrierConfigManager)
1185 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Niklas Lindgrena02964d2018-09-21 14:01:57 +02001186 // Handle specific carrier config values for the default data SIM
1187 int defaultDataSubId = SubscriptionManager.from(context)
1188 .getDefaultDataSubscriptionId();
1189 PersistableBundle b = configMgr.getConfigForSubId(defaultDataSubId);
Wenting Xiong63364fe2017-02-07 19:12:27 +08001190 if (b != null) {
1191 config.alwaysShowDataRatIcon = b.getBoolean(
1192 CarrierConfigManager.KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL);
Niklas Lindgrena02964d2018-09-21 14:01:57 +02001193 config.show4gForLte = b.getBoolean(
1194 CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
vagdevi3f2b9a52019-08-09 09:45:14 -07001195 config.show4gFor3g = b.getBoolean(
1196 CarrierConfigManager.KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL);
Niklas Lindgrena02964d2018-09-21 14:01:57 +02001197 config.hideLtePlus = b.getBoolean(
1198 CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL);
Wenting Xiong63364fe2017-02-07 19:12:27 +08001199 }
Pengquan Menga62d32b2018-12-06 17:38:38 -08001200
Jason Monkd2263cd2014-11-10 14:22:56 -05001201 return config;
John Spurlockaf8d6c42014-05-07 17:49:08 -04001202 }
John Spurlockaf8d6c42014-05-07 17:49:08 -04001203 }
1204}