FileDocCategorySizeDatePackage
NetworkControllerImpl.javaAPI DocAndroid 5.1 API78893Thu Mar 12 22:22:42 GMT 2015com.android.systemui.statusbar.policy

NetworkControllerImpl

public class NetworkControllerImpl extends android.content.BroadcastReceiver implements com.android.systemui.DemoMode, NetworkController
Platform implementation of the network controller.

Fields Summary
static final String
TAG
static final boolean
DEBUG
static final boolean
CHATTY
static final boolean
RECORD_HISTORY
static final int
HISTORY_SIZE
private static final int
INET_CONDITION_THRESHOLD
private final android.content.Context
mContext
private final android.telephony.TelephonyManager
mPhone
private final android.net.wifi.WifiManager
mWifiManager
private final android.net.ConnectivityManager
mConnectivityManager
private final android.telephony.SubscriptionManager
mSubscriptionManager
private final boolean
mHasMobileDataFeature
private Config
mConfig
final WifiSignalController
mWifiSignalController
final Map
mMobileSignalControllers
private MobileSignalController
mDefaultSignalController
private final AccessPointControllerImpl
mAccessPoints
private final MobileDataControllerImpl
mMobileDataController
private boolean
mBluetoothTethered
private boolean
mEthernetConnected
private boolean
mConnected
private boolean
mInetCondition
private final BitSet
mConnectedTransports
private final BitSet
mValidatedTransports
private boolean
mAirplaneMode
private boolean
mHasNoSims
private Locale
mLocale
private List
mCurrentSubscriptions
private ArrayList
mEmergencyListeners
private ArrayList
mCarrierListeners
private ArrayList
mSignalClusters
private ArrayList
mSignalsChangedCallbacks
boolean
mListening
private int
mCurrentUserId
private boolean
mDemoMode
private int
mDemoInetCondition
private WifiSignalController.WifiState
mDemoWifiState
private final android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
mSubscriptionListener
Constructors Summary
public NetworkControllerImpl(android.content.Context context)
Construct this controller object and register for updates.


                 
       
        this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
                (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
                SubscriptionManager.from(context), Config.readConfig(context),
                new AccessPointControllerImpl(context), new MobileDataControllerImpl(context));
        registerListeners();
    
NetworkControllerImpl(android.content.Context context, android.net.ConnectivityManager connectivityManager, android.telephony.TelephonyManager telephonyManager, android.net.wifi.WifiManager wifiManager, android.telephony.SubscriptionManager subManager, Config config, AccessPointControllerImpl accessPointController, MobileDataControllerImpl mobileDataController)

        mContext = context;
        mConfig = config;

        mSubscriptionManager = subManager;
        mConnectivityManager = connectivityManager;
        mHasMobileDataFeature =
                mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);

        // telephony
        mPhone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);

        // wifi
        mWifiManager = wifiManager;

        mLocale = mContext.getResources().getConfiguration().locale;
        mAccessPoints = accessPointController;
        mMobileDataController = mobileDataController;
        mMobileDataController.setNetworkController(this);
        // TODO: Find a way to move this into MobileDataController.
        mMobileDataController.setCallback(new MobileDataControllerImpl.Callback() {
            @Override
            public void onMobileDataEnabled(boolean enabled) {
                notifyMobileDataEnabled(enabled);
            }
        });
        mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
                mSignalsChangedCallbacks, mSignalClusters, this);

        // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
        updateAirplaneMode(true /* force callback */);
        mAccessPoints.setNetworkController(this);
    
Methods Summary
public voidaddCarrierLabel(com.android.systemui.statusbar.policy.NetworkControllerImpl$CarrierLabelListener listener)

        mCarrierListeners.add(listener);
        refreshCarrierLabel();
    
public voidaddEmergencyListener(com.android.systemui.statusbar.policy.NetworkControllerImpl$EmergencyListener listener)

        mEmergencyListeners.add(listener);
        listener.setEmergencyCallsOnly(isEmergencyOnly());
    
public voidaddNetworkSignalChangedCallback(NetworkSignalChangedCallback cb)

        mSignalsChangedCallbacks.add(cb);
        cb.onAirplaneModeChanged(mAirplaneMode);
        cb.onNoSimVisibleChanged(mHasNoSims);
        mWifiSignalController.notifyListeners();
        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.notifyListeners();
        }
    
public voidaddSignalCluster(com.android.systemui.statusbar.policy.NetworkControllerImpl$SignalCluster cluster)

        mSignalClusters.add(cluster);
        cluster.setSubs(mCurrentSubscriptions);
        cluster.setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON,
                R.string.accessibility_airplane_mode);
        cluster.setNoSims(mHasNoSims);
        mWifiSignalController.notifyListeners();
        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.notifyListeners();
        }
    
