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