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