public voiddispatchDemoCommand(java.lang.String command, android.os.Bundle args)

        if (!mDemoMode && command.equals(COMMAND_ENTER)) {
            if (DEBUG) Log.d(TAG, "Entering demo mode");
            unregisterListeners();
            mDemoMode = true;
            mDemoInetCondition = mInetCondition ? 1 : 0;
            mDemoWifiState = mWifiSignalController.getState();
        } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
            if (DEBUG) Log.d(TAG, "Exiting demo mode");
            mDemoMode = false;
            // Update what MobileSignalControllers, because they may change
            // to set the number of sim slots.
            updateMobileControllers();
            for (MobileSignalController controller : mMobileSignalControllers.values()) {
                controller.resetLastState();
            }
            mWifiSignalController.resetLastState();
            registerListeners();
            notifyAllListeners();
            refreshCarrierLabel();
        } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
            String airplane = args.getString("airplane");
            if (airplane != null) {
                boolean show = airplane.equals("show");
                int length = mSignalClusters.size();
                for (int i = 0; i < length; i++) {
                    mSignalClusters.get(i).setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON,
                            R.string.accessibility_airplane_mode);
                }
            }
            String fully = args.getString("fully");
            if (fully != null) {
                mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0;
                mWifiSignalController.setInetCondition(mDemoInetCondition);
                for (MobileSignalController controller : mMobileSignalControllers.values()) {
                    controller.setInetCondition(mDemoInetCondition, mDemoInetCondition);
                }
            }
            String wifi = args.getString("wifi");
            if (wifi != null) {
                boolean show = wifi.equals("show");
                String level = args.getString("level");
                if (level != null) {
                    mDemoWifiState.level = level.equals("null") ? -1
                            : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
                    mDemoWifiState.connected = mDemoWifiState.level >= 0;
                }
                mDemoWifiState.enabled = show;
                mWifiSignalController.notifyListeners();
            }
            String sims = args.getString("sims");
            if (sims != null) {
                int num = Integer.parseInt(sims);
                List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>();
                if (num != mMobileSignalControllers.size()) {
                    mMobileSignalControllers.clear();
                    int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
                    for (int i = start /* get out of normal index range */; i < start + num; i++) {
                        SubscriptionInfo info = new SubscriptionInfo(i, "", i, "", "", 0, 0, "", 0,
                                null, 0, 0, "");
                        subs.add(info);
                        mMobileSignalControllers.put(i, new MobileSignalController(mContext,
                                mConfig, mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks,
                                mSignalClusters, this, info));
                    }
                }
                final int n = mSignalClusters.size();
                for (int i = 0; i < n; i++) {
                    mSignalClusters.get(i).setSubs(subs);
                }
            }
            String nosim = args.getString("nosim");
            if (nosim != null) {
                boolean show = nosim.equals("show");
                final int n = mSignalClusters.size();
                for (int i = 0; i < n; i++) {
                    mSignalClusters.get(i).setNoSims(show);
                }
            }
            String mobile = args.getString("mobile");
            if (mobile != null) {
                boolean show = mobile.equals("show");
                String datatype = args.getString("datatype");
                String slotString = args.getString("slot");
                int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString);
                // Hack to index linearly for easy use.
                MobileSignalController controller = mMobileSignalControllers
                        .values().toArray(new MobileSignalController[0])[slot];
                controller.getState().dataSim = datatype != null;
                if (datatype != null) {
                    controller.getState().iconGroup =
                            datatype.equals("1x") ? TelephonyIcons.ONE_X :
                            datatype.equals("3g") ? TelephonyIcons.THREE_G :
                            datatype.equals("4g") ? TelephonyIcons.FOUR_G :
                            datatype.equals("e") ? TelephonyIcons.E :
                            datatype.equals("g") ? TelephonyIcons.G :
                            datatype.equals("h") ? TelephonyIcons.H :
                            datatype.equals("lte") ? TelephonyIcons.LTE :
                            datatype.equals("roam") ? TelephonyIcons.ROAMING :
                            TelephonyIcons.UNKNOWN;
                }
                int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
                String level = args.getString("level");
                if (level != null) {
                    controller.getState().level = level.equals("null") ? -1
                            : Math.min(Integer.parseInt(level), icons[0].length - 1);
                    controller.getState().connected = controller.getState().level >= 0;
                }
                controller.getState().enabled = show;
                controller.notifyListeners();
            }
            refreshCarrierLabel();
        }
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        pw.println("NetworkController state:");

        pw.println("  - telephony ------");
        pw.print("  hasVoiceCallingFeature()=");
        pw.println(hasVoiceCallingFeature());

        pw.println("  - Bluetooth ----");
        pw.print("  mBtReverseTethered=");
        pw.println(mBluetoothTethered);

        pw.println("  - connectivity ------");
        pw.print("  mConnectedTransports=");
        pw.println(mConnectedTransports);
        pw.print("  mValidatedTransports=");
        pw.println(mValidatedTransports);
        pw.print("  mInetCondition=");
        pw.println(mInetCondition);
        pw.print("  mAirplaneMode=");
        pw.println(mAirplaneMode);
        pw.print("  mLocale=");
        pw.println(mLocale);

        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.dump(pw);
        }
        mWifiSignalController.dump(pw);
    
