Home | History | Annotate | Download | only in policy
      1 /*
      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 
     17 package com.android.systemui.statusbar.policy;
     18 
     19 import android.content.BroadcastReceiver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentFilter;
     23 import android.content.res.Resources;
     24 import android.net.ConnectivityManager;
     25 import android.net.NetworkInfo;
     26 import android.net.wifi.WifiConfiguration;
     27 import android.net.wifi.WifiInfo;
     28 import android.net.wifi.WifiManager;
     29 import android.net.wimax.WimaxManagerConstants;
     30 import android.os.AsyncTask;
     31 import android.os.Bundle;
     32 import android.os.Handler;
     33 import android.os.Message;
     34 import android.os.Messenger;
     35 import android.provider.Settings;
     36 import android.telephony.PhoneStateListener;
     37 import android.telephony.ServiceState;
     38 import android.telephony.SignalStrength;
     39 import android.telephony.TelephonyManager;
     40 import android.util.Log;
     41 import android.view.View;
     42 import android.widget.TextView;
     43 
     44 import com.android.internal.telephony.IccCardConstants;
     45 import com.android.internal.telephony.TelephonyIntents;
     46 import com.android.internal.telephony.cdma.EriInfo;
     47 import com.android.internal.util.AsyncChannel;
     48 import com.android.systemui.DemoMode;
     49 import com.android.systemui.R;
     50 import com.android.systemui.statusbar.phone.StatusBarHeaderView;
     51 
     52 import java.io.FileDescriptor;
     53 import java.io.PrintWriter;
     54 import java.util.ArrayList;
     55 import java.util.List;
     56 import java.util.Locale;
     57 
     58 /** Platform implementation of the network controller. **/
     59 public class NetworkControllerImpl extends BroadcastReceiver
     60         implements NetworkController, DemoMode {
     61     // debug
     62     static final String TAG = "StatusBar.NetworkController";
     63     static final boolean DEBUG = false;
     64     static final boolean CHATTY = false; // additional diagnostics, but not logspew
     65 
     66     // telephony
     67     boolean mHspaDataDistinguishable;
     68     final TelephonyManager mPhone;
     69     boolean mDataConnected;
     70     IccCardConstants.State mSimState = IccCardConstants.State.READY;
     71     int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
     72     int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     73     int mDataState = TelephonyManager.DATA_DISCONNECTED;
     74     int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
     75     ServiceState mServiceState;
     76     SignalStrength mSignalStrength;
     77     int[] mDataIconList = TelephonyIcons.DATA_G[0];
     78     String mNetworkName;
     79     String mNetworkNameDefault;
     80     String mNetworkNameSeparator;
     81     int mPhoneSignalIconId;
     82     int mQSPhoneSignalIconId;
     83     int mDataDirectionIconId; // data + data direction on phones
     84     int mDataSignalIconId;
     85     int mDataTypeIconId;
     86     int mQSDataTypeIconId;
     87     int mAirplaneIconId;
     88     boolean mDataActive;
     89     boolean mNoSim;
     90     int mLastSignalLevel;
     91     boolean mShowPhoneRSSIForData = false;
     92     boolean mShowAtLeastThreeGees = false;
     93     boolean mAlwaysShowCdmaRssi = false;
     94 
     95     String mContentDescriptionPhoneSignal;
     96     String mContentDescriptionWifi;
     97     String mContentDescriptionWimax;
     98     String mContentDescriptionCombinedSignal;
     99     String mContentDescriptionDataType;
    100 
    101     // wifi
    102     final WifiManager mWifiManager;
    103     AsyncChannel mWifiChannel;
    104     boolean mWifiEnabled, mWifiConnected;
    105     int mWifiRssi, mWifiLevel;
    106     String mWifiSsid;
    107     int mWifiIconId = 0;
    108     int mQSWifiIconId = 0;
    109     int mWifiActivity = WifiManager.DATA_ACTIVITY_NONE;
    110 
    111     // bluetooth
    112     private boolean mBluetoothTethered = false;
    113     private int mBluetoothTetherIconId =
    114         com.android.internal.R.drawable.stat_sys_tether_bluetooth;
    115 
    116     //wimax
    117     private boolean mWimaxSupported = false;
    118     private boolean mIsWimaxEnabled = false;
    119     private boolean mWimaxConnected = false;
    120     private boolean mWimaxIdle = false;
    121     private int mWimaxIconId = 0;
    122     private int mWimaxSignal = 0;
    123     private int mWimaxState = 0;
    124     private int mWimaxExtraState = 0;
    125 
    126     // data connectivity (regardless of state, can we access the internet?)
    127     // state of inet connection - 0 not connected, 100 connected
    128     private boolean mConnected = false;
    129     private int mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
    130     private String mConnectedNetworkTypeName;
    131     private int mLastConnectedNetworkType = ConnectivityManager.TYPE_NONE;
    132 
    133     private int mInetCondition = 0;
    134     private int mLastInetCondition = 0;
    135     private static final int INET_CONDITION_THRESHOLD = 50;
    136 
    137     private boolean mAirplaneMode = false;
    138     private boolean mLastAirplaneMode = true;
    139 
    140     private Locale mLocale = null;
    141     private Locale mLastLocale = null;
    142 
    143     // our ui
    144     Context mContext;
    145     ArrayList<TextView> mCombinedLabelViews = new ArrayList<TextView>();
    146     ArrayList<TextView> mMobileLabelViews = new ArrayList<TextView>();
    147     ArrayList<TextView> mWifiLabelViews = new ArrayList<TextView>();
    148     ArrayList<StatusBarHeaderView> mEmergencyViews = new ArrayList<>();
    149     ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
    150     ArrayList<NetworkSignalChangedCallback> mSignalsChangedCallbacks =
    151             new ArrayList<NetworkSignalChangedCallback>();
    152     int mLastPhoneSignalIconId = -1;
    153     int mLastDataDirectionIconId = -1;
    154     int mLastWifiIconId = -1;
    155     int mLastWimaxIconId = -1;
    156     int mLastCombinedSignalIconId = -1;
    157     int mLastDataTypeIconId = -1;
    158     String mLastCombinedLabel = "";
    159 
    160     private boolean mHasMobileDataFeature;
    161 
    162     boolean mDataAndWifiStacked = false;
    163 
    164     public interface SignalCluster {
    165         void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription);
    166         void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon,
    167                 String contentDescription, String typeContentDescription, boolean roaming,
    168                 boolean isTypeIconWide);
    169         void setIsAirplaneMode(boolean is, int airplaneIcon);
    170     }
    171 
    172     private final WifiAccessPointController mAccessPoints;
    173     private final MobileDataController mMobileDataController;
    174 
    175     /**
    176      * Construct this controller object and register for updates.
    177      */
    178     public NetworkControllerImpl(Context context) {
    179         mContext = context;
    180         final Resources res = context.getResources();
    181 
    182         ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
    183                 Context.CONNECTIVITY_SERVICE);
    184         mHasMobileDataFeature = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
    185 
    186         mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData);
    187         mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
    188         mAlwaysShowCdmaRssi = res.getBoolean(
    189                 com.android.internal.R.bool.config_alwaysUseCdmaRssi);
    190 
    191         // set up the default wifi icon, used when no radios have ever appeared
    192         updateWifiIcons();
    193         updateWimaxIcons();
    194 
    195         // telephony
    196         mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    197         mPhone.listen(mPhoneStateListener,
    198                           PhoneStateListener.LISTEN_SERVICE_STATE
    199                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
    200                         | PhoneStateListener.LISTEN_CALL_STATE
    201                         | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
    202                         | PhoneStateListener.LISTEN_DATA_ACTIVITY);
    203         mHspaDataDistinguishable = mContext.getResources().getBoolean(
    204                 R.bool.config_hspa_data_distinguishable);
    205         mNetworkNameSeparator = mContext.getString(R.string.status_bar_network_name_separator);
    206         mNetworkNameDefault = mContext.getString(
    207                 com.android.internal.R.string.lockscreen_carrier_default);
    208         mNetworkName = mNetworkNameDefault;
    209 
    210         // wifi
    211         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    212         Handler handler = new WifiHandler();
    213         mWifiChannel = new AsyncChannel();
    214         Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
    215         if (wifiMessenger != null) {
    216             mWifiChannel.connect(mContext, handler, wifiMessenger);
    217         }
    218 
    219         // broadcasts
    220         IntentFilter filter = new IntentFilter();
    221         filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
    222         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    223         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    224         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
    225         filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
    226         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
    227         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
    228         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
    229         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    230         mWimaxSupported = mContext.getResources().getBoolean(
    231                 com.android.internal.R.bool.config_wimaxEnabled);
    232         if(mWimaxSupported) {
    233             filter.addAction(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION);
    234             filter.addAction(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION);
    235             filter.addAction(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION);
    236         }
    237         context.registerReceiver(this, filter);
    238 
    239         // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
    240         updateAirplaneMode();
    241 
    242         mLastLocale = mContext.getResources().getConfiguration().locale;
    243         mAccessPoints = new WifiAccessPointController(mContext);
    244         mMobileDataController = new MobileDataController(mContext);
    245         mMobileDataController.setCallback(new MobileDataController.Callback() {
    246             @Override
    247             public void onMobileDataEnabled(boolean enabled) {
    248                 notifyMobileDataEnabled(enabled);
    249             }
    250         });
    251     }
    252 
    253     private void notifyMobileDataEnabled(boolean enabled) {
    254         for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
    255             cb.onMobileDataEnabled(enabled);
    256         }
    257     }
    258 
    259     public boolean hasMobileDataFeature() {
    260         return mHasMobileDataFeature;
    261     }
    262 
    263     public boolean hasVoiceCallingFeature() {
    264         return mPhone.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE;
    265     }
    266 
    267     public boolean isEmergencyOnly() {
    268         return (mServiceState != null && mServiceState.isEmergencyOnly());
    269     }
    270 
    271     public void addCombinedLabelView(TextView v) {
    272         mCombinedLabelViews.add(v);
    273     }
    274 
    275     public void addMobileLabelView(TextView v) {
    276         mMobileLabelViews.add(v);
    277     }
    278 
    279     public void addWifiLabelView(TextView v) {
    280         mWifiLabelViews.add(v);
    281     }
    282 
    283     public void addEmergencyLabelView(StatusBarHeaderView v) {
    284         mEmergencyViews.add(v);
    285     }
    286 
    287     public void addSignalCluster(SignalCluster cluster) {
    288         mSignalClusters.add(cluster);
    289         refreshSignalCluster(cluster);
    290     }
    291 
    292     public void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
    293         mSignalsChangedCallbacks.add(cb);
    294         notifySignalsChangedCallbacks(cb);
    295     }
    296 
    297     public void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
    298         mSignalsChangedCallbacks.remove(cb);
    299     }
    300 
    301     @Override
    302     public void addAccessPointCallback(AccessPointCallback callback) {
    303         mAccessPoints.addCallback(callback);
    304     }
    305 
    306     @Override
    307     public void removeAccessPointCallback(AccessPointCallback callback) {
    308         mAccessPoints.removeCallback(callback);
    309     }
    310 
    311     @Override
    312     public void scanForAccessPoints() {
    313         mAccessPoints.scan();
    314     }
    315 
    316     @Override
    317     public void connect(AccessPoint ap) {
    318         mAccessPoints.connect(ap);
    319     }
    320 
    321     @Override
    322     public void setWifiEnabled(final boolean enabled) {
    323         new AsyncTask<Void, Void, Void>() {
    324             @Override
    325             protected Void doInBackground(Void... args) {
    326                 // Disable tethering if enabling Wifi
    327                 final int wifiApState = mWifiManager.getWifiApState();
    328                 if (enabled && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
    329                                (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
    330                     mWifiManager.setWifiApEnabled(null, false);
    331                 }
    332 
    333                 mWifiManager.setWifiEnabled(enabled);
    334                 return null;
    335             }
    336         }.execute();
    337     }
    338 
    339     @Override
    340     public DataUsageInfo getDataUsageInfo() {
    341         final DataUsageInfo info =  mMobileDataController.getDataUsageInfo();
    342         if (info != null) {
    343             info.carrier = mNetworkName;
    344         }
    345         return info;
    346     }
    347 
    348     @Override
    349     public boolean isMobileDataSupported() {
    350         return mMobileDataController.isMobileDataSupported();
    351     }
    352 
    353     @Override
    354     public boolean isMobileDataEnabled() {
    355         return mMobileDataController.isMobileDataEnabled();
    356     }
    357 
    358     @Override
    359     public void setMobileDataEnabled(boolean enabled) {
    360         mMobileDataController.setMobileDataEnabled(enabled);
    361     }
    362 
    363     private boolean isTypeIconWide(int iconId) {
    364         return TelephonyIcons.ICON_LTE == iconId || TelephonyIcons.ICON_1X == iconId
    365                 || TelephonyIcons.ICON_3G == iconId || TelephonyIcons.ICON_4G == iconId;
    366     }
    367 
    368     private boolean isQsTypeIconWide(int iconId) {
    369         return TelephonyIcons.QS_ICON_LTE == iconId || TelephonyIcons.QS_ICON_1X == iconId
    370                 || TelephonyIcons.QS_ICON_3G == iconId || TelephonyIcons.QS_ICON_4G == iconId;
    371     }
    372 
    373     public void refreshSignalCluster(SignalCluster cluster) {
    374         if (mDemoMode) return;
    375         cluster.setWifiIndicators(
    376                 // only show wifi in the cluster if connected or if wifi-only
    377                 mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature),
    378                 mWifiIconId,
    379                 mContentDescriptionWifi);
    380 
    381         if (mIsWimaxEnabled && mWimaxConnected) {
    382             // wimax is special
    383             cluster.setMobileDataIndicators(
    384                     true,
    385                     mAlwaysShowCdmaRssi ? mPhoneSignalIconId : mWimaxIconId,
    386                     mDataTypeIconId,
    387                     mContentDescriptionWimax,
    388                     mContentDescriptionDataType,
    389                     mDataTypeIconId == TelephonyIcons.ROAMING_ICON,
    390                     false /* isTypeIconWide */ );
    391         } else {
    392             // normal mobile data
    393             cluster.setMobileDataIndicators(
    394                     mHasMobileDataFeature,
    395                     mShowPhoneRSSIForData ? mPhoneSignalIconId : mDataSignalIconId,
    396                     mDataTypeIconId,
    397                     mContentDescriptionPhoneSignal,
    398                     mContentDescriptionDataType,
    399                     mDataTypeIconId == TelephonyIcons.ROAMING_ICON,
    400                     isTypeIconWide(mDataTypeIconId));
    401         }
    402         cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId);
    403     }
    404 
    405     void notifySignalsChangedCallbacks(NetworkSignalChangedCallback cb) {
    406         // only show wifi in the cluster if connected or if wifi-only
    407         boolean wifiEnabled = mWifiEnabled && (mWifiConnected || !mHasMobileDataFeature);
    408         String wifiDesc = wifiEnabled ?
    409                 mWifiSsid : null;
    410         boolean wifiIn = wifiEnabled && mWifiSsid != null
    411                 && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
    412                 || mWifiActivity == WifiManager.DATA_ACTIVITY_IN);
    413         boolean wifiOut = wifiEnabled && mWifiSsid != null
    414                 && (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
    415                 || mWifiActivity == WifiManager.DATA_ACTIVITY_OUT);
    416         cb.onWifiSignalChanged(mWifiEnabled, mWifiConnected, mQSWifiIconId, wifiIn, wifiOut,
    417                 mContentDescriptionWifi, wifiDesc);
    418 
    419         boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
    420                 || mDataActivity == TelephonyManager.DATA_ACTIVITY_IN);
    421         boolean mobileOut = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
    422                 || mDataActivity == TelephonyManager.DATA_ACTIVITY_OUT);
    423         if (isEmergencyOnly()) {
    424             cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId,
    425                     mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
    426                     mContentDescriptionDataType, null, mNoSim, isQsTypeIconWide(mQSDataTypeIconId));
    427         } else {
    428             if (mIsWimaxEnabled && mWimaxConnected) {
    429                 // Wimax is special
    430                 cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId,
    431                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
    432                         mContentDescriptionDataType, mNetworkName, mNoSim,
    433                         isQsTypeIconWide(mQSDataTypeIconId));
    434             } else {
    435                 // Normal mobile data
    436                 cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId,
    437                         mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut,
    438                         mContentDescriptionDataType, mNetworkName, mNoSim,
    439                         isQsTypeIconWide(mQSDataTypeIconId));
    440             }
    441         }
    442         cb.onAirplaneModeChanged(mAirplaneMode);
    443     }
    444 
    445     public void setStackedMode(boolean stacked) {
    446         mDataAndWifiStacked = true;
    447     }
    448 
    449     @Override
    450     public void onReceive(Context context, Intent intent) {
    451         final String action = intent.getAction();
    452         if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
    453                 || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
    454                 || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    455             updateWifiState(intent);
    456             refreshViews();
    457         } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
    458             updateSimState(intent);
    459             updateDataIcon();
    460             refreshViews();
    461         } else if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
    462             updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
    463                         intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
    464                         intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
    465                         intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
    466             refreshViews();
    467         } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE) ||
    468                  action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
    469             updateConnectivity(intent);
    470             refreshViews();
    471         } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
    472             refreshLocale();
    473             refreshViews();
    474         } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
    475             refreshLocale();
    476             updateAirplaneMode();
    477             refreshViews();
    478         } else if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION) ||
    479                 action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION) ||
    480                 action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
    481             updateWimaxState(intent);
    482             refreshViews();
    483         }
    484     }
    485 
    486 
    487     // ===== Telephony ==============================================================
    488 
    489     PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    490         @Override
    491         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    492             if (DEBUG) {
    493                 Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
    494                     ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
    495             }
    496             mSignalStrength = signalStrength;
    497             updateTelephonySignalStrength();
    498             refreshViews();
    499         }
    500 
    501         @Override
    502         public void onServiceStateChanged(ServiceState state) {
    503             if (DEBUG) {
    504                 Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
    505                         + " dataState=" + state.getDataRegState());
    506             }
    507             mServiceState = state;
    508             updateTelephonySignalStrength();
    509             updateDataNetType();
    510             updateDataIcon();
    511             refreshViews();
    512         }
    513 
    514         @Override
    515         public void onCallStateChanged(int state, String incomingNumber) {
    516             if (DEBUG) {
    517                 Log.d(TAG, "onCallStateChanged state=" + state);
    518             }
    519             // In cdma, if a voice call is made, RSSI should switch to 1x.
    520             if (isCdma()) {
    521                 updateTelephonySignalStrength();
    522                 refreshViews();
    523             }
    524         }
    525 
    526         @Override
    527         public void onDataConnectionStateChanged(int state, int networkType) {
    528             if (DEBUG) {
    529                 Log.d(TAG, "onDataConnectionStateChanged: state=" + state
    530                         + " type=" + networkType);
    531             }
    532             mDataState = state;
    533             mDataNetType = networkType;
    534             updateDataNetType();
    535             updateDataIcon();
    536             refreshViews();
    537         }
    538 
    539         @Override
    540         public void onDataActivity(int direction) {
    541             if (DEBUG) {
    542                 Log.d(TAG, "onDataActivity: direction=" + direction);
    543             }
    544             mDataActivity = direction;
    545             updateDataIcon();
    546             refreshViews();
    547         }
    548     };
    549 
    550     private final void updateSimState(Intent intent) {
    551         String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
    552         if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
    553             mSimState = IccCardConstants.State.ABSENT;
    554         }
    555         else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
    556             mSimState = IccCardConstants.State.READY;
    557         }
    558         else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
    559             final String lockedReason =
    560                     intent.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
    561             if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
    562                 mSimState = IccCardConstants.State.PIN_REQUIRED;
    563             }
    564             else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
    565                 mSimState = IccCardConstants.State.PUK_REQUIRED;
    566             }
    567             else {
    568                 mSimState = IccCardConstants.State.NETWORK_LOCKED;
    569             }
    570         } else {
    571             mSimState = IccCardConstants.State.UNKNOWN;
    572         }
    573         if (DEBUG) Log.d(TAG, "updateSimState: mSimState=" + mSimState);
    574     }
    575 
    576     private boolean isCdma() {
    577         return (mSignalStrength != null) && !mSignalStrength.isGsm();
    578     }
    579 
    580     private boolean hasService() {
    581         boolean retVal;
    582         if (mServiceState != null) {
    583             // Consider the device to be in service if either voice or data service is available.
    584             // Some SIM cards are marketed as data-only and do not support voice service, and on
    585             // these SIM cards, we want to show signal bars for data service as well as the "no
    586             // service" or "emergency calls only" text that indicates that voice is not available.
    587             switch(mServiceState.getVoiceRegState()) {
    588                 case ServiceState.STATE_POWER_OFF:
    589                     retVal = false;
    590                     break;
    591                 case ServiceState.STATE_OUT_OF_SERVICE:
    592                 case ServiceState.STATE_EMERGENCY_ONLY:
    593                     retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
    594                     break;
    595                 default:
    596                     retVal = true;
    597             }
    598         } else {
    599             retVal = false;
    600         }
    601         if (DEBUG) Log.d(TAG, "hasService: mServiceState=" + mServiceState + " retVal=" + retVal);
    602         return retVal;
    603     }
    604 
    605     private void updateAirplaneMode() {
    606         mAirplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
    607             Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
    608     }
    609 
    610     private void refreshLocale() {
    611         mLocale = mContext.getResources().getConfiguration().locale;
    612     }
    613 
    614     private final void updateTelephonySignalStrength() {
    615         if (DEBUG) {
    616             Log.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService()
    617                     + " ss=" + mSignalStrength);
    618         }
    619         if (!hasService()) {
    620             if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
    621             mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
    622             mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
    623             mDataSignalIconId = R.drawable.stat_sys_signal_null;
    624             mContentDescriptionPhoneSignal = mContext.getString(
    625                     AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
    626         } else {
    627             if (mSignalStrength == null) {
    628                 if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
    629                 mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
    630                 mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
    631                 mDataSignalIconId = R.drawable.stat_sys_signal_null;
    632                 mContentDescriptionPhoneSignal = mContext.getString(
    633                         AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
    634             } else {
    635                 int iconLevel;
    636                 int[] iconList;
    637                 if (isCdma() && mAlwaysShowCdmaRssi) {
    638                     mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel();
    639                     if (DEBUG) {
    640                         Log.d(TAG, "updateTelephonySignalStrength:"
    641                             + " mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
    642                             + " set to cdmaLevel=" + mSignalStrength.getCdmaLevel()
    643                             + " instead of level=" + mSignalStrength.getLevel());
    644                     }
    645                 } else {
    646                     mLastSignalLevel = iconLevel = mSignalStrength.getLevel();
    647                 }
    648 
    649                 if (isRoaming()) {
    650                     iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
    651                 } else {
    652                     iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
    653                 }
    654                 mPhoneSignalIconId = iconList[iconLevel];
    655                 mQSPhoneSignalIconId =
    656                         TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mInetCondition][iconLevel];
    657                 mContentDescriptionPhoneSignal = mContext.getString(
    658                         AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]);
    659                 mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
    660                 if (DEBUG) Log.d(TAG, "updateTelephonySignalStrength: iconLevel=" + iconLevel);
    661             }
    662         }
    663     }
    664 
    665     private int inetConditionForNetwork(int networkType) {
    666         return (mInetCondition == 1 && mConnectedNetworkType == networkType) ? 1 : 0;
    667     }
    668 
    669     private final void updateDataNetType() {
    670         int inetCondition;
    671         mDataTypeIconId = mQSDataTypeIconId = 0;
    672         if (mIsWimaxEnabled && mWimaxConnected) {
    673             // wimax is a special 4g network not handled by telephony
    674             inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIMAX);
    675             mDataIconList = TelephonyIcons.DATA_4G[inetCondition];
    676             mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_4g;
    677             mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[inetCondition];
    678             mContentDescriptionDataType = mContext.getString(
    679                     R.string.accessibility_data_connection_4g);
    680         } else {
    681             inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_MOBILE);
    682             final boolean showDataTypeIcon = (inetCondition > 0);
    683             switch (mDataNetType) {
    684                 case TelephonyManager.NETWORK_TYPE_UNKNOWN:
    685                     if (!mShowAtLeastThreeGees) {
    686                         mDataIconList = TelephonyIcons.DATA_G[inetCondition];
    687                         mContentDescriptionDataType = "";
    688                         break;
    689                     } else {
    690                         // fall through
    691                     }
    692                 case TelephonyManager.NETWORK_TYPE_EDGE:
    693                     if (!mShowAtLeastThreeGees) {
    694                         mDataIconList = TelephonyIcons.DATA_E[inetCondition];
    695                         mDataTypeIconId = showDataTypeIcon ?
    696                                 R.drawable.stat_sys_data_fully_connected_e : 0;
    697                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_E[inetCondition];
    698                         mContentDescriptionDataType = mContext.getString(
    699                                 R.string.accessibility_data_connection_edge);
    700                         break;
    701                     } else {
    702                         // fall through
    703                     }
    704                 case TelephonyManager.NETWORK_TYPE_UMTS:
    705                     mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
    706                     mDataTypeIconId = showDataTypeIcon ?
    707                                 R.drawable.stat_sys_data_fully_connected_3g : 0;
    708                     mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
    709                     mContentDescriptionDataType = mContext.getString(
    710                             R.string.accessibility_data_connection_3g);
    711                     break;
    712                 case TelephonyManager.NETWORK_TYPE_HSDPA:
    713                 case TelephonyManager.NETWORK_TYPE_HSUPA:
    714                 case TelephonyManager.NETWORK_TYPE_HSPA:
    715                 case TelephonyManager.NETWORK_TYPE_HSPAP:
    716                     if (mHspaDataDistinguishable) {
    717                         mDataIconList = TelephonyIcons.DATA_H[inetCondition];
    718                         mDataTypeIconId = showDataTypeIcon ?
    719                                 R.drawable.stat_sys_data_fully_connected_h : 0;
    720                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_H[inetCondition];
    721                         mContentDescriptionDataType = mContext.getString(
    722                                 R.string.accessibility_data_connection_3_5g);
    723                     } else {
    724                         mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
    725                         mDataTypeIconId = showDataTypeIcon ?
    726                                 R.drawable.stat_sys_data_fully_connected_3g : 0;
    727                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
    728                         mContentDescriptionDataType = mContext.getString(
    729                                 R.string.accessibility_data_connection_3g);
    730                     }
    731                     break;
    732                 case TelephonyManager.NETWORK_TYPE_CDMA:
    733                     if (!mShowAtLeastThreeGees) {
    734                         // display 1xRTT for IS95A/B
    735                         mDataIconList = TelephonyIcons.DATA_1X[inetCondition];
    736                         mDataTypeIconId = showDataTypeIcon ?
    737                                 R.drawable.stat_sys_data_fully_connected_1x : 0;
    738                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[inetCondition];
    739                         mContentDescriptionDataType = mContext.getString(
    740                                 R.string.accessibility_data_connection_cdma);
    741                         break;
    742                     } else {
    743                         // fall through
    744                     }
    745                 case TelephonyManager.NETWORK_TYPE_1xRTT:
    746                     if (!mShowAtLeastThreeGees) {
    747                         mDataIconList = TelephonyIcons.DATA_1X[inetCondition];
    748                         mDataTypeIconId = showDataTypeIcon ?
    749                                 R.drawable.stat_sys_data_fully_connected_1x : 0;
    750                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[inetCondition];
    751                         mContentDescriptionDataType = mContext.getString(
    752                                 R.string.accessibility_data_connection_cdma);
    753                         break;
    754                     } else {
    755                         // fall through
    756                     }
    757                 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
    758                 case TelephonyManager.NETWORK_TYPE_EVDO_A:
    759                 case TelephonyManager.NETWORK_TYPE_EVDO_B:
    760                 case TelephonyManager.NETWORK_TYPE_EHRPD:
    761                     mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
    762                     mDataTypeIconId = showDataTypeIcon ?
    763                                 R.drawable.stat_sys_data_fully_connected_3g : 0;
    764                     mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
    765                     mContentDescriptionDataType = mContext.getString(
    766                             R.string.accessibility_data_connection_3g);
    767                     break;
    768                 case TelephonyManager.NETWORK_TYPE_LTE:
    769                     boolean show4GforLTE = mContext.getResources().getBoolean(R.bool.config_show4GForLTE);
    770                     if (show4GforLTE) {
    771                         mDataIconList = TelephonyIcons.DATA_4G[inetCondition];
    772                         mDataTypeIconId = showDataTypeIcon ?
    773                                 R.drawable.stat_sys_data_fully_connected_4g : 0;
    774                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[inetCondition];
    775                         mContentDescriptionDataType = mContext.getString(
    776                                 R.string.accessibility_data_connection_4g);
    777                     } else {
    778                         mDataIconList = TelephonyIcons.DATA_LTE[inetCondition];
    779                         mDataTypeIconId = showDataTypeIcon ? TelephonyIcons.ICON_LTE : 0;
    780                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_LTE[inetCondition];
    781                         mContentDescriptionDataType = mContext.getString(
    782                                 R.string.accessibility_data_connection_lte);
    783                     }
    784                     break;
    785                 default:
    786                     if (!mShowAtLeastThreeGees) {
    787                         mDataIconList = TelephonyIcons.DATA_G[inetCondition];
    788                         mDataTypeIconId = showDataTypeIcon ?
    789                                 R.drawable.stat_sys_data_fully_connected_g : 0;
    790                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_G[inetCondition];
    791                         mContentDescriptionDataType = mContext.getString(
    792                                 R.string.accessibility_data_connection_gprs);
    793                     } else {
    794                         mDataIconList = TelephonyIcons.DATA_3G[inetCondition];
    795                         mDataTypeIconId = showDataTypeIcon ?
    796                                 R.drawable.stat_sys_data_fully_connected_3g : 0;
    797                         mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[inetCondition];
    798                         mContentDescriptionDataType = mContext.getString(
    799                                 R.string.accessibility_data_connection_3g);
    800                     }
    801                     break;
    802             }
    803         }
    804 
    805         if (isRoaming()) {
    806             mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
    807             mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
    808         }
    809     }
    810 
    811     boolean isCdmaEri() {
    812         if (mServiceState != null) {
    813             final int iconIndex = mServiceState.getCdmaEriIconIndex();
    814             if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) {
    815                 final int iconMode = mServiceState.getCdmaEriIconMode();
    816                 if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
    817                         || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) {
    818                     return true;
    819                 }
    820             }
    821         }
    822         return false;
    823     }
    824 
    825     private boolean isRoaming() {
    826         if (isCdma()) {
    827             return isCdmaEri();
    828         } else {
    829             return mServiceState != null && mServiceState.getRoaming();
    830         }
    831     }
    832 
    833     private final void updateDataIcon() {
    834         int iconId;
    835         boolean visible = true;
    836 
    837         if (!isCdma()) {
    838             // GSM case, we have to check also the sim state
    839             if (mSimState == IccCardConstants.State.READY ||
    840                     mSimState == IccCardConstants.State.UNKNOWN) {
    841                 mNoSim = false;
    842                 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
    843                     switch (mDataActivity) {
    844                         case TelephonyManager.DATA_ACTIVITY_IN:
    845                             iconId = mDataIconList[1];
    846                             break;
    847                         case TelephonyManager.DATA_ACTIVITY_OUT:
    848                             iconId = mDataIconList[2];
    849                             break;
    850                         case TelephonyManager.DATA_ACTIVITY_INOUT:
    851                             iconId = mDataIconList[3];
    852                             break;
    853                         default:
    854                             iconId = mDataIconList[0];
    855                             break;
    856                     }
    857                     mDataDirectionIconId = iconId;
    858                 } else {
    859                     iconId = 0;
    860                     visible = false;
    861                 }
    862             } else {
    863                 iconId = 0;
    864                 mNoSim = true;
    865                 visible = false; // no SIM? no data
    866             }
    867         } else {
    868             // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
    869             if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
    870                 switch (mDataActivity) {
    871                     case TelephonyManager.DATA_ACTIVITY_IN:
    872                         iconId = mDataIconList[1];
    873                         break;
    874                     case TelephonyManager.DATA_ACTIVITY_OUT:
    875                         iconId = mDataIconList[2];
    876                         break;
    877                     case TelephonyManager.DATA_ACTIVITY_INOUT:
    878                         iconId = mDataIconList[3];
    879                         break;
    880                     case TelephonyManager.DATA_ACTIVITY_DORMANT:
    881                     default:
    882                         iconId = mDataIconList[0];
    883                         break;
    884                 }
    885             } else {
    886                 iconId = 0;
    887                 visible = false;
    888             }
    889         }
    890 
    891         mDataDirectionIconId = iconId;
    892         mDataConnected = visible;
    893     }
    894 
    895     void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
    896         if (false) {
    897             Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
    898                     + " showPlmn=" + showPlmn + " plmn=" + plmn);
    899         }
    900         StringBuilder str = new StringBuilder();
    901         boolean something = false;
    902         if (showPlmn && plmn != null) {
    903             str.append(plmn);
    904             something = true;
    905         }
    906         if (showSpn && spn != null) {
    907             if (something) {
    908                 str.append(mNetworkNameSeparator);
    909             }
    910             str.append(spn);
    911             something = true;
    912         }
    913         if (something) {
    914             mNetworkName = str.toString();
    915         } else {
    916             mNetworkName = mNetworkNameDefault;
    917         }
    918     }
    919 
    920     // ===== Wifi ===================================================================
    921 
    922     class WifiHandler extends Handler {
    923         @Override
    924         public void handleMessage(Message msg) {
    925             switch (msg.what) {
    926                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
    927                     if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
    928                         mWifiChannel.sendMessage(Message.obtain(this,
    929                                 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
    930                     } else {
    931                         Log.e(TAG, "Failed to connect to wifi");
    932                     }
    933                     break;
    934                 case WifiManager.DATA_ACTIVITY_NOTIFICATION:
    935                     if (msg.arg1 != mWifiActivity) {
    936                         mWifiActivity = msg.arg1;
    937                         refreshViews();
    938                     }
    939                     break;
    940                 default:
    941                     //Ignore
    942                     break;
    943             }
    944         }
    945     }
    946 
    947     private void updateWifiState(Intent intent) {
    948         final String action = intent.getAction();
    949         if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
    950             mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
    951                     WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
    952 
    953         } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    954             final NetworkInfo networkInfo = (NetworkInfo)
    955                     intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
    956             boolean wasConnected = mWifiConnected;
    957             mWifiConnected = networkInfo != null && networkInfo.isConnected();
    958             // If Connected grab the signal strength and ssid
    959             if (mWifiConnected) {
    960                 // try getting it out of the intent first
    961                 WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
    962                 if (info == null) {
    963                     info = mWifiManager.getConnectionInfo();
    964                 }
    965                 if (info != null) {
    966                     mWifiSsid = huntForSsid(info);
    967                 } else {
    968                     mWifiSsid = null;
    969                 }
    970             } else if (!mWifiConnected) {
    971                 mWifiSsid = null;
    972             }
    973         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
    974             mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
    975             mWifiLevel = WifiManager.calculateSignalLevel(
    976                     mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT);
    977         }
    978 
    979         updateWifiIcons();
    980     }
    981 
    982     private void updateWifiIcons() {
    983         int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIFI);
    984         if (mWifiConnected) {
    985             mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[inetCondition][mWifiLevel];
    986             mQSWifiIconId = WifiIcons.QS_WIFI_SIGNAL_STRENGTH[inetCondition][mWifiLevel];
    987             mContentDescriptionWifi = mContext.getString(
    988                     AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[mWifiLevel]);
    989         } else {
    990             if (mDataAndWifiStacked) {
    991                 mWifiIconId = 0;
    992                 mQSWifiIconId = 0;
    993             } else {
    994                 mWifiIconId = mWifiEnabled ? R.drawable.stat_sys_wifi_signal_null : 0;
    995                 mQSWifiIconId = mWifiEnabled ? R.drawable.ic_qs_wifi_no_network : 0;
    996             }
    997             mContentDescriptionWifi = mContext.getString(R.string.accessibility_no_wifi);
    998         }
    999     }
   1000 
   1001     private String huntForSsid(WifiInfo info) {
   1002         String ssid = info.getSSID();
   1003         if (ssid != null) {
   1004             return ssid;
   1005         }
   1006         // OK, it's not in the connectionInfo; we have to go hunting for it
   1007         List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
   1008         for (WifiConfiguration net : networks) {
   1009             if (net.networkId == info.getNetworkId()) {
   1010                 return net.SSID;
   1011             }
   1012         }
   1013         return null;
   1014     }
   1015 
   1016 
   1017     // ===== Wimax ===================================================================
   1018     private final void updateWimaxState(Intent intent) {
   1019         final String action = intent.getAction();
   1020         boolean wasConnected = mWimaxConnected;
   1021         if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION)) {
   1022             int wimaxStatus = intent.getIntExtra(WimaxManagerConstants.EXTRA_4G_STATE,
   1023                     WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
   1024             mIsWimaxEnabled = (wimaxStatus ==
   1025                     WimaxManagerConstants.NET_4G_STATE_ENABLED);
   1026         } else if (action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION)) {
   1027             mWimaxSignal = intent.getIntExtra(WimaxManagerConstants.EXTRA_NEW_SIGNAL_LEVEL, 0);
   1028         } else if (action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
   1029             mWimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATE,
   1030                     WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
   1031             mWimaxExtraState = intent.getIntExtra(
   1032                     WimaxManagerConstants.EXTRA_WIMAX_STATE_DETAIL,
   1033                     WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
   1034             mWimaxConnected = (mWimaxState ==
   1035                     WimaxManagerConstants.WIMAX_STATE_CONNECTED);
   1036             mWimaxIdle = (mWimaxExtraState == WimaxManagerConstants.WIMAX_IDLE);
   1037         }
   1038         updateDataNetType();
   1039         updateWimaxIcons();
   1040     }
   1041 
   1042     private void updateWimaxIcons() {
   1043         if (mIsWimaxEnabled) {
   1044             if (mWimaxConnected) {
   1045                 int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_WIMAX);
   1046                 if (mWimaxIdle)
   1047                     mWimaxIconId = WimaxIcons.WIMAX_IDLE;
   1048                 else
   1049                     mWimaxIconId = WimaxIcons.WIMAX_SIGNAL_STRENGTH[inetCondition][mWimaxSignal];
   1050                 mContentDescriptionWimax = mContext.getString(
   1051                         AccessibilityContentDescriptions.WIMAX_CONNECTION_STRENGTH[mWimaxSignal]);
   1052             } else {
   1053                 mWimaxIconId = WimaxIcons.WIMAX_DISCONNECTED;
   1054                 mContentDescriptionWimax = mContext.getString(R.string.accessibility_no_wimax);
   1055             }
   1056         } else {
   1057             mWimaxIconId = 0;
   1058         }
   1059     }
   1060 
   1061     // ===== Full or limited Internet connectivity ==================================
   1062 
   1063     private void updateConnectivity(Intent intent) {
   1064         if (CHATTY) {
   1065             Log.d(TAG, "updateConnectivity: intent=" + intent);
   1066         }
   1067 
   1068         final ConnectivityManager connManager = (ConnectivityManager) mContext
   1069                 .getSystemService(Context.CONNECTIVITY_SERVICE);
   1070         final NetworkInfo info = connManager.getActiveNetworkInfo();
   1071 
   1072         // Are we connected at all, by any interface?
   1073         mConnected = info != null && info.isConnected();
   1074         if (mConnected) {
   1075             mConnectedNetworkType = info.getType();
   1076             mConnectedNetworkTypeName = info.getTypeName();
   1077         } else {
   1078             mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
   1079             mConnectedNetworkTypeName = null;
   1080         }
   1081 
   1082         int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
   1083 
   1084         if (CHATTY) {
   1085             Log.d(TAG, "updateConnectivity: networkInfo=" + info);
   1086             Log.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
   1087         }
   1088 
   1089         mInetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
   1090 
   1091         if (info != null && info.getType() == ConnectivityManager.TYPE_BLUETOOTH) {
   1092             mBluetoothTethered = info.isConnected();
   1093         } else {
   1094             mBluetoothTethered = false;
   1095         }
   1096 
   1097         // We want to update all the icons, all at once, for any condition change
   1098         updateDataNetType();
   1099         updateWimaxIcons();
   1100         updateDataIcon();
   1101         updateTelephonySignalStrength();
   1102         updateWifiIcons();
   1103     }
   1104 
   1105 
   1106     // ===== Update the views =======================================================
   1107 
   1108     void refreshViews() {
   1109         Context context = mContext;
   1110 
   1111         int combinedSignalIconId = 0;
   1112         String combinedLabel = "";
   1113         String wifiLabel = "";
   1114         String mobileLabel = "";
   1115         int N;
   1116         final boolean emergencyOnly = isEmergencyOnly();
   1117 
   1118         if (!mHasMobileDataFeature) {
   1119             mDataSignalIconId = mPhoneSignalIconId = 0;
   1120             mQSPhoneSignalIconId = 0;
   1121             mobileLabel = "";
   1122         } else {
   1123             // We want to show the carrier name if in service and either:
   1124             //   - We are connected to mobile data, or
   1125             //   - We are not connected to mobile data, as long as the *reason* packets are not
   1126             //     being routed over that link is that we have better connectivity via wifi.
   1127             // If data is disconnected for some other reason but wifi (or ethernet/bluetooth)
   1128             // is connected, we show nothing.
   1129             // Otherwise (nothing connected) we show "No internet connection".
   1130 
   1131             if (mDataConnected) {
   1132                 mobileLabel = mNetworkName;
   1133             } else if (mConnected || emergencyOnly) {
   1134                 if (hasService() || emergencyOnly) {
   1135                     // The isEmergencyOnly test covers the case of a phone with no SIM
   1136                     mobileLabel = mNetworkName;
   1137                 } else {
   1138                     // Tablets, basically
   1139                     mobileLabel = "";
   1140                 }
   1141             } else {
   1142                 mobileLabel
   1143                     = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
   1144             }
   1145 
   1146             // Now for things that should only be shown when actually using mobile data.
   1147             if (mDataConnected) {
   1148                 combinedSignalIconId = mDataSignalIconId;
   1149 
   1150                 combinedLabel = mobileLabel;
   1151                 combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
   1152                 mContentDescriptionCombinedSignal = mContentDescriptionDataType;
   1153             }
   1154         }
   1155 
   1156         if (mWifiConnected) {
   1157             if (mWifiSsid == null) {
   1158                 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
   1159             } else {
   1160                 wifiLabel = mWifiSsid;
   1161                 if (DEBUG) {
   1162                     wifiLabel += "xxxxXXXXxxxxXXXX";
   1163                 }
   1164             }
   1165 
   1166             combinedLabel = wifiLabel;
   1167             combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
   1168             mContentDescriptionCombinedSignal = mContentDescriptionWifi;
   1169         } else {
   1170             if (mHasMobileDataFeature) {
   1171                 wifiLabel = "";
   1172             } else {
   1173                 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
   1174             }
   1175         }
   1176 
   1177         if (mBluetoothTethered) {
   1178             combinedLabel = mContext.getString(R.string.bluetooth_tethered);
   1179             combinedSignalIconId = mBluetoothTetherIconId;
   1180             mContentDescriptionCombinedSignal = mContext.getString(
   1181                     R.string.accessibility_bluetooth_tether);
   1182         }
   1183 
   1184         final boolean ethernetConnected = (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET);
   1185         if (ethernetConnected) {
   1186             combinedLabel = context.getString(R.string.ethernet_label);
   1187         }
   1188 
   1189         if (mAirplaneMode &&
   1190                 (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
   1191             // Only display the flight-mode icon if not in "emergency calls only" mode.
   1192 
   1193             // look again; your radios are now airplanes
   1194             mContentDescriptionPhoneSignal = mContext.getString(
   1195                     R.string.accessibility_airplane_mode);
   1196             mAirplaneIconId = TelephonyIcons.FLIGHT_MODE_ICON;
   1197             mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0;
   1198             mQSPhoneSignalIconId = 0;
   1199 
   1200             // combined values from connected wifi take precedence over airplane mode
   1201             if (mWifiConnected) {
   1202                 // Suppress "No internet connection." from mobile if wifi connected.
   1203                 mobileLabel = "";
   1204             } else {
   1205                 if (mHasMobileDataFeature) {
   1206                     // let the mobile icon show "No internet connection."
   1207                     wifiLabel = "";
   1208                 } else {
   1209                     wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
   1210                     combinedLabel = wifiLabel;
   1211                 }
   1212                 mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal;
   1213                 combinedSignalIconId = mDataSignalIconId;
   1214             }
   1215         }
   1216         else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected && !ethernetConnected) {
   1217             // pretty much totally disconnected
   1218 
   1219             combinedLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
   1220             // On devices without mobile radios, we want to show the wifi icon
   1221             combinedSignalIconId =
   1222                 mHasMobileDataFeature ? mDataSignalIconId : mWifiIconId;
   1223             mContentDescriptionCombinedSignal = mHasMobileDataFeature
   1224                 ? mContentDescriptionDataType : mContentDescriptionWifi;
   1225 
   1226             int inetCondition = inetConditionForNetwork(ConnectivityManager.TYPE_MOBILE);
   1227 
   1228             mDataTypeIconId = 0;
   1229             mQSDataTypeIconId = 0;
   1230             if (isRoaming()) {
   1231                 mDataTypeIconId = TelephonyIcons.ROAMING_ICON;
   1232                 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition];
   1233             }
   1234         }
   1235 
   1236         if (mDemoMode) {
   1237             mQSWifiIconId = mDemoWifiLevel < 0 ? R.drawable.ic_qs_wifi_no_network
   1238                     : WifiIcons.QS_WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
   1239             mQSPhoneSignalIconId = mDemoMobileLevel < 0 ? R.drawable.ic_qs_signal_no_signal :
   1240                     TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mDemoInetCondition][mDemoMobileLevel];
   1241             mQSDataTypeIconId = mDemoQSDataTypeIconId;
   1242         }
   1243 
   1244         if (DEBUG) {
   1245             Log.d(TAG, "refreshViews connected={"
   1246                     + (mWifiConnected?" wifi":"")
   1247                     + (mDataConnected?" data":"")
   1248                     + " } level="
   1249                     + ((mSignalStrength == null)?"??":Integer.toString(mSignalStrength.getLevel()))
   1250                     + " combinedSignalIconId=0x"
   1251                     + Integer.toHexString(combinedSignalIconId)
   1252                     + "/" + getResourceName(combinedSignalIconId)
   1253                     + " mobileLabel=" + mobileLabel
   1254                     + " wifiLabel=" + wifiLabel
   1255                     + " emergencyOnly=" + emergencyOnly
   1256                     + " combinedLabel=" + combinedLabel
   1257                     + " mAirplaneMode=" + mAirplaneMode
   1258                     + " mDataActivity=" + mDataActivity
   1259                     + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId)
   1260                     + " mQSPhoneSignalIconId=0x" + Integer.toHexString(mQSPhoneSignalIconId)
   1261                     + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId)
   1262                     + " mDataSignalIconId=0x" + Integer.toHexString(mDataSignalIconId)
   1263                     + " mDataTypeIconId=0x" + Integer.toHexString(mDataTypeIconId)
   1264                     + " mQSDataTypeIconId=0x" + Integer.toHexString(mQSDataTypeIconId)
   1265                     + " mWifiIconId=0x" + Integer.toHexString(mWifiIconId)
   1266                     + " mQSWifiIconId=0x" + Integer.toHexString(mQSWifiIconId)
   1267                     + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId));
   1268         }
   1269 
   1270         // update QS
   1271         for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) {
   1272             notifySignalsChangedCallbacks(cb);
   1273         }
   1274 
   1275         if (mLastPhoneSignalIconId          != mPhoneSignalIconId
   1276          || mLastWifiIconId                 != mWifiIconId
   1277          || mLastInetCondition              != mInetCondition
   1278          || mLastWimaxIconId                != mWimaxIconId
   1279          || mLastDataTypeIconId             != mDataTypeIconId
   1280          || mLastAirplaneMode               != mAirplaneMode
   1281          || mLastLocale                     != mLocale
   1282          || mLastConnectedNetworkType       != mConnectedNetworkType)
   1283         {
   1284             // NB: the mLast*s will be updated later
   1285             for (SignalCluster cluster : mSignalClusters) {
   1286                 refreshSignalCluster(cluster);
   1287             }
   1288         }
   1289 
   1290         if (mLastAirplaneMode != mAirplaneMode) {
   1291             mLastAirplaneMode = mAirplaneMode;
   1292         }
   1293 
   1294         if (mLastLocale != mLocale) {
   1295             mLastLocale = mLocale;
   1296         }
   1297 
   1298         // the phone icon on phones
   1299         if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
   1300             mLastPhoneSignalIconId = mPhoneSignalIconId;
   1301         }
   1302 
   1303         // the data icon on phones
   1304         if (mLastDataDirectionIconId != mDataDirectionIconId) {
   1305             mLastDataDirectionIconId = mDataDirectionIconId;
   1306         }
   1307 
   1308         // the wifi icon on phones
   1309         if (mLastWifiIconId != mWifiIconId) {
   1310             mLastWifiIconId = mWifiIconId;
   1311         }
   1312 
   1313         if (mLastInetCondition != mInetCondition) {
   1314             mLastInetCondition = mInetCondition;
   1315         }
   1316 
   1317         if (mLastConnectedNetworkType != mConnectedNetworkType) {
   1318             mLastConnectedNetworkType = mConnectedNetworkType;
   1319         }
   1320 
   1321         // the wimax icon on phones
   1322         if (mLastWimaxIconId != mWimaxIconId) {
   1323             mLastWimaxIconId = mWimaxIconId;
   1324         }
   1325         // the combined data signal icon
   1326         if (mLastCombinedSignalIconId != combinedSignalIconId) {
   1327             mLastCombinedSignalIconId = combinedSignalIconId;
   1328         }
   1329 
   1330         // the data network type overlay
   1331         if (mLastDataTypeIconId != mDataTypeIconId) {
   1332             mLastDataTypeIconId = mDataTypeIconId;
   1333         }
   1334 
   1335         // the combinedLabel in the notification panel
   1336         if (!mLastCombinedLabel.equals(combinedLabel)) {
   1337             mLastCombinedLabel = combinedLabel;
   1338             N = mCombinedLabelViews.size();
   1339             for (int i=0; i<N; i++) {
   1340                 TextView v = mCombinedLabelViews.get(i);
   1341                 v.setText(combinedLabel);
   1342             }
   1343         }
   1344 
   1345         // wifi label
   1346         N = mWifiLabelViews.size();
   1347         for (int i=0; i<N; i++) {
   1348             TextView v = mWifiLabelViews.get(i);
   1349             v.setText(wifiLabel);
   1350             if ("".equals(wifiLabel)) {
   1351                 v.setVisibility(View.GONE);
   1352             } else {
   1353                 v.setVisibility(View.VISIBLE);
   1354             }
   1355         }
   1356 
   1357         // mobile label
   1358         N = mMobileLabelViews.size();
   1359         for (int i=0; i<N; i++) {
   1360             TextView v = mMobileLabelViews.get(i);
   1361             v.setText(mobileLabel);
   1362             if ("".equals(mobileLabel)) {
   1363                 v.setVisibility(View.GONE);
   1364             } else {
   1365                 v.setVisibility(View.VISIBLE);
   1366             }
   1367         }
   1368 
   1369         // e-call label
   1370         N = mEmergencyViews.size();
   1371         for (int i=0; i<N; i++) {
   1372             StatusBarHeaderView v = mEmergencyViews.get(i);
   1373             v.setShowEmergencyCallsOnly(emergencyOnly);
   1374         }
   1375     }
   1376 
   1377     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1378         pw.println("NetworkController state:");
   1379         pw.println(String.format("  %s network type %d (%s)",
   1380                 mConnected?"CONNECTED":"DISCONNECTED",
   1381                 mConnectedNetworkType, mConnectedNetworkTypeName));
   1382         pw.println("  - telephony ------");
   1383         pw.print("  hasVoiceCallingFeature()=");
   1384         pw.println(hasVoiceCallingFeature());
   1385         pw.print("  hasService()=");
   1386         pw.println(hasService());
   1387         pw.print("  mHspaDataDistinguishable=");
   1388         pw.println(mHspaDataDistinguishable);
   1389         pw.print("  mDataConnected=");
   1390         pw.println(mDataConnected);
   1391         pw.print("  mSimState=");
   1392         pw.println(mSimState);
   1393         pw.print("  mPhoneState=");
   1394         pw.println(mPhoneState);
   1395         pw.print("  mDataState=");
   1396         pw.println(mDataState);
   1397         pw.print("  mDataActivity=");
   1398         pw.println(mDataActivity);
   1399         pw.print("  mDataNetType=");
   1400         pw.print(mDataNetType);
   1401         pw.print("/");
   1402         pw.println(TelephonyManager.getNetworkTypeName(mDataNetType));
   1403         pw.print("  mServiceState=");
   1404         pw.println(mServiceState);
   1405         pw.print("  mSignalStrength=");
   1406         pw.println(mSignalStrength);
   1407         pw.print("  mLastSignalLevel=");
   1408         pw.println(mLastSignalLevel);
   1409         pw.print("  mNetworkName=");
   1410         pw.println(mNetworkName);
   1411         pw.print("  mNetworkNameDefault=");
   1412         pw.println(mNetworkNameDefault);
   1413         pw.print("  mNetworkNameSeparator=");
   1414         pw.println(mNetworkNameSeparator.replace("\n","\\n"));
   1415         pw.print("  mPhoneSignalIconId=0x");
   1416         pw.print(Integer.toHexString(mPhoneSignalIconId));
   1417         pw.print("/");
   1418         pw.print("  mQSPhoneSignalIconId=0x");
   1419         pw.print(Integer.toHexString(mQSPhoneSignalIconId));
   1420         pw.print("/");
   1421         pw.println(getResourceName(mPhoneSignalIconId));
   1422         pw.print("  mDataDirectionIconId=");
   1423         pw.print(Integer.toHexString(mDataDirectionIconId));
   1424         pw.print("/");
   1425         pw.println(getResourceName(mDataDirectionIconId));
   1426         pw.print("  mDataSignalIconId=");
   1427         pw.print(Integer.toHexString(mDataSignalIconId));
   1428         pw.print("/");
   1429         pw.println(getResourceName(mDataSignalIconId));
   1430         pw.print("  mDataTypeIconId=");
   1431         pw.print(Integer.toHexString(mDataTypeIconId));
   1432         pw.print("/");
   1433         pw.println(getResourceName(mDataTypeIconId));
   1434         pw.print("  mQSDataTypeIconId=");
   1435         pw.print(Integer.toHexString(mQSDataTypeIconId));
   1436         pw.print("/");
   1437         pw.println(getResourceName(mQSDataTypeIconId));
   1438 
   1439         pw.println("  - wifi ------");
   1440         pw.print("  mWifiEnabled=");
   1441         pw.println(mWifiEnabled);
   1442         pw.print("  mWifiConnected=");
   1443         pw.println(mWifiConnected);
   1444         pw.print("  mWifiRssi=");
   1445         pw.println(mWifiRssi);
   1446         pw.print("  mWifiLevel=");
   1447         pw.println(mWifiLevel);
   1448         pw.print("  mWifiSsid=");
   1449         pw.println(mWifiSsid);
   1450         pw.println(String.format("  mWifiIconId=0x%08x/%s",
   1451                     mWifiIconId, getResourceName(mWifiIconId)));
   1452         pw.println(String.format("  mQSWifiIconId=0x%08x/%s",
   1453                     mQSWifiIconId, getResourceName(mQSWifiIconId)));
   1454         pw.print("  mWifiActivity=");
   1455         pw.println(mWifiActivity);
   1456 
   1457         if (mWimaxSupported) {
   1458             pw.println("  - wimax ------");
   1459             pw.print("  mIsWimaxEnabled="); pw.println(mIsWimaxEnabled);
   1460             pw.print("  mWimaxConnected="); pw.println(mWimaxConnected);
   1461             pw.print("  mWimaxIdle="); pw.println(mWimaxIdle);
   1462             pw.println(String.format("  mWimaxIconId=0x%08x/%s",
   1463                         mWimaxIconId, getResourceName(mWimaxIconId)));
   1464             pw.println(String.format("  mWimaxSignal=%d", mWimaxSignal));
   1465             pw.println(String.format("  mWimaxState=%d", mWimaxState));
   1466             pw.println(String.format("  mWimaxExtraState=%d", mWimaxExtraState));
   1467         }
   1468 
   1469         pw.println("  - Bluetooth ----");
   1470         pw.print("  mBtReverseTethered=");
   1471         pw.println(mBluetoothTethered);
   1472 
   1473         pw.println("  - connectivity ------");
   1474         pw.print("  mInetCondition=");
   1475         pw.println(mInetCondition);
   1476 
   1477         pw.println("  - icons ------");
   1478         pw.print("  mLastPhoneSignalIconId=0x");
   1479         pw.print(Integer.toHexString(mLastPhoneSignalIconId));
   1480         pw.print("/");
   1481         pw.println(getResourceName(mLastPhoneSignalIconId));
   1482         pw.print("  mLastDataDirectionIconId=0x");
   1483         pw.print(Integer.toHexString(mLastDataDirectionIconId));
   1484         pw.print("/");
   1485         pw.println(getResourceName(mLastDataDirectionIconId));
   1486         pw.print("  mLastWifiIconId=0x");
   1487         pw.print(Integer.toHexString(mLastWifiIconId));
   1488         pw.print("/");
   1489         pw.println(getResourceName(mLastWifiIconId));
   1490         pw.print("  mLastCombinedSignalIconId=0x");
   1491         pw.print(Integer.toHexString(mLastCombinedSignalIconId));
   1492         pw.print("/");
   1493         pw.println(getResourceName(mLastCombinedSignalIconId));
   1494         pw.print("  mLastDataTypeIconId=0x");
   1495         pw.print(Integer.toHexString(mLastDataTypeIconId));
   1496         pw.print("/");
   1497         pw.println(getResourceName(mLastDataTypeIconId));
   1498         pw.print("  mLastCombinedLabel=");
   1499         pw.print(mLastCombinedLabel);
   1500         pw.println("");
   1501     }
   1502 
   1503     private String getResourceName(int resId) {
   1504         if (resId != 0) {
   1505             final Resources res = mContext.getResources();
   1506             try {
   1507                 return res.getResourceName(resId);
   1508             } catch (android.content.res.Resources.NotFoundException ex) {
   1509                 return "(unknown)";
   1510             }
   1511         } else {
   1512             return "(null)";
   1513         }
   1514     }
   1515 
   1516     private boolean mDemoMode;
   1517     private int mDemoInetCondition;
   1518     private int mDemoWifiLevel;
   1519     private int mDemoDataTypeIconId;
   1520     private int mDemoQSDataTypeIconId;
   1521     private int mDemoMobileLevel;
   1522 
   1523     @Override
   1524     public void dispatchDemoCommand(String command, Bundle args) {
   1525         if (!mDemoMode && command.equals(COMMAND_ENTER)) {
   1526             mDemoMode = true;
   1527             mDemoWifiLevel = mWifiLevel;
   1528             mDemoInetCondition = mInetCondition;
   1529             mDemoDataTypeIconId = mDataTypeIconId;
   1530             mDemoQSDataTypeIconId = mQSDataTypeIconId;
   1531             mDemoMobileLevel = mLastSignalLevel;
   1532         } else if (mDemoMode && command.equals(COMMAND_EXIT)) {
   1533             mDemoMode = false;
   1534             for (SignalCluster cluster : mSignalClusters) {
   1535                 refreshSignalCluster(cluster);
   1536             }
   1537             refreshViews();
   1538         } else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
   1539             String airplane = args.getString("airplane");
   1540             if (airplane != null) {
   1541                 boolean show = airplane.equals("show");
   1542                 for (SignalCluster cluster : mSignalClusters) {
   1543                     cluster.setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON);
   1544                 }
   1545             }
   1546             String fully = args.getString("fully");
   1547             if (fully != null) {
   1548                 mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0;
   1549             }
   1550             String wifi = args.getString("wifi");
   1551             if (wifi != null) {
   1552                 boolean show = wifi.equals("show");
   1553                 String level = args.getString("level");
   1554                 if (level != null) {
   1555                     mDemoWifiLevel = level.equals("null") ? -1
   1556                             : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1);
   1557                 }
   1558                 int iconId = mDemoWifiLevel < 0 ? R.drawable.stat_sys_wifi_signal_null
   1559                         : WifiIcons.WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel];
   1560                 for (SignalCluster cluster : mSignalClusters) {
   1561                     cluster.setWifiIndicators(
   1562                             show,
   1563                             iconId,
   1564                             "Demo");
   1565                 }
   1566                 refreshViews();
   1567             }
   1568             String mobile = args.getString("mobile");
   1569             if (mobile != null) {
   1570                 boolean show = mobile.equals("show");
   1571                 String datatype = args.getString("datatype");
   1572                 if (datatype != null) {
   1573                     mDemoDataTypeIconId =
   1574                             datatype.equals("1x") ? TelephonyIcons.ICON_1X :
   1575                             datatype.equals("3g") ? TelephonyIcons.ICON_3G :
   1576                             datatype.equals("4g") ? TelephonyIcons.ICON_4G :
   1577                             datatype.equals("e") ? R.drawable.stat_sys_data_fully_connected_e :
   1578                             datatype.equals("g") ? R.drawable.stat_sys_data_fully_connected_g :
   1579                             datatype.equals("h") ? R.drawable.stat_sys_data_fully_connected_h :
   1580                             datatype.equals("lte") ? TelephonyIcons.ICON_LTE :
   1581                             datatype.equals("roam") ? TelephonyIcons.ROAMING_ICON :
   1582                             0;
   1583                     mDemoQSDataTypeIconId =
   1584                             datatype.equals("1x") ? TelephonyIcons.QS_ICON_1X :
   1585                             datatype.equals("3g") ? TelephonyIcons.QS_ICON_3G :
   1586                             datatype.equals("4g") ? TelephonyIcons.QS_ICON_4G :
   1587                             datatype.equals("e") ? R.drawable.ic_qs_signal_e :
   1588                             datatype.equals("g") ? R.drawable.ic_qs_signal_g :
   1589                             datatype.equals("h") ? R.drawable.ic_qs_signal_h :
   1590                             datatype.equals("lte") ? TelephonyIcons.QS_ICON_LTE :
   1591                             datatype.equals("roam") ? R.drawable.ic_qs_signal_r :
   1592                             0;
   1593                 }
   1594                 int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH;
   1595                 String level = args.getString("level");
   1596                 if (level != null) {
   1597                     mDemoMobileLevel = level.equals("null") ? -1
   1598                             : Math.min(Integer.parseInt(level), icons[0].length - 1);
   1599                 }
   1600                 int iconId = mDemoMobileLevel < 0 ? R.drawable.stat_sys_signal_null :
   1601                         icons[mDemoInetCondition][mDemoMobileLevel];
   1602                 for (SignalCluster cluster : mSignalClusters) {
   1603                     cluster.setMobileDataIndicators(
   1604                             show,
   1605                             iconId,
   1606                             mDemoDataTypeIconId,
   1607                             "Demo",
   1608                             "Demo",
   1609                             mDemoDataTypeIconId == TelephonyIcons.ROAMING_ICON,
   1610                             isTypeIconWide(mDemoDataTypeIconId));
   1611                 }
   1612                 refreshViews();
   1613             }
   1614         }
   1615     }
   1616 }
   1617