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 java.io.FileDescriptor;
     20 import java.io.PrintWriter;
     21 import java.util.ArrayList;
     22 import java.util.List;
     23 
     24 import android.content.BroadcastReceiver;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.content.IntentFilter;
     28 import android.content.res.Resources;
     29 import android.net.ConnectivityManager;
     30 import android.net.NetworkInfo;
     31 import android.net.wifi.WifiConfiguration;
     32 import android.net.wifi.WifiInfo;
     33 import android.net.wifi.WifiManager;
     34 import android.net.wimax.WimaxManagerConstants;
     35 import android.os.Binder;
     36 import android.os.Handler;
     37 import android.os.Message;
     38 import android.os.Messenger;
     39 import android.os.RemoteException;
     40 import android.os.SystemProperties;
     41 import android.provider.Settings;
     42 import android.provider.Telephony;
     43 import android.telephony.PhoneStateListener;
     44 import android.telephony.ServiceState;
     45 import android.telephony.SignalStrength;
     46 import android.telephony.TelephonyManager;
     47 import android.util.Slog;
     48 import android.view.View;
     49 import android.widget.ImageView;
     50 import android.widget.TextView;
     51 
     52 import com.android.internal.app.IBatteryStats;
     53 import com.android.internal.telephony.IccCard;
     54 import com.android.internal.telephony.TelephonyIntents;
     55 import com.android.internal.telephony.cdma.EriInfo;
     56 import com.android.server.am.BatteryStatsService;
     57 import com.android.internal.util.AsyncChannel;
     58 
     59 import com.android.systemui.R;
     60 
     61 public class NetworkController extends BroadcastReceiver {
     62     // debug
     63     static final String TAG = "StatusBar.NetworkController";
     64     static final boolean DEBUG = false;
     65     static final boolean CHATTY = false; // additional diagnostics, but not logspew
     66 
     67     // telephony
     68     boolean mHspaDataDistinguishable;
     69     final TelephonyManager mPhone;
     70     boolean mDataConnected;
     71     IccCard.State mSimState = IccCard.State.READY;
     72     int mPhoneState = TelephonyManager.CALL_STATE_IDLE;
     73     int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     74     int mDataState = TelephonyManager.DATA_DISCONNECTED;
     75     int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
     76     ServiceState mServiceState;
     77     SignalStrength mSignalStrength;
     78     int[] mDataIconList = TelephonyIcons.DATA_G[0];
     79     String mNetworkName;
     80     String mNetworkNameDefault;
     81     String mNetworkNameSeparator;
     82     int mPhoneSignalIconId;
     83     int mDataDirectionIconId; // data + data direction on phones
     84     int mDataSignalIconId;
     85     int mDataTypeIconId;
     86     boolean mDataActive;
     87     int mMobileActivityIconId; // overlay arrows for data direction
     88     int mLastSignalLevel;
     89     boolean mShowPhoneRSSIForData = false;
     90     boolean mShowAtLeastThreeGees = false;
     91 
     92     String mContentDescriptionPhoneSignal;
     93     String mContentDescriptionWifi;
     94     String mContentDescriptionWimax;
     95     String mContentDescriptionCombinedSignal;
     96     String mContentDescriptionDataType;
     97 
     98     // wifi
     99     final WifiManager mWifiManager;
    100     AsyncChannel mWifiChannel;
    101     boolean mWifiEnabled, mWifiConnected;
    102     int mWifiRssi, mWifiLevel;
    103     String mWifiSsid;
    104     int mWifiIconId = 0;
    105     int mWifiActivityIconId = 0; // overlay arrows for wifi direction
    106     int mWifiActivity = WifiManager.DATA_ACTIVITY_NONE;
    107 
    108     // bluetooth
    109     private boolean mBluetoothTethered = false;
    110     private int mBluetoothTetherIconId =
    111         com.android.internal.R.drawable.stat_sys_tether_bluetooth;
    112 
    113     //wimax
    114     private boolean mWimaxSupported = false;
    115     private boolean mIsWimaxEnabled = false;
    116     private boolean mWimaxConnected = false;
    117     private boolean mWimaxIdle = false;
    118     private int mWimaxIconId = 0;
    119     private int mWimaxSignal = 0;
    120     private int mWimaxState = 0;
    121     private int mWimaxExtraState = 0;
    122     // data connectivity (regardless of state, can we access the internet?)
    123     // state of inet connection - 0 not connected, 100 connected
    124     private int mInetCondition = 0;
    125     private static final int INET_CONDITION_THRESHOLD = 50;
    126 
    127     private boolean mAirplaneMode = false;
    128 
    129     // our ui
    130     Context mContext;
    131     ArrayList<ImageView> mPhoneSignalIconViews = new ArrayList<ImageView>();
    132     ArrayList<ImageView> mDataDirectionIconViews = new ArrayList<ImageView>();
    133     ArrayList<ImageView> mDataDirectionOverlayIconViews = new ArrayList<ImageView>();
    134     ArrayList<ImageView> mWifiIconViews = new ArrayList<ImageView>();
    135     ArrayList<ImageView> mWimaxIconViews = new ArrayList<ImageView>();
    136     ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>();
    137     ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>();
    138     ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
    139     ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
    140     int mLastPhoneSignalIconId = -1;
    141     int mLastDataDirectionIconId = -1;
    142     int mLastDataDirectionOverlayIconId = -1;
    143     int mLastWifiIconId = -1;
    144     int mLastWimaxIconId = -1;
    145     int mLastCombinedSignalIconId = -1;
    146     int mLastDataTypeIconId = -1;
    147     String mLastLabel = "";
    148 
    149     private boolean mHasMobileDataFeature;
    150 
    151     boolean mDataAndWifiStacked = false;
    152 
    153     // yuck -- stop doing this here and put it in the framework
    154     IBatteryStats mBatteryStats;
    155 
    156     public interface SignalCluster {
    157         void setWifiIndicators(boolean visible, int strengthIcon, int activityIcon,
    158                 String contentDescription);
    159         void setMobileDataIndicators(boolean visible, int strengthIcon, int activityIcon,
    160                 int typeIcon, String contentDescription, String typeContentDescription);
    161         void setIsAirplaneMode(boolean is);
    162     }
    163 
    164     /**
    165      * Construct this controller object and register for updates.
    166      */
    167     public NetworkController(Context context) {
    168         mContext = context;
    169         final Resources res = context.getResources();
    170 
    171         ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
    172                 Context.CONNECTIVITY_SERVICE);
    173         mHasMobileDataFeature = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
    174 
    175         mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData);
    176         mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
    177 
    178         // set up the default wifi icon, used when no radios have ever appeared
    179         updateWifiIcons();
    180         updateWimaxIcons();
    181 
    182         // telephony
    183         mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    184         mPhone.listen(mPhoneStateListener,
    185                           PhoneStateListener.LISTEN_SERVICE_STATE
    186                         | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
    187                         | PhoneStateListener.LISTEN_CALL_STATE
    188                         | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
    189                         | PhoneStateListener.LISTEN_DATA_ACTIVITY);
    190         mHspaDataDistinguishable = mContext.getResources().getBoolean(
    191                 R.bool.config_hspa_data_distinguishable);
    192         mNetworkNameSeparator = mContext.getString(R.string.status_bar_network_name_separator);
    193         mNetworkNameDefault = mContext.getString(
    194                 com.android.internal.R.string.lockscreen_carrier_default);
    195         mNetworkName = mNetworkNameDefault;
    196 
    197         // wifi
    198         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    199         Handler handler = new WifiHandler();
    200         mWifiChannel = new AsyncChannel();
    201         Messenger wifiMessenger = mWifiManager.getMessenger();
    202         if (wifiMessenger != null) {
    203             mWifiChannel.connect(mContext, handler, wifiMessenger);
    204         }
    205 
    206         // broadcasts
    207         IntentFilter filter = new IntentFilter();
    208         filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
    209         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    210         filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    211         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
    212         filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
    213         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
    214         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
    215         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
    216         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    217         mWimaxSupported = mContext.getResources().getBoolean(
    218                 com.android.internal.R.bool.config_wimaxEnabled);
    219         if(mWimaxSupported) {
    220             filter.addAction(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION);
    221             filter.addAction(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION);
    222             filter.addAction(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION);
    223         }
    224         context.registerReceiver(this, filter);
    225 
    226         // AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
    227         updateAirplaneMode();
    228 
    229         // yuck
    230         mBatteryStats = BatteryStatsService.getService();
    231     }
    232 
    233     public void addPhoneSignalIconView(ImageView v) {
    234         mPhoneSignalIconViews.add(v);
    235     }
    236 
    237     public void addDataDirectionIconView(ImageView v) {
    238         mDataDirectionIconViews.add(v);
    239     }
    240 
    241     public void addDataDirectionOverlayIconView(ImageView v) {
    242         mDataDirectionOverlayIconViews.add(v);
    243     }
    244 
    245     public void addWifiIconView(ImageView v) {
    246         mWifiIconViews.add(v);
    247     }
    248     public void addWimaxIconView(ImageView v) {
    249         mWimaxIconViews.add(v);
    250     }
    251 
    252     public void addCombinedSignalIconView(ImageView v) {
    253         mCombinedSignalIconViews.add(v);
    254     }
    255 
    256     public void addDataTypeIconView(ImageView v) {
    257         mDataTypeIconViews.add(v);
    258     }
    259 
    260     public void addLabelView(TextView v) {
    261         mLabelViews.add(v);
    262     }
    263 
    264     public void addSignalCluster(SignalCluster cluster) {
    265         mSignalClusters.add(cluster);
    266         refreshSignalCluster(cluster);
    267     }
    268 
    269     public void refreshSignalCluster(SignalCluster cluster) {
    270         cluster.setWifiIndicators(
    271                 mWifiConnected, // only show wifi in the cluster if connected
    272                 mWifiIconId,
    273                 mWifiActivityIconId,
    274                 mContentDescriptionWifi);
    275 
    276         if (mIsWimaxEnabled && mWimaxConnected) {
    277             // wimax is special
    278             cluster.setMobileDataIndicators(
    279                     true,
    280                     mWimaxIconId,
    281                     mMobileActivityIconId,
    282                     mDataTypeIconId,
    283                     mContentDescriptionWimax,
    284                     mContentDescriptionDataType);
    285         } else {
    286             // normal mobile data
    287             cluster.setMobileDataIndicators(
    288                     mHasMobileDataFeature,
    289                     mShowPhoneRSSIForData ? mPhoneSignalIconId : mDataSignalIconId,
    290                     mMobileActivityIconId,
    291                     mDataTypeIconId,
    292                     mContentDescriptionPhoneSignal,
    293                     mContentDescriptionDataType);
    294         }
    295         cluster.setIsAirplaneMode(mAirplaneMode);
    296     }
    297 
    298     public void setStackedMode(boolean stacked) {
    299         mDataAndWifiStacked = true;
    300     }
    301 
    302     @Override
    303     public void onReceive(Context context, Intent intent) {
    304         final String action = intent.getAction();
    305         if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
    306                 || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)
    307                 || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    308             updateWifiState(intent);
    309             refreshViews();
    310         } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
    311             updateSimState(intent);
    312             updateDataIcon();
    313             refreshViews();
    314         } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) {
    315             updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
    316                         intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
    317                         intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
    318                         intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
    319             refreshViews();
    320         } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
    321                  action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
    322             updateConnectivity(intent);
    323             refreshViews();
    324         } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
    325             refreshViews();
    326         } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
    327             updateAirplaneMode();
    328             refreshViews();
    329         } else if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION) ||
    330                 action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION) ||
    331                 action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
    332             updateWimaxState(intent);
    333             refreshViews();
    334         }
    335     }
    336 
    337 
    338     // ===== Telephony ==============================================================
    339 
    340     PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
    341         @Override
    342         public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    343             if (DEBUG) {
    344                 Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
    345                     ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
    346             }
    347             mSignalStrength = signalStrength;
    348             updateTelephonySignalStrength();
    349             refreshViews();
    350         }
    351 
    352         @Override
    353         public void onServiceStateChanged(ServiceState state) {
    354             if (DEBUG) {
    355                 Slog.d(TAG, "onServiceStateChanged state=" + state.getState());
    356             }
    357             mServiceState = state;
    358             updateTelephonySignalStrength();
    359             updateDataNetType();
    360             updateDataIcon();
    361             refreshViews();
    362         }
    363 
    364         @Override
    365         public void onCallStateChanged(int state, String incomingNumber) {
    366             if (DEBUG) {
    367                 Slog.d(TAG, "onCallStateChanged state=" + state);
    368             }
    369             // In cdma, if a voice call is made, RSSI should switch to 1x.
    370             if (isCdma()) {
    371                 updateTelephonySignalStrength();
    372                 refreshViews();
    373             }
    374         }
    375 
    376         @Override
    377         public void onDataConnectionStateChanged(int state, int networkType) {
    378             if (DEBUG) {
    379                 Slog.d(TAG, "onDataConnectionStateChanged: state=" + state
    380                         + " type=" + networkType);
    381             }
    382             mDataState = state;
    383             mDataNetType = networkType;
    384             updateDataNetType();
    385             updateDataIcon();
    386             refreshViews();
    387         }
    388 
    389         @Override
    390         public void onDataActivity(int direction) {
    391             if (DEBUG) {
    392                 Slog.d(TAG, "onDataActivity: direction=" + direction);
    393             }
    394             mDataActivity = direction;
    395             updateDataIcon();
    396             refreshViews();
    397         }
    398     };
    399 
    400     private final void updateSimState(Intent intent) {
    401         String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
    402         if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
    403             mSimState = IccCard.State.ABSENT;
    404         }
    405         else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
    406             mSimState = IccCard.State.READY;
    407         }
    408         else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
    409             final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
    410             if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
    411                 mSimState = IccCard.State.PIN_REQUIRED;
    412             }
    413             else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
    414                 mSimState = IccCard.State.PUK_REQUIRED;
    415             }
    416             else {
    417                 mSimState = IccCard.State.NETWORK_LOCKED;
    418             }
    419         } else {
    420             mSimState = IccCard.State.UNKNOWN;
    421         }
    422     }
    423 
    424     private boolean isCdma() {
    425         return (mSignalStrength != null) && !mSignalStrength.isGsm();
    426     }
    427 
    428     private boolean hasService() {
    429         if (mServiceState != null) {
    430             switch (mServiceState.getState()) {
    431                 case ServiceState.STATE_OUT_OF_SERVICE:
    432                 case ServiceState.STATE_POWER_OFF:
    433                     return false;
    434                 default:
    435                     return true;
    436             }
    437         } else {
    438             return false;
    439         }
    440     }
    441 
    442     private void updateAirplaneMode() {
    443         mAirplaneMode = (Settings.System.getInt(mContext.getContentResolver(),
    444             Settings.System.AIRPLANE_MODE_ON, 0) == 1);
    445     }
    446 
    447     private final void updateTelephonySignalStrength() {
    448         if (!hasService()) {
    449             if (CHATTY) Slog.d(TAG, "updateTelephonySignalStrength: !hasService()");
    450             mPhoneSignalIconId = R.drawable.stat_sys_signal_0;
    451             mDataSignalIconId = R.drawable.stat_sys_signal_0;
    452         } else {
    453             if (mSignalStrength == null) {
    454                 if (CHATTY) Slog.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
    455                 mPhoneSignalIconId = R.drawable.stat_sys_signal_0;
    456                 mDataSignalIconId = R.drawable.stat_sys_signal_0;
    457                 mContentDescriptionPhoneSignal = mContext.getString(
    458                         AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
    459             } else {
    460                 int iconLevel;
    461                 int[] iconList;
    462                 mLastSignalLevel = iconLevel = mSignalStrength.getLevel();
    463                 if (isCdma()) {
    464                     if (isCdmaEri()) {
    465                         iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
    466                     } else {
    467                         iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
    468                     }
    469                 } else {
    470                     // Though mPhone is a Manager, this call is not an IPC
    471                     if (mPhone.isNetworkRoaming()) {
    472                         iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
    473                     } else {
    474                         iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
    475                     }
    476                 }
    477                 mPhoneSignalIconId = iconList[iconLevel];
    478                 mContentDescriptionPhoneSignal = mContext.getString(
    479                         AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]);
    480 
    481                 mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
    482             }
    483         }
    484     }
    485 
    486     private final void updateDataNetType() {
    487         if (mIsWimaxEnabled && mWimaxConnected) {
    488             // wimax is a special 4g network not handled by telephony
    489             mDataIconList = TelephonyIcons.DATA_4G[mInetCondition];
    490             mDataTypeIconId = R.drawable.stat_sys_data_connected_4g;
    491             mContentDescriptionDataType = mContext.getString(
    492                     R.string.accessibility_data_connection_4g);
    493         } else {
    494             switch (mDataNetType) {
    495                 case TelephonyManager.NETWORK_TYPE_UNKNOWN:
    496                     if (!mShowAtLeastThreeGees) {
    497                         mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
    498                         mDataTypeIconId = 0;
    499                         mContentDescriptionDataType = mContext.getString(
    500                                 R.string.accessibility_data_connection_gprs);
    501                         break;
    502                     } else {
    503                         // fall through
    504                     }
    505                 case TelephonyManager.NETWORK_TYPE_EDGE:
    506                     if (!mShowAtLeastThreeGees) {
    507                         mDataIconList = TelephonyIcons.DATA_E[mInetCondition];
    508                         mDataTypeIconId = R.drawable.stat_sys_data_connected_e;
    509                         mContentDescriptionDataType = mContext.getString(
    510                                 R.string.accessibility_data_connection_edge);
    511                         break;
    512                     } else {
    513                         // fall through
    514                     }
    515                 case TelephonyManager.NETWORK_TYPE_UMTS:
    516                     mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
    517                     mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
    518                     mContentDescriptionDataType = mContext.getString(
    519                             R.string.accessibility_data_connection_3g);
    520                     break;
    521                 case TelephonyManager.NETWORK_TYPE_HSDPA:
    522                 case TelephonyManager.NETWORK_TYPE_HSUPA:
    523                 case TelephonyManager.NETWORK_TYPE_HSPA:
    524                 case TelephonyManager.NETWORK_TYPE_HSPAP:
    525                     if (mHspaDataDistinguishable) {
    526                         mDataIconList = TelephonyIcons.DATA_H[mInetCondition];
    527                         mDataTypeIconId = R.drawable.stat_sys_data_connected_h;
    528                         mContentDescriptionDataType = mContext.getString(
    529                                 R.string.accessibility_data_connection_3_5g);
    530                     } else {
    531                         mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
    532                         mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
    533                         mContentDescriptionDataType = mContext.getString(
    534                                 R.string.accessibility_data_connection_3g);
    535                     }
    536                     break;
    537                 case TelephonyManager.NETWORK_TYPE_CDMA:
    538                     // display 1xRTT for IS95A/B
    539                     mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
    540                     mDataTypeIconId = R.drawable.stat_sys_data_connected_1x;
    541                     mContentDescriptionDataType = mContext.getString(
    542                             R.string.accessibility_data_connection_cdma);
    543                     break;
    544                 case TelephonyManager.NETWORK_TYPE_1xRTT:
    545                     mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
    546                     mDataTypeIconId = R.drawable.stat_sys_data_connected_1x;
    547                     mContentDescriptionDataType = mContext.getString(
    548                             R.string.accessibility_data_connection_cdma);
    549                     break;
    550                 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
    551                 case TelephonyManager.NETWORK_TYPE_EVDO_A:
    552                 case TelephonyManager.NETWORK_TYPE_EVDO_B:
    553                 case TelephonyManager.NETWORK_TYPE_EHRPD:
    554                     mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
    555                     mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
    556                     mContentDescriptionDataType = mContext.getString(
    557                             R.string.accessibility_data_connection_3g);
    558                     break;
    559                 case TelephonyManager.NETWORK_TYPE_LTE:
    560                     mDataIconList = TelephonyIcons.DATA_4G[mInetCondition];
    561                     mDataTypeIconId = R.drawable.stat_sys_data_connected_4g;
    562                     mContentDescriptionDataType = mContext.getString(
    563                             R.string.accessibility_data_connection_4g);
    564                     break;
    565                 default:
    566                     if (!mShowAtLeastThreeGees) {
    567                         mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
    568                         mDataTypeIconId = R.drawable.stat_sys_data_connected_g;
    569                         mContentDescriptionDataType = mContext.getString(
    570                                 R.string.accessibility_data_connection_gprs);
    571                     } else {
    572                         mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
    573                         mDataTypeIconId = R.drawable.stat_sys_data_connected_3g;
    574                         mContentDescriptionDataType = mContext.getString(
    575                                 R.string.accessibility_data_connection_3g);
    576                     }
    577                     break;
    578             }
    579         }
    580 
    581         if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) {
    582             mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
    583         }
    584     }
    585 
    586     boolean isCdmaEri() {
    587         if (mServiceState != null) {
    588             final int iconIndex = mServiceState.getCdmaEriIconIndex();
    589             if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) {
    590                 final int iconMode = mServiceState.getCdmaEriIconMode();
    591                 if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
    592                         || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) {
    593                     return true;
    594                 }
    595             }
    596         }
    597         return false;
    598     }
    599 
    600     private final void updateDataIcon() {
    601         int iconId;
    602         boolean visible = true;
    603 
    604         if (!isCdma()) {
    605             // GSM case, we have to check also the sim state
    606             if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) {
    607                 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
    608                     switch (mDataActivity) {
    609                         case TelephonyManager.DATA_ACTIVITY_IN:
    610                             iconId = mDataIconList[1];
    611                             break;
    612                         case TelephonyManager.DATA_ACTIVITY_OUT:
    613                             iconId = mDataIconList[2];
    614                             break;
    615                         case TelephonyManager.DATA_ACTIVITY_INOUT:
    616                             iconId = mDataIconList[3];
    617                             break;
    618                         default:
    619                             iconId = mDataIconList[0];
    620                             break;
    621                     }
    622                     mDataDirectionIconId = iconId;
    623                 } else {
    624                     iconId = 0;
    625                     visible = false;
    626                 }
    627             } else {
    628                 iconId = R.drawable.stat_sys_no_sim;
    629                 visible = false; // no SIM? no data
    630             }
    631         } else {
    632             // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
    633             if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) {
    634                 switch (mDataActivity) {
    635                     case TelephonyManager.DATA_ACTIVITY_IN:
    636                         iconId = mDataIconList[1];
    637                         break;
    638                     case TelephonyManager.DATA_ACTIVITY_OUT:
    639                         iconId = mDataIconList[2];
    640                         break;
    641                     case TelephonyManager.DATA_ACTIVITY_INOUT:
    642                         iconId = mDataIconList[3];
    643                         break;
    644                     case TelephonyManager.DATA_ACTIVITY_DORMANT:
    645                     default:
    646                         iconId = mDataIconList[0];
    647                         break;
    648                 }
    649             } else {
    650                 iconId = 0;
    651                 visible = false;
    652             }
    653         }
    654 
    655         // yuck - this should NOT be done by the status bar
    656         long ident = Binder.clearCallingIdentity();
    657         try {
    658             mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible);
    659         } catch (RemoteException e) {
    660         } finally {
    661             Binder.restoreCallingIdentity(ident);
    662         }
    663 
    664         mDataDirectionIconId = iconId;
    665         mDataConnected = visible;
    666     }
    667 
    668     void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) {
    669         if (false) {
    670             Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn
    671                     + " showPlmn=" + showPlmn + " plmn=" + plmn);
    672         }
    673         StringBuilder str = new StringBuilder();
    674         boolean something = false;
    675         if (showPlmn && plmn != null) {
    676             str.append(plmn);
    677             something = true;
    678         }
    679         if (showSpn && spn != null) {
    680             if (something) {
    681                 str.append(mNetworkNameSeparator);
    682             }
    683             str.append(spn);
    684             something = true;
    685         }
    686         if (something) {
    687             mNetworkName = str.toString();
    688         } else {
    689             mNetworkName = mNetworkNameDefault;
    690         }
    691     }
    692 
    693     // ===== Wifi ===================================================================
    694 
    695     class WifiHandler extends Handler {
    696         @Override
    697         public void handleMessage(Message msg) {
    698             switch (msg.what) {
    699                 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
    700                     if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
    701                         mWifiChannel.sendMessage(Message.obtain(this,
    702                                 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
    703                     } else {
    704                         Slog.e(TAG, "Failed to connect to wifi");
    705                     }
    706                     break;
    707                 case WifiManager.DATA_ACTIVITY_NOTIFICATION:
    708                     if (msg.arg1 != mWifiActivity) {
    709                         mWifiActivity = msg.arg1;
    710                         refreshViews();
    711                     }
    712                     break;
    713                 default:
    714                     //Ignore
    715                     break;
    716             }
    717         }
    718     }
    719 
    720     private void updateWifiState(Intent intent) {
    721         final String action = intent.getAction();
    722         if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
    723             mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
    724                     WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
    725 
    726         } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    727             final NetworkInfo networkInfo = (NetworkInfo)
    728                     intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
    729             boolean wasConnected = mWifiConnected;
    730             mWifiConnected = networkInfo != null && networkInfo.isConnected();
    731             // If we just connected, grab the inintial signal strength and ssid
    732             if (mWifiConnected && !wasConnected) {
    733                 // try getting it out of the intent first
    734                 WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
    735                 if (info == null) {
    736                     info = mWifiManager.getConnectionInfo();
    737                 }
    738                 if (info != null) {
    739                     mWifiSsid = huntForSsid(info);
    740                 } else {
    741                     mWifiSsid = null;
    742                 }
    743             } else if (!mWifiConnected) {
    744                 mWifiSsid = null;
    745             }
    746             // Apparently the wifi level is not stable at this point even if we've just connected to
    747             // the network; we need to wait for an RSSI_CHANGED_ACTION for that. So let's just set
    748             // it to 0 for now
    749             mWifiLevel = 0;
    750             mWifiRssi = -200;
    751         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
    752             if (mWifiConnected) {
    753                 mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
    754                 mWifiLevel = WifiManager.calculateSignalLevel(
    755                         mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT);
    756             }
    757         }
    758 
    759         updateWifiIcons();
    760     }
    761 
    762     private void updateWifiIcons() {
    763         if (mWifiConnected) {
    764             mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel];
    765             mContentDescriptionWifi = mContext.getString(
    766                     AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[mWifiLevel]);
    767         } else {
    768             if (mDataAndWifiStacked) {
    769                 mWifiIconId = 0;
    770             } else {
    771                 mWifiIconId = mWifiEnabled ? WifiIcons.WIFI_SIGNAL_STRENGTH[0][0] : 0;
    772             }
    773             mContentDescriptionWifi = mContext.getString(R.string.accessibility_no_wifi);
    774         }
    775     }
    776 
    777     private String huntForSsid(WifiInfo info) {
    778         String ssid = info.getSSID();
    779         if (ssid != null) {
    780             return ssid;
    781         }
    782         // OK, it's not in the connectionInfo; we have to go hunting for it
    783         List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks();
    784         for (WifiConfiguration net : networks) {
    785             if (net.networkId == info.getNetworkId()) {
    786                 return net.SSID;
    787             }
    788         }
    789         return null;
    790     }
    791 
    792 
    793     // ===== Wimax ===================================================================
    794     private final void updateWimaxState(Intent intent) {
    795         final String action = intent.getAction();
    796         boolean wasConnected = mWimaxConnected;
    797         if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION)) {
    798             int wimaxStatus = intent.getIntExtra(WimaxManagerConstants.EXTRA_4G_STATE,
    799                     WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
    800             mIsWimaxEnabled = (wimaxStatus ==
    801                     WimaxManagerConstants.NET_4G_STATE_ENABLED);
    802         } else if (action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION)) {
    803             mWimaxSignal = intent.getIntExtra(WimaxManagerConstants.EXTRA_NEW_SIGNAL_LEVEL, 0);
    804         } else if (action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) {
    805             mWimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATE,
    806                     WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
    807             mWimaxExtraState = intent.getIntExtra(
    808                     WimaxManagerConstants.EXTRA_WIMAX_STATE_DETAIL,
    809                     WimaxManagerConstants.NET_4G_STATE_UNKNOWN);
    810             mWimaxConnected = (mWimaxState ==
    811                     WimaxManagerConstants.WIMAX_STATE_CONNECTED);
    812             mWimaxIdle = (mWimaxExtraState == WimaxManagerConstants.WIMAX_IDLE);
    813         }
    814         updateDataNetType();
    815         updateWimaxIcons();
    816     }
    817 
    818     private void updateWimaxIcons() {
    819         if (mIsWimaxEnabled) {
    820             if (mWimaxConnected) {
    821                 if (mWimaxIdle)
    822                     mWimaxIconId = WimaxIcons.WIMAX_IDLE;
    823                 else
    824                     mWimaxIconId = WimaxIcons.WIMAX_SIGNAL_STRENGTH[mInetCondition][mWimaxSignal];
    825                 mContentDescriptionWimax = mContext.getString(
    826                         AccessibilityContentDescriptions.WIMAX_CONNECTION_STRENGTH[mWimaxSignal]);
    827             } else {
    828                 mWimaxIconId = WimaxIcons.WIMAX_DISCONNECTED;
    829                 mContentDescriptionWimax = mContext.getString(R.string.accessibility_no_wimax);
    830             }
    831         } else {
    832             mWimaxIconId = 0;
    833         }
    834     }
    835 
    836     // ===== Full or limited Internet connectivity ==================================
    837 
    838     private void updateConnectivity(Intent intent) {
    839         if (CHATTY) {
    840             Slog.d(TAG, "updateConnectivity: intent=" + intent);
    841         }
    842 
    843         NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra(
    844                 ConnectivityManager.EXTRA_NETWORK_INFO));
    845         int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
    846 
    847         if (CHATTY) {
    848             Slog.d(TAG, "updateConnectivity: networkInfo=" + info);
    849             Slog.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus);
    850         }
    851 
    852         mInetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0);
    853 
    854         if (info != null && info.getType() == ConnectivityManager.TYPE_BLUETOOTH) {
    855             mBluetoothTethered = info.isConnected();
    856         } else {
    857             mBluetoothTethered = false;
    858         }
    859 
    860         // We want to update all the icons, all at once, for any condition change
    861         updateDataNetType();
    862         updateWimaxIcons();
    863         updateDataIcon();
    864         updateTelephonySignalStrength();
    865         updateWifiIcons();
    866     }
    867 
    868 
    869     // ===== Update the views =======================================================
    870 
    871     void refreshViews() {
    872         Context context = mContext;
    873 
    874         int combinedSignalIconId = 0;
    875         int combinedActivityIconId = 0;
    876         String label = "";
    877         int N;
    878 
    879         if (mDataConnected) {
    880             label = mNetworkName;
    881             combinedSignalIconId = mDataSignalIconId;
    882             switch (mDataActivity) {
    883                 case TelephonyManager.DATA_ACTIVITY_IN:
    884                     mMobileActivityIconId = R.drawable.stat_sys_signal_in;
    885                     break;
    886                 case TelephonyManager.DATA_ACTIVITY_OUT:
    887                     mMobileActivityIconId = R.drawable.stat_sys_signal_out;
    888                     break;
    889                 case TelephonyManager.DATA_ACTIVITY_INOUT:
    890                     mMobileActivityIconId = R.drawable.stat_sys_signal_inout;
    891                     break;
    892                 default:
    893                     mMobileActivityIconId = 0;
    894                     break;
    895             }
    896 
    897             combinedActivityIconId = mMobileActivityIconId;
    898             combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
    899             mContentDescriptionCombinedSignal = mContentDescriptionDataType;
    900         }
    901 
    902         if (mWifiConnected) {
    903             if (mWifiSsid == null) {
    904                 label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
    905                 mWifiActivityIconId = 0; // no wifis, no bits
    906             } else {
    907                 label = mWifiSsid;
    908                 switch (mWifiActivity) {
    909                     case WifiManager.DATA_ACTIVITY_IN:
    910                         mWifiActivityIconId = R.drawable.stat_sys_wifi_in;
    911                         break;
    912                     case WifiManager.DATA_ACTIVITY_OUT:
    913                         mWifiActivityIconId = R.drawable.stat_sys_wifi_out;
    914                         break;
    915                     case WifiManager.DATA_ACTIVITY_INOUT:
    916                         mWifiActivityIconId = R.drawable.stat_sys_wifi_inout;
    917                         break;
    918                     case WifiManager.DATA_ACTIVITY_NONE:
    919                         mWifiActivityIconId = 0;
    920                         break;
    921                 }
    922             }
    923 
    924             combinedActivityIconId = mWifiActivityIconId;
    925             combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
    926             mContentDescriptionCombinedSignal = mContentDescriptionWifi;
    927         }
    928 
    929         if (mBluetoothTethered) {
    930             label = mContext.getString(R.string.bluetooth_tethered);
    931             combinedSignalIconId = mBluetoothTetherIconId;
    932             mContentDescriptionCombinedSignal = mContext.getString(
    933                     R.string.accessibility_bluetooth_tether);
    934         }
    935 
    936         if (mAirplaneMode &&
    937                 (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
    938             // Only display the flight-mode icon if not in "emergency calls only" mode.
    939 
    940             // look again; your radios are now airplanes
    941             mContentDescriptionPhoneSignal = mContext.getString(
    942                     R.string.accessibility_airplane_mode);
    943             mPhoneSignalIconId = mDataSignalIconId = R.drawable.stat_sys_signal_flightmode;
    944             mDataTypeIconId = 0;
    945 
    946             // combined values from connected wifi take precedence over airplane mode
    947             if (!mWifiConnected) {
    948                 label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
    949                 mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal;
    950                 combinedSignalIconId = mDataSignalIconId;
    951             }
    952         }
    953         else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected) {
    954             // pretty much totally disconnected
    955 
    956             label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
    957             // On devices without mobile radios, we want to show the wifi icon
    958             combinedSignalIconId =
    959                 mHasMobileDataFeature ? mDataSignalIconId : mWifiIconId;
    960             mContentDescriptionCombinedSignal = mHasMobileDataFeature
    961                 ? mContentDescriptionDataType : mContentDescriptionWifi;
    962 
    963             if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) {
    964                 mDataTypeIconId = R.drawable.stat_sys_data_connected_roam;
    965             } else {
    966                 mDataTypeIconId = 0;
    967             }
    968         }
    969 
    970         if (DEBUG) {
    971             Slog.d(TAG, "refreshViews connected={"
    972                     + (mWifiConnected?" wifi":"")
    973                     + (mDataConnected?" data":"")
    974                     + " } level="
    975                     + ((mSignalStrength == null)?"??":Integer.toString(mSignalStrength.getLevel()))
    976                     + " combinedSignalIconId=0x"
    977                     + Integer.toHexString(combinedSignalIconId)
    978                     + "/" + getResourceName(combinedSignalIconId)
    979                     + " combinedActivityIconId=0x" + Integer.toHexString(combinedActivityIconId)
    980                     + " mAirplaneMode=" + mAirplaneMode
    981                     + " mDataActivity=" + mDataActivity
    982                     + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId)
    983                     + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId)
    984                     + " mDataSignalIconId=0x" + Integer.toHexString(mDataSignalIconId)
    985                     + " mDataTypeIconId=0x" + Integer.toHexString(mDataTypeIconId)
    986                     + " mWifiIconId=0x" + Integer.toHexString(mWifiIconId)
    987                     + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId));
    988         }
    989 
    990         if (mLastPhoneSignalIconId          != mPhoneSignalIconId
    991          || mLastDataDirectionOverlayIconId != combinedActivityIconId
    992          || mLastWifiIconId                 != mWifiIconId
    993          || mLastWimaxIconId                != mWimaxIconId
    994          || mLastDataTypeIconId             != mDataTypeIconId)
    995         {
    996             // NB: the mLast*s will be updated later
    997             for (SignalCluster cluster : mSignalClusters) {
    998                 refreshSignalCluster(cluster);
    999             }
   1000         }
   1001 
   1002         // the phone icon on phones
   1003         if (mLastPhoneSignalIconId != mPhoneSignalIconId) {
   1004             mLastPhoneSignalIconId = mPhoneSignalIconId;
   1005             N = mPhoneSignalIconViews.size();
   1006             for (int i=0; i<N; i++) {
   1007                 final ImageView v = mPhoneSignalIconViews.get(i);
   1008                 v.setImageResource(mPhoneSignalIconId);
   1009                 v.setContentDescription(mContentDescriptionPhoneSignal);
   1010             }
   1011         }
   1012 
   1013         // the data icon on phones
   1014         if (mLastDataDirectionIconId != mDataDirectionIconId) {
   1015             mLastDataDirectionIconId = mDataDirectionIconId;
   1016             N = mDataDirectionIconViews.size();
   1017             for (int i=0; i<N; i++) {
   1018                 final ImageView v = mDataDirectionIconViews.get(i);
   1019                 v.setImageResource(mDataDirectionIconId);
   1020                 v.setContentDescription(mContentDescriptionDataType);
   1021             }
   1022         }
   1023 
   1024         // the wifi icon on phones
   1025         if (mLastWifiIconId != mWifiIconId) {
   1026             mLastWifiIconId = mWifiIconId;
   1027             N = mWifiIconViews.size();
   1028             for (int i=0; i<N; i++) {
   1029                 final ImageView v = mWifiIconViews.get(i);
   1030                 if (mWifiIconId == 0) {
   1031                     v.setVisibility(View.INVISIBLE);
   1032                 } else {
   1033                     v.setVisibility(View.VISIBLE);
   1034                     v.setImageResource(mWifiIconId);
   1035                     v.setContentDescription(mContentDescriptionWifi);
   1036                 }
   1037             }
   1038         }
   1039 
   1040         // the wimax icon on phones
   1041         if (mLastWimaxIconId != mWimaxIconId) {
   1042             mLastWimaxIconId = mWimaxIconId;
   1043             N = mWimaxIconViews.size();
   1044             for (int i=0; i<N; i++) {
   1045                 final ImageView v = mWimaxIconViews.get(i);
   1046                 if (mWimaxIconId == 0) {
   1047                     v.setVisibility(View.INVISIBLE);
   1048                 } else {
   1049                     v.setVisibility(View.VISIBLE);
   1050                     v.setImageResource(mWimaxIconId);
   1051                     v.setContentDescription(mContentDescriptionWimax);
   1052                 }
   1053            }
   1054         }
   1055         // the combined data signal icon
   1056         if (mLastCombinedSignalIconId != combinedSignalIconId) {
   1057             mLastCombinedSignalIconId = combinedSignalIconId;
   1058             N = mCombinedSignalIconViews.size();
   1059             for (int i=0; i<N; i++) {
   1060                 final ImageView v = mCombinedSignalIconViews.get(i);
   1061                 v.setImageResource(combinedSignalIconId);
   1062                 v.setContentDescription(mContentDescriptionCombinedSignal);
   1063             }
   1064         }
   1065 
   1066         // the data network type overlay
   1067         if (mLastDataTypeIconId != mDataTypeIconId) {
   1068             mLastDataTypeIconId = mDataTypeIconId;
   1069             N = mDataTypeIconViews.size();
   1070             for (int i=0; i<N; i++) {
   1071                 final ImageView v = mDataTypeIconViews.get(i);
   1072                 if (mDataTypeIconId == 0) {
   1073                     v.setVisibility(View.INVISIBLE);
   1074                 } else {
   1075                     v.setVisibility(View.VISIBLE);
   1076                     v.setImageResource(mDataTypeIconId);
   1077                     v.setContentDescription(mContentDescriptionDataType);
   1078                 }
   1079             }
   1080         }
   1081 
   1082         // the data direction overlay
   1083         if (mLastDataDirectionOverlayIconId != combinedActivityIconId) {
   1084             if (DEBUG) {
   1085                 Slog.d(TAG, "changing data overlay icon id to " + combinedActivityIconId);
   1086             }
   1087             mLastDataDirectionOverlayIconId = combinedActivityIconId;
   1088             N = mDataDirectionOverlayIconViews.size();
   1089             for (int i=0; i<N; i++) {
   1090                 final ImageView v = mDataDirectionOverlayIconViews.get(i);
   1091                 if (combinedActivityIconId == 0) {
   1092                     v.setVisibility(View.INVISIBLE);
   1093                 } else {
   1094                     v.setVisibility(View.VISIBLE);
   1095                     v.setImageResource(combinedActivityIconId);
   1096                     v.setContentDescription(mContentDescriptionDataType);
   1097                 }
   1098             }
   1099         }
   1100 
   1101         // the label in the notification panel
   1102         if (!mLastLabel.equals(label)) {
   1103             mLastLabel = label;
   1104             N = mLabelViews.size();
   1105             for (int i=0; i<N; i++) {
   1106                 TextView v = mLabelViews.get(i);
   1107                 v.setText(label);
   1108             }
   1109         }
   1110     }
   1111 
   1112     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   1113         pw.println("NetworkController state:");
   1114         pw.println("  - telephony ------");
   1115         pw.print("  hasService()=");
   1116         pw.println(hasService());
   1117         pw.print("  mHspaDataDistinguishable=");
   1118         pw.println(mHspaDataDistinguishable);
   1119         pw.print("  mDataConnected=");
   1120         pw.println(mDataConnected);
   1121         pw.print("  mSimState=");
   1122         pw.println(mSimState);
   1123         pw.print("  mPhoneState=");
   1124         pw.println(mPhoneState);
   1125         pw.print("  mDataState=");
   1126         pw.println(mDataState);
   1127         pw.print("  mDataActivity=");
   1128         pw.println(mDataActivity);
   1129         pw.print("  mDataNetType=");
   1130         pw.print(mDataNetType);
   1131         pw.print("/");
   1132         pw.println(TelephonyManager.getNetworkTypeName(mDataNetType));
   1133         pw.print("  mServiceState=");
   1134         pw.println(mServiceState);
   1135         pw.print("  mSignalStrength=");
   1136         pw.println(mSignalStrength);
   1137         pw.print("  mLastSignalLevel=");
   1138         pw.println(mLastSignalLevel);
   1139         pw.print("  mNetworkName=");
   1140         pw.println(mNetworkName);
   1141         pw.print("  mNetworkNameDefault=");
   1142         pw.println(mNetworkNameDefault);
   1143         pw.print("  mNetworkNameSeparator=");
   1144         pw.println(mNetworkNameSeparator.replace("\n","\\n"));
   1145         pw.print("  mPhoneSignalIconId=0x");
   1146         pw.print(Integer.toHexString(mPhoneSignalIconId));
   1147         pw.print("/");
   1148         pw.println(getResourceName(mPhoneSignalIconId));
   1149         pw.print("  mDataDirectionIconId=");
   1150         pw.print(Integer.toHexString(mDataDirectionIconId));
   1151         pw.print("/");
   1152         pw.println(getResourceName(mDataDirectionIconId));
   1153         pw.print("  mDataSignalIconId=");
   1154         pw.print(Integer.toHexString(mDataSignalIconId));
   1155         pw.print("/");
   1156         pw.println(getResourceName(mDataSignalIconId));
   1157         pw.print("  mDataTypeIconId=");
   1158         pw.print(Integer.toHexString(mDataTypeIconId));
   1159         pw.print("/");
   1160         pw.println(getResourceName(mDataTypeIconId));
   1161 
   1162         pw.println("  - wifi ------");
   1163         pw.print("  mWifiEnabled=");
   1164         pw.println(mWifiEnabled);
   1165         pw.print("  mWifiConnected=");
   1166         pw.println(mWifiConnected);
   1167         pw.print("  mWifiRssi=");
   1168         pw.println(mWifiRssi);
   1169         pw.print("  mWifiLevel=");
   1170         pw.println(mWifiLevel);
   1171         pw.print("  mWifiSsid=");
   1172         pw.println(mWifiSsid);
   1173         pw.println(String.format("  mWifiIconId=0x%08x/%s",
   1174                     mWifiIconId, getResourceName(mWifiIconId)));
   1175         pw.print("  mWifiActivity=");
   1176         pw.println(mWifiActivity);
   1177 
   1178         if (mWimaxSupported) {
   1179             pw.println("  - wimax ------");
   1180             pw.print("  mIsWimaxEnabled="); pw.println(mIsWimaxEnabled);
   1181             pw.print("  mWimaxConnected="); pw.println(mWimaxConnected);
   1182             pw.print("  mWimaxIdle="); pw.println(mWimaxIdle);
   1183             pw.println(String.format("  mWimaxIconId=0x%08x/%s",
   1184                         mWimaxIconId, getResourceName(mWimaxIconId)));
   1185             pw.println(String.format("  mWimaxSignal=%d", mWimaxSignal));
   1186             pw.println(String.format("  mWimaxState=%d", mWimaxState));
   1187             pw.println(String.format("  mWimaxExtraState=%d", mWimaxExtraState));
   1188         }
   1189 
   1190         pw.println("  - Bluetooth ----");
   1191         pw.print("  mBtReverseTethered=");
   1192         pw.println(mBluetoothTethered);
   1193 
   1194         pw.println("  - connectivity ------");
   1195         pw.print("  mInetCondition=");
   1196         pw.println(mInetCondition);
   1197 
   1198         pw.println("  - icons ------");
   1199         pw.print("  mLastPhoneSignalIconId=0x");
   1200         pw.print(Integer.toHexString(mLastPhoneSignalIconId));
   1201         pw.print("/");
   1202         pw.println(getResourceName(mLastPhoneSignalIconId));
   1203         pw.print("  mLastDataDirectionIconId=0x");
   1204         pw.print(Integer.toHexString(mLastDataDirectionIconId));
   1205         pw.print("/");
   1206         pw.println(getResourceName(mLastDataDirectionIconId));
   1207         pw.print("  mLastDataDirectionOverlayIconId=0x");
   1208         pw.print(Integer.toHexString(mLastDataDirectionOverlayIconId));
   1209         pw.print("/");
   1210         pw.println(getResourceName(mLastDataDirectionOverlayIconId));
   1211         pw.print("  mLastWifiIconId=0x");
   1212         pw.print(Integer.toHexString(mLastWifiIconId));
   1213         pw.print("/");
   1214         pw.println(getResourceName(mLastWifiIconId));
   1215         pw.print("  mLastCombinedSignalIconId=0x");
   1216         pw.print(Integer.toHexString(mLastCombinedSignalIconId));
   1217         pw.print("/");
   1218         pw.println(getResourceName(mLastCombinedSignalIconId));
   1219         pw.print("  mLastDataTypeIconId=0x");
   1220         pw.print(Integer.toHexString(mLastDataTypeIconId));
   1221         pw.print("/");
   1222         pw.println(getResourceName(mLastDataTypeIconId));
   1223         pw.print("  mLastLabel=");
   1224         pw.print(mLastLabel);
   1225         pw.println("");
   1226     }
   1227 
   1228     private String getResourceName(int resId) {
   1229         if (resId != 0) {
   1230             final Resources res = mContext.getResources();
   1231             try {
   1232                 return res.getResourceName(resId);
   1233             } catch (android.content.res.Resources.NotFoundException ex) {
   1234                 return "(unknown)";
   1235             }
   1236         } else {
   1237             return "(null)";
   1238         }
   1239     }
   1240 
   1241 }
   1242