public AccessPointControllergetAccessPointController()

        return mAccessPoints;
    
public intgetConnectedWifiLevel()

        return mWifiSignalController.getState().level;
    
private com.android.systemui.statusbar.policy.NetworkControllerImpl$MobileSignalControllergetDataController()

        int dataSubId = SubscriptionManager.getDefaultDataSubId();
        if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
            if (DEBUG) Log.e(TAG, "No data sim selected");
            return mDefaultSignalController;
        }
        if (mMobileSignalControllers.containsKey(dataSubId)) {
            return mMobileSignalControllers.get(dataSubId);
        }
        if (DEBUG) Log.e(TAG, "Cannot find controller for data sub: " + dataSubId);
        return mDefaultSignalController;
    
public MobileDataControllergetMobileDataController()

        return mMobileDataController;
    
public java.lang.StringgetMobileNetworkName()

        MobileSignalController controller = getDataController();
        return controller != null ? controller.getState().networkName : "";
    
voidhandleConfigurationChanged()

        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.setConfiguration(mConfig);
        }
        refreshLocale();
        refreshCarrierLabel();
    
booleanhasCorrectMobileControllers(java.util.List allSubscriptions)

        if (allSubscriptions.size() != mMobileSignalControllers.size()) {
            return false;
        }
        for (SubscriptionInfo info : allSubscriptions) {
            if (!mMobileSignalControllers.containsKey(info.getSubscriptionId())) {
                return false;
            }
        }
        return true;
    
public booleanhasMobileDataFeature()

        return mHasMobileDataFeature;
    
public booleanhasVoiceCallingFeature()

        return mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
    
public booleanisEmergencyOnly()

        int voiceSubId = SubscriptionManager.getDefaultVoiceSubId();
        if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) {
            for (MobileSignalController mobileSignalController :
                                            mMobileSignalControllers.values()) {
                if (!mobileSignalController.isEmergencyOnly()) {
                    return false;
                }
            }
        }
        if (mMobileSignalControllers.containsKey(voiceSubId)) {
            return mMobileSignalControllers.get(voiceSubId).isEmergencyOnly();
        }
        if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
        // Something is wrong, better assume we can't make calls...
        return true;
    
private booleanisMobileDataConnected()

        MobileSignalController controller = getDataController();
        return controller != null ? controller.getState().dataConnected : false;
    
private voidnotifyAllListeners()
Forces update of all callbacks on both SignalClusters and NetworkSignalChangedCallbacks.

        notifyListeners();
        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.notifyListeners();
        }
        mWifiSignalController.notifyListeners();
    
private voidnotifyListeners()
Notifies listeners of changes in state of to the NetworkController, but does not notify for any info on SignalControllers, for that call notifyAllListeners.

        int length = mSignalClusters.size();
        for (int i = 0; i < length; i++) {
            mSignalClusters.get(i).setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON,
                    R.string.accessibility_airplane_mode);
            mSignalClusters.get(i).setNoSims(mHasNoSims);
        }
        int signalsChangedLength = mSignalsChangedCallbacks.size();
        for (int i = 0; i < signalsChangedLength; i++) {
            mSignalsChangedCallbacks.get(i).onAirplaneModeChanged(mAirplaneMode);
            mSignalsChangedCallbacks.get(i).onNoSimVisibleChanged(mHasNoSims);
        }
    
private voidnotifyMobileDataEnabled(boolean enabled)

        final int length = mSignalsChangedCallbacks.size();
        for (int i = 0; i < length; i++) {
            mSignalsChangedCallbacks.get(i).onMobileDataEnabled(enabled);
        }
    
