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