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