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