MobileSignalController.java revision 0288de0e5635b714273ff8185b4bdbfb9ece447c
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 */ 16package com.android.systemui.statusbar.policy; 17 18import android.content.Context; 19import android.content.Intent; 20import android.database.ContentObserver; 21import android.net.NetworkCapabilities; 22import android.os.Handler; 23import android.os.Looper; 24import android.provider.Settings.Global; 25import android.telephony.PhoneStateListener; 26import android.telephony.ServiceState; 27import android.telephony.SignalStrength; 28import android.telephony.SubscriptionInfo; 29import android.telephony.SubscriptionManager; 30import android.telephony.TelephonyManager; 31import android.text.TextUtils; 32import android.util.Log; 33import android.util.SparseArray; 34 35import com.android.internal.annotations.VisibleForTesting; 36import com.android.internal.telephony.TelephonyIntents; 37import com.android.internal.telephony.cdma.EriInfo; 38import com.android.systemui.R; 39import com.android.systemui.statusbar.policy.NetworkController.IconState; 40import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; 41import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config; 42import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults; 43 44import java.io.PrintWriter; 45import java.util.BitSet; 46import java.util.Objects; 47 48 49public class MobileSignalController extends SignalController< 50 MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> { 51 private final TelephonyManager mPhone; 52 private final SubscriptionDefaults mDefaults; 53 private final String mNetworkNameDefault; 54 private final String mNetworkNameSeparator; 55 private final ContentObserver mObserver; 56 @VisibleForTesting 57 final PhoneStateListener mPhoneStateListener; 58 // Save entire info for logging, we only use the id. 59 final SubscriptionInfo mSubscriptionInfo; 60 61 // @VisibleForDemoMode 62 final SparseArray<MobileIconGroup> mNetworkToIconLookup; 63 64 // Since some pieces of the phone state are interdependent we store it locally, 65 // this could potentially become part of MobileState for simplification/complication 66 // of code. 67 private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 68 private int mDataState = TelephonyManager.DATA_DISCONNECTED; 69 private ServiceState mServiceState; 70 private SignalStrength mSignalStrength; 71 private MobileIconGroup mDefaultIcons; 72 private Config mConfig; 73 74 // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't 75 // need listener lists anymore. 76 public MobileSignalController(Context context, Config config, boolean hasMobileData, 77 TelephonyManager phone, CallbackHandler callbackHandler, 78 NetworkControllerImpl networkController, SubscriptionInfo info, 79 SubscriptionDefaults defaults, Looper receiverLooper) { 80 super("MobileSignalController(" + info.getSubscriptionId() + ")", context, 81 NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler, 82 networkController); 83 mNetworkToIconLookup = new SparseArray<>(); 84 mConfig = config; 85 mPhone = phone; 86 mDefaults = defaults; 87 mSubscriptionInfo = info; 88 mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(), 89 receiverLooper); 90 mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator); 91 mNetworkNameDefault = getStringIfExists( 92 com.android.internal.R.string.lockscreen_carrier_default); 93 94 mapIconSets(); 95 96 String networkName = info.getCarrierName() != null ? info.getCarrierName().toString() 97 : mNetworkNameDefault; 98 mLastState.networkName = mCurrentState.networkName = networkName; 99 mLastState.networkNameData = mCurrentState.networkNameData = networkName; 100 mLastState.enabled = mCurrentState.enabled = hasMobileData; 101 mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons; 102 // Get initial data sim state. 103 updateDataSim(); 104 mObserver = new ContentObserver(new Handler(receiverLooper)) { 105 @Override 106 public void onChange(boolean selfChange) { 107 updateTelephony(); 108 } 109 }; 110 } 111 112 public void setConfiguration(Config config) { 113 mConfig = config; 114 mapIconSets(); 115 updateTelephony(); 116 } 117 118 public int getDataContentDescription() { 119 return getIcons().mDataContentDescription; 120 } 121 122 public void setAirplaneMode(boolean airplaneMode) { 123 mCurrentState.airplaneMode = airplaneMode; 124 notifyListenersIfNecessary(); 125 } 126 127 public void setUserSetupComplete(boolean userSetup) { 128 mCurrentState.userSetup = userSetup; 129 notifyListenersIfNecessary(); 130 } 131 132 @Override 133 public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) { 134 boolean isValidated = validatedTransports.get(mTransportType); 135 mCurrentState.isDefault = connectedTransports.get(mTransportType); 136 // Only show this as not having connectivity if we are default. 137 mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0; 138 notifyListenersIfNecessary(); 139 } 140 141 public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) { 142 mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode; 143 updateTelephony(); 144 } 145 146 /** 147 * Start listening for phone state changes. 148 */ 149 public void registerListener() { 150 mPhone.listen(mPhoneStateListener, 151 PhoneStateListener.LISTEN_SERVICE_STATE 152 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS 153 | PhoneStateListener.LISTEN_CALL_STATE 154 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE 155 | PhoneStateListener.LISTEN_DATA_ACTIVITY 156 | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE); 157 mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA), 158 true, mObserver); 159 mContext.getContentResolver().registerContentObserver(Global.getUriFor( 160 Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()), 161 true, mObserver); 162 } 163 164 /** 165 * Stop listening for phone state changes. 166 */ 167 public void unregisterListener() { 168 mPhone.listen(mPhoneStateListener, 0); 169 mContext.getContentResolver().unregisterContentObserver(mObserver); 170 } 171 172 /** 173 * Produce a mapping of data network types to icon groups for simple and quick use in 174 * updateTelephony. 175 */ 176 private void mapIconSets() { 177 mNetworkToIconLookup.clear(); 178 179 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G); 180 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G); 181 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G); 182 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G); 183 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G); 184 185 if (!mConfig.showAtLeast3G) { 186 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN, 187 TelephonyIcons.UNKNOWN); 188 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, TelephonyIcons.E); 189 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, TelephonyIcons.ONE_X); 190 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyIcons.ONE_X); 191 192 mDefaultIcons = TelephonyIcons.G; 193 } else { 194 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN, 195 TelephonyIcons.THREE_G); 196 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, 197 TelephonyIcons.THREE_G); 198 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, 199 TelephonyIcons.THREE_G); 200 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, 201 TelephonyIcons.THREE_G); 202 mDefaultIcons = TelephonyIcons.THREE_G; 203 } 204 205 MobileIconGroup hGroup = TelephonyIcons.THREE_G; 206 if (mConfig.hspaDataDistinguishable) { 207 hGroup = TelephonyIcons.H; 208 } 209 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSDPA, hGroup); 210 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSUPA, hGroup); 211 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup); 212 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hGroup); 213 214 if (mConfig.show4gForLte) { 215 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G); 216 if (mConfig.hideLtePlus) { 217 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, 218 TelephonyIcons.FOUR_G); 219 } else { 220 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, 221 TelephonyIcons.FOUR_G_PLUS); 222 } 223 } else { 224 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE); 225 if (mConfig.hideLtePlus) { 226 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, 227 TelephonyIcons.LTE); 228 } else { 229 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA, 230 TelephonyIcons.LTE_PLUS); 231 } 232 } 233 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.WFC); 234 } 235 236 @Override 237 public void notifyListeners(SignalCallback callback) { 238 MobileIconGroup icons = getIcons(); 239 240 String contentDescription = getStringIfExists(getContentDescription()); 241 String dataContentDescription = getStringIfExists(icons.mDataContentDescription); 242 final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED 243 && mCurrentState.userSetup; 244 245 // Show icon in QS when we are connected or data is disabled. 246 boolean showDataIcon = mCurrentState.dataConnected || dataDisabled; 247 IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode, 248 getCurrentIconId(), contentDescription); 249 250 int qsTypeIcon = 0; 251 IconState qsIcon = null; 252 String description = null; 253 // Only send data sim callbacks to QS. 254 if (mCurrentState.dataSim) { 255 qsTypeIcon = showDataIcon ? icons.mQsDataType : 0; 256 qsIcon = new IconState(mCurrentState.enabled 257 && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription); 258 description = mCurrentState.isEmergency ? null : mCurrentState.networkName; 259 } 260 boolean activityIn = mCurrentState.dataConnected 261 && !mCurrentState.carrierNetworkChangeMode 262 && mCurrentState.activityIn; 263 boolean activityOut = mCurrentState.dataConnected 264 && !mCurrentState.carrierNetworkChangeMode 265 && mCurrentState.activityOut; 266 showDataIcon &= mCurrentState.isDefault || dataDisabled; 267 int typeIcon = showDataIcon ? icons.mDataType : 0; 268 callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon, 269 activityIn, activityOut, dataContentDescription, description, icons.mIsWide, 270 mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming); 271 } 272 273 @Override 274 protected MobileState cleanState() { 275 return new MobileState(); 276 } 277 278 private boolean hasService() { 279 if (mServiceState != null) { 280 // Consider the device to be in service if either voice or data 281 // service is available. Some SIM cards are marketed as data-only 282 // and do not support voice service, and on these SIM cards, we 283 // want to show signal bars for data service as well as the "no 284 // service" or "emergency calls only" text that indicates that voice 285 // is not available. 286 switch (mServiceState.getVoiceRegState()) { 287 case ServiceState.STATE_POWER_OFF: 288 return false; 289 case ServiceState.STATE_OUT_OF_SERVICE: 290 case ServiceState.STATE_EMERGENCY_ONLY: 291 return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE; 292 default: 293 return true; 294 } 295 } else { 296 return false; 297 } 298 } 299 300 private boolean isCdma() { 301 return (mSignalStrength != null) && !mSignalStrength.isGsm(); 302 } 303 304 public boolean isEmergencyOnly() { 305 return (mServiceState != null && mServiceState.isEmergencyOnly()); 306 } 307 308 private boolean isRoaming() { 309 if (isCdma()) { 310 final int iconMode = mServiceState.getCdmaEriIconMode(); 311 return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF 312 && (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL 313 || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH); 314 } else { 315 return mServiceState != null && mServiceState.getRoaming(); 316 } 317 } 318 319 private boolean isCarrierNetworkChangeActive() { 320 return mCurrentState.carrierNetworkChangeMode; 321 } 322 323 public void handleBroadcast(Intent intent) { 324 String action = intent.getAction(); 325 if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) { 326 updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false), 327 intent.getStringExtra(TelephonyIntents.EXTRA_SPN), 328 intent.getStringExtra(TelephonyIntents.EXTRA_DATA_SPN), 329 intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false), 330 intent.getStringExtra(TelephonyIntents.EXTRA_PLMN)); 331 notifyListenersIfNecessary(); 332 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) { 333 updateDataSim(); 334 notifyListenersIfNecessary(); 335 } 336 } 337 338 private void updateDataSim() { 339 int defaultDataSub = mDefaults.getDefaultDataSubId(); 340 if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) { 341 mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId(); 342 } else { 343 // There doesn't seem to be a data sim selected, however if 344 // there isn't a MobileSignalController with dataSim set, then 345 // QS won't get any callbacks and will be blank. Instead 346 // lets just assume we are the data sim (which will basically 347 // show one at random) in QS until one is selected. The user 348 // should pick one soon after, so we shouldn't be in this state 349 // for long. 350 mCurrentState.dataSim = true; 351 } 352 } 353 354 /** 355 * Updates the network's name based on incoming spn and plmn. 356 */ 357 void updateNetworkName(boolean showSpn, String spn, String dataSpn, 358 boolean showPlmn, String plmn) { 359 if (CHATTY) { 360 Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn 361 + " spn=" + spn + " dataSpn=" + dataSpn 362 + " showPlmn=" + showPlmn + " plmn=" + plmn); 363 } 364 StringBuilder str = new StringBuilder(); 365 StringBuilder strData = new StringBuilder(); 366 if (showPlmn && plmn != null) { 367 str.append(plmn); 368 strData.append(plmn); 369 } 370 if (showSpn && spn != null) { 371 if (str.length() != 0) { 372 str.append(mNetworkNameSeparator); 373 } 374 str.append(spn); 375 } 376 if (str.length() != 0) { 377 mCurrentState.networkName = str.toString(); 378 } else { 379 mCurrentState.networkName = mNetworkNameDefault; 380 } 381 if (showSpn && dataSpn != null) { 382 if (strData.length() != 0) { 383 strData.append(mNetworkNameSeparator); 384 } 385 strData.append(dataSpn); 386 } 387 if (strData.length() != 0) { 388 mCurrentState.networkNameData = strData.toString(); 389 } else { 390 mCurrentState.networkNameData = mNetworkNameDefault; 391 } 392 } 393 394 /** 395 * Updates the current state based on mServiceState, mSignalStrength, mDataNetType, 396 * mDataState, and mSimState. It should be called any time one of these is updated. 397 * This will call listeners if necessary. 398 */ 399 private final void updateTelephony() { 400 if (DEBUG) { 401 Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService() 402 + " ss=" + mSignalStrength); 403 } 404 mCurrentState.connected = hasService() && mSignalStrength != null; 405 if (mCurrentState.connected) { 406 if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) { 407 mCurrentState.level = mSignalStrength.getCdmaLevel(); 408 } else { 409 mCurrentState.level = mSignalStrength.getLevel(); 410 } 411 } 412 if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) { 413 mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType); 414 } else { 415 mCurrentState.iconGroup = mDefaultIcons; 416 } 417 mCurrentState.dataConnected = mCurrentState.connected 418 && mDataState == TelephonyManager.DATA_CONNECTED; 419 420 mCurrentState.roaming = isRoaming(); 421 if (isCarrierNetworkChangeActive()) { 422 mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE; 423 } else if (isDataDisabled()) { 424 mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED; 425 } 426 if (isEmergencyOnly() != mCurrentState.isEmergency) { 427 mCurrentState.isEmergency = isEmergencyOnly(); 428 mNetworkController.recalculateEmergency(); 429 } 430 // Fill in the network name if we think we have it. 431 if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null 432 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) { 433 mCurrentState.networkName = mServiceState.getOperatorAlphaShort(); 434 } 435 436 notifyListenersIfNecessary(); 437 } 438 439 private boolean isDataDisabled() { 440 return !mPhone.getDataEnabled(mSubscriptionInfo.getSubscriptionId()); 441 } 442 443 @VisibleForTesting 444 void setActivity(int activity) { 445 mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT 446 || activity == TelephonyManager.DATA_ACTIVITY_IN; 447 mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT 448 || activity == TelephonyManager.DATA_ACTIVITY_OUT; 449 notifyListenersIfNecessary(); 450 } 451 452 @Override 453 public void dump(PrintWriter pw) { 454 super.dump(pw); 455 pw.println(" mSubscription=" + mSubscriptionInfo + ","); 456 pw.println(" mServiceState=" + mServiceState + ","); 457 pw.println(" mSignalStrength=" + mSignalStrength + ","); 458 pw.println(" mDataState=" + mDataState + ","); 459 pw.println(" mDataNetType=" + mDataNetType + ","); 460 } 461 462 class MobilePhoneStateListener extends PhoneStateListener { 463 public MobilePhoneStateListener(int subId, Looper looper) { 464 super(subId, looper); 465 } 466 467 @Override 468 public void onSignalStrengthsChanged(SignalStrength signalStrength) { 469 if (DEBUG) { 470 Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength + 471 ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel()))); 472 } 473 mSignalStrength = signalStrength; 474 updateTelephony(); 475 } 476 477 @Override 478 public void onServiceStateChanged(ServiceState state) { 479 if (DEBUG) { 480 Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState() 481 + " dataState=" + state.getDataRegState()); 482 } 483 mServiceState = state; 484 mDataNetType = state.getDataNetworkType(); 485 if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE && mServiceState != null && 486 mServiceState.isUsingCarrierAggregation()) { 487 mDataNetType = TelephonyManager.NETWORK_TYPE_LTE_CA; 488 } 489 updateTelephony(); 490 } 491 492 @Override 493 public void onDataConnectionStateChanged(int state, int networkType) { 494 if (DEBUG) { 495 Log.d(mTag, "onDataConnectionStateChanged: state=" + state 496 + " type=" + networkType); 497 } 498 mDataState = state; 499 mDataNetType = networkType; 500 if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE && mServiceState != null && 501 mServiceState.isUsingCarrierAggregation()) { 502 mDataNetType = TelephonyManager.NETWORK_TYPE_LTE_CA; 503 } 504 updateTelephony(); 505 } 506 507 @Override 508 public void onDataActivity(int direction) { 509 if (DEBUG) { 510 Log.d(mTag, "onDataActivity: direction=" + direction); 511 } 512 setActivity(direction); 513 } 514 515 @Override 516 public void onCarrierNetworkChange(boolean active) { 517 if (DEBUG) { 518 Log.d(mTag, "onCarrierNetworkChange: active=" + active); 519 } 520 mCurrentState.carrierNetworkChangeMode = active; 521 522 updateTelephony(); 523 } 524 }; 525 526 static class MobileIconGroup extends SignalController.IconGroup { 527 final int mDataContentDescription; // mContentDescriptionDataType 528 final int mDataType; 529 final boolean mIsWide; 530 final int mQsDataType; 531 532 public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc, 533 int sbNullState, int qsNullState, int sbDiscState, int qsDiscState, 534 int discContentDesc, int dataContentDesc, int dataType, boolean isWide, 535 int qsDataType) { 536 super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState, 537 qsDiscState, discContentDesc); 538 mDataContentDescription = dataContentDesc; 539 mDataType = dataType; 540 mIsWide = isWide; 541 mQsDataType = qsDataType; 542 } 543 } 544 545 static class MobileState extends SignalController.State { 546 String networkName; 547 String networkNameData; 548 boolean dataSim; 549 boolean dataConnected; 550 boolean isEmergency; 551 boolean airplaneMode; 552 boolean carrierNetworkChangeMode; 553 boolean isDefault; 554 boolean userSetup; 555 boolean roaming; 556 557 @Override 558 public void copyFrom(State s) { 559 super.copyFrom(s); 560 MobileState state = (MobileState) s; 561 dataSim = state.dataSim; 562 networkName = state.networkName; 563 networkNameData = state.networkNameData; 564 dataConnected = state.dataConnected; 565 isDefault = state.isDefault; 566 isEmergency = state.isEmergency; 567 airplaneMode = state.airplaneMode; 568 carrierNetworkChangeMode = state.carrierNetworkChangeMode; 569 userSetup = state.userSetup; 570 roaming = state.roaming; 571 } 572 573 @Override 574 protected void toString(StringBuilder builder) { 575 super.toString(builder); 576 builder.append(','); 577 builder.append("dataSim=").append(dataSim).append(','); 578 builder.append("networkName=").append(networkName).append(','); 579 builder.append("networkNameData=").append(networkNameData).append(','); 580 builder.append("dataConnected=").append(dataConnected).append(','); 581 builder.append("roaming=").append(roaming).append(','); 582 builder.append("isDefault=").append(isDefault).append(','); 583 builder.append("isEmergency=").append(isEmergency).append(','); 584 builder.append("airplaneMode=").append(airplaneMode).append(','); 585 builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode) 586 .append(','); 587 builder.append("userSetup=").append(userSetup); 588 } 589 590 @Override 591 public boolean equals(Object o) { 592 return super.equals(o) 593 && Objects.equals(((MobileState) o).networkName, networkName) 594 && Objects.equals(((MobileState) o).networkNameData, networkNameData) 595 && ((MobileState) o).dataSim == dataSim 596 && ((MobileState) o).dataConnected == dataConnected 597 && ((MobileState) o).isEmergency == isEmergency 598 && ((MobileState) o).airplaneMode == airplaneMode 599 && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode 600 && ((MobileState) o).userSetup == userSetup 601 && ((MobileState) o).isDefault == isDefault 602 && ((MobileState) o).roaming == roaming; 603 } 604 } 605} 606