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