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 17 package com.android.systemui.statusbar.policy; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.content.res.Resources; 24 import android.net.ConnectivityManager; 25 import android.net.NetworkInfo; 26 import android.net.wifi.WifiConfiguration; 27 import android.net.wifi.WifiInfo; 28 import android.net.wifi.WifiManager; 29 import android.net.wimax.WimaxManagerConstants; 30 import android.os.Bundle; 31 import android.os.Handler; 32 import android.os.Message; 33 import android.os.Messenger; 34 import android.provider.Settings; 35 import android.telephony.PhoneStateListener; 36 import android.telephony.ServiceState; 37 import android.telephony.SignalStrength; 38 import android.telephony.TelephonyManager; 39 import android.util.Log; 40 import android.view.View; 41 import android.widget.TextView; 42 43 import com.android.internal.telephony.IccCardConstants; 44 import com.android.internal.telephony.TelephonyIntents; 45 import com.android.internal.telephony.cdma.EriInfo; 46 import com.android.internal.util.AsyncChannel; 47 import com.android.systemui.DemoMode; 48 import com.android.systemui.R; 49 50 import java.io.FileDescriptor; 51 import java.io.PrintWriter; 52 import java.util.ArrayList; 53 import java.util.List; 54 import java.util.Locale; 55 56 public 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 mPhoneSignalIconId = R.drawable.stat_sys_signal_null; 518 mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal; 519 mDataSignalIconId = R.drawable.stat_sys_signal_null; 520 } else { 521 if (mSignalStrength == null) { 522 if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null"); 523 mPhoneSignalIconId = R.drawable.stat_sys_signal_null; 524 mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal; 525 mDataSignalIconId = R.drawable.stat_sys_signal_null; 526 mContentDescriptionPhoneSignal = mContext.getString( 527 AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]); 528 } else { 529 int iconLevel; 530 int[] iconList; 531 if (isCdma() && mAlwaysShowCdmaRssi) { 532 mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel(); 533 if(DEBUG) Log.d(TAG, "mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi 534 + " set to cdmaLevel=" + mSignalStrength.getCdmaLevel() 535 + " instead of level=" + mSignalStrength.getLevel()); 536 } else { 537 mLastSignalLevel = iconLevel = mSignalStrength.getLevel(); 538 } 539 540 if (isCdma()) { 541 if (isCdmaEri()) { 542 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition]; 543 } else { 544 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition]; 545 } 546 } else { 547 // Though mPhone is a Manager, this call is not an IPC 548 if (mPhone.isNetworkRoaming()) { 549 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition]; 550 } else { 551 iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition]; 552 } 553 } 554 mPhoneSignalIconId = iconList[iconLevel]; 555 mQSPhoneSignalIconId = 556 TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[mInetCondition][iconLevel]; 557 mContentDescriptionPhoneSignal = mContext.getString( 558 AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]); 559 mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel]; 560 } 561 } 562 } 563 564 private final void updateDataNetType() { 565 if (mIsWimaxEnabled && mWimaxConnected) { 566 // wimax is a special 4g network not handled by telephony 567 mDataIconList = TelephonyIcons.DATA_4G[mInetCondition]; 568 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_4g; 569 mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[mInetCondition]; 570 mContentDescriptionDataType = mContext.getString( 571 R.string.accessibility_data_connection_4g); 572 } else { 573 switch (mDataNetType) { 574 case TelephonyManager.NETWORK_TYPE_UNKNOWN: 575 if (!mShowAtLeastThreeGees) { 576 mDataIconList = TelephonyIcons.DATA_G[mInetCondition]; 577 mDataTypeIconId = 0; 578 mQSDataTypeIconId = 0; 579 mContentDescriptionDataType = mContext.getString( 580 R.string.accessibility_data_connection_gprs); 581 break; 582 } else { 583 // fall through 584 } 585 case TelephonyManager.NETWORK_TYPE_EDGE: 586 if (!mShowAtLeastThreeGees) { 587 mDataIconList = TelephonyIcons.DATA_E[mInetCondition]; 588 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_e; 589 mQSDataTypeIconId = TelephonyIcons.QS_DATA_E[mInetCondition]; 590 mContentDescriptionDataType = mContext.getString( 591 R.string.accessibility_data_connection_edge); 592 break; 593 } else { 594 // fall through 595 } 596 case TelephonyManager.NETWORK_TYPE_UMTS: 597 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 598 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g; 599 mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition]; 600 mContentDescriptionDataType = mContext.getString( 601 R.string.accessibility_data_connection_3g); 602 break; 603 case TelephonyManager.NETWORK_TYPE_HSDPA: 604 case TelephonyManager.NETWORK_TYPE_HSUPA: 605 case TelephonyManager.NETWORK_TYPE_HSPA: 606 case TelephonyManager.NETWORK_TYPE_HSPAP: 607 if (mHspaDataDistinguishable) { 608 mDataIconList = TelephonyIcons.DATA_H[mInetCondition]; 609 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_h; 610 mQSDataTypeIconId = TelephonyIcons.QS_DATA_H[mInetCondition]; 611 mContentDescriptionDataType = mContext.getString( 612 R.string.accessibility_data_connection_3_5g); 613 } else { 614 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 615 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g; 616 mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition]; 617 mContentDescriptionDataType = mContext.getString( 618 R.string.accessibility_data_connection_3g); 619 } 620 break; 621 case TelephonyManager.NETWORK_TYPE_CDMA: 622 if (!mShowAtLeastThreeGees) { 623 // display 1xRTT for IS95A/B 624 mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; 625 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_1x; 626 mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[mInetCondition]; 627 mContentDescriptionDataType = mContext.getString( 628 R.string.accessibility_data_connection_cdma); 629 break; 630 } else { 631 // fall through 632 } 633 case TelephonyManager.NETWORK_TYPE_1xRTT: 634 if (!mShowAtLeastThreeGees) { 635 mDataIconList = TelephonyIcons.DATA_1X[mInetCondition]; 636 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_1x; 637 mQSDataTypeIconId = TelephonyIcons.QS_DATA_1X[mInetCondition]; 638 mContentDescriptionDataType = mContext.getString( 639 R.string.accessibility_data_connection_cdma); 640 break; 641 } else { 642 // fall through 643 } 644 case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through 645 case TelephonyManager.NETWORK_TYPE_EVDO_A: 646 case TelephonyManager.NETWORK_TYPE_EVDO_B: 647 case TelephonyManager.NETWORK_TYPE_EHRPD: 648 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 649 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g; 650 mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition]; 651 mContentDescriptionDataType = mContext.getString( 652 R.string.accessibility_data_connection_3g); 653 break; 654 case TelephonyManager.NETWORK_TYPE_LTE: 655 boolean show4GforLTE = mContext.getResources().getBoolean(R.bool.config_show4GForLTE); 656 if (show4GforLTE) { 657 mDataIconList = TelephonyIcons.DATA_4G[mInetCondition]; 658 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_4g; 659 mQSDataTypeIconId = TelephonyIcons.QS_DATA_4G[mInetCondition]; 660 mContentDescriptionDataType = mContext.getString( 661 R.string.accessibility_data_connection_4g); 662 } else { 663 mDataIconList = TelephonyIcons.DATA_LTE[mInetCondition]; 664 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_lte; 665 mQSDataTypeIconId = TelephonyIcons.QS_DATA_LTE[mInetCondition]; 666 mContentDescriptionDataType = mContext.getString( 667 R.string.accessibility_data_connection_lte); 668 } 669 break; 670 default: 671 if (!mShowAtLeastThreeGees) { 672 mDataIconList = TelephonyIcons.DATA_G[mInetCondition]; 673 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_g; 674 mQSDataTypeIconId = TelephonyIcons.QS_DATA_G[mInetCondition]; 675 mContentDescriptionDataType = mContext.getString( 676 R.string.accessibility_data_connection_gprs); 677 } else { 678 mDataIconList = TelephonyIcons.DATA_3G[mInetCondition]; 679 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_3g; 680 mQSDataTypeIconId = TelephonyIcons.QS_DATA_3G[mInetCondition]; 681 mContentDescriptionDataType = mContext.getString( 682 R.string.accessibility_data_connection_3g); 683 } 684 break; 685 } 686 } 687 688 if (isCdma()) { 689 if (isCdmaEri()) { 690 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam; 691 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; 692 } 693 } else if (mPhone.isNetworkRoaming()) { 694 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam; 695 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; 696 } 697 } 698 699 boolean isCdmaEri() { 700 if (mServiceState != null) { 701 final int iconIndex = mServiceState.getCdmaEriIconIndex(); 702 if (iconIndex != EriInfo.ROAMING_INDICATOR_OFF) { 703 final int iconMode = mServiceState.getCdmaEriIconMode(); 704 if (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL 705 || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH) { 706 return true; 707 } 708 } 709 } 710 return false; 711 } 712 713 private final void updateDataIcon() { 714 int iconId; 715 boolean visible = true; 716 717 if (!isCdma()) { 718 // GSM case, we have to check also the sim state 719 if (mSimState == IccCardConstants.State.READY || 720 mSimState == IccCardConstants.State.UNKNOWN) { 721 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { 722 switch (mDataActivity) { 723 case TelephonyManager.DATA_ACTIVITY_IN: 724 iconId = mDataIconList[1]; 725 break; 726 case TelephonyManager.DATA_ACTIVITY_OUT: 727 iconId = mDataIconList[2]; 728 break; 729 case TelephonyManager.DATA_ACTIVITY_INOUT: 730 iconId = mDataIconList[3]; 731 break; 732 default: 733 iconId = mDataIconList[0]; 734 break; 735 } 736 mDataDirectionIconId = iconId; 737 } else { 738 iconId = 0; 739 visible = false; 740 } 741 } else { 742 iconId = R.drawable.stat_sys_no_sim; 743 visible = false; // no SIM? no data 744 } 745 } else { 746 // CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT 747 if (hasService() && mDataState == TelephonyManager.DATA_CONNECTED) { 748 switch (mDataActivity) { 749 case TelephonyManager.DATA_ACTIVITY_IN: 750 iconId = mDataIconList[1]; 751 break; 752 case TelephonyManager.DATA_ACTIVITY_OUT: 753 iconId = mDataIconList[2]; 754 break; 755 case TelephonyManager.DATA_ACTIVITY_INOUT: 756 iconId = mDataIconList[3]; 757 break; 758 case TelephonyManager.DATA_ACTIVITY_DORMANT: 759 default: 760 iconId = mDataIconList[0]; 761 break; 762 } 763 } else { 764 iconId = 0; 765 visible = false; 766 } 767 } 768 769 mDataDirectionIconId = iconId; 770 mDataConnected = visible; 771 } 772 773 void updateNetworkName(boolean showSpn, String spn, boolean showPlmn, String plmn) { 774 if (false) { 775 Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn + " spn=" + spn 776 + " showPlmn=" + showPlmn + " plmn=" + plmn); 777 } 778 StringBuilder str = new StringBuilder(); 779 boolean something = false; 780 if (showPlmn && plmn != null) { 781 str.append(plmn); 782 something = true; 783 } 784 if (showSpn && spn != null) { 785 if (something) { 786 str.append(mNetworkNameSeparator); 787 } 788 str.append(spn); 789 something = true; 790 } 791 if (something) { 792 mNetworkName = str.toString(); 793 } else { 794 mNetworkName = mNetworkNameDefault; 795 } 796 } 797 798 // ===== Wifi =================================================================== 799 800 class WifiHandler extends Handler { 801 @Override 802 public void handleMessage(Message msg) { 803 switch (msg.what) { 804 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 805 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 806 mWifiChannel.sendMessage(Message.obtain(this, 807 AsyncChannel.CMD_CHANNEL_FULL_CONNECTION)); 808 } else { 809 Log.e(TAG, "Failed to connect to wifi"); 810 } 811 break; 812 case WifiManager.DATA_ACTIVITY_NOTIFICATION: 813 if (msg.arg1 != mWifiActivity) { 814 mWifiActivity = msg.arg1; 815 refreshViews(); 816 } 817 break; 818 default: 819 //Ignore 820 break; 821 } 822 } 823 } 824 825 private void updateWifiState(Intent intent) { 826 final String action = intent.getAction(); 827 if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 828 mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 829 WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; 830 831 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 832 final NetworkInfo networkInfo = (NetworkInfo) 833 intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 834 boolean wasConnected = mWifiConnected; 835 mWifiConnected = networkInfo != null && networkInfo.isConnected(); 836 // If we just connected, grab the inintial signal strength and ssid 837 if (mWifiConnected && !wasConnected) { 838 // try getting it out of the intent first 839 WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); 840 if (info == null) { 841 info = mWifiManager.getConnectionInfo(); 842 } 843 if (info != null) { 844 mWifiSsid = huntForSsid(info); 845 } else { 846 mWifiSsid = null; 847 } 848 } else if (!mWifiConnected) { 849 mWifiSsid = null; 850 } 851 } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 852 mWifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); 853 mWifiLevel = WifiManager.calculateSignalLevel( 854 mWifiRssi, WifiIcons.WIFI_LEVEL_COUNT); 855 } 856 857 updateWifiIcons(); 858 } 859 860 private void updateWifiIcons() { 861 if (mWifiConnected) { 862 mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel]; 863 mQSWifiIconId = WifiIcons.QS_WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel]; 864 mContentDescriptionWifi = mContext.getString( 865 AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[mWifiLevel]); 866 } else { 867 if (mDataAndWifiStacked) { 868 mWifiIconId = 0; 869 mQSWifiIconId = 0; 870 } else { 871 mWifiIconId = mWifiEnabled ? R.drawable.stat_sys_wifi_signal_null : 0; 872 mQSWifiIconId = mWifiEnabled ? R.drawable.ic_qs_wifi_no_network : 0; 873 } 874 mContentDescriptionWifi = mContext.getString(R.string.accessibility_no_wifi); 875 } 876 } 877 878 private String huntForSsid(WifiInfo info) { 879 String ssid = info.getSSID(); 880 if (ssid != null) { 881 return ssid; 882 } 883 // OK, it's not in the connectionInfo; we have to go hunting for it 884 List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks(); 885 for (WifiConfiguration net : networks) { 886 if (net.networkId == info.getNetworkId()) { 887 return net.SSID; 888 } 889 } 890 return null; 891 } 892 893 894 // ===== Wimax =================================================================== 895 private final void updateWimaxState(Intent intent) { 896 final String action = intent.getAction(); 897 boolean wasConnected = mWimaxConnected; 898 if (action.equals(WimaxManagerConstants.NET_4G_STATE_CHANGED_ACTION)) { 899 int wimaxStatus = intent.getIntExtra(WimaxManagerConstants.EXTRA_4G_STATE, 900 WimaxManagerConstants.NET_4G_STATE_UNKNOWN); 901 mIsWimaxEnabled = (wimaxStatus == 902 WimaxManagerConstants.NET_4G_STATE_ENABLED); 903 } else if (action.equals(WimaxManagerConstants.SIGNAL_LEVEL_CHANGED_ACTION)) { 904 mWimaxSignal = intent.getIntExtra(WimaxManagerConstants.EXTRA_NEW_SIGNAL_LEVEL, 0); 905 } else if (action.equals(WimaxManagerConstants.WIMAX_NETWORK_STATE_CHANGED_ACTION)) { 906 mWimaxState = intent.getIntExtra(WimaxManagerConstants.EXTRA_WIMAX_STATE, 907 WimaxManagerConstants.NET_4G_STATE_UNKNOWN); 908 mWimaxExtraState = intent.getIntExtra( 909 WimaxManagerConstants.EXTRA_WIMAX_STATE_DETAIL, 910 WimaxManagerConstants.NET_4G_STATE_UNKNOWN); 911 mWimaxConnected = (mWimaxState == 912 WimaxManagerConstants.WIMAX_STATE_CONNECTED); 913 mWimaxIdle = (mWimaxExtraState == WimaxManagerConstants.WIMAX_IDLE); 914 } 915 updateDataNetType(); 916 updateWimaxIcons(); 917 } 918 919 private void updateWimaxIcons() { 920 if (mIsWimaxEnabled) { 921 if (mWimaxConnected) { 922 if (mWimaxIdle) 923 mWimaxIconId = WimaxIcons.WIMAX_IDLE; 924 else 925 mWimaxIconId = WimaxIcons.WIMAX_SIGNAL_STRENGTH[mInetCondition][mWimaxSignal]; 926 mContentDescriptionWimax = mContext.getString( 927 AccessibilityContentDescriptions.WIMAX_CONNECTION_STRENGTH[mWimaxSignal]); 928 } else { 929 mWimaxIconId = WimaxIcons.WIMAX_DISCONNECTED; 930 mContentDescriptionWimax = mContext.getString(R.string.accessibility_no_wimax); 931 } 932 } else { 933 mWimaxIconId = 0; 934 } 935 } 936 937 // ===== Full or limited Internet connectivity ================================== 938 939 private void updateConnectivity(Intent intent) { 940 if (CHATTY) { 941 Log.d(TAG, "updateConnectivity: intent=" + intent); 942 } 943 944 final ConnectivityManager connManager = (ConnectivityManager) mContext 945 .getSystemService(Context.CONNECTIVITY_SERVICE); 946 final NetworkInfo info = connManager.getActiveNetworkInfo(); 947 948 // Are we connected at all, by any interface? 949 mConnected = info != null && info.isConnected(); 950 if (mConnected) { 951 mConnectedNetworkType = info.getType(); 952 mConnectedNetworkTypeName = info.getTypeName(); 953 } else { 954 mConnectedNetworkType = ConnectivityManager.TYPE_NONE; 955 mConnectedNetworkTypeName = null; 956 } 957 958 int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0); 959 960 if (CHATTY) { 961 Log.d(TAG, "updateConnectivity: networkInfo=" + info); 962 Log.d(TAG, "updateConnectivity: connectionStatus=" + connectionStatus); 963 } 964 965 mInetCondition = (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0); 966 967 if (info != null && info.getType() == ConnectivityManager.TYPE_BLUETOOTH) { 968 mBluetoothTethered = info.isConnected(); 969 } else { 970 mBluetoothTethered = false; 971 } 972 973 // We want to update all the icons, all at once, for any condition change 974 updateDataNetType(); 975 updateWimaxIcons(); 976 updateDataIcon(); 977 updateTelephonySignalStrength(); 978 updateWifiIcons(); 979 } 980 981 982 // ===== Update the views ======================================================= 983 984 void refreshViews() { 985 Context context = mContext; 986 987 int combinedSignalIconId = 0; 988 String combinedLabel = ""; 989 String wifiLabel = ""; 990 String mobileLabel = ""; 991 int N; 992 final boolean emergencyOnly = isEmergencyOnly(); 993 994 if (!mHasMobileDataFeature) { 995 mDataSignalIconId = mPhoneSignalIconId = 0; 996 mQSPhoneSignalIconId = 0; 997 mobileLabel = ""; 998 } else { 999 // We want to show the carrier name if in service and either: 1000 // - We are connected to mobile data, or 1001 // - We are not connected to mobile data, as long as the *reason* packets are not 1002 // being routed over that link is that we have better connectivity via wifi. 1003 // If data is disconnected for some other reason but wifi (or ethernet/bluetooth) 1004 // is connected, we show nothing. 1005 // Otherwise (nothing connected) we show "No internet connection". 1006 1007 if (mDataConnected) { 1008 mobileLabel = mNetworkName; 1009 } else if (mConnected || emergencyOnly) { 1010 if (hasService() || emergencyOnly) { 1011 // The isEmergencyOnly test covers the case of a phone with no SIM 1012 mobileLabel = mNetworkName; 1013 } else { 1014 // Tablets, basically 1015 mobileLabel = ""; 1016 } 1017 } else { 1018 mobileLabel 1019 = context.getString(R.string.status_bar_settings_signal_meter_disconnected); 1020 } 1021 1022 // Now for things that should only be shown when actually using mobile data. 1023 if (mDataConnected) { 1024 combinedSignalIconId = mDataSignalIconId; 1025 1026 combinedLabel = mobileLabel; 1027 combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon() 1028 mContentDescriptionCombinedSignal = mContentDescriptionDataType; 1029 } 1030 } 1031 1032 if (mWifiConnected) { 1033 if (mWifiSsid == null) { 1034 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid); 1035 } else { 1036 wifiLabel = mWifiSsid; 1037 if (DEBUG) { 1038 wifiLabel += "xxxxXXXXxxxxXXXX"; 1039 } 1040 } 1041 1042 combinedLabel = wifiLabel; 1043 combinedSignalIconId = mWifiIconId; // set by updateWifiIcons() 1044 mContentDescriptionCombinedSignal = mContentDescriptionWifi; 1045 } else { 1046 if (mHasMobileDataFeature) { 1047 wifiLabel = ""; 1048 } else { 1049 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected); 1050 } 1051 } 1052 1053 if (mBluetoothTethered) { 1054 combinedLabel = mContext.getString(R.string.bluetooth_tethered); 1055 combinedSignalIconId = mBluetoothTetherIconId; 1056 mContentDescriptionCombinedSignal = mContext.getString( 1057 R.string.accessibility_bluetooth_tether); 1058 } 1059 1060 final boolean ethernetConnected = (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET); 1061 if (ethernetConnected) { 1062 combinedLabel = context.getString(R.string.ethernet_label); 1063 } 1064 1065 if (mAirplaneMode && 1066 (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) { 1067 // Only display the flight-mode icon if not in "emergency calls only" mode. 1068 1069 // look again; your radios are now airplanes 1070 mContentDescriptionPhoneSignal = mContext.getString( 1071 R.string.accessibility_airplane_mode); 1072 mAirplaneIconId = FLIGHT_MODE_ICON; 1073 mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0; 1074 mQSPhoneSignalIconId = 0; 1075 1076 // combined values from connected wifi take precedence over airplane mode 1077 if (mWifiConnected) { 1078 // Suppress "No internet connection." from mobile if wifi connected. 1079 mobileLabel = ""; 1080 } else { 1081 if (mHasMobileDataFeature) { 1082 // let the mobile icon show "No internet connection." 1083 wifiLabel = ""; 1084 } else { 1085 wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected); 1086 combinedLabel = wifiLabel; 1087 } 1088 mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal; 1089 combinedSignalIconId = mDataSignalIconId; 1090 } 1091 } 1092 else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected && !ethernetConnected) { 1093 // pretty much totally disconnected 1094 1095 combinedLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected); 1096 // On devices without mobile radios, we want to show the wifi icon 1097 combinedSignalIconId = 1098 mHasMobileDataFeature ? mDataSignalIconId : mWifiIconId; 1099 mContentDescriptionCombinedSignal = mHasMobileDataFeature 1100 ? mContentDescriptionDataType : mContentDescriptionWifi; 1101 1102 mDataTypeIconId = 0; 1103 mQSDataTypeIconId = 0; 1104 if (isCdma()) { 1105 if (isCdmaEri()) { 1106 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam; 1107 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; 1108 } 1109 } else if (mPhone.isNetworkRoaming()) { 1110 mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_roam; 1111 mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; 1112 } 1113 } 1114 1115 if (DEBUG) { 1116 Log.d(TAG, "refreshViews connected={" 1117 + (mWifiConnected?" wifi":"") 1118 + (mDataConnected?" data":"") 1119 + " } level=" 1120 + ((mSignalStrength == null)?"??":Integer.toString(mSignalStrength.getLevel())) 1121 + " combinedSignalIconId=0x" 1122 + Integer.toHexString(combinedSignalIconId) 1123 + "/" + getResourceName(combinedSignalIconId) 1124 + " mobileLabel=" + mobileLabel 1125 + " wifiLabel=" + wifiLabel 1126 + " emergencyOnly=" + emergencyOnly 1127 + " combinedLabel=" + combinedLabel 1128 + " mAirplaneMode=" + mAirplaneMode 1129 + " mDataActivity=" + mDataActivity 1130 + " mPhoneSignalIconId=0x" + Integer.toHexString(mPhoneSignalIconId) 1131 + " mQSPhoneSignalIconId=0x" + Integer.toHexString(mQSPhoneSignalIconId) 1132 + " mDataDirectionIconId=0x" + Integer.toHexString(mDataDirectionIconId) 1133 + " mDataSignalIconId=0x" + Integer.toHexString(mDataSignalIconId) 1134 + " mDataTypeIconId=0x" + Integer.toHexString(mDataTypeIconId) 1135 + " mQSDataTypeIconId=0x" + Integer.toHexString(mQSDataTypeIconId) 1136 + " mWifiIconId=0x" + Integer.toHexString(mWifiIconId) 1137 + " mQSWifiIconId=0x" + Integer.toHexString(mQSWifiIconId) 1138 + " mBluetoothTetherIconId=0x" + Integer.toHexString(mBluetoothTetherIconId)); 1139 } 1140 1141 // update QS 1142 for (NetworkSignalChangedCallback cb : mSignalsChangedCallbacks) { 1143 notifySignalsChangedCallbacks(cb); 1144 } 1145 1146 if (mLastPhoneSignalIconId != mPhoneSignalIconId 1147 || mLastWifiIconId != mWifiIconId 1148 || mLastWimaxIconId != mWimaxIconId 1149 || mLastDataTypeIconId != mDataTypeIconId 1150 || mLastAirplaneMode != mAirplaneMode 1151 || mLastLocale != mLocale) 1152 { 1153 // NB: the mLast*s will be updated later 1154 for (SignalCluster cluster : mSignalClusters) { 1155 refreshSignalCluster(cluster); 1156 } 1157 } 1158 1159 if (mLastAirplaneMode != mAirplaneMode) { 1160 mLastAirplaneMode = mAirplaneMode; 1161 } 1162 1163 if (mLastLocale != mLocale) { 1164 mLastLocale = mLocale; 1165 } 1166 1167 // the phone icon on phones 1168 if (mLastPhoneSignalIconId != mPhoneSignalIconId) { 1169 mLastPhoneSignalIconId = mPhoneSignalIconId; 1170 } 1171 1172 // the data icon on phones 1173 if (mLastDataDirectionIconId != mDataDirectionIconId) { 1174 mLastDataDirectionIconId = mDataDirectionIconId; 1175 } 1176 1177 // the wifi icon on phones 1178 if (mLastWifiIconId != mWifiIconId) { 1179 mLastWifiIconId = mWifiIconId; 1180 } 1181 1182 // the wimax icon on phones 1183 if (mLastWimaxIconId != mWimaxIconId) { 1184 mLastWimaxIconId = mWimaxIconId; 1185 } 1186 // the combined data signal icon 1187 if (mLastCombinedSignalIconId != combinedSignalIconId) { 1188 mLastCombinedSignalIconId = combinedSignalIconId; 1189 } 1190 1191 // the data network type overlay 1192 if (mLastDataTypeIconId != mDataTypeIconId) { 1193 mLastDataTypeIconId = mDataTypeIconId; 1194 } 1195 1196 // the combinedLabel in the notification panel 1197 if (!mLastCombinedLabel.equals(combinedLabel)) { 1198 mLastCombinedLabel = combinedLabel; 1199 N = mCombinedLabelViews.size(); 1200 for (int i=0; i<N; i++) { 1201 TextView v = mCombinedLabelViews.get(i); 1202 v.setText(combinedLabel); 1203 } 1204 } 1205 1206 // wifi label 1207 N = mWifiLabelViews.size(); 1208 for (int i=0; i<N; i++) { 1209 TextView v = mWifiLabelViews.get(i); 1210 v.setText(wifiLabel); 1211 if ("".equals(wifiLabel)) { 1212 v.setVisibility(View.GONE); 1213 } else { 1214 v.setVisibility(View.VISIBLE); 1215 } 1216 } 1217 1218 // mobile label 1219 N = mMobileLabelViews.size(); 1220 for (int i=0; i<N; i++) { 1221 TextView v = mMobileLabelViews.get(i); 1222 v.setText(mobileLabel); 1223 if ("".equals(mobileLabel)) { 1224 v.setVisibility(View.GONE); 1225 } else { 1226 v.setVisibility(View.VISIBLE); 1227 } 1228 } 1229 1230 // e-call label 1231 N = mEmergencyLabelViews.size(); 1232 for (int i=0; i<N; i++) { 1233 TextView v = mEmergencyLabelViews.get(i); 1234 if (!emergencyOnly) { 1235 v.setVisibility(View.GONE); 1236 } else { 1237 v.setText(mobileLabel); // comes from the telephony stack 1238 v.setVisibility(View.VISIBLE); 1239 } 1240 } 1241 } 1242 1243 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1244 pw.println("NetworkController state:"); 1245 pw.println(String.format(" %s network type %d (%s)", 1246 mConnected?"CONNECTED":"DISCONNECTED", 1247 mConnectedNetworkType, mConnectedNetworkTypeName)); 1248 pw.println(" - telephony ------"); 1249 pw.print(" hasVoiceCallingFeature()="); 1250 pw.println(hasVoiceCallingFeature()); 1251 pw.print(" hasService()="); 1252 pw.println(hasService()); 1253 pw.print(" mHspaDataDistinguishable="); 1254 pw.println(mHspaDataDistinguishable); 1255 pw.print(" mDataConnected="); 1256 pw.println(mDataConnected); 1257 pw.print(" mSimState="); 1258 pw.println(mSimState); 1259 pw.print(" mPhoneState="); 1260 pw.println(mPhoneState); 1261 pw.print(" mDataState="); 1262 pw.println(mDataState); 1263 pw.print(" mDataActivity="); 1264 pw.println(mDataActivity); 1265 pw.print(" mDataNetType="); 1266 pw.print(mDataNetType); 1267 pw.print("/"); 1268 pw.println(TelephonyManager.getNetworkTypeName(mDataNetType)); 1269 pw.print(" mServiceState="); 1270 pw.println(mServiceState); 1271 pw.print(" mSignalStrength="); 1272 pw.println(mSignalStrength); 1273 pw.print(" mLastSignalLevel="); 1274 pw.println(mLastSignalLevel); 1275 pw.print(" mNetworkName="); 1276 pw.println(mNetworkName); 1277 pw.print(" mNetworkNameDefault="); 1278 pw.println(mNetworkNameDefault); 1279 pw.print(" mNetworkNameSeparator="); 1280 pw.println(mNetworkNameSeparator.replace("\n","\\n")); 1281 pw.print(" mPhoneSignalIconId=0x"); 1282 pw.print(Integer.toHexString(mPhoneSignalIconId)); 1283 pw.print("/"); 1284 pw.print(" mQSPhoneSignalIconId=0x"); 1285 pw.print(Integer.toHexString(mQSPhoneSignalIconId)); 1286 pw.print("/"); 1287 pw.println(getResourceName(mPhoneSignalIconId)); 1288 pw.print(" mDataDirectionIconId="); 1289 pw.print(Integer.toHexString(mDataDirectionIconId)); 1290 pw.print("/"); 1291 pw.println(getResourceName(mDataDirectionIconId)); 1292 pw.print(" mDataSignalIconId="); 1293 pw.print(Integer.toHexString(mDataSignalIconId)); 1294 pw.print("/"); 1295 pw.println(getResourceName(mDataSignalIconId)); 1296 pw.print(" mDataTypeIconId="); 1297 pw.print(Integer.toHexString(mDataTypeIconId)); 1298 pw.print("/"); 1299 pw.println(getResourceName(mDataTypeIconId)); 1300 pw.print(" mQSDataTypeIconId="); 1301 pw.print(Integer.toHexString(mQSDataTypeIconId)); 1302 pw.print("/"); 1303 pw.println(getResourceName(mQSDataTypeIconId)); 1304 1305 pw.println(" - wifi ------"); 1306 pw.print(" mWifiEnabled="); 1307 pw.println(mWifiEnabled); 1308 pw.print(" mWifiConnected="); 1309 pw.println(mWifiConnected); 1310 pw.print(" mWifiRssi="); 1311 pw.println(mWifiRssi); 1312 pw.print(" mWifiLevel="); 1313 pw.println(mWifiLevel); 1314 pw.print(" mWifiSsid="); 1315 pw.println(mWifiSsid); 1316 pw.println(String.format(" mWifiIconId=0x%08x/%s", 1317 mWifiIconId, getResourceName(mWifiIconId))); 1318 pw.println(String.format(" mQSWifiIconId=0x%08x/%s", 1319 mQSWifiIconId, getResourceName(mQSWifiIconId))); 1320 pw.print(" mWifiActivity="); 1321 pw.println(mWifiActivity); 1322 1323 if (mWimaxSupported) { 1324 pw.println(" - wimax ------"); 1325 pw.print(" mIsWimaxEnabled="); pw.println(mIsWimaxEnabled); 1326 pw.print(" mWimaxConnected="); pw.println(mWimaxConnected); 1327 pw.print(" mWimaxIdle="); pw.println(mWimaxIdle); 1328 pw.println(String.format(" mWimaxIconId=0x%08x/%s", 1329 mWimaxIconId, getResourceName(mWimaxIconId))); 1330 pw.println(String.format(" mWimaxSignal=%d", mWimaxSignal)); 1331 pw.println(String.format(" mWimaxState=%d", mWimaxState)); 1332 pw.println(String.format(" mWimaxExtraState=%d", mWimaxExtraState)); 1333 } 1334 1335 pw.println(" - Bluetooth ----"); 1336 pw.print(" mBtReverseTethered="); 1337 pw.println(mBluetoothTethered); 1338 1339 pw.println(" - connectivity ------"); 1340 pw.print(" mInetCondition="); 1341 pw.println(mInetCondition); 1342 1343 pw.println(" - icons ------"); 1344 pw.print(" mLastPhoneSignalIconId=0x"); 1345 pw.print(Integer.toHexString(mLastPhoneSignalIconId)); 1346 pw.print("/"); 1347 pw.println(getResourceName(mLastPhoneSignalIconId)); 1348 pw.print(" mLastDataDirectionIconId=0x"); 1349 pw.print(Integer.toHexString(mLastDataDirectionIconId)); 1350 pw.print("/"); 1351 pw.println(getResourceName(mLastDataDirectionIconId)); 1352 pw.print(" mLastWifiIconId=0x"); 1353 pw.print(Integer.toHexString(mLastWifiIconId)); 1354 pw.print("/"); 1355 pw.println(getResourceName(mLastWifiIconId)); 1356 pw.print(" mLastCombinedSignalIconId=0x"); 1357 pw.print(Integer.toHexString(mLastCombinedSignalIconId)); 1358 pw.print("/"); 1359 pw.println(getResourceName(mLastCombinedSignalIconId)); 1360 pw.print(" mLastDataTypeIconId=0x"); 1361 pw.print(Integer.toHexString(mLastDataTypeIconId)); 1362 pw.print("/"); 1363 pw.println(getResourceName(mLastDataTypeIconId)); 1364 pw.print(" mLastCombinedLabel="); 1365 pw.print(mLastCombinedLabel); 1366 pw.println(""); 1367 } 1368 1369 private String getResourceName(int resId) { 1370 if (resId != 0) { 1371 final Resources res = mContext.getResources(); 1372 try { 1373 return res.getResourceName(resId); 1374 } catch (android.content.res.Resources.NotFoundException ex) { 1375 return "(unknown)"; 1376 } 1377 } else { 1378 return "(null)"; 1379 } 1380 } 1381 1382 private boolean mDemoMode; 1383 private int mDemoInetCondition; 1384 private int mDemoWifiLevel; 1385 private int mDemoDataTypeIconId; 1386 private int mDemoMobileLevel; 1387 1388 @Override 1389 public void dispatchDemoCommand(String command, Bundle args) { 1390 if (!mDemoMode && command.equals(COMMAND_ENTER)) { 1391 mDemoMode = true; 1392 mDemoWifiLevel = mWifiLevel; 1393 mDemoInetCondition = mInetCondition; 1394 mDemoDataTypeIconId = mDataTypeIconId; 1395 mDemoMobileLevel = mLastSignalLevel; 1396 } else if (mDemoMode && command.equals(COMMAND_EXIT)) { 1397 mDemoMode = false; 1398 for (SignalCluster cluster : mSignalClusters) { 1399 refreshSignalCluster(cluster); 1400 } 1401 } else if (mDemoMode && command.equals(COMMAND_NETWORK)) { 1402 String airplane = args.getString("airplane"); 1403 if (airplane != null) { 1404 boolean show = airplane.equals("show"); 1405 for (SignalCluster cluster : mSignalClusters) { 1406 cluster.setIsAirplaneMode(show, FLIGHT_MODE_ICON); 1407 } 1408 } 1409 String fully = args.getString("fully"); 1410 if (fully != null) { 1411 mDemoInetCondition = Boolean.parseBoolean(fully) ? 1 : 0; 1412 } 1413 String wifi = args.getString("wifi"); 1414 if (wifi != null) { 1415 boolean show = wifi.equals("show"); 1416 String level = args.getString("level"); 1417 if (level != null) { 1418 mDemoWifiLevel = level.equals("null") ? -1 1419 : Math.min(Integer.parseInt(level), WifiIcons.WIFI_LEVEL_COUNT - 1); 1420 } 1421 int iconId = mDemoWifiLevel < 0 ? R.drawable.stat_sys_wifi_signal_null 1422 : WifiIcons.WIFI_SIGNAL_STRENGTH[mDemoInetCondition][mDemoWifiLevel]; 1423 for (SignalCluster cluster : mSignalClusters) { 1424 cluster.setWifiIndicators( 1425 show, 1426 iconId, 1427 "Demo"); 1428 } 1429 } 1430 String mobile = args.getString("mobile"); 1431 if (mobile != null) { 1432 boolean show = mobile.equals("show"); 1433 String datatype = args.getString("datatype"); 1434 if (datatype != null) { 1435 mDemoDataTypeIconId = 1436 datatype.equals("1x") ? R.drawable.stat_sys_data_fully_connected_1x : 1437 datatype.equals("3g") ? R.drawable.stat_sys_data_fully_connected_3g : 1438 datatype.equals("4g") ? R.drawable.stat_sys_data_fully_connected_4g : 1439 datatype.equals("e") ? R.drawable.stat_sys_data_fully_connected_e : 1440 datatype.equals("g") ? R.drawable.stat_sys_data_fully_connected_g : 1441 datatype.equals("h") ? R.drawable.stat_sys_data_fully_connected_h : 1442 datatype.equals("lte") ? R.drawable.stat_sys_data_fully_connected_lte : 1443 datatype.equals("roam") 1444 ? R.drawable.stat_sys_data_fully_connected_roam : 1445 0; 1446 } 1447 int[][] icons = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH; 1448 String level = args.getString("level"); 1449 if (level != null) { 1450 mDemoMobileLevel = level.equals("null") ? -1 1451 : Math.min(Integer.parseInt(level), icons[0].length - 1); 1452 } 1453 int iconId = mDemoMobileLevel < 0 ? R.drawable.stat_sys_signal_null : 1454 icons[mDemoInetCondition][mDemoMobileLevel]; 1455 for (SignalCluster cluster : mSignalClusters) { 1456 cluster.setMobileDataIndicators( 1457 show, 1458 iconId, 1459 mDemoDataTypeIconId, 1460 "Demo", 1461 "Demo"); 1462 } 1463 } 1464 } 1465 } 1466 } 1467