blob: 24e3c78679f6df83020721ed3aa21f853d5057e0 [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
Lorenzo Colitti403aa262014-11-28 11:21:30 +090019import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
Jason Monkda68f592015-01-07 10:55:58 -050020
John Spurlockaf8d6c42014-05-07 17:49:08 -040021import android.content.BroadcastReceiver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.content.res.Resources;
26import android.net.ConnectivityManager;
Lorenzo Colitti403aa262014-11-28 11:21:30 +090027import android.net.NetworkCapabilities;
John Spurlockaf8d6c42014-05-07 17:49:08 -040028import android.net.wifi.WifiManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -040029import android.os.AsyncTask;
30import android.os.Bundle;
Jason Monk07b75fe2015-05-14 16:47:03 -040031import android.os.Handler;
Jason Monk30d80042015-05-08 16:54:18 -040032import android.os.Looper;
John Spurlockaf8d6c42014-05-07 17:49:08 -040033import android.provider.Settings;
Jason Monkb5746272014-11-12 16:50:31 -050034import android.telephony.SubscriptionInfo;
35import android.telephony.SubscriptionManager;
36import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
John Spurlockaf8d6c42014-05-07 17:49:08 -040037import android.telephony.TelephonyManager;
Jason Monkb5746272014-11-12 16:50:31 -050038import android.text.TextUtils;
John Spurlockaf8d6c42014-05-07 17:49:08 -040039import android.util.Log;
John Spurlockcf053c12015-05-14 16:33:59 -040040import android.util.MathUtils;
John Spurlockaf8d6c42014-05-07 17:49:08 -040041
Jason Monke0cdb602014-11-05 12:39:45 -050042import com.android.internal.annotations.VisibleForTesting;
Jason Monkb5746272014-11-12 16:50:31 -050043import com.android.internal.telephony.PhoneConstants;
John Spurlockaf8d6c42014-05-07 17:49:08 -040044import com.android.internal.telephony.TelephonyIntents;
John Spurlockaf8d6c42014-05-07 17:49:08 -040045import com.android.systemui.DemoMode;
46import com.android.systemui.R;
47
48import java.io.FileDescriptor;
49import java.io.PrintWriter;
50import java.util.ArrayList;
Lorenzo Colitti403aa262014-11-28 11:21:30 +090051import java.util.BitSet;
Jason Monkb5746272014-11-12 16:50:31 -050052import java.util.Collections;
53import java.util.Comparator;
Jason Monkd2263cd2014-11-10 14:22:56 -050054import java.util.HashMap;
John Spurlockaf8d6c42014-05-07 17:49:08 -040055import java.util.List;
56import java.util.Locale;
Jason Monkd2263cd2014-11-10 14:22:56 -050057import java.util.Map;
John Spurlockaf8d6c42014-05-07 17:49:08 -040058
59/** Platform implementation of the network controller. **/
60public class NetworkControllerImpl extends BroadcastReceiver
61 implements NetworkController, DemoMode {
62 // debug
Jason Monkd2263cd2014-11-10 14:22:56 -050063 static final String TAG = "NetworkController";
64 static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
65 // additional diagnostics, but not logspew
Jason Monk07b75fe2015-05-14 16:47:03 -040066 static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG);
John Spurlockaf8d6c42014-05-07 17:49:08 -040067
Jason Monkd2263cd2014-11-10 14:22:56 -050068 private final Context mContext;
69 private final TelephonyManager mPhone;
70 private final WifiManager mWifiManager;
71 private final ConnectivityManager mConnectivityManager;
Jason Monkb5746272014-11-12 16:50:31 -050072 private final SubscriptionManager mSubscriptionManager;
Jason Monkd2263cd2014-11-10 14:22:56 -050073 private final boolean mHasMobileDataFeature;
Jason Monkc6cc6262015-06-11 11:10:15 -040074 private final SubscriptionDefaults mSubDefaults;
Jason Monk3aaabd72014-12-12 11:11:44 -050075 private Config mConfig;
John Spurlockaf8d6c42014-05-07 17:49:08 -040076
Jason Monkd2263cd2014-11-10 14:22:56 -050077 // Subcontrollers.
78 @VisibleForTesting
79 final WifiSignalController mWifiSignalController;
Lorenzo Colittid46bb582015-04-27 20:32:01 +090080
81 @VisibleForTesting
82 final EthernetSignalController mEthernetSignalController;
83
Jason Monkd2263cd2014-11-10 14:22:56 -050084 @VisibleForTesting
Jason Monkb5746272014-11-12 16:50:31 -050085 final Map<Integer, MobileSignalController> mMobileSignalControllers =
86 new HashMap<Integer, MobileSignalController>();
87 // When no SIMs are around at setup, and one is added later, it seems to default to the first
88 // SIM for most actions. This may be null if there aren't any SIMs around.
89 private MobileSignalController mDefaultSignalController;
Jason Monk0e2400f2014-11-21 11:08:55 -050090 private final AccessPointControllerImpl mAccessPoints;
Jason Monkd2263cd2014-11-10 14:22:56 -050091 private final MobileDataControllerImpl mMobileDataController;
John Spurlockaf8d6c42014-05-07 17:49:08 -040092
Jason Monkd2263cd2014-11-10 14:22:56 -050093 private boolean mInetCondition; // Used for Logging and demo.
Lorenzo Colitti23dd1762014-09-10 22:58:54 +090094
Lorenzo Colitti403aa262014-11-28 11:21:30 +090095 // BitSets indicating which network transport types (e.g., TRANSPORT_WIFI, TRANSPORT_MOBILE) are
96 // connected and validated, respectively.
97 private final BitSet mConnectedTransports = new BitSet();
98 private final BitSet mValidatedTransports = new BitSet();
99
Jason Monkd2263cd2014-11-10 14:22:56 -0500100 // States that don't belong to a subcontroller.
John Spurlockaf8d6c42014-05-07 17:49:08 -0400101 private boolean mAirplaneMode = false;
Jason Monkb5746272014-11-12 16:50:31 -0500102 private boolean mHasNoSims;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400103 private Locale mLocale = null;
Jason Monkb5746272014-11-12 16:50:31 -0500104 // This list holds our ordering.
John Spurlockcf053c12015-05-14 16:33:59 -0400105 private List<SubscriptionInfo> mCurrentSubscriptions = new ArrayList<>();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400106
Jason Monkc014dec2014-12-12 11:49:55 -0500107 @VisibleForTesting
108 boolean mListening;
John Spurlock7f8f22a2014-07-02 18:54:17 -0400109
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900110 // The current user ID.
111 private int mCurrentUserId;
112
Jason Monk8fcab352015-06-29 10:57:00 -0400113 private OnSubscriptionsChangedListener mSubscriptionListener;
114
Jason Monk07b75fe2015-05-14 16:47:03 -0400115 // Handler that all broadcasts are received on.
116 private final Handler mReceiverHandler;
117 // Handler that all callbacks are made on.
118 private final CallbackHandler mCallbackHandler;
119
John Spurlockaf8d6c42014-05-07 17:49:08 -0400120 /**
121 * Construct this controller object and register for updates.
122 */
Jason Monk30d80042015-05-08 16:54:18 -0400123 public NetworkControllerImpl(Context context, Looper bgLooper) {
Jason Monkf13b4b32014-11-07 16:39:34 -0500124 this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
125 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
Jason Monk29f7a7b2014-11-17 14:40:56 -0500126 (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
Jason Monk07b75fe2015-05-14 16:47:03 -0400127 SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
128 new CallbackHandler(),
Jason Monk30d80042015-05-08 16:54:18 -0400129 new AccessPointControllerImpl(context, bgLooper),
Jason Monkc6cc6262015-06-11 11:10:15 -0400130 new MobileDataControllerImpl(context),
131 new SubscriptionDefaults());
Jason Monk07b75fe2015-05-14 16:47:03 -0400132 mReceiverHandler.post(mRegisterListeners);
Jason Monkf13b4b32014-11-07 16:39:34 -0500133 }
134
135 @VisibleForTesting
136 NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
Jason Monkb5746272014-11-12 16:50:31 -0500137 TelephonyManager telephonyManager, WifiManager wifiManager,
Jason Monk07b75fe2015-05-14 16:47:03 -0400138 SubscriptionManager subManager, Config config, Looper bgLooper,
139 CallbackHandler callbackHandler,
Jason Monkd2263cd2014-11-10 14:22:56 -0500140 AccessPointControllerImpl accessPointController,
Jason Monkc6cc6262015-06-11 11:10:15 -0400141 MobileDataControllerImpl mobileDataController,
142 SubscriptionDefaults defaultsHandler) {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400143 mContext = context;
Jason Monkb5746272014-11-12 16:50:31 -0500144 mConfig = config;
Jason Monk07b75fe2015-05-14 16:47:03 -0400145 mReceiverHandler = new Handler(bgLooper);
146 mCallbackHandler = callbackHandler;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400147
Jason Monkb5746272014-11-12 16:50:31 -0500148 mSubscriptionManager = subManager;
Jason Monkc6cc6262015-06-11 11:10:15 -0400149 mSubDefaults = defaultsHandler;
Jason Monkf13b4b32014-11-07 16:39:34 -0500150 mConnectivityManager = connectivityManager;
151 mHasMobileDataFeature =
152 mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400153
John Spurlockaf8d6c42014-05-07 17:49:08 -0400154 // telephony
Jason Monk07b75fe2015-05-14 16:47:03 -0400155 mPhone = telephonyManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400156
157 // wifi
Jason Monkf13b4b32014-11-07 16:39:34 -0500158 mWifiManager = wifiManager;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400159
Jason Monkd2263cd2014-11-10 14:22:56 -0500160 mLocale = mContext.getResources().getConfiguration().locale;
Jason Monk29f7a7b2014-11-17 14:40:56 -0500161 mAccessPoints = accessPointController;
162 mMobileDataController = mobileDataController;
Jason Monkd2263cd2014-11-10 14:22:56 -0500163 mMobileDataController.setNetworkController(this);
164 // TODO: Find a way to move this into MobileDataController.
165 mMobileDataController.setCallback(new MobileDataControllerImpl.Callback() {
Jason Monke0cdb602014-11-05 12:39:45 -0500166 @Override
167 public void onMobileDataEnabled(boolean enabled) {
Jason Monk07b75fe2015-05-14 16:47:03 -0400168 mCallbackHandler.setMobileDataEnabled(enabled);
Jason Monke0cdb602014-11-05 12:39:45 -0500169 }
170 });
Jason Monkd2263cd2014-11-10 14:22:56 -0500171 mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
Jason Monk07b75fe2015-05-14 16:47:03 -0400172 mCallbackHandler, this);
Jason Monkd2263cd2014-11-10 14:22:56 -0500173
Jason Monk07b75fe2015-05-14 16:47:03 -0400174 mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900175
Jason Monkd2263cd2014-11-10 14:22:56 -0500176 // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
Jason Monkb5746272014-11-12 16:50:31 -0500177 updateAirplaneMode(true /* force callback */);
Jason Monke0cdb602014-11-05 12:39:45 -0500178 }
179
Jason Monkf13b4b32014-11-07 16:39:34 -0500180 private void registerListeners() {
Jason Monkb5746272014-11-12 16:50:31 -0500181 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
182 mobileSignalController.registerListener();
183 }
Jason Monk8fcab352015-06-29 10:57:00 -0400184 if (mSubscriptionListener == null) {
185 mSubscriptionListener = new SubListener();
186 }
Wink Saville071743f2015-01-12 17:11:04 -0800187 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Jason Monke0cdb602014-11-05 12:39:45 -0500188
John Spurlockaf8d6c42014-05-07 17:49:08 -0400189 // broadcasts
190 IntentFilter filter = new IntentFilter();
191 filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
192 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
193 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
194 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Jason Monkb5746272014-11-12 16:50:31 -0500195 filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
196 filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400197 filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
Erik Kline32830cc2015-04-21 13:09:15 +0900198 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400199 filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
200 filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
201 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
Jason Monk07b75fe2015-05-14 16:47:03 -0400202 mContext.registerReceiver(this, filter, null, mReceiverHandler);
Jason Monkb5746272014-11-12 16:50:31 -0500203 mListening = true;
204
205 updateMobileControllers();
John Spurlockb98f7472014-07-08 17:09:42 -0400206 }
207
Jason Monkd2263cd2014-11-10 14:22:56 -0500208 private void unregisterListeners() {
Jason Monkb5746272014-11-12 16:50:31 -0500209 mListening = false;
210 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
211 mobileSignalController.unregisterListener();
212 }
Wink Saville071743f2015-01-12 17:11:04 -0800213 mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
Jason Monkd2263cd2014-11-10 14:22:56 -0500214 mContext.unregisterReceiver(this);
Jason Monk5d325072014-10-27 11:38:47 -0400215 }
216
Jason Monk0e2400f2014-11-21 11:08:55 -0500217 public int getConnectedWifiLevel() {
218 return mWifiSignalController.getState().level;
219 }
220
Jason Monk5d325072014-10-27 11:38:47 -0400221 @Override
Jason Monkd2263cd2014-11-10 14:22:56 -0500222 public AccessPointController getAccessPointController() {
223 return mAccessPoints;
224 }
225
226 @Override
227 public MobileDataController getMobileDataController() {
228 return mMobileDataController;
229 }
230
231 public void addEmergencyListener(EmergencyListener listener) {
Jason Monk07b75fe2015-05-14 16:47:03 -0400232 mCallbackHandler.setListening(listener, true);
233 mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
John Spurlockaf8d6c42014-05-07 17:49:08 -0400234 }
235
236 public boolean hasMobileDataFeature() {
237 return mHasMobileDataFeature;
238 }
239
240 public boolean hasVoiceCallingFeature() {
241 return mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
242 }
243
Jason Monkb5746272014-11-12 16:50:31 -0500244 private MobileSignalController getDataController() {
Jason Monkc6cc6262015-06-11 11:10:15 -0400245 int dataSubId = mSubDefaults.getDefaultDataSubId();
Wink Savillea54bf652014-12-11 13:37:50 -0800246 if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
Jason Monkb5746272014-11-12 16:50:31 -0500247 if (DEBUG) Log.e(TAG, "No data sim selected");
248 return mDefaultSignalController;
249 }
250 if (mMobileSignalControllers.containsKey(dataSubId)) {
251 return mMobileSignalControllers.get(dataSubId);
252 }
Dan Sandlerc8466322014-12-08 15:42:52 -0500253 if (DEBUG) Log.e(TAG, "Cannot find controller for data sub: " + dataSubId);
Jason Monkb5746272014-11-12 16:50:31 -0500254 return mDefaultSignalController;
255 }
256
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700257 public String getMobileDataNetworkName() {
Jason Monkb5746272014-11-12 16:50:31 -0500258 MobileSignalController controller = getDataController();
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700259 return controller != null ? controller.getState().networkNameData : "";
Jason Monkd2263cd2014-11-10 14:22:56 -0500260 }
261
John Spurlockaf8d6c42014-05-07 17:49:08 -0400262 public boolean isEmergencyOnly() {
Jason Monkc6cc6262015-06-11 11:10:15 -0400263 int voiceSubId = mSubDefaults.getDefaultVoiceSubId();
Wink Savillea54bf652014-12-11 13:37:50 -0800264 if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) {
265 for (MobileSignalController mobileSignalController :
266 mMobileSignalControllers.values()) {
Jason Monkc6cc6262015-06-11 11:10:15 -0400267 if (!mobileSignalController.getState().isEmergency) {
268 if (DEBUG) Log.d(TAG, "Found emergency " + mobileSignalController.mTag);
Jason Monkb5746272014-11-12 16:50:31 -0500269 return false;
270 }
271 }
272 }
273 if (mMobileSignalControllers.containsKey(voiceSubId)) {
Jason Monkc6cc6262015-06-11 11:10:15 -0400274 if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId);
275 return mMobileSignalControllers.get(voiceSubId).getState().isEmergency;
Jason Monkb5746272014-11-12 16:50:31 -0500276 }
Dan Sandlerc8466322014-12-08 15:42:52 -0500277 if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
Jason Monkb5746272014-11-12 16:50:31 -0500278 // Something is wrong, better assume we can't make calls...
279 return true;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400280 }
281
Jason Monkd2263cd2014-11-10 14:22:56 -0500282 /**
283 * Emergency status may have changed (triggered by MobileSignalController),
284 * so we should recheck and send out the state to listeners.
285 */
286 void recalculateEmergency() {
Jason Monk07b75fe2015-05-14 16:47:03 -0400287 mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
John Spurlockaf8d6c42014-05-07 17:49:08 -0400288 }
289
Jason Monk07b75fe2015-05-14 16:47:03 -0400290 public void addSignalCallback(SignalCallback cb) {
291 mCallbackHandler.setListening(cb, true);
292 mCallbackHandler.setSubs(mCurrentSubscriptions);
293 mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode,
294 TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
295 mCallbackHandler.setNoSims(mHasNoSims);
Jason Monkd2263cd2014-11-10 14:22:56 -0500296 mWifiSignalController.notifyListeners();
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900297 mEthernetSignalController.notifyListeners();
Jason Monkb5746272014-11-12 16:50:31 -0500298 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
299 mobileSignalController.notifyListeners();
300 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400301 }
302
Jason Monk07b75fe2015-05-14 16:47:03 -0400303 @Override
304 public void removeSignalCallback(SignalCallback cb) {
305 mCallbackHandler.setListening(cb, false);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400306 }
307
308 @Override
309 public void setWifiEnabled(final boolean enabled) {
310 new AsyncTask<Void, Void, Void>() {
311 @Override
312 protected Void doInBackground(Void... args) {
313 // Disable tethering if enabling Wifi
314 final int wifiApState = mWifiManager.getWifiApState();
315 if (enabled && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
Jason Monkd2263cd2014-11-10 14:22:56 -0500316 (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400317 mWifiManager.setWifiApEnabled(null, false);
318 }
319
320 mWifiManager.setWifiEnabled(enabled);
321 return null;
322 }
323 }.execute();
324 }
325
John Spurlockb98f7472014-07-08 17:09:42 -0400326 @Override
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900327 public void onUserSwitched(int newUserId) {
328 mCurrentUserId = newUserId;
329 mAccessPoints.onUserSwitched(newUserId);
330 updateConnectivity();
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900331 }
332
333 @Override
John Spurlockaf8d6c42014-05-07 17:49:08 -0400334 public void onReceive(Context context, Intent intent) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500335 if (CHATTY) {
336 Log.d(TAG, "onReceive: intent=" + intent);
337 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400338 final String action = intent.getAction();
Erik Kline32830cc2015-04-21 13:09:15 +0900339 if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
Jason Monkd2263cd2014-11-10 14:22:56 -0500340 action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900341 updateConnectivity();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400342 } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
Jason Monk3aaabd72014-12-12 11:11:44 -0500343 handleConfigurationChanged();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400344 } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
345 refreshLocale();
Jason Monkd2263cd2014-11-10 14:22:56 -0500346 updateAirplaneMode(false);
Jason Monkb5746272014-11-12 16:50:31 -0500347 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED)) {
348 // We are using different subs now, we might be able to make calls.
349 recalculateEmergency();
350 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
351 // Notify every MobileSignalController so they can know whether they are the
352 // data sim or not.
353 for (MobileSignalController controller : mMobileSignalControllers.values()) {
354 controller.handleBroadcast(intent);
355 }
356 } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
357 // Might have different subscriptions now.
358 updateMobileControllers();
359 } else {
360 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
361 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea54bf652014-12-11 13:37:50 -0800362 if (SubscriptionManager.isValidSubscriptionId(subId)) {
Jason Monkb5746272014-11-12 16:50:31 -0500363 if (mMobileSignalControllers.containsKey(subId)) {
364 mMobileSignalControllers.get(subId).handleBroadcast(intent);
365 } else {
366 // Can't find this subscription... We must be out of date.
367 updateMobileControllers();
368 }
369 } else {
370 // No sub id, must be for the wifi.
371 mWifiSignalController.handleBroadcast(intent);
372 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400373 }
Jason Monkb5746272014-11-12 16:50:31 -0500374 }
375
Sungmin Choi6be4f6b2015-07-07 13:06:59 +0900376 public void handleConfigurationChanged() {
377 mConfig = Config.readConfig(mContext);
Jason Monk3aaabd72014-12-12 11:11:44 -0500378 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
379 mobileSignalController.setConfiguration(mConfig);
380 }
381 refreshLocale();
Jason Monk3aaabd72014-12-12 11:11:44 -0500382 }
383
Jason Monkb5746272014-11-12 16:50:31 -0500384 private void updateMobileControllers() {
385 if (!mListening) {
386 return;
387 }
Jason Monkc6cc6262015-06-11 11:10:15 -0400388 doUpdateMobileControllers();
389 }
390
391 @VisibleForTesting
392 void doUpdateMobileControllers() {
Jason Monkb5746272014-11-12 16:50:31 -0500393 List<SubscriptionInfo> subscriptions = mSubscriptionManager.getActiveSubscriptionInfoList();
Jason Monkc9f05712014-12-15 12:24:10 -0500394 if (subscriptions == null) {
395 subscriptions = Collections.emptyList();
396 }
Jason Monkb5746272014-11-12 16:50:31 -0500397 // If there have been no relevant changes to any of the subscriptions, we can leave as is.
398 if (hasCorrectMobileControllers(subscriptions)) {
399 // Even if the controllers are correct, make sure we have the right no sims state.
400 // Such as on boot, don't need any controllers, because there are no sims,
401 // but we still need to update the no sim state.
402 updateNoSims();
403 return;
404 }
405 setCurrentSubscriptions(subscriptions);
406 updateNoSims();
Jason Monkc6cc6262015-06-11 11:10:15 -0400407 recalculateEmergency();
Jason Monkb5746272014-11-12 16:50:31 -0500408 }
409
Jason Monk21d05a02014-12-02 12:46:58 -0500410 @VisibleForTesting
411 protected void updateNoSims() {
412 boolean hasNoSims = mHasMobileDataFeature && mMobileSignalControllers.size() == 0;
Jason Monkb5746272014-11-12 16:50:31 -0500413 if (hasNoSims != mHasNoSims) {
414 mHasNoSims = hasNoSims;
Jason Monk259e06f2015-06-18 14:07:26 -0400415 mCallbackHandler.setNoSims(mHasNoSims);
Jason Monkb5746272014-11-12 16:50:31 -0500416 }
417 }
418
419 @VisibleForTesting
420 void setCurrentSubscriptions(List<SubscriptionInfo> subscriptions) {
421 Collections.sort(subscriptions, new Comparator<SubscriptionInfo>() {
422 @Override
423 public int compare(SubscriptionInfo lhs, SubscriptionInfo rhs) {
424 return lhs.getSimSlotIndex() == rhs.getSimSlotIndex()
425 ? lhs.getSubscriptionId() - rhs.getSubscriptionId()
426 : lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
427 }
428 });
Jason Monkb5746272014-11-12 16:50:31 -0500429 mCurrentSubscriptions = subscriptions;
430
431 HashMap<Integer, MobileSignalController> cachedControllers =
432 new HashMap<Integer, MobileSignalController>(mMobileSignalControllers);
433 mMobileSignalControllers.clear();
434 final int num = subscriptions.size();
435 for (int i = 0; i < num; i++) {
436 int subId = subscriptions.get(i).getSubscriptionId();
437 // If we have a copy of this controller already reuse it, otherwise make a new one.
438 if (cachedControllers.containsKey(subId)) {
Jason Monkc014dec2014-12-12 11:49:55 -0500439 mMobileSignalControllers.put(subId, cachedControllers.remove(subId));
Jason Monkb5746272014-11-12 16:50:31 -0500440 } else {
441 MobileSignalController controller = new MobileSignalController(mContext, mConfig,
Jason Monk07b75fe2015-05-14 16:47:03 -0400442 mHasMobileDataFeature, mPhone, mCallbackHandler,
Jason Monkc6cc6262015-06-11 11:10:15 -0400443 this, subscriptions.get(i), mSubDefaults, mReceiverHandler.getLooper());
Jason Monkb5746272014-11-12 16:50:31 -0500444 mMobileSignalControllers.put(subId, controller);
445 if (subscriptions.get(i).getSimSlotIndex() == 0) {
446 mDefaultSignalController = controller;
447 }
448 if (mListening) {
449 controller.registerListener();
450 }
451 }
452 }
453 if (mListening) {
454 for (Integer key : cachedControllers.keySet()) {
455 if (cachedControllers.get(key) == mDefaultSignalController) {
456 mDefaultSignalController = null;
457 }
458 cachedControllers.get(key).unregisterListener();
459 }
460 }
Jason Monk8fcab352015-06-29 10:57:00 -0400461 mCallbackHandler.setSubs(subscriptions);
462 notifyAllListeners();
463
Jason Monk25d8a482014-12-09 12:27:24 -0500464 // There may be new MobileSignalControllers around, make sure they get the current
465 // inet condition and airplane mode.
466 pushConnectivityToSignals();
467 updateAirplaneMode(true /* force */);
Jason Monkb5746272014-11-12 16:50:31 -0500468 }
469
Jason Monkc014dec2014-12-12 11:49:55 -0500470 @VisibleForTesting
471 boolean hasCorrectMobileControllers(List<SubscriptionInfo> allSubscriptions) {
Jason Monkc9f05712014-12-15 12:24:10 -0500472 if (allSubscriptions.size() != mMobileSignalControllers.size()) {
473 return false;
Jason Monkb5746272014-11-12 16:50:31 -0500474 }
475 for (SubscriptionInfo info : allSubscriptions) {
476 if (!mMobileSignalControllers.containsKey(info.getSubscriptionId())) {
477 return false;
478 }
479 }
480 return true;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400481 }
482
Jason Monkd2263cd2014-11-10 14:22:56 -0500483 private void updateAirplaneMode(boolean force) {
484 boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
485 Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
486 if (airplaneMode != mAirplaneMode || force) {
487 mAirplaneMode = airplaneMode;
Jason Monkb5746272014-11-12 16:50:31 -0500488 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
489 mobileSignalController.setAirplaneMode(mAirplaneMode);
490 }
491 notifyListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400492 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400493 }
494
495 private void refreshLocale() {
Jason Monkd2263cd2014-11-10 14:22:56 -0500496 Locale current = mContext.getResources().getConfiguration().locale;
Jason Monkb5746272014-11-12 16:50:31 -0500497 if (!current.equals(mLocale)) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500498 mLocale = current;
499 notifyAllListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400500 }
501 }
502
Jason Monkd2263cd2014-11-10 14:22:56 -0500503 /**
Jason Monkb5746272014-11-12 16:50:31 -0500504 * Forces update of all callbacks on both SignalClusters and
505 * NetworkSignalChangedCallbacks.
506 */
Jason Monkd2263cd2014-11-10 14:22:56 -0500507 private void notifyAllListeners() {
Jason Monkb5746272014-11-12 16:50:31 -0500508 notifyListeners();
509 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
510 mobileSignalController.notifyListeners();
511 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500512 mWifiSignalController.notifyListeners();
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900513 mEthernetSignalController.notifyListeners();
Jason Monkd2263cd2014-11-10 14:22:56 -0500514 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400515
Jason Monkb5746272014-11-12 16:50:31 -0500516 /**
517 * Notifies listeners of changes in state of to the NetworkController, but
518 * does not notify for any info on SignalControllers, for that call
519 * notifyAllListeners.
520 */
521 private void notifyListeners() {
Jason Monk07b75fe2015-05-14 16:47:03 -0400522 mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode,
523 TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
524 mCallbackHandler.setNoSims(mHasNoSims);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400525 }
526
Jason Monkd2263cd2014-11-10 14:22:56 -0500527 /**
528 * Update the Inet conditions and what network we are connected to.
529 */
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900530 private void updateConnectivity() {
531 mConnectedTransports.clear();
532 mValidatedTransports.clear();
533 for (NetworkCapabilities nc :
534 mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) {
535 for (int transportType : nc.getTransportTypes()) {
536 mConnectedTransports.set(transportType);
537 if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
538 mValidatedTransports.set(transportType);
539 }
540 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400541 }
542
John Spurlockaf8d6c42014-05-07 17:49:08 -0400543 if (CHATTY) {
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900544 Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports);
545 Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400546 }
547
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900548 mInetCondition = !mValidatedTransports.isEmpty();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400549
Jason Monk25d8a482014-12-09 12:27:24 -0500550 pushConnectivityToSignals();
551 }
552
553 /**
554 * Pushes the current connectivity state to all SignalControllers.
555 */
556 private void pushConnectivityToSignals() {
John Spurlockaf8d6c42014-05-07 17:49:08 -0400557 // We want to update all the icons, all at once, for any condition change
Jason Monkb5746272014-11-12 16:50:31 -0500558 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
Jason Monk33f8ae72015-05-08 10:45:15 -0400559 mobileSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
Jason Monkb5746272014-11-12 16:50:31 -0500560 }
Jason Monk33f8ae72015-05-08 10:45:15 -0400561 mWifiSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
562 mEthernetSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400563 }
564
John Spurlockaf8d6c42014-05-07 17:49:08 -0400565 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
566 pw.println("NetworkController state:");
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900567
John Spurlockaf8d6c42014-05-07 17:49:08 -0400568 pw.println(" - telephony ------");
569 pw.print(" hasVoiceCallingFeature()=");
570 pw.println(hasVoiceCallingFeature());
John Spurlockaf8d6c42014-05-07 17:49:08 -0400571
John Spurlockaf8d6c42014-05-07 17:49:08 -0400572 pw.println(" - connectivity ------");
Lorenzo Colitti403aa262014-11-28 11:21:30 +0900573 pw.print(" mConnectedTransports=");
574 pw.println(mConnectedTransports);
575 pw.print(" mValidatedTransports=");
576 pw.println(mValidatedTransports);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400577 pw.print(" mInetCondition=");
578 pw.println(mInetCondition);
Jason Monkd2263cd2014-11-10 14:22:56 -0500579 pw.print(" mAirplaneMode=");
580 pw.println(mAirplaneMode);
581 pw.print(" mLocale=");
582 pw.println(mLocale);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400583
Jason Monkb5746272014-11-12 16:50:31 -0500584 for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
585 mobileSignalController.dump(pw);
586 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500587 mWifiSignalController.dump(pw);
Jason Monkd52356a2015-01-28 10:40:41 -0500588
Lorenzo Colittid46bb582015-04-27 20:32:01 +0900589 mEthernetSignalController.dump(pw);
590
Jason Monkd52356a2015-01-28 10:40:41 -0500591 mAccessPoints.dump(pw);
John Spurlockaf8d6c42014-05-07 17:49:08 -0400592 }
593
594 private boolean mDemoMode;
Jason Monk33f8ae72015-05-08 10:45:15 -0400595 private boolean mDemoInetCondition;
Jason Monkd2263cd2014-11-10 14:22:56 -0500596 private WifiSignalController.WifiState mDemoWifiState;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400597
598 @Override
599 public void dispatchDemoCommand(String command, Bundle args) {
600 if (!mDemoMode && command.equals(COMMAND_ENTER)) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500601 if (DEBUG) Log.d(TAG, "Entering demo mode");
602 unregisterListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400603 mDemoMode = true;
Jason Monk33f8ae72015-05-08 10:45:15 -0400604 mDemoInetCondition = mInetCondition;
Jason Monkd2263cd2014-11-10 14:22:56 -0500605 mDemoWifiState = mWifiSignalController.getState();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400606 } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500607 if (DEBUG) Log.d(TAG, "Exiting demo mode");
John Spurlockaf8d6c42014-05-07 17:49:08 -0400608 mDemoMode = false;
Jason Monkb5746272014-11-12 16:50:31 -0500609 // Update what MobileSignalControllers, because they may change
610 // to set the number of sim slots.
611 updateMobileControllers();
612 for (MobileSignalController controller : mMobileSignalControllers.values()) {
613 controller.resetLastState();
614 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500615 mWifiSignalController.resetLastState();
Jason Monk07b75fe2015-05-14 16:47:03 -0400616 mReceiverHandler.post(mRegisterListeners);
Jason Monkd2263cd2014-11-10 14:22:56 -0500617 notifyAllListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400618 } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
619 String airplane = args.getString("airplane");
620 if (airplane != null) {
621 boolean show = airplane.equals("show");
Jason Monk07b75fe2015-05-14 16:47:03 -0400622 mCallbackHandler.setIsAirplaneMode(new IconState(show,
623 TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode,
624 mContext));
John Spurlockaf8d6c42014-05-07 17:49:08 -0400625 }
626 String fully = args.getString("fully");
627 if (fully != null) {
Jason Monk33f8ae72015-05-08 10:45:15 -0400628 mDemoInetCondition = Boolean.parseBoolean(fully);
629 BitSet connected = new BitSet();
630
631 if (mDemoInetCondition) {
632 connected.set(mWifiSignalController.mTransportType);
633 }
634 mWifiSignalController.updateConnectivity(connected, connected);
Jason Monkb5746272014-11-12 16:50:31 -0500635 for (MobileSignalController controller : mMobileSignalControllers.values()) {
Jason Monk33f8ae72015-05-08 10:45:15 -0400636 if (mDemoInetCondition) {
637 connected.set(controller.mTransportType);
638 }
639 controller.updateConnectivity(connected, connected);
Jason Monkb5746272014-11-12 16:50:31 -0500640 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400641 }
642 String wifi = args.getString("wifi");
643 if (wifi != null) {
644 boolean show = wifi.equals("show");
645 String level = args.getString("level");
646 if (level != null) {
Jason Monkd2263cd2014-11-10 14:22:56 -0500647 mDemoWifiState.level = level.equals("null") ? -1
John Spurlockaf8d6c42014-05-07 17:49:08 -0400648 : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
Jason Monkd2263cd2014-11-10 14:22:56 -0500649 mDemoWifiState.connected = mDemoWifiState.level >= 0;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400650 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500651 mDemoWifiState.enabled = show;
652 mWifiSignalController.notifyListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400653 }
Jason Monkb5746272014-11-12 16:50:31 -0500654 String sims = args.getString("sims");
655 if (sims != null) {
John Spurlockcf053c12015-05-14 16:33:59 -0400656 int num = MathUtils.constrain(Integer.parseInt(sims), 1, 8);
657 List<SubscriptionInfo> subs = new ArrayList<>();
Jason Monkb5746272014-11-12 16:50:31 -0500658 if (num != mMobileSignalControllers.size()) {
659 mMobileSignalControllers.clear();
660 int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
661 for (int i = start /* get out of normal index range */; i < start + num; i++) {
John Spurlockcf053c12015-05-14 16:33:59 -0400662 subs.add(addSignalController(i, i));
Jason Monkb5746272014-11-12 16:50:31 -0500663 }
664 }
Jason Monk07b75fe2015-05-14 16:47:03 -0400665 mCallbackHandler.setSubs(subs);
Jason Monkb5746272014-11-12 16:50:31 -0500666 }
667 String nosim = args.getString("nosim");
668 if (nosim != null) {
Jason Monk259e06f2015-06-18 14:07:26 -0400669 mHasNoSims = nosim.equals("show");
670 mCallbackHandler.setNoSims(mHasNoSims);
Jason Monkb5746272014-11-12 16:50:31 -0500671 }
John Spurlockaf8d6c42014-05-07 17:49:08 -0400672 String mobile = args.getString("mobile");
673 if (mobile != null) {
674 boolean show = mobile.equals("show");
675 String datatype = args.getString("datatype");
Jason Monkb5746272014-11-12 16:50:31 -0500676 String slotString = args.getString("slot");
677 int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString);
John Spurlockcf053c12015-05-14 16:33:59 -0400678 slot = MathUtils.constrain(slot, 0, 8);
679 // Ensure we have enough sim slots
680 List<SubscriptionInfo> subs = new ArrayList<>();
681 while (mMobileSignalControllers.size() <= slot) {
682 int nextSlot = mMobileSignalControllers.size();
683 subs.add(addSignalController(nextSlot, nextSlot));
684 }
685 if (!subs.isEmpty()) {
Jason Monk07b75fe2015-05-14 16:47:03 -0400686 mCallbackHandler.setSubs(subs);
John Spurlockcf053c12015-05-14 16:33:59 -0400687 }
Jason Monkb5746272014-11-12 16:50:31 -0500688 // Hack to index linearly for easy use.
689 MobileSignalController controller = mMobileSignalControllers
690 .values().toArray(new MobileSignalController[0])[slot];
691 controller.getState().dataSim = datatype != null;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400692 if (datatype != null) {
Jason Monkb5746272014-11-12 16:50:31 -0500693 controller.getState().iconGroup =
Jason Monkd2263cd2014-11-10 14:22:56 -0500694 datatype.equals("1x") ? TelephonyIcons.ONE_X :
695 datatype.equals("3g") ? TelephonyIcons.THREE_G :
696 datatype.equals("4g") ? TelephonyIcons.FOUR_G :
697 datatype.equals("e") ? TelephonyIcons.E :
698 datatype.equals("g") ? TelephonyIcons.G :
699 datatype.equals("h") ? TelephonyIcons.H :
700 datatype.equals("lte") ? TelephonyIcons.LTE :
701 datatype.equals("roam") ? TelephonyIcons.ROAMING :
702 TelephonyIcons.UNKNOWN;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400703 }
704 int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
705 String level = args.getString("level");
706 if (level != null) {
Jason Monkb5746272014-11-12 16:50:31 -0500707 controller.getState().level = level.equals("null") ? -1
John Spurlockaf8d6c42014-05-07 17:49:08 -0400708 : Math.min(Integer.parseInt(level), icons[0].length - 1);
Jason Monkb5746272014-11-12 16:50:31 -0500709 controller.getState().connected = controller.getState().level >= 0;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400710 }
Jason Monkb5746272014-11-12 16:50:31 -0500711 controller.getState().enabled = show;
712 controller.notifyListeners();
John Spurlockaf8d6c42014-05-07 17:49:08 -0400713 }
Andrew Flynna478d702015-04-14 23:33:45 -0400714 String carrierNetworkChange = args.getString("carriernetworkchange");
715 if (carrierNetworkChange != null) {
716 boolean show = carrierNetworkChange.equals("show");
717 for (MobileSignalController controller : mMobileSignalControllers.values()) {
718 controller.setCarrierNetworkChangeMode(show);
719 }
720 }
Jason Monkd2263cd2014-11-10 14:22:56 -0500721 }
722 }
723
John Spurlockcf053c12015-05-14 16:33:59 -0400724 private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
725 SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
726 null, 0, 0, "");
727 mMobileSignalControllers.put(id, new MobileSignalController(mContext,
Jason Monk07b75fe2015-05-14 16:47:03 -0400728 mConfig, mHasMobileDataFeature, mPhone, mCallbackHandler, this, info,
Jason Monkc6cc6262015-06-11 11:10:15 -0400729 mSubDefaults, mReceiverHandler.getLooper()));
John Spurlockcf053c12015-05-14 16:33:59 -0400730 return info;
731 }
732
Jason Monk8fcab352015-06-29 10:57:00 -0400733 private class SubListener extends OnSubscriptionsChangedListener {
Jason Monkc9f05712014-12-15 12:24:10 -0500734 @Override
735 public void onSubscriptionsChanged() {
Jason Monkb5746272014-11-12 16:50:31 -0500736 updateMobileControllers();
Jason Monk8fcab352015-06-29 10:57:00 -0400737 }
738 }
Jason Monkb5746272014-11-12 16:50:31 -0500739
Jason Monk07b75fe2015-05-14 16:47:03 -0400740 /**
741 * Used to register listeners from the BG Looper, this way the PhoneStateListeners that
742 * get created will also run on the BG Looper.
743 */
744 private final Runnable mRegisterListeners = new Runnable() {
745 @Override
746 public void run() {
747 registerListeners();
748 }
749 };
Jason Monkd2263cd2014-11-10 14:22:56 -0500750
751 public interface EmergencyListener {
752 void setEmergencyCallsOnly(boolean emergencyOnly);
753 }
754
Jason Monkc6cc6262015-06-11 11:10:15 -0400755 public static class SubscriptionDefaults {
756 public int getDefaultVoiceSubId() {
757 return SubscriptionManager.getDefaultVoiceSubId();
758 }
759
760 public int getDefaultDataSubId() {
761 return SubscriptionManager.getDefaultDataSubId();
762 }
763 }
764
Jason Monkd2263cd2014-11-10 14:22:56 -0500765 @VisibleForTesting
766 static class Config {
Jason Monkb5746272014-11-12 16:50:31 -0500767 boolean showAtLeast3G = false;
Jason Monkd2263cd2014-11-10 14:22:56 -0500768 boolean alwaysShowCdmaRssi = false;
769 boolean show4gForLte = false;
770 boolean hspaDataDistinguishable;
771
772 static Config readConfig(Context context) {
773 Config config = new Config();
774 Resources res = context.getResources();
775
Jason Monkb5746272014-11-12 16:50:31 -0500776 config.showAtLeast3G = res.getBoolean(R.bool.config_showMin3G);
Jason Monkd2263cd2014-11-10 14:22:56 -0500777 config.alwaysShowCdmaRssi =
778 res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
779 config.show4gForLte = res.getBoolean(R.bool.config_show4GForLTE);
780 config.hspaDataDistinguishable =
781 res.getBoolean(R.bool.config_hspa_data_distinguishable);
782 return config;
John Spurlockaf8d6c42014-05-07 17:49:08 -0400783 }
784 }
785}