public voidonReceive(android.content.Context context, android.content.Intent intent)

        if (CHATTY) {
            Log.d(TAG, "onReceive: intent=" + intent);
        }
        final String action = intent.getAction();
        if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE) ||
                action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
            updateConnectivity();
            refreshCarrierLabel();
        } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
            mConfig = Config.readConfig(mContext);
            handleConfigurationChanged();
        } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
            refreshLocale();
            updateAirplaneMode(false);
            refreshCarrierLabel();
        } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED)) {
            // We are using different subs now, we might be able to make calls.
            recalculateEmergency();
        } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
            // Notify every MobileSignalController so they can know whether they are the
            // data sim or not.
            for (MobileSignalController controller : mMobileSignalControllers.values()) {
                controller.handleBroadcast(intent);
            }
        } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
            // Might have different subscriptions now.
            updateMobileControllers();
        } else {
            int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
            if (SubscriptionManager.isValidSubscriptionId(subId)) {
                if (mMobileSignalControllers.containsKey(subId)) {
                    mMobileSignalControllers.get(subId).handleBroadcast(intent);
                } else {
                    // Can't find this subscription...  We must be out of date.
                    updateMobileControllers();
                }
            } else {
                // No sub id, must be for the wifi.
                mWifiSignalController.handleBroadcast(intent);
            }
        }
    
public voidonUserSwitched(int newUserId)

        mCurrentUserId = newUserId;
        mAccessPoints.onUserSwitched(newUserId);
        updateConnectivity();
        refreshCarrierLabel();
    
private voidpushConnectivityToSignals()
Pushes the current connectivity state to all SignalControllers.

        // We want to update all the icons, all at once, for any condition change
        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.setInetCondition(
                    mInetCondition ? 1 : 0,
                    mValidatedTransports.get(mobileSignalController.getTransportType()) ? 1 : 0);
        }
        mWifiSignalController.setInetCondition(
                mValidatedTransports.get(mWifiSignalController.getTransportType()) ? 1 : 0);
    
voidrecalculateEmergency()
Emergency status may have changed (triggered by MobileSignalController), so we should recheck and send out the state to listeners.

        final boolean emergencyOnly = isEmergencyOnly();
        final int length = mEmergencyListeners.size();
        for (int i = 0; i < length; i++) {
            mEmergencyListeners.get(i).setEmergencyCallsOnly(emergencyOnly);
        }
        // If the emergency has a chance to change, then so does the carrier
        // label.
        refreshCarrierLabel();
    
voidrefreshCarrierLabel()
Recalculate and update the carrier label.

        Context context = mContext;

        WifiSignalController.WifiState wifiState = mWifiSignalController.getState();
        String label = "";
        for (MobileSignalController controller : mMobileSignalControllers.values()) {
            label = controller.getLabel(label, mConnected, mHasMobileDataFeature);
        }

        // TODO Simplify this ugliness, some of the flows below shouldn't be possible anymore
        // but stay for the sake of history.
        if (mBluetoothTethered && !mHasMobileDataFeature) {
            label = mContext.getString(R.string.bluetooth_tethered);
        }

        if (mEthernetConnected && !mHasMobileDataFeature) {
            label = context.getString(R.string.ethernet_label);
        }

        if (mAirplaneMode && !isEmergencyOnly()) {
            // combined values from connected wifi take precedence over airplane mode
            if (wifiState.connected && mHasMobileDataFeature) {
                // Suppress "No internet connection." from mobile if wifi connected.
                label = "";
            } else {
                 if (!mHasMobileDataFeature) {
                      label = context.getString(
                              R.string.status_bar_settings_signal_meter_disconnected);
                 }
            }
        } else if (!isMobileDataConnected() && !wifiState.connected && !mBluetoothTethered &&
                 !mEthernetConnected && !mHasMobileDataFeature) {
            // Pretty much no connection.
            label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
        }

        // for mobile devices, we always show mobile connection info here (SPN/PLMN)
        // for other devices, we show whatever network is connected
        // This is determined above by references to mHasMobileDataFeature.
        int length = mCarrierListeners.size();
        for (int i = 0; i < length; i++) {
            mCarrierListeners.get(i).setCarrierLabel(label);
        }
    
private voidrefreshLocale()

        Locale current = mContext.getResources().getConfiguration().locale;
        if (!current.equals(mLocale)) {
            mLocale = current;
            notifyAllListeners();
        }
    
private voidregisterListeners()

        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.registerListener();
        }
        mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);

        // broadcasts
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
        filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
        filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
        filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
        filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        mContext.registerReceiver(this, filter);
        mListening = true;

        updateMobileControllers();
    
public voidremoveNetworkSignalChangedCallback(NetworkSignalChangedCallback cb)

        mSignalsChangedCallbacks.remove(cb);
    
