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