1 /* 2 * Copyright (C) 2015 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 package com.android.systemui.statusbar.connectivity; 17 18 import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID; 19 20 import android.content.Context; 21 import android.content.Intent; 22 import android.database.ContentObserver; 23 import android.net.NetworkCapabilities; 24 import android.os.Handler; 25 import android.os.Looper; 26 import android.provider.Settings.Global; 27 import android.telephony.CellSignalStrength; 28 import android.telephony.CellSignalStrengthCdma; 29 import android.telephony.SignalStrength; 30 import android.telephony.SubscriptionInfo; 31 import android.telephony.SubscriptionManager; 32 import android.telephony.TelephonyManager; 33 import android.text.Html; 34 import android.text.TextUtils; 35 import android.util.Log; 36 37 import com.android.internal.annotations.VisibleForTesting; 38 import com.android.settingslib.SignalIcon.MobileIconGroup; 39 import com.android.settingslib.graph.SignalDrawable; 40 import com.android.settingslib.mobile.MobileMappings.Config; 41 import com.android.settingslib.mobile.MobileStatusTracker; 42 import com.android.settingslib.mobile.MobileStatusTracker.MobileStatus; 43 import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults; 44 import com.android.settingslib.mobile.TelephonyIcons; 45 import com.android.settingslib.net.SignalStrengthUtil; 46 import com.android.systemui.res.R; 47 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor; 48 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy; 49 import com.android.systemui.util.CarrierConfigTracker; 50 51 import java.io.PrintWriter; 52 import java.text.SimpleDateFormat; 53 import java.util.BitSet; 54 import java.util.List; 55 import java.util.Map; 56 57 /** 58 * Monitors the mobile signal changes and update the SysUI icons. 59 * 60 * @deprecated Use {@link MobileIconsInteractor} instead. 61 */ 62 @Deprecated 63 public class MobileSignalController extends SignalController<MobileState, MobileIconGroup> { 64 private static final SimpleDateFormat SSDF = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); 65 private static final int STATUS_HISTORY_SIZE = 64; 66 private final TelephonyManager mPhone; 67 private final CarrierConfigTracker mCarrierConfigTracker; 68 private final SubscriptionDefaults mDefaults; 69 private final MobileMappingsProxy mMobileMappingsProxy; 70 private final String mNetworkNameDefault; 71 private final String mNetworkNameSeparator; 72 private final ContentObserver mObserver; 73 // Save entire info for logging, we only use the id. 74 final SubscriptionInfo mSubscriptionInfo; 75 private Map<String, MobileIconGroup> mNetworkToIconLookup; 76 77 private MobileIconGroup mDefaultIcons; 78 private Config mConfig; 79 @VisibleForTesting 80 boolean mInflateSignalStrengths = false; 81 @VisibleForTesting 82 final MobileStatusTracker mMobileStatusTracker; 83 84 // Save the previous STATUS_HISTORY_SIZE states for logging. 85 private final String[] mMobileStatusHistory = new String[STATUS_HISTORY_SIZE]; 86 // Where to copy the next state into. 87 private int mMobileStatusHistoryIndex; 88 89 private final MobileStatusTracker.Callback mMobileCallback = 90 new MobileStatusTracker.Callback() { 91 private String mLastStatus; 92 93 @Override 94 public void onMobileStatusChanged(boolean updateTelephony, 95 MobileStatus mobileStatus) { 96 if (DEBUG) { 97 Log.d(mTag, "onMobileStatusChanged=" 98 + " updateTelephony=" + updateTelephony 99 + " mobileStatus=" + mobileStatus.toString()); 100 } 101 String currentStatus = mobileStatus.toString(); 102 if (!currentStatus.equals(mLastStatus)) { 103 mLastStatus = currentStatus; 104 String status = new StringBuilder() 105 .append(SSDF.format(System.currentTimeMillis())).append(",") 106 .append(currentStatus) 107 .toString(); 108 recordLastMobileStatus(status); 109 } 110 updateMobileStatus(mobileStatus); 111 if (updateTelephony) { 112 updateTelephony(); 113 } else { 114 notifyListenersIfNecessary(); 115 } 116 } 117 }; 118 119 // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't 120 // need listener lists anymore. MobileSignalController( Context context, Config config, boolean hasMobileData, TelephonyManager phone, CallbackHandler callbackHandler, NetworkControllerImpl networkController, MobileMappingsProxy mobileMappingsProxy, SubscriptionInfo info, SubscriptionDefaults defaults, Looper receiverLooper, CarrierConfigTracker carrierConfigTracker, MobileStatusTrackerFactory mobileStatusTrackerFactory )121 public MobileSignalController( 122 Context context, 123 Config config, 124 boolean hasMobileData, 125 TelephonyManager phone, 126 CallbackHandler callbackHandler, 127 NetworkControllerImpl networkController, 128 MobileMappingsProxy mobileMappingsProxy, 129 SubscriptionInfo info, 130 SubscriptionDefaults defaults, 131 Looper receiverLooper, 132 CarrierConfigTracker carrierConfigTracker, 133 MobileStatusTrackerFactory mobileStatusTrackerFactory 134 ) { 135 super("MobileSignalController(" + info.getSubscriptionId() + ")", context, 136 NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler, 137 networkController); 138 mCarrierConfigTracker = carrierConfigTracker; 139 mConfig = config; 140 mPhone = phone; 141 mDefaults = defaults; 142 mSubscriptionInfo = info; 143 mMobileMappingsProxy = mobileMappingsProxy; 144 mNetworkNameSeparator = getTextIfExists( 145 R.string.status_bar_network_name_separator).toString(); 146 mNetworkNameDefault = getTextIfExists( 147 com.android.internal.R.string.lockscreen_carrier_default).toString(); 148 149 mNetworkToIconLookup = mMobileMappingsProxy.mapIconSets(mConfig); 150 mDefaultIcons = mMobileMappingsProxy.getDefaultIcons(mConfig); 151 152 String networkName = info.getCarrierName() != null ? info.getCarrierName().toString() 153 : mNetworkNameDefault; 154 mLastState.networkName = mCurrentState.networkName = networkName; 155 mLastState.networkNameData = mCurrentState.networkNameData = networkName; 156 mLastState.enabled = mCurrentState.enabled = hasMobileData; 157 mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons; 158 mObserver = new ContentObserver(new Handler(receiverLooper)) { 159 @Override 160 public void onChange(boolean selfChange) { 161 updateTelephony(); 162 } 163 }; 164 mMobileStatusTracker = mobileStatusTrackerFactory.createTracker(mMobileCallback); 165 } 166 setConfiguration(Config config)167 void setConfiguration(Config config) { 168 mConfig = config; 169 updateInflateSignalStrength(); 170 mNetworkToIconLookup = mMobileMappingsProxy.mapIconSets(mConfig); 171 mDefaultIcons = mMobileMappingsProxy.getDefaultIcons(mConfig); 172 updateTelephony(); 173 } 174 setAirplaneMode(boolean airplaneMode)175 void setAirplaneMode(boolean airplaneMode) { 176 mCurrentState.airplaneMode = airplaneMode; 177 notifyListenersIfNecessary(); 178 } 179 setUserSetupComplete(boolean userSetup)180 void setUserSetupComplete(boolean userSetup) { 181 mCurrentState.userSetup = userSetup; 182 notifyListenersIfNecessary(); 183 } 184 185 @Override updateConnectivity(BitSet connectedTransports, BitSet validatedTransports)186 public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) { 187 boolean isValidated = validatedTransports.get(mTransportType); 188 mCurrentState.isDefault = connectedTransports.get(mTransportType); 189 // Only show this as not having connectivity if we are default. 190 mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0; 191 notifyListenersIfNecessary(); 192 } 193 setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode)194 void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) { 195 mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode; 196 updateTelephony(); 197 } 198 199 /** 200 * Start listening for phone state changes. 201 */ registerListener()202 public void registerListener() { 203 mMobileStatusTracker.setListening(true); 204 mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA), 205 true, mObserver); 206 mContext.getContentResolver().registerContentObserver(Global.getUriFor( 207 Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()), 208 true, mObserver); 209 } 210 211 /** 212 * Stop listening for phone state changes. 213 */ unregisterListener()214 public void unregisterListener() { 215 mMobileStatusTracker.setListening(false); 216 mContext.getContentResolver().unregisterContentObserver(mObserver); 217 } 218 updateInflateSignalStrength()219 private void updateInflateSignalStrength() { 220 mInflateSignalStrengths = SignalStrengthUtil.shouldInflateSignalStrength(mContext, 221 mSubscriptionInfo.getSubscriptionId()); 222 } 223 getNumLevels()224 private int getNumLevels() { 225 if (mInflateSignalStrengths) { 226 return CellSignalStrength.getNumSignalStrengthLevels() + 1; 227 } 228 return CellSignalStrength.getNumSignalStrengthLevels(); 229 } 230 231 @Override getCurrentIconId()232 public int getCurrentIconId() { 233 if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) { 234 return SignalDrawable.getCarrierChangeState(getNumLevels()); 235 } else if (mCurrentState.connected) { 236 int level = mCurrentState.level; 237 if (mInflateSignalStrengths) { 238 level++; 239 } 240 boolean dataDisabled = mCurrentState.userSetup 241 && (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED 242 || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA 243 && mCurrentState.defaultDataOff)); 244 boolean noInternet = mCurrentState.inetCondition == 0; 245 boolean cutOut = dataDisabled || noInternet; 246 return SignalDrawable.getState(level, getNumLevels(), cutOut); 247 } else if (mCurrentState.enabled) { 248 return SignalDrawable.getEmptyState(getNumLevels()); 249 } else { 250 return 0; 251 } 252 } 253 254 @Override getQsCurrentIconId()255 public int getQsCurrentIconId() { 256 return getCurrentIconId(); 257 } 258 259 @Override notifyListeners(SignalCallback callback)260 public void notifyListeners(SignalCallback callback) { 261 // If the device is on carrier merged WiFi, we should let WifiSignalController to control 262 // the SysUI states. 263 if (mNetworkController.isCarrierMergedWifi(mSubscriptionInfo.getSubscriptionId())) { 264 return; 265 } 266 MobileIconGroup icons = getIcons(); 267 268 String contentDescription = getTextIfExists(getContentDescription()).toString(); 269 CharSequence dataContentDescriptionHtml = getTextIfExists(icons.dataContentDescription); 270 271 //TODO: Hacky 272 // The data content description can sometimes be shown in a text view and might come to us 273 // as HTML. Strip any styling here so that listeners don't have to care 274 CharSequence dataContentDescription = Html.fromHtml( 275 dataContentDescriptionHtml.toString(), 0).toString(); 276 if (mCurrentState.inetCondition == 0) { 277 dataContentDescription = mContext.getString(R.string.data_connection_no_internet); 278 } 279 280 int iconId = mCurrentState.getNetworkTypeIcon(mContext); 281 final QsInfo qsInfo = getQsInfo(contentDescription, iconId); 282 final SbInfo sbInfo = getSbInfo(contentDescription, iconId); 283 284 MobileDataIndicators mobileDataIndicators = new MobileDataIndicators( 285 sbInfo.icon, 286 qsInfo.icon, 287 sbInfo.ratTypeIcon, 288 qsInfo.ratTypeIcon, 289 mCurrentState.hasActivityIn(), 290 mCurrentState.hasActivityOut(), 291 dataContentDescription, 292 dataContentDescriptionHtml, 293 qsInfo.description, 294 mSubscriptionInfo.getSubscriptionId(), 295 mCurrentState.roaming, 296 sbInfo.showTriangle); 297 callback.setMobileDataIndicators(mobileDataIndicators); 298 } 299 getQsInfo(String contentDescription, int dataTypeIcon)300 private QsInfo getQsInfo(String contentDescription, int dataTypeIcon) { 301 int qsTypeIcon = 0; 302 IconState qsIcon = null; 303 CharSequence qsDescription = null; 304 305 if (mCurrentState.dataSim) { 306 // only show QS icons if the state is also default 307 if (!mCurrentState.isDefault) { 308 return new QsInfo(qsTypeIcon, qsIcon, qsDescription); 309 } 310 311 if (mCurrentState.showQuickSettingsRatIcon() || mConfig.alwaysShowDataRatIcon) { 312 qsTypeIcon = dataTypeIcon; 313 } 314 315 boolean qsIconVisible = mCurrentState.enabled && !mCurrentState.isEmergency; 316 qsIcon = new IconState(qsIconVisible, getQsCurrentIconId(), contentDescription); 317 318 if (!mCurrentState.isEmergency) { 319 qsDescription = mCurrentState.networkName; 320 } 321 } 322 323 return new QsInfo(qsTypeIcon, qsIcon, qsDescription); 324 } 325 getSbInfo(String contentDescription, int dataTypeIcon)326 private SbInfo getSbInfo(String contentDescription, int dataTypeIcon) { 327 final boolean dataDisabled = mCurrentState.isDataDisabledOrNotDefault(); 328 IconState statusIcon = new IconState( 329 mCurrentState.enabled && !mCurrentState.airplaneMode, 330 getCurrentIconId(), contentDescription); 331 332 boolean showDataIconInStatusBar = 333 (mCurrentState.dataConnected && mCurrentState.isDefault) || dataDisabled; 334 int typeIcon = 335 (showDataIconInStatusBar || mConfig.alwaysShowDataRatIcon) ? dataTypeIcon : 0; 336 boolean showTriangle = mCurrentState.enabled && !mCurrentState.airplaneMode; 337 338 return new SbInfo(showTriangle, typeIcon, statusIcon); 339 } 340 341 @Override cleanState()342 protected MobileState cleanState() { 343 return new MobileState(); 344 } 345 isInService()346 public boolean isInService() { 347 return mCurrentState.isInService(); 348 } 349 getNetworkNameForCarrierWiFi()350 String getNetworkNameForCarrierWiFi() { 351 return mPhone.getSimOperatorName(); 352 } 353 isRoaming()354 private boolean isRoaming() { 355 // During a carrier change, roaming indications need to be suppressed. 356 if (isCarrierNetworkChangeActive()) { 357 return false; 358 } 359 if (mCurrentState.isCdma()) { 360 return mPhone.getCdmaEnhancedRoamingIndicatorDisplayNumber() 361 != TelephonyManager.ERI_OFF; 362 } else { 363 return mCurrentState.isRoaming(); 364 } 365 } 366 isCarrierNetworkChangeActive()367 private boolean isCarrierNetworkChangeActive() { 368 return mCurrentState.carrierNetworkChangeMode; 369 } 370 handleBroadcast(Intent intent)371 void handleBroadcast(Intent intent) { 372 String action = intent.getAction(); 373 if (action.equals(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)) { 374 updateNetworkName(intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false), 375 intent.getStringExtra(TelephonyManager.EXTRA_SPN), 376 intent.getStringExtra(TelephonyManager.EXTRA_DATA_SPN), 377 intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false), 378 intent.getStringExtra(TelephonyManager.EXTRA_PLMN)); 379 notifyListenersIfNecessary(); 380 } else if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) { 381 updateDataSim(); 382 notifyListenersIfNecessary(); 383 } else if (action.equals(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED)) { 384 int carrierId = intent.getIntExtra( 385 TelephonyManager.EXTRA_CARRIER_ID, UNKNOWN_CARRIER_ID); 386 mCurrentState.setCarrierId(carrierId); 387 } 388 } 389 updateDataSim()390 private void updateDataSim() { 391 int activeDataSubId = mDefaults.getActiveDataSubId(); 392 if (SubscriptionManager.isValidSubscriptionId(activeDataSubId)) { 393 mCurrentState.dataSim = activeDataSubId == mSubscriptionInfo.getSubscriptionId(); 394 } else { 395 // There doesn't seem to be a data sim selected, however if 396 // there isn't a MobileSignalController with dataSim set, then 397 // QS won't get any callbacks and will be blank. Instead 398 // lets just assume we are the data sim (which will basically 399 // show one at random) in QS until one is selected. The user 400 // should pick one soon after, so we shouldn't be in this state 401 // for long. 402 mCurrentState.dataSim = true; 403 } 404 } 405 406 /** 407 * Updates the network's name based on incoming spn and plmn. 408 */ updateNetworkName(boolean showSpn, String spn, String dataSpn, boolean showPlmn, String plmn)409 void updateNetworkName(boolean showSpn, String spn, String dataSpn, 410 boolean showPlmn, String plmn) { 411 if (CHATTY) { 412 Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn 413 + " spn=" + spn + " dataSpn=" + dataSpn 414 + " showPlmn=" + showPlmn + " plmn=" + plmn); 415 } 416 StringBuilder str = new StringBuilder(); 417 StringBuilder strData = new StringBuilder(); 418 if (showPlmn && plmn != null) { 419 str.append(plmn); 420 strData.append(plmn); 421 } 422 if (showSpn && spn != null) { 423 if (str.length() != 0) { 424 str.append(mNetworkNameSeparator); 425 } 426 str.append(spn); 427 } 428 if (str.length() != 0) { 429 mCurrentState.networkName = str.toString(); 430 } else { 431 mCurrentState.networkName = mNetworkNameDefault; 432 } 433 if (showSpn && dataSpn != null) { 434 if (strData.length() != 0) { 435 strData.append(mNetworkNameSeparator); 436 } 437 strData.append(dataSpn); 438 } 439 if (strData.length() != 0) { 440 mCurrentState.networkNameData = strData.toString(); 441 } else { 442 mCurrentState.networkNameData = mNetworkNameDefault; 443 } 444 } 445 446 /** 447 * Extracts the CellSignalStrengthCdma from SignalStrength then returns the level 448 */ getCdmaLevel(SignalStrength signalStrength)449 private int getCdmaLevel(SignalStrength signalStrength) { 450 List<CellSignalStrengthCdma> signalStrengthCdma = 451 signalStrength.getCellSignalStrengths(CellSignalStrengthCdma.class); 452 if (!signalStrengthCdma.isEmpty()) { 453 return signalStrengthCdma.get(0).getLevel(); 454 } 455 return CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 456 } 457 updateMobileStatus(MobileStatus mobileStatus)458 private void updateMobileStatus(MobileStatus mobileStatus) { 459 mCurrentState.setFromMobileStatus(mobileStatus); 460 } 461 getSignalLevel(SignalStrength signalStrength)462 int getSignalLevel(SignalStrength signalStrength) { 463 if (signalStrength == null) { 464 return 0; 465 } 466 if (!signalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) { 467 return getCdmaLevel(signalStrength); 468 } else { 469 return signalStrength.getLevel(); 470 } 471 } 472 473 /** 474 * Updates the current state based on ServiceState, SignalStrength, DataState, 475 * TelephonyDisplayInfo, and sim state. It should be called any time one of these is updated. 476 * This will call listeners if necessary. 477 */ updateTelephony()478 private void updateTelephony() { 479 if (DEBUG) { 480 Log.d(mTag, "updateTelephonySignalStrength: hasService=" 481 + mCurrentState.isInService() 482 + " ss=" + mCurrentState.signalStrength 483 + " displayInfo=" + mCurrentState.telephonyDisplayInfo); 484 } 485 checkDefaultData(); 486 mCurrentState.connected = mCurrentState.isInService(); 487 if (mCurrentState.connected) { 488 mCurrentState.level = getSignalLevel(mCurrentState.signalStrength); 489 } 490 491 mCurrentState.setCarrierId(mPhone.getSimCarrierId()); 492 String iconKey = mMobileMappingsProxy.getIconKey(mCurrentState.telephonyDisplayInfo); 493 if (mNetworkToIconLookup.get(iconKey) != null) { 494 mCurrentState.iconGroup = mNetworkToIconLookup.get(iconKey); 495 } else { 496 mCurrentState.iconGroup = mDefaultIcons; 497 } 498 mCurrentState.dataConnected = mCurrentState.isDataConnected(); 499 500 mCurrentState.roaming = isRoaming(); 501 if (isCarrierNetworkChangeActive()) { 502 mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE; 503 } else if (isDataDisabled() && !mConfig.alwaysShowDataRatIcon) { 504 if (mSubscriptionInfo.getSubscriptionId() != mDefaults.getDefaultDataSubId()) { 505 mCurrentState.iconGroup = TelephonyIcons.NOT_DEFAULT_DATA; 506 } else { 507 mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED; 508 } 509 } 510 if (mCurrentState.isEmergencyOnly() != mCurrentState.isEmergency) { 511 mCurrentState.isEmergency = mCurrentState.isEmergencyOnly(); 512 mNetworkController.recalculateEmergency(); 513 } 514 // Fill in the network name if we think we have it. 515 if (mCurrentState.networkName.equals(mNetworkNameDefault) 516 && !TextUtils.isEmpty(mCurrentState.getOperatorAlphaShort())) { 517 mCurrentState.networkName = mCurrentState.getOperatorAlphaShort(); 518 } 519 // If this is the data subscription, update the currentState data name 520 if (mCurrentState.networkNameData.equals(mNetworkNameDefault) 521 && mCurrentState.dataSim 522 && !TextUtils.isEmpty(mCurrentState.getOperatorAlphaShort())) { 523 mCurrentState.networkNameData = mCurrentState.getOperatorAlphaShort(); 524 } 525 526 notifyListenersIfNecessary(); 527 } 528 529 /** 530 * If we are controlling the NOT_DEFAULT_DATA icon, check the status of the other one 531 */ checkDefaultData()532 private void checkDefaultData() { 533 if (mCurrentState.iconGroup != TelephonyIcons.NOT_DEFAULT_DATA) { 534 mCurrentState.defaultDataOff = false; 535 return; 536 } 537 538 mCurrentState.defaultDataOff = mNetworkController.isDataControllerDisabled(); 539 } 540 onMobileDataChanged()541 void onMobileDataChanged() { 542 checkDefaultData(); 543 notifyListenersIfNecessary(); 544 } 545 isDataDisabled()546 boolean isDataDisabled() { 547 return !mPhone.isDataConnectionAllowed(); 548 } 549 550 @VisibleForTesting setActivity(int activity)551 void setActivity(int activity) { 552 mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT 553 || activity == TelephonyManager.DATA_ACTIVITY_IN; 554 mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT 555 || activity == TelephonyManager.DATA_ACTIVITY_OUT; 556 notifyListenersIfNecessary(); 557 } 558 recordLastMobileStatus(String mobileStatus)559 private void recordLastMobileStatus(String mobileStatus) { 560 mMobileStatusHistory[mMobileStatusHistoryIndex] = mobileStatus; 561 mMobileStatusHistoryIndex = (mMobileStatusHistoryIndex + 1) % STATUS_HISTORY_SIZE; 562 } 563 564 @Override dump(PrintWriter pw)565 public void dump(PrintWriter pw) { 566 super.dump(pw); 567 pw.println(" mSubscription=" + mSubscriptionInfo + ","); 568 pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ","); 569 pw.println(" isDataDisabled=" + isDataDisabled() + ","); 570 pw.println(" mNetworkToIconLookup=" + mNetworkToIconLookup + ","); 571 pw.println(" mMobileStatusTracker.isListening=" + mMobileStatusTracker.isListening()); 572 pw.println(" MobileStatusHistory"); 573 int size = 0; 574 for (int i = 0; i < STATUS_HISTORY_SIZE; i++) { 575 if (mMobileStatusHistory[i] != null) { 576 size++; 577 } 578 } 579 // Print out the previous states in ordered number. 580 for (int i = mMobileStatusHistoryIndex + STATUS_HISTORY_SIZE - 1; 581 i >= mMobileStatusHistoryIndex + STATUS_HISTORY_SIZE - size; i--) { 582 pw.println(" Previous MobileStatus(" 583 + (mMobileStatusHistoryIndex + STATUS_HISTORY_SIZE - i) + "): " 584 + mMobileStatusHistory[i & (STATUS_HISTORY_SIZE - 1)]); 585 } 586 587 dumpTableData(pw); 588 } 589 590 /** Box for QS icon info */ 591 private static final class QsInfo { 592 final int ratTypeIcon; 593 final IconState icon; 594 final CharSequence description; 595 QsInfo(int typeIcon, IconState iconState, CharSequence desc)596 QsInfo(int typeIcon, IconState iconState, CharSequence desc) { 597 ratTypeIcon = typeIcon; 598 icon = iconState; 599 description = desc; 600 } 601 602 @Override toString()603 public String toString() { 604 return "QsInfo: ratTypeIcon=" + ratTypeIcon + " icon=" + icon; 605 } 606 } 607 608 /** Box for status bar icon info */ 609 private static final class SbInfo { 610 final boolean showTriangle; 611 final int ratTypeIcon; 612 final IconState icon; 613 SbInfo(boolean show, int typeIcon, IconState iconState)614 SbInfo(boolean show, int typeIcon, IconState iconState) { 615 showTriangle = show; 616 ratTypeIcon = typeIcon; 617 icon = iconState; 618 } 619 620 @Override toString()621 public String toString() { 622 return "SbInfo: showTriangle=" + showTriangle + " ratTypeIcon=" + ratTypeIcon 623 + " icon=" + icon; 624 } 625 } 626 } 627