voidsetCurrentSubscriptions(java.util.List subscriptions)

        Collections.sort(subscriptions, new Comparator<SubscriptionInfo>() {
            @Override
            public int compare(SubscriptionInfo lhs, SubscriptionInfo rhs) {
                return lhs.getSimSlotIndex() == rhs.getSimSlotIndex()
                        ? lhs.getSubscriptionId() - rhs.getSubscriptionId()
                        : lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
            }
        });
        final int length = mSignalClusters.size();
        for (int i = 0; i < length; i++) {
            mSignalClusters.get(i).setSubs(subscriptions);
        }
        mCurrentSubscriptions = subscriptions;

        HashMap<Integer, MobileSignalController> cachedControllers =
                new HashMap<Integer, MobileSignalController>(mMobileSignalControllers);
        mMobileSignalControllers.clear();
        final int num = subscriptions.size();
        for (int i = 0; i < num; i++) {
            int subId = subscriptions.get(i).getSubscriptionId();
            // If we have a copy of this controller already reuse it, otherwise make a new one.
            if (cachedControllers.containsKey(subId)) {
                mMobileSignalControllers.put(subId, cachedControllers.remove(subId));
            } else {
                MobileSignalController controller = new MobileSignalController(mContext, mConfig,
                        mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks, mSignalClusters,
                        this, subscriptions.get(i));
                mMobileSignalControllers.put(subId, controller);
                if (subscriptions.get(i).getSimSlotIndex() == 0) {
                    mDefaultSignalController = controller;
                }
                if (mListening) {
                    controller.registerListener();
                }
            }
        }
        if (mListening) {
            for (Integer key : cachedControllers.keySet()) {
                if (cachedControllers.get(key) == mDefaultSignalController) {
                    mDefaultSignalController = null;
                }
                cachedControllers.get(key).unregisterListener();
            }
        }
        // There may be new MobileSignalControllers around, make sure they get the current
        // inet condition and airplane mode.
        pushConnectivityToSignals();
        updateAirplaneMode(true /* force */);
    
public voidsetWifiEnabled(boolean enabled)

        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... args) {
                // Disable tethering if enabling Wifi
                final int wifiApState = mWifiManager.getWifiApState();
                if (enabled && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
                        (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
                    mWifiManager.setWifiApEnabled(null, false);
                }

                mWifiManager.setWifiEnabled(enabled);
                return null;
            }
        }.execute();
    
private voidunregisterListeners()

        mListening = false;
        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
            mobileSignalController.unregisterListener();
        }
        mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
        mContext.unregisterReceiver(this);
    
private voidupdateAirplaneMode(boolean force)

        boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
        if (airplaneMode != mAirplaneMode || force) {
            mAirplaneMode = airplaneMode;
            for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
                mobileSignalController.setAirplaneMode(mAirplaneMode);
            }
            notifyListeners();
            refreshCarrierLabel();
        }
    
private voidupdateConnectivity()
Update the Inet conditions and what network we are connected to.

        mConnectedTransports.clear();
        mValidatedTransports.clear();
        for (NetworkCapabilities nc :
                mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) {
            for (int transportType : nc.getTransportTypes()) {
                mConnectedTransports.set(transportType);
                if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
                    mValidatedTransports.set(transportType);
                }
            }
        }

        if (CHATTY) {
            Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports);
            Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports);
        }

        mConnected = !mConnectedTransports.isEmpty();
        mInetCondition = !mValidatedTransports.isEmpty();
        mBluetoothTethered = mConnectedTransports.get(TRANSPORT_BLUETOOTH);
        mEthernetConnected = mConnectedTransports.get(TRANSPORT_ETHERNET);

        pushConnectivityToSignals();
    
private voidupdateMobileControllers()

        if (!mListening) {
            return;
        }
        List<SubscriptionInfo> subscriptions = mSubscriptionManager.getActiveSubscriptionInfoList();
        if (subscriptions == null) {
            subscriptions = Collections.emptyList();
        }
        // If there have been no relevant changes to any of the subscriptions, we can leave as is.
        if (hasCorrectMobileControllers(subscriptions)) {
            // Even if the controllers are correct, make sure we have the right no sims state.
            // Such as on boot, don't need any controllers, because there are no sims,
            // but we still need to update the no sim state.
            updateNoSims();
            return;
        }
        setCurrentSubscriptions(subscriptions);
        updateNoSims();
    
protected voidupdateNoSims()

        boolean hasNoSims = mHasMobileDataFeature && mMobileSignalControllers.size() == 0;
        if (hasNoSims != mHasNoSims) {
            mHasNoSims = hasNoSims;
            notifyListeners();
        }