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