NetworkController.java revision 40cdd9b65091f402ae229a15cf001826b317d1c9
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.systemui.statusbar.policy; 18 19import java.io.FileDescriptor; 20import java.io.PrintWriter; 21import java.util.ArrayList; 22import java.util.List; 23 24import android.content.BroadcastReceiver; 25import android.content.Context; 26import android.content.Intent; 27import android.content.IntentFilter; 28import android.content.res.Resources; 29import android.net.ConnectivityManager; 30import android.net.NetworkInfo; 31import android.net.wifi.SupplicantState; 32import android.net.wifi.WifiConfiguration; 33import android.net.wifi.WifiInfo; 34import android.net.wifi.WifiManager; 35import android.os.Binder; 36import android.os.RemoteException; 37import android.provider.Settings; 38import android.provider.Telephony; 39import android.telephony.PhoneStateListener; 40import android.telephony.ServiceState; 41import android.telephony.SignalStrength; 42import android.telephony.TelephonyManager; 43import android.util.Slog; 44import android.view.View; 45import android.widget.ImageView; 46import android.widget.TextView; 47 48import com.android.internal.app.IBatteryStats; 49import com.android.internal.telephony.IccCard; 50import com.android.internal.telephony.TelephonyIntents; 51import com.android.internal.telephony.cdma.EriInfo; 52import com.android.server.am.BatteryStatsService; 53 54import com.android.systemui.R; 55 56public class NetworkController extends BroadcastReceiver { 57 // debug 58 static final String TAG = "StatusBar.NetworkController"; 59 static final boolean DEBUG = false; 60 61 // telephony 62 boolean mHspaDataDistinguishable; 63 final TelephonyManager mPhone; 64 boolean mDataConnected; 65 IccCard.State mSimState = IccCard.State.READY; 66 int mPhoneState = TelephonyManager.CALL_STATE_IDLE; 67 int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 68 int mDataState = TelephonyManager.DATA_DISCONNECTED; 69 int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE; 70 ServiceState mServiceState; 71 SignalStrength mSignalStrength; 72 int[] mDataIconList = TelephonyIcons.DATA_G[0]; 73 String mNetworkName; 74 String mNetworkNameDefault; 75 String mNetworkNameSeparator; 76 int mPhoneSignalIconId; 77 int mDataDirectionIconId; 78 int mDataSignalIconId; 79 int mDataTypeIconId; 80 81 // wifi 82 final WifiManager mWifiManager; 83 boolean mWifiEnabled, mWifiConnected; 84 int mWifiLevel; 85 String mWifiSsid; 86 int mWifiIconId; 87 88 // bluetooth 89 private boolean mBluetoothTethered = false; 90 private int mBluetoothTetherIconId = 91 com.android.internal.R.drawable.stat_sys_tether_bluetooth; 92 93 // data connectivity (regardless of state, can we access the internet?) 94 // state of inet connection - 0 not connected, 100 connected 95 private int mInetCondition = 0; 96 private static final int INET_CONDITION_THRESHOLD = 50; 97 98 // our ui 99 Context mContext; 100 ArrayList<ImageView> mPhoneSignalIconViews = new ArrayList<ImageView>(); 101 ArrayList<ImageView> mDataDirectionIconViews = new ArrayList<ImageView>(); 102 ArrayList<ImageView> mWifiIconViews = new ArrayList<ImageView>(); 103 ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>(); 104 ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>(); 105 ArrayList<TextView> mLabelViews = new ArrayList<TextView>(); 106 int mLastPhoneSignalIconId = -1; 107 int mLastDataDirectionIconId = -1; 108 int mLastWifiIconId = -1; 109 int mLastCombinedSignalIconId = -1; 110 int mLastDataTypeIconId = -1; 111 String mLastLabel = ""; 112 113 // yuck -- stop doing this here and put it in the framework 114 IBatteryStats mBatteryStats; 115 116 /** 117 * Construct this controller object and register for updates. 118 */ 119 public NetworkController(Context context) { 120 mContext = context; 121 122 // telephony 123 mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 124 mPhone.listen(mPhoneStateListener, 125 PhoneStateListener.LISTEN_SERVICE_STATE 126 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS 127 | PhoneStateListener.LISTEN_CALL_STATE 128 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 129 | PhoneStateListener.LISTEN_DATA_ACTIVITY); 130 mHspaDataDistinguishable = mContext.getResources().getBoolean( 131 R.bool.config_hspa_data_distinguishable); 132 mNetworkNameSeparator = mContext.getString(R.string.status_bar_network_name_separator); 133 mNetworkNameDefault = mContext.getString( 134 com.android.internal.R.string.lockscreen_carrier_default); 135 mNetworkName = mNetworkNameDefault; 136 137 // wifi 138 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 139 140 // broadcasts 141 IntentFilter filter = new IntentFilter(); 142 filter.addAction(WifiManager.RSSI_CHANGED_ACTION); 143 filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 144 filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 145 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 146 filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION); 147 filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 148 filter.addAction(ConnectivityManager.INET_CONDITION_ACTION); 149 context.registerReceiver(this, filter); 150 151 // yuck 152 mBatteryStats = BatteryStatsService.getService(); 153 } 154 155 public void addPhoneSignalIconView(ImageView v) { 156 mPhoneSignalIconViews.add(v); 157 } 158 159 public void addDataDirectionIconView(ImageView v) { 160 mDataDirectionIconViews.add(v); 161 } 162 163 public void addWifiIconView(ImageView v) { 164 mWifiIconViews.add(v); 165 } 166 167 public void addCombinedSignalIconView(ImageView v) { 168 mCombinedSignalIconViews.add(v); 169 } 170 171 public void addDataTypeIconView(ImageView v) { 172 mDataTypeIconViews.add(v); 173 } 174 175 public void addLabelView(TextView v) { 176 mLabelViews.add(v); 177 } 178 179 public void onReceive(Context context, Intent intent) { 180 final String action = intent.getAction(); 181 if (action.equals(WifiManager.RSSI_CHANGED_ACTION) 182 || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) 183 || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 184 updateWifiState(intent); 185 refreshViews(); 186 } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { 187 updateSimState(intent); 188 updateDataIcon(); 189 refreshViews(); 190 } else if (action.equals(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION)) { 191 updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false), 192 intent.getStringExtra(Telephony.Intents.EXTRA_SPN), 193 intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false), 194 intent.getStringExtra(Telephony.Intents.EXTRA_PLMN)); 195 refreshViews(); 196 } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) || 197 action.equals(ConnectivityManager.INET_CONDITION_ACTION)) { 198 updateConnectivity(intent); 199 refreshViews(); 200 } 201 } 202 203 204 // ===== Telephony ============================================================== 205 206 PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 207 @Override 208 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 209 if (DEBUG) { 210 Slog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength); 211 } 212 mSignalStrength = signalStrength; 213 updateTelephonySignalStrength(); 214 refreshViews(); 215 } 216 217 @Override 218 public void onServiceStateChanged(ServiceState state) { 219 if (DEBUG) { 220 Slog.d(TAG, "onServiceStateChanged state=" + state.getState()); 221 } 222 mServiceState = state; 223 updateTelephonySignalStrength(); 224 updateDataIcon(); 225 refreshViews(); 226 } 227 228 @Override 229 public void onCallStateChanged(int state, String incomingNumber) { 230 if (DEBUG) { 231 Slog.d(TAG, "onCallStateChanged state=" + state); 232 } 233 // In cdma, if a voice call is made, RSSI should switch to 1x. 234 if (isCdma()) { 235 updateTelephonySignalStrength(); 236 refreshViews(); 237 } 238 } 239 240 @Override 241 public void onDataConnectionStateChanged(int state, int networkType) { 242 if (DEBUG) { 243 Slog.d(TAG, "onDataConnectionStateChanged: state=" + state 244 + " type=" + networkType); 245 } 246 mDataState = state; 247 mDataNetType = networkType; 248 updateDataNetType(); 249 updateDataIcon(); 250 refreshViews(); 251 } 252 253 @Override 254 public void onDataActivity(int direction) { 255 if (DEBUG) { 256 Slog.d(TAG, "onDataActivity: direction=" + direction); 257 } 258 mDataActivity = direction; 259 updateDataIcon(); 260 refreshViews(); 261 } 262 }; 263 264 private final void updateSimState(Intent intent) { 265 String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); 266 if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { 267 mSimState = IccCard.State.ABSENT; 268 } 269 else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { 270 mSimState = IccCard.State.READY; 271 } 272 else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { 273 final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); 274 if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { 275 mSimState = IccCard.State.PIN_REQUIRED; 276 } 277 else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { 278 mSimState = IccCard.State.PUK_REQUIRED; 279 } 280 else { 281 mSimState = IccCard.State.NETWORK_LOCKED; 282 } 283 } else { 284 mSimState = IccCard.State.UNKNOWN; 285 } 286 } 287 288 private boolean isCdma() { 289 return (mSignalStrength != null) && !mSignalStrength.isGsm(); 290 } 291 292 private boolean isEvdo() { 293 return ((mServiceState != null) 294 && ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0) 295 || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_A) 296 || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_B))); 297 } 298 299 private boolean hasService() { 300 if (mServiceState != null) { 301 switch (mServiceState.getState()) { 302 case ServiceState.STATE_OUT_OF_SERVICE: 303 case ServiceState.STATE_POWER_OFF: 304 return false; 305 default: 306 return true; 307 } 308 } else { 309 return false; 310 } 311 } 312 313 private int getCdmaLevel() { 314 if (mSignalStrength == null) return 0; 315 final int cdmaDbm = mSignalStrength.getCdmaDbm(); 316 final int cdmaEcio = mSignalStrength.getCdmaEcio(); 317 int levelDbm = 0; 318 int levelEcio = 0; 319 320 if (cdmaDbm >= -75) levelDbm = 4; 321 else if (cdmaDbm >= -85) levelDbm = 3; 322 else if (cdmaDbm >= -95) levelDbm = 2; 323 else if (cdmaDbm >= -100) levelDbm = 1; 324 else levelDbm = 0; 325 326 // Ec/Io are in dB*10 327 if (cdmaEcio >= -90) levelEcio = 4; 328 else if (cdmaEcio >= -110) levelEcio = 3; 329 else if (cdmaEcio >= -130) levelEcio = 2; 330 else if (cdmaEcio >= -150) levelEcio = 1; 331 else levelEcio = 0; 332 333 return (levelDbm < levelEcio) ? levelDbm : levelEcio; 334 } 335 336 private int getEvdoLevel() { 337 if (mSignalStrength == null) return 0; 338 int evdoDbm = mSignalStrength.getEvdoDbm(); 339 int evdoSnr = mSignalStrength.getEvdoSnr(); 340 int levelEvdoDbm = 0; 341 int levelEvdoSnr = 0; 342 343 if (evdoDbm >= -65) levelEvdoDbm = 4; 344 else if (evdoDbm >= -75) levelEvdoDbm = 3; 345 else if (evdoDbm >= -90) levelEvdoDbm = 2; 346 else if (evdoDbm >= -105) levelEvdoDbm = 1; 347 else levelEvdoDbm = 0; 348 349 if (evdoSnr >= 7) levelEvdoSnr = 4; 350 else if (evdoSnr >= 5) levelEvdoSnr = 3; 351 else if (evdoSnr >= 3) levelEvdoSnr = 2; 352 else if (evdoSnr >= 1) levelEvdoSnr = 1; 353 else levelEvdoSnr = 0; 354 355 return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 356 } 357 358 private final void updateTelephonySignalStrength() { 359 // Display signal strength while in "emergency calls only" mode 360 if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) { 361 //Slog.d(TAG, "updateTelephonySignalStrength: no service"); 362 if (Settings.System.getInt(mContext.getContentResolver(), 363 Settings.System.AIRPLANE_MODE_ON, 0) == 1) { 364 mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode; 365 mDataSignalIconId = R.drawable.stat_sys_signal_flightmode; 366 } else { 367 mPhoneSignalIconId = R.drawable.stat_sys_signal_null; 368 mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null 369 } 370 } else { 371 if (mSignalStrength == null) { 372 mPhoneSignalIconId = R.drawable.stat_sys_signal_null; 373 mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null 374 } else if (isCdma()) { 375 // If 3G(EV) and 1x network are available than 3G should be 376 // displayed, displayed RSSI should be from the EV side. 377 // If a voice call is made then RSSI should switch to 1x. 378 int iconLevel; 379 if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){ 380 iconLevel = getEvdoLevel(); 381 } else { 382 iconLevel = getCdmaLevel(); 383 } 384 int[] iconList; 385 if (isCdmaEri()) { 386 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition]; 387 } else { 388 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition]; 389 } 390 mPhoneSignalIconId = iconList[iconLevel]; 391 mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel]; 392 } else { 393 int asu = mSignalStrength.getGsmSignalStrength(); 394 395 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 396 // asu = 0 (-113dB or less) is very weak 397 // signal, its better to show 0 bars to the user in such cases. 398 // asu = 99 is a special case, where the signal strength is unknown. 399 int iconLevel; 400 if (asu <= 2 || asu == 99) iconLevel = 0; 401 else if (asu >= 12) iconLevel = 4; 402 else if (asu >= 8) iconLevel = 3; 403 else if (asu >= 5) iconLevel = 2; 404 else iconLevel = 1; 405 406 // Though mPhone is a Manager, this call is not an IPC 407 int[] iconList; 408 if (mPhone.isNetworkRoaming()) { 409 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition]; 410 } else { 411 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition]; 412 } 413 mPhoneSignalIconId = iconList[iconLevel]; 414 mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel]; 415 } 416 } 417 } 418 419 private final void updateDataNetType() { 420 switch (mDataNetType) { 421 case TelephonyManager.NETWORK_TYPE_UNKNOWN: 422 mDataIconList = TelephonyIcons.DATA_G[mInetCondition]; 423 mDataTypeIconId = 0; 424 break; 425 case TelephonyManager.NETWORK_TYPE_EDGE: 426 mDataIconList = TelephonyIcons.DATA_E[mInetCondition]; 427 mDataTypeIconId = R.drawable.stat_sys_signal_edge; 428 break; 429 case TelephonyManager.NETWORK_TYPE_UMTS: 430 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 431 mDataTypeIconId = R.drawable.stat_sys_signal_3g; 432 break; 433 case TelephonyManager.NETWORK_TYPE_HSDPA: 434 case TelephonyManager.NETWORK_TYPE_HSUPA: 435 case TelephonyManager.NETWORK_TYPE_HSPA: 436 if (mHspaDataDistinguishable) { 437 mDataIconList = TelephonyIcons.DATA_H[mInetCondition]; 438 mDataTypeIconId = R.drawable.stat_sys_signal_hsdpa; 439 } else { 440 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 441 mDataTypeIconId = R.drawable.stat_sys_signal_3g; 442 } 443 break; 444 case TelephonyManager.NETWORK_TYPE_CDMA: 445 // display 1xRTT for IS95A/B 446 mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; 447 mDataTypeIconId = R.drawable.stat_sys_signal_1x; 448 break; 449 case TelephonyManager.NETWORK_TYPE_1xRTT: 450 mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; 451 mDataTypeIconId = R.drawable.stat_sys_signal_1x; 452 break; 453 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through 454 case TelephonyManager.NETWORK_TYPE_EVDO_A: 455 case TelephonyManager.NETWORK_TYPE_EVDO_B: 456 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 457 mDataTypeIconId = R.drawable.stat_sys_signal_3g; 458 break; 459 // TODO - add support for NETWORK_TYPE_LTE and NETWORK_TYPE_EHRPD 460 default: 461 mDataIconList = TelephonyIcons.DATA_G[mInetCondition]; 462 mDataTypeIconId = R.drawable.stat_sys_signal_gprs; 463 break; 464 } 465 if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) { 466 mDataTypeIconId = R.drawable.stat_sys_signal_roam; 467 } 468 } 469 470 boolean isCdmaEri() { 471 final int iconIndex = mServiceState.getCdmaEriIconIndex(); 472 if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) { 473 final int iconMode = mServiceState.getCdmaEriIconMode(); 474 if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL 475 || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) { 476 return true; 477 } 478 } 479 return false; 480 } 481 482 private final void updateDataIcon() { 483 int iconId; 484 boolean visible = true; 485 486 if (!isCdma()) { 487 // GSM case, we have to check also the sim state 488 if (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN) { 489 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { 490 switch (mDataActivity) { 491 case TelephonyManager.DATA_ACTIVITY_IN: 492 iconId = mDataIconList[1]; 493 break; 494 case TelephonyManager.DATA_ACTIVITY_OUT: 495 iconId = mDataIconList[2]; 496 break; 497 case TelephonyManager.DATA_ACTIVITY_INOUT: 498 iconId = mDataIconList[3]; 499 break; 500 default: 501 iconId = mDataIconList[0]; 502 break; 503 } 504 mDataDirectionIconId = iconId; 505 } else { 506 iconId = 0; 507 visible = false; 508 } 509 } else { 510 iconId = R.drawable.stat_sys_no_sim; 511 } 512 } else { 513 // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT 514 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { 515 switch (mDataActivity) { 516 case TelephonyManager.DATA_ACTIVITY_IN: 517 iconId = mDataIconList[1]; 518 break; 519 case TelephonyManager.DATA_ACTIVITY_OUT: 520 iconId = mDataIconList[2]; 521 break; 522 case TelephonyManager.DATA_ACTIVITY_INOUT: 523 iconId = mDataIconList[3]; 524 break; 525 case TelephonyManager.DATA_ACTIVITY_DORMANT: 526 default: 527 iconId = mDataIconList[0]; 528 break; 529 } 530 } else { 531 iconId = 0; 532 visible = false; 533 } 534 } 535 536 // yuck - this should NOT be done by the status bar 537 long ident = Binder.clearCallingIdentity(); 538 try { 539 mBatteryStats.notePhoneDataConnectionState(mPhone.getNetworkType(), visible); 540 } catch (RemoteException e) { 541 } finally { 542 Binder.restoreCallingIdentity(ident); 543 } 544 545 mDataDirectionIconId = iconId; 546 mDataConnected = visible; 547 } 548 549 void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) { 550 if (false) { 551 Slog.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn 552 + " showPlmn=" + showPlmn + " plmn=" + plmn); 553 } 554 StringBuilder str = new StringBuilder(); 555 boolean something = false; 556 if (showPlmn && plmn != null) { 557 str.append(plmn); 558 something = true; 559 } 560 if (showSpn && spn != null) { 561 if (something) { 562 str.append(mNetworkNameSeparator); 563 } 564 str.append(spn); 565 something = true; 566 } 567 if (something) { 568 mNetworkName = str.toString(); 569 } else { 570 mNetworkName = mNetworkNameDefault; 571 } 572 } 573 574 // ===== Wifi =================================================================== 575 576 private void updateWifiState(Intent intent) { 577 final String action = intent.getAction(); 578 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 579 mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 580 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; 581 582 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 583 final NetworkInfo networkInfo = (NetworkInfo) 584 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 585 boolean wasConnected = mWifiConnected; 586 mWifiConnected = networkInfo != null && networkInfo.isConnected(); 587 // If we just connected, grab the inintial signal strength and ssid 588 if (mWifiConnected && !wasConnected) { 589 WifiInfo info = mWifiManager.getConnectionInfo(); 590 if (info != null) { 591 mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(), 592 WifiIcons.WIFI_LEVEL_COUNT); 593 mWifiSsid = huntForSsid(info); 594 } else { 595 mWifiLevel = 0; 596 mWifiSsid = null; 597 } 598 } else if (!mWifiConnected) { 599 mWifiLevel = 0; 600 mWifiSsid = null; 601 } 602 603 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 604 if (mWifiConnected) { 605 final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); 606 mWifiLevel = WifiManager.calculateSignalLevel(newRssi, WifiIcons.WIFI_LEVEL_COUNT); 607 } 608 } 609 610 updateWifiIcons(); 611 } 612 613 private void updateWifiIcons() { 614 if (mWifiConnected) { 615 mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel]; 616 } else { 617 mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]; 618 } 619 } 620 621 private String huntForSsid(WifiInfo info) { 622 String ssid = info.getSSID(); 623 if (ssid != null) { 624 return ssid; 625 } 626 // OK, it's not in the connectionInfo; we have to go hunting for it 627 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks(); 628 for (WifiConfiguration net : networks) { 629 if (net.networkId == info.getNetworkId()) { 630 return net.SSID; 631 } 632 } 633 return null; 634 } 635 636 637 // ===== Full or limited Internet connectivity ================================== 638 639 private void updateConnectivity(Intent intent) { 640 NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra( 641 ConnectivityManager.EXTRA_NETWORK_INFO)); 642 int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0); 643 644 int inetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0); 645 646 switch (info.getType()) { 647 case ConnectivityManager.TYPE_MOBILE: 648 mInetCondition = inetCondition; 649 updateDataNetType(); 650 updateDataIcon(); 651 updateTelephonySignalStrength(); // apply any change in connectionStatus 652 break; 653 case ConnectivityManager.TYPE_WIFI: 654 mInetCondition = inetCondition; 655 updateWifiIcons(); 656 break; 657 case ConnectivityManager.TYPE_BLUETOOTH: 658 mInetCondition = inetCondition; 659 if (info != null) { 660 mBluetoothTethered = info.isConnected() ? true: false; 661 } else { 662 mBluetoothTethered = false; 663 } 664 break; 665 } 666 } 667 668 669 // ===== Update the views ======================================================= 670 671 // figure out what to show- there should be one connected network or nothing 672 // General order of preference is: wifi, 3G than bluetooth. This might vary by product. 673 void refreshViews() { 674 Context context = mContext; 675 676 int combinedSignalIconId; 677 int dataTypeIconId; 678 String label; 679 int N; 680 681 if (mWifiConnected) { 682 if (mWifiSsid == null) { 683 label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid); 684 } else { 685 label = mWifiSsid; 686 } 687 combinedSignalIconId = mWifiIconId; 688 dataTypeIconId = 0; 689 } else if (mDataConnected) { 690 label = mNetworkName; 691 combinedSignalIconId = mDataSignalIconId; 692 dataTypeIconId = mDataTypeIconId; 693 } else if (mBluetoothTethered) { 694 label = mContext.getString(R.string.bluetooth_tethered); 695 combinedSignalIconId = mBluetoothTetherIconId; 696 dataTypeIconId = 0; 697 } else { 698 label = context.getString(R.string.status_bar_settings_signal_meter_disconnected); 699 combinedSignalIconId = mDataSignalIconId; 700 dataTypeIconId = 0; 701 } 702 703 if (false) { 704 Slog.d(TAG, "refreshViews combinedSignalIconId=0x" 705 + Integer.toHexString(mPhoneSignalIconId) 706 + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId) 707 + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId) 708 + " mDataSignalIconId=0x" + Integer.toHexString(mDataSignalIconId) 709 + " mDataTypeIconId=0x" + Integer.toHexString(mDataTypeIconId) 710 + " mWifiIconId=0x" + Integer.toHexString(mWifiIconId) 711 + "mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId)); 712 } 713 714 // the phone icon on phones 715 if (mLastPhoneSignalIconId != mPhoneSignalIconId) { 716 mLastPhoneSignalIconId = mPhoneSignalIconId; 717 N = mPhoneSignalIconViews.size(); 718 for (int i=0; i<N; i++) { 719 final ImageView v = mPhoneSignalIconViews.get(i); 720 v.setImageResource(mPhoneSignalIconId); 721 } 722 } 723 724 // the data icon on phones 725 if (mLastDataDirectionIconId != mDataDirectionIconId) { 726 mLastDataDirectionIconId = mDataDirectionIconId; 727 N = mDataDirectionIconViews.size(); 728 for (int i=0; i<N; i++) { 729 final ImageView v = mDataDirectionIconViews.get(i); 730 v.setImageResource(mDataDirectionIconId); 731 } 732 } 733 734 // the wifi icon on phones 735 if (mLastWifiIconId != mWifiIconId) { 736 mLastWifiIconId = mWifiIconId; 737 N = mWifiIconViews.size(); 738 for (int i=0; i<N; i++) { 739 final ImageView v = mWifiIconViews.get(i); 740 v.setImageResource(mWifiIconId); 741 } 742 } 743 744 // the combined data signal icon 745 if (mLastCombinedSignalIconId != combinedSignalIconId) { 746 mLastCombinedSignalIconId = combinedSignalIconId; 747 N = mCombinedSignalIconViews.size(); 748 for (int i=0; i<N; i++) { 749 final ImageView v = mCombinedSignalIconViews.get(i); 750 v.setImageResource(combinedSignalIconId); 751 } 752 } 753 754 // the data network type overlay 755 if (mLastDataTypeIconId != dataTypeIconId) { 756 mLastDataTypeIconId = dataTypeIconId; 757 N = mDataTypeIconViews.size(); 758 for (int i=0; i<N; i++) { 759 final ImageView v = mDataTypeIconViews.get(i); 760 if (dataTypeIconId == 0) { 761 v.setVisibility(View.INVISIBLE); 762 } else { 763 v.setVisibility(View.VISIBLE); 764 v.setImageResource(dataTypeIconId); 765 } 766 } 767 } 768 769 // the label in the notification panel 770 if (!mLastLabel.equals(label)) { 771 mLastLabel = label; 772 N = mLabelViews.size(); 773 for (int i=0; i<N; i++) { 774 TextView v = mLabelViews.get(i); 775 v.setText(label); 776 } 777 } 778 } 779 780 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 781 pw.println(" - telephony ------"); 782 pw.print(" mHspaDataDistinguishable="); 783 pw.println(mHspaDataDistinguishable); 784 pw.print(" mDataConnected="); 785 pw.println(mDataConnected); 786 pw.print(" mSimState="); 787 pw.println(mSimState); 788 pw.print(" mPhoneState="); 789 pw.println(mPhoneState); 790 pw.print(" mDataState="); 791 pw.println(mDataState); 792 pw.print(" mDataActivity="); 793 pw.println(mDataActivity); 794 pw.print(" mServiceState="); 795 pw.println(mServiceState.toString()); 796 pw.print(" mNetworkName="); 797 pw.println(mNetworkName); 798 pw.print(" mNetworkNameDefault="); 799 pw.println(mNetworkNameDefault); 800 pw.print(" mNetworkNameSeparator="); 801 pw.println(mNetworkNameSeparator); 802 pw.print(" mPhoneSignalIconId=0x"); 803 pw.print(Integer.toHexString(mPhoneSignalIconId)); 804 pw.print("/"); 805 pw.println(getResourceName(mPhoneSignalIconId)); 806 pw.print(" mDataDirectionIconId="); 807 pw.print(Integer.toHexString(mDataDirectionIconId)); 808 pw.print("/"); 809 pw.println(getResourceName(mDataDirectionIconId)); 810 pw.print(" mDataSignalIconId="); 811 pw.print(Integer.toHexString(mDataSignalIconId)); 812 pw.print("/"); 813 pw.println(getResourceName(mDataSignalIconId)); 814 pw.print(" mDataTypeIconId="); 815 pw.print(Integer.toHexString(mDataTypeIconId)); 816 pw.print("/"); 817 pw.println(getResourceName(mDataTypeIconId)); 818 819 pw.println(" - wifi ------"); 820 pw.print(" mWifiEnabled="); 821 pw.println(mWifiEnabled); 822 pw.print(" mWifiConnected="); 823 pw.println(mWifiConnected); 824 pw.print(" mWifiLevel="); 825 pw.println(mWifiLevel); 826 pw.print(" mWifiSsid="); 827 pw.println(mWifiSsid); 828 pw.print(" mWifiIconId="); 829 pw.println(mWifiIconId); 830 831 pw.println(" - Bluetooth ----"); 832 pw.print(" mBtReverseTethered="); 833 pw.println(mBluetoothTethered); 834 835 pw.println(" - connectivity ------"); 836 pw.print(" mInetCondition="); 837 pw.println(mInetCondition); 838 839 pw.println(" - icons ------"); 840 pw.print(" mLastPhoneSignalIconId=0x"); 841 pw.print(Integer.toHexString(mLastPhoneSignalIconId)); 842 pw.print("/"); 843 pw.println(getResourceName(mLastPhoneSignalIconId)); 844 pw.print(" mLastDataDirectionIconId=0x"); 845 pw.print(Integer.toHexString(mLastDataDirectionIconId)); 846 pw.print("/"); 847 pw.println(getResourceName(mLastDataDirectionIconId)); 848 pw.print(" mLastWifiIconId=0x"); 849 pw.print(Integer.toHexString(mLastWifiIconId)); 850 pw.print("/"); 851 pw.println(getResourceName(mLastWifiIconId)); 852 pw.print(" mLastCombinedSignalIconId=0x"); 853 pw.print(Integer.toHexString(mLastCombinedSignalIconId)); 854 pw.print("/"); 855 pw.println(getResourceName(mLastCombinedSignalIconId)); 856 pw.print(" mLastDataTypeIconId=0x"); 857 pw.print(Integer.toHexString(mLastDataTypeIconId)); 858 pw.print("/"); 859 pw.println(getResourceName(mLastCombinedSignalIconId)); 860 pw.print(" mLastLabel="); 861 pw.print(mLastLabel); 862 } 863 864 private String getResourceName(int resId) { 865 if (resId == 0) { 866 final Resources res = mContext.getResources(); 867 try { 868 return res.getResourceName(resId); 869 } catch (android.content.res.Resources.NotFoundException ex) { 870 return "(unknown)"; 871 } 872 } else { 873 return "(null)"; 874 } 875 } 876 877} 878