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