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