1 /* 2 * Copyright (C) 2006 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.internal.telephony; 18 19 import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId; 20 21 import static com.android.internal.telephony.CarrierActionAgent.CARRIER_ACTION_SET_RADIO_ENABLED; 22 import static com.android.internal.telephony.uicc.IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN; 23 import static com.android.internal.telephony.uicc.IccRecords.CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN; 24 25 import android.annotation.IntDef; 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.app.AlarmManager; 29 import android.app.Notification; 30 import android.app.NotificationManager; 31 import android.app.PendingIntent; 32 import android.compat.annotation.UnsupportedAppUsage; 33 import android.content.BroadcastReceiver; 34 import android.content.ContentResolver; 35 import android.content.ContentValues; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.IntentFilter; 39 import android.content.SharedPreferences; 40 import android.content.res.Resources; 41 import android.hardware.radio.V1_0.CellInfoType; 42 import android.net.NetworkCapabilities; 43 import android.os.AsyncResult; 44 import android.os.BaseBundle; 45 import android.os.Handler; 46 import android.os.Message; 47 import android.os.Parcel; 48 import android.os.PersistableBundle; 49 import android.os.Registrant; 50 import android.os.RegistrantList; 51 import android.os.SystemClock; 52 import android.os.SystemProperties; 53 import android.os.TimestampedValue; 54 import android.os.UserHandle; 55 import android.os.WorkSource; 56 import android.preference.PreferenceManager; 57 import android.provider.Settings; 58 import android.sysprop.TelephonyProperties; 59 import android.telephony.AccessNetworkConstants; 60 import android.telephony.AccessNetworkConstants.AccessNetworkType; 61 import android.telephony.AccessNetworkConstants.TransportType; 62 import android.telephony.CarrierConfigManager; 63 import android.telephony.CellIdentity; 64 import android.telephony.CellIdentityCdma; 65 import android.telephony.CellIdentityGsm; 66 import android.telephony.CellIdentityLte; 67 import android.telephony.CellIdentityNr; 68 import android.telephony.CellIdentityTdscdma; 69 import android.telephony.CellIdentityWcdma; 70 import android.telephony.CellInfo; 71 import android.telephony.CellSignalStrengthLte; 72 import android.telephony.CellSignalStrengthNr; 73 import android.telephony.DataSpecificRegistrationInfo; 74 import android.telephony.NetworkRegistrationInfo; 75 import android.telephony.PhysicalChannelConfig; 76 import android.telephony.ServiceState; 77 import android.telephony.ServiceState.RilRadioTechnology; 78 import android.telephony.SignalStrength; 79 import android.telephony.SignalThresholdInfo; 80 import android.telephony.SubscriptionInfo; 81 import android.telephony.SubscriptionManager; 82 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; 83 import android.telephony.TelephonyManager; 84 import android.telephony.VoiceSpecificRegistrationInfo; 85 import android.text.TextUtils; 86 import android.util.EventLog; 87 import android.util.LocalLog; 88 import android.util.Pair; 89 import android.util.SparseArray; 90 import android.util.SparseBooleanArray; 91 92 import com.android.internal.annotations.VisibleForTesting; 93 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager; 94 import com.android.internal.telephony.cdma.EriInfo; 95 import com.android.internal.telephony.cdma.EriManager; 96 import com.android.internal.telephony.cdnr.CarrierDisplayNameData; 97 import com.android.internal.telephony.cdnr.CarrierDisplayNameResolver; 98 import com.android.internal.telephony.dataconnection.DataConnection; 99 import com.android.internal.telephony.dataconnection.DcTracker; 100 import com.android.internal.telephony.dataconnection.TransportManager; 101 import com.android.internal.telephony.metrics.TelephonyMetrics; 102 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState; 103 import com.android.internal.telephony.uicc.IccCardStatus.CardState; 104 import com.android.internal.telephony.uicc.IccRecords; 105 import com.android.internal.telephony.uicc.RuimRecords; 106 import com.android.internal.telephony.uicc.SIMRecords; 107 import com.android.internal.telephony.uicc.UiccCard; 108 import com.android.internal.telephony.uicc.UiccCardApplication; 109 import com.android.internal.telephony.uicc.UiccController; 110 import com.android.internal.telephony.uicc.UiccProfile; 111 import com.android.internal.telephony.util.ArrayUtils; 112 import com.android.internal.telephony.util.NotificationChannelController; 113 import com.android.internal.telephony.util.TelephonyUtils; 114 import com.android.internal.util.IndentingPrintWriter; 115 import com.android.telephony.Rlog; 116 117 import java.io.FileDescriptor; 118 import java.io.PrintWriter; 119 import java.lang.annotation.Retention; 120 import java.lang.annotation.RetentionPolicy; 121 import java.util.ArrayList; 122 import java.util.Arrays; 123 import java.util.Collections; 124 import java.util.Comparator; 125 import java.util.HashSet; 126 import java.util.LinkedList; 127 import java.util.List; 128 import java.util.Set; 129 import java.util.concurrent.TimeUnit; 130 import java.util.concurrent.atomic.AtomicInteger; 131 import java.util.regex.Matcher; 132 import java.util.regex.Pattern; 133 import java.util.regex.PatternSyntaxException; 134 import java.util.stream.Collectors; 135 136 /** 137 * {@hide} 138 */ 139 public class ServiceStateTracker extends Handler { 140 static final String LOG_TAG = "SST"; 141 static final boolean DBG = true; 142 private static final boolean VDBG = false; // STOPSHIP if true 143 144 private static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming"; 145 146 private static final long SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS = 147 TimeUnit.SECONDS.toMillis(10); 148 149 @UnsupportedAppUsage 150 private CommandsInterface mCi; 151 @UnsupportedAppUsage 152 private UiccController mUiccController = null; 153 @UnsupportedAppUsage 154 private UiccCardApplication mUiccApplcation = null; 155 @UnsupportedAppUsage 156 private IccRecords mIccRecords = null; 157 158 private boolean mVoiceCapable; 159 160 @UnsupportedAppUsage 161 public ServiceState mSS; 162 @UnsupportedAppUsage 163 private ServiceState mNewSS; 164 // A placeholder service state which will always be out of service. This is broadcast to 165 // listeners when the subscription ID for a phone becomes invalid so that they get a final 166 // state update. 167 private final ServiceState mOutOfServiceSS; 168 169 // This is the minimum interval at which CellInfo requests will be serviced by the modem. 170 // Any requests that arrive within MinInterval of the previous reuqest will simply receive the 171 // cached result. This is a power-saving feature, because requests to the modem may require 172 // wakeup of a separate chip and bus communication. Because the cost of wakeups is 173 // architecture dependent, it would be preferable if this sort of optimization could be 174 // handled in SoC-specific code, but for now, keep it here to ensure that in case further 175 // optimizations are not present elsewhere, there is a power-management scheme of last resort. 176 private int mCellInfoMinIntervalMs = 2000; 177 178 // Maximum time to wait for a CellInfo request before assuming it won't arrive and returning 179 // null to callers. Note, that if a CellInfo response does arrive later, then it will be 180 // treated as an UNSOL, which means it will be cached as well as sent to registrants; thus, 181 // this only impacts the behavior of one-shot requests (be they blocking or non-blocking). 182 private static final long CELL_INFO_LIST_QUERY_TIMEOUT = 2000; 183 184 private long mLastCellInfoReqTime; 185 private List<CellInfo> mLastCellInfoList = null; 186 private List<PhysicalChannelConfig> mLastPhysicalChannelConfigList = null; 187 188 @UnsupportedAppUsage 189 private SignalStrength mSignalStrength; 190 private long mSignalStrengthUpdatedTime; 191 192 // TODO - this should not be public, right now used externally GsmConnetion. 193 public RestrictedState mRestrictedState; 194 195 /** 196 * A unique identifier to track requests associated with a poll 197 * and ignore stale responses. The value is a count-down of 198 * expected responses in this pollingContext. 199 */ 200 @VisibleForTesting 201 public int[] mPollingContext; 202 @UnsupportedAppUsage 203 private boolean mDesiredPowerState; 204 205 /** 206 * By default, strength polling is enabled. However, if we're 207 * getting unsolicited signal strength updates from the radio, set 208 * value to true and don't bother polling any more. 209 */ 210 private boolean mDontPollSignalStrength = false; 211 212 @UnsupportedAppUsage 213 private RegistrantList mVoiceRoamingOnRegistrants = new RegistrantList(); 214 @UnsupportedAppUsage 215 private RegistrantList mVoiceRoamingOffRegistrants = new RegistrantList(); 216 @UnsupportedAppUsage 217 private RegistrantList mDataRoamingOnRegistrants = new RegistrantList(); 218 @UnsupportedAppUsage 219 private RegistrantList mDataRoamingOffRegistrants = new RegistrantList(); 220 protected SparseArray<RegistrantList> mAttachedRegistrants = new SparseArray<>(); 221 protected SparseArray<RegistrantList> mDetachedRegistrants = new SparseArray(); 222 private RegistrantList mVoiceRegStateOrRatChangedRegistrants = new RegistrantList(); 223 private SparseArray<RegistrantList> mDataRegStateOrRatChangedRegistrants = new SparseArray<>(); 224 @UnsupportedAppUsage 225 private RegistrantList mNetworkAttachedRegistrants = new RegistrantList(); 226 private RegistrantList mNetworkDetachedRegistrants = new RegistrantList(); 227 private RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList(); 228 private RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList(); 229 private RegistrantList mImsCapabilityChangedRegistrants = new RegistrantList(); 230 private RegistrantList mNrStateChangedRegistrants = new RegistrantList(); 231 private RegistrantList mNrFrequencyChangedRegistrants = new RegistrantList(); 232 233 /* Radio power off pending flag and tag counter */ 234 private boolean mPendingRadioPowerOffAfterDataOff = false; 235 private int mPendingRadioPowerOffAfterDataOffTag = 0; 236 237 /** Signal strength poll rate. */ 238 private static final int POLL_PERIOD_MILLIS = 20 * 1000; 239 240 /** Waiting period before recheck gprs and voice registration. */ 241 public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000; 242 243 /** GSM events */ 244 protected static final int EVENT_RADIO_STATE_CHANGED = 1; 245 protected static final int EVENT_NETWORK_STATE_CHANGED = 2; 246 protected static final int EVENT_GET_SIGNAL_STRENGTH = 3; 247 protected static final int EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION = 4; 248 protected static final int EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION = 5; 249 protected static final int EVENT_POLL_STATE_PS_IWLAN_REGISTRATION = 6; 250 protected static final int EVENT_POLL_STATE_OPERATOR = 7; 251 protected static final int EVENT_POLL_SIGNAL_STRENGTH = 10; 252 protected static final int EVENT_NITZ_TIME = 11; 253 protected static final int EVENT_SIGNAL_STRENGTH_UPDATE = 12; 254 protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14; 255 protected static final int EVENT_GET_LOC_DONE = 15; 256 protected static final int EVENT_SIM_RECORDS_LOADED = 16; 257 protected static final int EVENT_SIM_READY = 17; 258 protected static final int EVENT_LOCATION_UPDATES_ENABLED = 18; 259 protected static final int EVENT_GET_PREFERRED_NETWORK_TYPE = 19; 260 protected static final int EVENT_SET_PREFERRED_NETWORK_TYPE = 20; 261 protected static final int EVENT_RESET_PREFERRED_NETWORK_TYPE = 21; 262 protected static final int EVENT_CHECK_REPORT_GPRS = 22; 263 protected static final int EVENT_RESTRICTED_STATE_CHANGED = 23; 264 265 /** CDMA events */ 266 protected static final int EVENT_RUIM_READY = 26; 267 protected static final int EVENT_RUIM_RECORDS_LOADED = 27; 268 protected static final int EVENT_POLL_STATE_CDMA_SUBSCRIPTION = 34; 269 protected static final int EVENT_NV_READY = 35; 270 protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37; 271 protected static final int EVENT_SET_RADIO_POWER_OFF = 38; 272 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 39; 273 protected static final int EVENT_CDMA_PRL_VERSION_CHANGED = 40; 274 275 protected static final int EVENT_RADIO_ON = 41; 276 public static final int EVENT_ICC_CHANGED = 42; 277 protected static final int EVENT_GET_CELL_INFO_LIST = 43; 278 protected static final int EVENT_UNSOL_CELL_INFO_LIST = 44; 279 protected static final int EVENT_CHANGE_IMS_STATE = 45; 280 protected static final int EVENT_IMS_STATE_CHANGED = 46; 281 protected static final int EVENT_IMS_STATE_DONE = 47; 282 protected static final int EVENT_IMS_CAPABILITY_CHANGED = 48; 283 protected static final int EVENT_ALL_DATA_DISCONNECTED = 49; 284 protected static final int EVENT_PHONE_TYPE_SWITCHED = 50; 285 protected static final int EVENT_RADIO_POWER_FROM_CARRIER = 51; 286 protected static final int EVENT_IMS_SERVICE_STATE_CHANGED = 53; 287 protected static final int EVENT_RADIO_POWER_OFF_DONE = 54; 288 protected static final int EVENT_PHYSICAL_CHANNEL_CONFIG = 55; 289 protected static final int EVENT_CELL_LOCATION_RESPONSE = 56; 290 protected static final int EVENT_CARRIER_CONFIG_CHANGED = 57; 291 private static final int EVENT_POLL_STATE_REQUEST = 58; 292 293 /** 294 * The current service state. 295 * 296 * This is a column name in {@link android.provider.Telephony.ServiceStateTable}. 297 * 298 * Copied from packages/services/Telephony/src/com/android/phone/ServiceStateProvider.java 299 */ 300 private static final String SERVICE_STATE = "service_state"; 301 302 @Retention(RetentionPolicy.SOURCE) 303 @IntDef(prefix = {"CARRIER_NAME_DISPLAY_BITMASK"}, 304 value = {CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN, 305 CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN}, 306 flag = true) 307 public @interface CarrierNameDisplayBitmask {} 308 309 // Show SPN only and only if this bit is set. 310 public static final int CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN = 1 << 0; 311 312 // Show PLMN only and only if this bit is set. 313 public static final int CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN = 1 << 1; 314 315 private List<Message> mPendingCellInfoRequests = new LinkedList<Message>(); 316 // @GuardedBy("mPendingCellInfoRequests") 317 private boolean mIsPendingCellInfoRequest = false; 318 319 /** Reason for registration denial. */ 320 protected static final String REGISTRATION_DENIED_GEN = "General"; 321 protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure"; 322 323 private CarrierDisplayNameResolver mCdnr; 324 325 private boolean mImsRegistrationOnOff = false; 326 private boolean mAlarmSwitch = false; 327 /** Radio is disabled by carrier. Radio power will not be override if this field is set */ 328 private boolean mRadioDisabledByCarrier = false; 329 private PendingIntent mRadioOffIntent = null; 330 private static final String ACTION_RADIO_OFF = "android.intent.action.ACTION_RADIO_OFF"; 331 private boolean mPowerOffDelayNeed = true; 332 @UnsupportedAppUsage 333 private boolean mDeviceShuttingDown = false; 334 /** Keep track of SPN display rules, so we only broadcast intent if something changes. */ 335 @UnsupportedAppUsage 336 private boolean mSpnUpdatePending = false; 337 @UnsupportedAppUsage 338 private String mCurSpn = null; 339 @UnsupportedAppUsage 340 private String mCurDataSpn = null; 341 @UnsupportedAppUsage 342 private String mCurPlmn = null; 343 @UnsupportedAppUsage 344 private boolean mCurShowPlmn = false; 345 @UnsupportedAppUsage 346 private boolean mCurShowSpn = false; 347 @UnsupportedAppUsage 348 @VisibleForTesting 349 public int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 350 private int mPrevSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 351 352 private boolean mImsRegistered = false; 353 354 @UnsupportedAppUsage 355 private SubscriptionManager mSubscriptionManager; 356 @UnsupportedAppUsage 357 private SubscriptionController mSubscriptionController; 358 @UnsupportedAppUsage 359 private final SstSubscriptionsChangedListener mOnSubscriptionsChangedListener = 360 new SstSubscriptionsChangedListener(); 361 362 363 private final RatRatcheter mRatRatcheter; 364 365 private final LocaleTracker mLocaleTracker; 366 367 private final LocalLog mRoamingLog = new LocalLog(10); 368 private final LocalLog mAttachLog = new LocalLog(10); 369 private final LocalLog mPhoneTypeLog = new LocalLog(10); 370 private final LocalLog mRatLog = new LocalLog(20); 371 private final LocalLog mRadioPowerLog = new LocalLog(20); 372 private final LocalLog mCdnrLogs = new LocalLog(64); 373 374 private Pattern mOperatorNameStringPattern; 375 376 private class SstSubscriptionsChangedListener extends OnSubscriptionsChangedListener { 377 public final AtomicInteger mPreviousSubId = 378 new AtomicInteger(SubscriptionManager.INVALID_SUBSCRIPTION_ID); 379 380 /** 381 * Callback invoked when there is any change to any SubscriptionInfo. Typically 382 * this method would invoke {@link SubscriptionManager#getActiveSubscriptionInfoList} 383 */ 384 @Override onSubscriptionsChanged()385 public void onSubscriptionsChanged() { 386 if (DBG) log("SubscriptionListener.onSubscriptionInfoChanged"); 387 // Set the network type, in case the radio does not restore it. 388 int subId = mPhone.getSubId(); 389 ServiceStateTracker.this.mPrevSubId = mPreviousSubId.get(); 390 if (mPreviousSubId.getAndSet(subId) != subId) { 391 if (SubscriptionManager.isValidSubscriptionId(subId)) { 392 Context context = mPhone.getContext(); 393 394 mPhone.notifyPhoneStateChanged(); 395 mPhone.notifyCallForwardingIndicator(); 396 if (!SubscriptionManager.isValidSubscriptionId( 397 ServiceStateTracker.this.mPrevSubId)) { 398 // just went from invalid to valid subId, so notify with current service 399 // state in case our service stat was never broadcasted (we don't notify 400 // service states when the subId is invalid) 401 mPhone.notifyServiceStateChanged(mSS); 402 } 403 404 boolean restoreSelection = !context.getResources().getBoolean( 405 com.android.internal.R.bool.skip_restoring_network_selection); 406 mPhone.sendSubscriptionSettings(restoreSelection); 407 408 setDataNetworkTypeForPhone(mSS.getRilDataRadioTechnology()); 409 410 if (mSpnUpdatePending) { 411 mSubscriptionController.setPlmnSpn(mPhone.getPhoneId(), mCurShowPlmn, 412 mCurPlmn, mCurShowSpn, mCurSpn); 413 mSpnUpdatePending = false; 414 } 415 416 // Remove old network selection sharedPreferences since SP key names are now 417 // changed to include subId. This will be done only once when upgrading from an 418 // older build that did not include subId in the names. 419 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( 420 context); 421 String oldNetworkSelection = sp.getString( 422 Phone.NETWORK_SELECTION_KEY, ""); 423 String oldNetworkSelectionName = sp.getString( 424 Phone.NETWORK_SELECTION_NAME_KEY, ""); 425 String oldNetworkSelectionShort = sp.getString( 426 Phone.NETWORK_SELECTION_SHORT_KEY, ""); 427 if (!TextUtils.isEmpty(oldNetworkSelection) || 428 !TextUtils.isEmpty(oldNetworkSelectionName) || 429 !TextUtils.isEmpty(oldNetworkSelectionShort)) { 430 SharedPreferences.Editor editor = sp.edit(); 431 editor.putString(Phone.NETWORK_SELECTION_KEY + subId, 432 oldNetworkSelection); 433 editor.putString(Phone.NETWORK_SELECTION_NAME_KEY + subId, 434 oldNetworkSelectionName); 435 editor.putString(Phone.NETWORK_SELECTION_SHORT_KEY + subId, 436 oldNetworkSelectionShort); 437 editor.remove(Phone.NETWORK_SELECTION_KEY); 438 editor.remove(Phone.NETWORK_SELECTION_NAME_KEY); 439 editor.remove(Phone.NETWORK_SELECTION_SHORT_KEY); 440 editor.commit(); 441 } 442 443 // Once sub id becomes valid, we need to update the service provider name 444 // displayed on the UI again. The old SPN update intents sent to 445 // MobileSignalController earlier were actually ignored due to invalid sub id. 446 updateSpnDisplay(); 447 } else { 448 if (SubscriptionManager.isValidSubscriptionId( 449 ServiceStateTracker.this.mPrevSubId)) { 450 // just went from valid to invalid subId, so notify phone state listeners 451 // with final broadcast 452 mPhone.notifyServiceStateChangedForSubId(mOutOfServiceSS, 453 ServiceStateTracker.this.mPrevSubId); 454 } 455 } 456 // update voicemail count and notify message waiting changed 457 mPhone.updateVoiceMail(); 458 } 459 } 460 }; 461 462 //Common 463 @UnsupportedAppUsage 464 protected final GsmCdmaPhone mPhone; 465 466 private CellIdentity mCellIdentity; 467 private static final int MS_PER_HOUR = 60 * 60 * 1000; 468 private final NitzStateMachine mNitzState; 469 470 /** 471 * Holds the last NITZ signal received. Used only for trying to determine an MCC from a CDMA 472 * SID. 473 */ 474 @Nullable 475 private NitzData mLastNitzData; 476 477 private final EriManager mEriManager; 478 @UnsupportedAppUsage 479 private final ContentResolver mCr; 480 481 //GSM 482 @UnsupportedAppUsage 483 private int mPreferredNetworkType; 484 @UnsupportedAppUsage 485 private int mMaxDataCalls = 1; 486 @UnsupportedAppUsage 487 private int mNewMaxDataCalls = 1; 488 @UnsupportedAppUsage 489 private int mReasonDataDenied = -1; 490 @UnsupportedAppUsage 491 private int mNewReasonDataDenied = -1; 492 493 /** 494 * The code of the rejection cause that is sent by network when the CS 495 * registration is rejected. It should be shown to the user as a notification. 496 */ 497 private int mRejectCode; 498 private int mNewRejectCode; 499 500 /** 501 * GSM voice roaming status solely based on TS 27.007 7.2 CREG. Only used by 502 * handlePollStateResult to store CREG roaming result. 503 */ 504 private boolean mGsmVoiceRoaming = false; 505 /** 506 * Gsm data roaming status solely based on TS 27.007 10.1.19 CGREG. Only used by 507 * handlePollStateResult to store CGREG roaming result. 508 */ 509 private boolean mGsmDataRoaming = false; 510 /** 511 * Mark when service state is in emergency call only mode 512 */ 513 @UnsupportedAppUsage 514 private boolean mEmergencyOnly = false; 515 /** Started the recheck process after finding gprs should registered but not. */ 516 @UnsupportedAppUsage 517 private boolean mStartedGprsRegCheck; 518 /** Already sent the event-log for no gprs register. */ 519 @UnsupportedAppUsage 520 private boolean mReportedGprsNoReg; 521 522 private CarrierServiceStateTracker mCSST; 523 /** 524 * The Notification object given to the NotificationManager. 525 */ 526 private Notification mNotification; 527 /** Notification type. */ 528 public static final int PS_ENABLED = 1001; // Access Control blocks data service 529 public static final int PS_DISABLED = 1002; // Access Control enables data service 530 public static final int CS_ENABLED = 1003; // Access Control blocks all voice/sms service 531 public static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service 532 public static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service 533 public static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service 534 public static final int CS_REJECT_CAUSE_ENABLED = 2001; // Notify MM rejection cause 535 public static final int CS_REJECT_CAUSE_DISABLED = 2002; // Cancel MM rejection cause 536 /** Notification id. */ 537 public static final int PS_NOTIFICATION = 888; // Id to update and cancel PS restricted 538 public static final int CS_NOTIFICATION = 999; // Id to update and cancel CS restricted 539 public static final int CS_REJECT_CAUSE_NOTIFICATION = 111; // Id to update and cancel MM 540 // rejection cause 541 542 /** To identify whether EVENT_SIM_READY is received or not */ 543 private boolean mIsSimReady = false; 544 545 private String mLastKnownNetworkCountry = ""; 546 547 @UnsupportedAppUsage 548 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 549 @Override 550 public void onReceive(Context context, Intent intent) { 551 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { 552 int phoneId = intent.getExtras().getInt(CarrierConfigManager.EXTRA_SLOT_INDEX); 553 // Ignore the carrier config changed if the phoneId is not matched. 554 if (phoneId == mPhone.getPhoneId()) { 555 sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED); 556 } 557 return; 558 } 559 560 // TODO: Remove this weird check left over from CDMA/GSM service state tracker merge. 561 if (!mPhone.isPhoneTypeGsm()) { 562 loge("Ignoring intent " + intent + " received on CDMA phone"); 563 return; 564 } 565 566 if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) { 567 // update emergency string whenever locale changed 568 updateSpnDisplay(); 569 } else if (intent.getAction().equals(ACTION_RADIO_OFF)) { 570 mAlarmSwitch = false; 571 powerOffRadioSafely(); 572 } else if (intent.getAction().equals(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) { 573 String lastKnownNetworkCountry = intent.getStringExtra( 574 TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY); 575 if (!mLastKnownNetworkCountry.equals(lastKnownNetworkCountry)) { 576 updateSpnDisplay(); 577 } 578 } 579 } 580 }; 581 582 //CDMA 583 // Min values used to by getOtasp() 584 public static final String UNACTIVATED_MIN2_VALUE = "000000"; 585 public static final String UNACTIVATED_MIN_VALUE = "1111110111"; 586 // Current Otasp value 587 private int mCurrentOtaspMode = TelephonyManager.OTASP_UNINITIALIZED; 588 @UnsupportedAppUsage 589 private int mRoamingIndicator; 590 private boolean mIsInPrl; 591 @UnsupportedAppUsage 592 private int mDefaultRoamingIndicator; 593 /** 594 * Initially assume no data connection. 595 */ 596 private int mRegistrationState = -1; 597 private RegistrantList mCdmaForSubscriptionInfoReadyRegistrants = new RegistrantList(); 598 private String mMdn; 599 private int mHomeSystemId[] = null; 600 private int mHomeNetworkId[] = null; 601 private String mMin; 602 private String mPrlVersion; 603 private boolean mIsMinInfoReady = false; 604 private boolean mIsEriTextLoaded = false; 605 private String mEriText; 606 @UnsupportedAppUsage 607 private boolean mIsSubscriptionFromRuim = false; 608 private CdmaSubscriptionSourceManager mCdmaSSM; 609 public static final String INVALID_MCC = "000"; 610 public static final String DEFAULT_MNC = "00"; 611 private HbpcdUtils mHbpcdUtils = null; 612 /* Used only for debugging purposes. */ 613 private String mRegistrationDeniedReason; 614 private String mCurrentCarrier = null; 615 616 private final TransportManager mTransportManager; 617 private final SparseArray<NetworkRegistrationManager> mRegStateManagers = new SparseArray<>(); 618 619 /* list of LTE EARFCNs (E-UTRA Absolute Radio Frequency Channel Number, 620 * Reference: 3GPP TS 36.104 5.4.3) 621 * inclusive ranges for which the lte rsrp boost is applied */ 622 private ArrayList<Pair<Integer, Integer>> mEarfcnPairListForRsrpBoost = null; 623 624 private int mLteRsrpBoost = 0; // offset which is reduced from the rsrp threshold 625 // while calculating signal strength level. 626 private final Object mLteRsrpBoostLock = new Object(); 627 private static final int INVALID_LTE_EARFCN = -1; 628 ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci)629 public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) { 630 mNitzState = TelephonyComponentFactory.getInstance() 631 .inject(NitzStateMachine.class.getName()) 632 .makeNitzStateMachine(phone); 633 mPhone = phone; 634 mCi = ci; 635 636 mCdnr = new CarrierDisplayNameResolver(mPhone); 637 638 mEriManager = TelephonyComponentFactory.getInstance().inject(EriManager.class.getName()) 639 .makeEriManager(mPhone, EriManager.ERI_FROM_XML); 640 641 mRatRatcheter = new RatRatcheter(mPhone); 642 mVoiceCapable = ((TelephonyManager) mPhone.getContext() 643 .getSystemService(Context.TELEPHONY_SERVICE)) 644 .isVoiceCapable(); 645 mUiccController = UiccController.getInstance(); 646 647 mOutOfServiceSS = new ServiceState(); 648 mOutOfServiceSS.setStateOutOfService(); 649 650 mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 651 mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null); 652 mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null); 653 mCi.registerForPhysicalChannelConfiguration(this, EVENT_PHYSICAL_CHANNEL_CONFIG, null); 654 655 mSubscriptionController = SubscriptionController.getInstance(); 656 mSubscriptionManager = SubscriptionManager.from(phone.getContext()); 657 mSubscriptionManager 658 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); 659 mRestrictedState = new RestrictedState(); 660 661 mTransportManager = mPhone.getTransportManager(); 662 663 for (int transportType : mTransportManager.getAvailableTransports()) { 664 mRegStateManagers.append(transportType, new NetworkRegistrationManager( 665 transportType, phone)); 666 mRegStateManagers.get(transportType).registerForNetworkRegistrationInfoChanged( 667 this, EVENT_NETWORK_STATE_CHANGED, null); 668 } 669 mLocaleTracker = TelephonyComponentFactory.getInstance() 670 .inject(LocaleTracker.class.getName()) 671 .makeLocaleTracker(mPhone, mNitzState, getLooper()); 672 673 mCi.registerForImsNetworkStateChanged(this, EVENT_IMS_STATE_CHANGED, null); 674 mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); 675 mCi.setOnNITZTime(this, EVENT_NITZ_TIME, null); 676 677 mCr = phone.getContext().getContentResolver(); 678 // system setting property AIRPLANE_MODE_ON is set in Settings. 679 int airplaneMode = Settings.Global.getInt(mCr, Settings.Global.AIRPLANE_MODE_ON, 0); 680 int enableCellularOnBoot = Settings.Global.getInt(mCr, 681 Settings.Global.ENABLE_CELLULAR_ON_BOOT, 1); 682 mDesiredPowerState = (enableCellularOnBoot > 0) && ! (airplaneMode > 0); 683 mRadioPowerLog.log("init : airplane mode = " + airplaneMode + " enableCellularOnBoot = " + 684 enableCellularOnBoot); 685 686 687 setSignalStrengthDefaultValues(); 688 mPhone.getCarrierActionAgent().registerForCarrierAction(CARRIER_ACTION_SET_RADIO_ENABLED, 689 this, EVENT_RADIO_POWER_FROM_CARRIER, null, false); 690 691 // Monitor locale change 692 Context context = mPhone.getContext(); 693 IntentFilter filter = new IntentFilter(); 694 filter.addAction(Intent.ACTION_LOCALE_CHANGED); 695 context.registerReceiver(mIntentReceiver, filter); 696 filter = new IntentFilter(); 697 filter.addAction(ACTION_RADIO_OFF); 698 context.registerReceiver(mIntentReceiver, filter); 699 filter = new IntentFilter(); 700 filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 701 context.registerReceiver(mIntentReceiver, filter); 702 filter = new IntentFilter(); 703 filter.addAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED); 704 context.registerReceiver(mIntentReceiver, filter); 705 706 mPhone.notifyOtaspChanged(TelephonyManager.OTASP_UNINITIALIZED); 707 708 mCi.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null); 709 updatePhoneType(); 710 711 mCSST = new CarrierServiceStateTracker(phone, this); 712 713 registerForNetworkAttached(mCSST, 714 CarrierServiceStateTracker.CARRIER_EVENT_VOICE_REGISTRATION, null); 715 registerForNetworkDetached(mCSST, 716 CarrierServiceStateTracker.CARRIER_EVENT_VOICE_DEREGISTRATION, null); 717 registerForDataConnectionAttached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mCSST, 718 CarrierServiceStateTracker.CARRIER_EVENT_DATA_REGISTRATION, null); 719 registerForDataConnectionDetached(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mCSST, 720 CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null); 721 registerForImsCapabilityChanged(mCSST, 722 CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null); 723 } 724 725 @VisibleForTesting updatePhoneType()726 public void updatePhoneType() { 727 728 // If we are previously voice roaming, we need to notify that roaming status changed before 729 // we change back to non-roaming. 730 if (mSS != null && mSS.getVoiceRoaming()) { 731 mVoiceRoamingOffRegistrants.notifyRegistrants(); 732 } 733 734 // If we are previously data roaming, we need to notify that roaming status changed before 735 // we change back to non-roaming. 736 if (mSS != null && mSS.getDataRoaming()) { 737 mDataRoamingOffRegistrants.notifyRegistrants(); 738 } 739 740 // If we are previously in service, we need to notify that we are out of service now. 741 if (mSS != null && mSS.getState() == ServiceState.STATE_IN_SERVICE) { 742 mNetworkDetachedRegistrants.notifyRegistrants(); 743 } 744 745 // If we are previously in service, we need to notify that we are out of service now. 746 for (int transport : mTransportManager.getAvailableTransports()) { 747 if (mSS != null) { 748 NetworkRegistrationInfo nrs = mSS.getNetworkRegistrationInfo( 749 NetworkRegistrationInfo.DOMAIN_PS, transport); 750 if (nrs != null && nrs.isInService() 751 && mDetachedRegistrants.get(transport) != null) { 752 mDetachedRegistrants.get(transport).notifyRegistrants(); 753 } 754 } 755 } 756 757 mSS = new ServiceState(); 758 mSS.setStateOutOfService(); 759 mNewSS = new ServiceState(); 760 mNewSS.setStateOutOfService(); 761 mLastCellInfoReqTime = 0; 762 mLastCellInfoList = null; 763 mSignalStrength = new SignalStrength(); 764 mStartedGprsRegCheck = false; 765 mReportedGprsNoReg = false; 766 mMdn = null; 767 mMin = null; 768 mPrlVersion = null; 769 mIsMinInfoReady = false; 770 mLastNitzData = null; 771 mNitzState.handleNetworkUnavailable(); 772 mCellIdentity = null; 773 mSignalStrengthUpdatedTime = System.currentTimeMillis(); 774 775 //cancel any pending pollstate request on voice tech switching 776 cancelPollState(); 777 778 if (mPhone.isPhoneTypeGsm()) { 779 //clear CDMA registrations first 780 if (mCdmaSSM != null) { 781 mCdmaSSM.dispose(this); 782 } 783 784 mCi.unregisterForCdmaPrlChanged(this); 785 mCi.unregisterForCdmaOtaProvision(this); 786 mPhone.unregisterForSimRecordsLoaded(this); 787 788 } else { 789 mPhone.registerForSimRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); 790 mCdmaSSM = CdmaSubscriptionSourceManager.getInstance(mPhone.getContext(), mCi, this, 791 EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null); 792 mIsSubscriptionFromRuim = (mCdmaSSM.getCdmaSubscriptionSource() == 793 CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM); 794 795 mCi.registerForCdmaPrlChanged(this, EVENT_CDMA_PRL_VERSION_CHANGED, null); 796 mCi.registerForCdmaOtaProvision(this, EVENT_OTA_PROVISION_STATUS_CHANGE, null); 797 798 mHbpcdUtils = new HbpcdUtils(mPhone.getContext()); 799 // update OTASP state in case previously set by another service 800 updateOtaspState(); 801 } 802 803 // This should be done after the technology specific initializations above since it relies 804 // on fields like mIsSubscriptionFromRuim (which is updated above) 805 onUpdateIccAvailability(); 806 807 setDataNetworkTypeForPhone(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN); 808 // Query signal strength from the modem after service tracker is created (i.e. boot up, 809 // switching between GSM and CDMA phone), because the unsolicited signal strength 810 // information might come late or even never come. This will get the accurate signal 811 // strength information displayed on the UI. 812 mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); 813 sendMessage(obtainMessage(EVENT_PHONE_TYPE_SWITCHED)); 814 815 logPhoneTypeChange(); 816 817 // Tell everybody that the registration state and RAT have changed. 818 notifyVoiceRegStateRilRadioTechnologyChanged(); 819 for (int transport : mTransportManager.getAvailableTransports()) { 820 notifyDataRegStateRilRadioTechnologyChanged(transport); 821 } 822 } 823 824 @VisibleForTesting requestShutdown()825 public void requestShutdown() { 826 if (mDeviceShuttingDown == true) return; 827 mDeviceShuttingDown = true; 828 mDesiredPowerState = false; 829 setPowerStateToDesired(); 830 } 831 dispose()832 public void dispose() { 833 mCi.unSetOnSignalStrengthUpdate(this); 834 mUiccController.unregisterForIccChanged(this); 835 mCi.unregisterForCellInfoList(this); 836 mCi.unregisterForPhysicalChannelConfiguration(this); 837 mSubscriptionManager 838 .removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); 839 mCi.unregisterForImsNetworkStateChanged(this); 840 mPhone.getCarrierActionAgent().unregisterForCarrierAction(this, 841 CARRIER_ACTION_SET_RADIO_ENABLED); 842 if (mCSST != null) { 843 mCSST.dispose(); 844 mCSST = null; 845 } 846 } 847 848 @UnsupportedAppUsage getDesiredPowerState()849 public boolean getDesiredPowerState() { 850 return mDesiredPowerState; 851 } getPowerStateFromCarrier()852 public boolean getPowerStateFromCarrier() { return !mRadioDisabledByCarrier; } 853 getPhysicalChannelConfigList()854 public List<PhysicalChannelConfig> getPhysicalChannelConfigList() { 855 return mLastPhysicalChannelConfigList; 856 } 857 858 private SignalStrength mLastSignalStrength = null; 859 @UnsupportedAppUsage notifySignalStrength()860 protected boolean notifySignalStrength() { 861 boolean notified = false; 862 if (!mSignalStrength.equals(mLastSignalStrength)) { 863 try { 864 mPhone.notifySignalStrength(); 865 notified = true; 866 mLastSignalStrength = mSignalStrength; 867 } catch (NullPointerException ex) { 868 loge("updateSignalStrength() Phone already destroyed: " + ex 869 + "SignalStrength not notified"); 870 } 871 } 872 return notified; 873 } 874 875 /** 876 * Notify all mVoiceRegStateOrRatChangedRegistrants using an 877 * AsyncResult in msg.obj where AsyncResult#result contains the 878 * new RAT as an Integer Object. 879 */ notifyVoiceRegStateRilRadioTechnologyChanged()880 protected void notifyVoiceRegStateRilRadioTechnologyChanged() { 881 int rat = mSS.getRilVoiceRadioTechnology(); 882 int vrs = mSS.getState(); 883 if (DBG) log("notifyVoiceRegStateRilRadioTechnologyChanged: vrs=" + vrs + " rat=" + rat); 884 885 mVoiceRegStateOrRatChangedRegistrants.notifyResult(new Pair<Integer, Integer>(vrs, rat)); 886 } 887 888 /** 889 * Get registration info 890 * 891 * @param transport The transport type 892 * @return Pair of registration info including {@link ServiceState.RegState} and 893 * {@link RilRadioTechnology}. 894 * 895 */ 896 @Nullable getRegistrationInfo(@ransportType int transport)897 private Pair<Integer, Integer> getRegistrationInfo(@TransportType int transport) { 898 NetworkRegistrationInfo nrs = mSS.getNetworkRegistrationInfo( 899 NetworkRegistrationInfo.DOMAIN_PS, transport); 900 if (nrs != null) { 901 int rat = ServiceState.networkTypeToRilRadioTechnology( 902 nrs.getAccessNetworkTechnology()); 903 int drs = regCodeToServiceState(nrs.getRegistrationState()); 904 return new Pair<>(drs, rat); 905 } 906 return null; 907 } 908 909 /** 910 * Notify all mDataConnectionRatChangeRegistrants using an 911 * AsyncResult in msg.obj where AsyncResult#result contains the 912 * new RAT as an Integer Object. 913 */ notifyDataRegStateRilRadioTechnologyChanged(@ransportType int transport)914 protected void notifyDataRegStateRilRadioTechnologyChanged(@TransportType int transport) { 915 RegistrantList registrantList = mDataRegStateOrRatChangedRegistrants.get(transport); 916 if (registrantList != null) { 917 Pair<Integer, Integer> registrationInfo = getRegistrationInfo(transport); 918 if (registrationInfo != null) { 919 registrantList.notifyResult(registrationInfo); 920 } 921 } 922 } 923 924 /** 925 * Some operators have been known to report registration failure 926 * data only devices, to fix that use DataRegState. 927 */ 928 @UnsupportedAppUsage useDataRegStateForDataOnlyDevices()929 protected void useDataRegStateForDataOnlyDevices() { 930 if (mVoiceCapable == false) { 931 if (DBG) { 932 log("useDataRegStateForDataOnlyDevice: VoiceRegState=" + mNewSS.getState() 933 + " DataRegState=" + mNewSS.getDataRegistrationState()); 934 } 935 // TODO: Consider not lying and instead have callers know the difference. 936 mNewSS.setVoiceRegState(mNewSS.getDataRegistrationState()); 937 } 938 } 939 940 @UnsupportedAppUsage updatePhoneObject()941 protected void updatePhoneObject() { 942 if (mPhone.getContext().getResources().getBoolean( 943 com.android.internal.R.bool.config_switch_phone_on_voice_reg_state_change)) { 944 // If the phone is not registered on a network, no need to update. 945 boolean isRegistered = mSS.getState() == ServiceState.STATE_IN_SERVICE 946 || mSS.getState() == ServiceState.STATE_EMERGENCY_ONLY; 947 if (!isRegistered) { 948 log("updatePhoneObject: Ignore update"); 949 return; 950 } 951 mPhone.updatePhoneObject(mSS.getRilVoiceRadioTechnology()); 952 } 953 } 954 955 /** 956 * Registration point for combined roaming on of mobile voice 957 * combined roaming is true when roaming is true and ONS differs SPN 958 * 959 * @param h handler to notify 960 * @param what what code of message when delivered 961 * @param obj placed in Message.obj 962 */ registerForVoiceRoamingOn(Handler h, int what, Object obj)963 public void registerForVoiceRoamingOn(Handler h, int what, Object obj) { 964 Registrant r = new Registrant(h, what, obj); 965 mVoiceRoamingOnRegistrants.add(r); 966 967 if (mSS.getVoiceRoaming()) { 968 r.notifyRegistrant(); 969 } 970 } 971 unregisterForVoiceRoamingOn(Handler h)972 public void unregisterForVoiceRoamingOn(Handler h) { 973 mVoiceRoamingOnRegistrants.remove(h); 974 } 975 976 /** 977 * Registration point for roaming off of mobile voice 978 * combined roaming is true when roaming is true and ONS differs SPN 979 * 980 * @param h handler to notify 981 * @param what what code of message when delivered 982 * @param obj placed in Message.obj 983 */ registerForVoiceRoamingOff(Handler h, int what, Object obj)984 public void registerForVoiceRoamingOff(Handler h, int what, Object obj) { 985 Registrant r = new Registrant(h, what, obj); 986 mVoiceRoamingOffRegistrants.add(r); 987 988 if (!mSS.getVoiceRoaming()) { 989 r.notifyRegistrant(); 990 } 991 } 992 unregisterForVoiceRoamingOff(Handler h)993 public void unregisterForVoiceRoamingOff(Handler h) { 994 mVoiceRoamingOffRegistrants.remove(h); 995 } 996 997 /** 998 * Registration point for combined roaming on of mobile data 999 * combined roaming is true when roaming is true and ONS differs SPN 1000 * 1001 * @param h handler to notify 1002 * @param what what code of message when delivered 1003 * @param obj placed in Message.obj 1004 */ registerForDataRoamingOn(Handler h, int what, Object obj)1005 public void registerForDataRoamingOn(Handler h, int what, Object obj) { 1006 Registrant r = new Registrant(h, what, obj); 1007 mDataRoamingOnRegistrants.add(r); 1008 1009 if (mSS.getDataRoaming()) { 1010 r.notifyRegistrant(); 1011 } 1012 } 1013 unregisterForDataRoamingOn(Handler h)1014 public void unregisterForDataRoamingOn(Handler h) { 1015 mDataRoamingOnRegistrants.remove(h); 1016 } 1017 1018 /** 1019 * Registration point for roaming off of mobile data 1020 * combined roaming is true when roaming is true and ONS differs SPN 1021 * 1022 * @param h handler to notify 1023 * @param what what code of message when delivered 1024 * @param obj placed in Message.obj 1025 * @param notifyNow notify upon registration if data roaming is off 1026 */ registerForDataRoamingOff(Handler h, int what, Object obj, boolean notifyNow)1027 public void registerForDataRoamingOff(Handler h, int what, Object obj, boolean notifyNow) { 1028 Registrant r = new Registrant(h, what, obj); 1029 mDataRoamingOffRegistrants.add(r); 1030 1031 if (notifyNow && !mSS.getDataRoaming()) { 1032 r.notifyRegistrant(); 1033 } 1034 } 1035 unregisterForDataRoamingOff(Handler h)1036 public void unregisterForDataRoamingOff(Handler h) { 1037 mDataRoamingOffRegistrants.remove(h); 1038 } 1039 1040 /** 1041 * Re-register network by toggling preferred network type. 1042 * This is a work-around to deregister and register network since there is 1043 * no ril api to set COPS=2 (deregister) only. 1044 * 1045 * @param onComplete is dispatched when this is complete. it will be 1046 * an AsyncResult, and onComplete.obj.exception will be non-null 1047 * on failure. 1048 */ 1049 @UnsupportedAppUsage reRegisterNetwork(Message onComplete)1050 public void reRegisterNetwork(Message onComplete) { 1051 mCi.getPreferredNetworkType( 1052 obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete)); 1053 } 1054 1055 /** 1056 * Turn on or off radio power. 1057 */ setRadioPower(boolean power)1058 public final void setRadioPower(boolean power) { 1059 setRadioPower(power, false, false, false); 1060 } 1061 1062 /** 1063 * Turn on or off radio power with option to specify whether it's for emergency call. 1064 * More details check {@link PhoneInternalInterface#setRadioPower( 1065 * boolean, boolean, boolean, boolean)}. 1066 */ setRadioPower(boolean power, boolean forEmergencyCall, boolean isSelectedPhoneForEmergencyCall, boolean forceApply)1067 public void setRadioPower(boolean power, boolean forEmergencyCall, 1068 boolean isSelectedPhoneForEmergencyCall, boolean forceApply) { 1069 log("setRadioPower forEmergencyCall " + forEmergencyCall + " forceApply " + forceApply); 1070 if (power == mDesiredPowerState && !forceApply) { 1071 log("setRadioPower mDesiredPowerState is already " + power + " Do nothing."); 1072 return; 1073 } 1074 1075 mDesiredPowerState = power; 1076 setPowerStateToDesired(forEmergencyCall, isSelectedPhoneForEmergencyCall, forceApply); 1077 } 1078 1079 /** 1080 * Radio power set from carrier action. if set to false means carrier desire to turn radio off 1081 * and radio wont be re-enabled unless carrier explicitly turn it back on. 1082 * @param enable indicate if radio power is enabled or disabled from carrier action. 1083 */ setRadioPowerFromCarrier(boolean enable)1084 public void setRadioPowerFromCarrier(boolean enable) { 1085 boolean disableByCarrier = !enable; 1086 if (mRadioDisabledByCarrier == disableByCarrier) { 1087 log("setRadioPowerFromCarrier mRadioDisabledByCarrier is already " 1088 + disableByCarrier + " Do nothing."); 1089 return; 1090 } 1091 1092 mRadioDisabledByCarrier = disableByCarrier; 1093 setPowerStateToDesired(); 1094 } 1095 1096 /** 1097 * These two flags manage the behavior of the cell lock -- the 1098 * lock should be held if either flag is true. The intention is 1099 * to allow temporary acquisition of the lock to get a single 1100 * update. Such a lock grab and release can thus be made to not 1101 * interfere with more permanent lock holds -- in other words, the 1102 * lock will only be released if both flags are false, and so 1103 * releases by temporary users will only affect the lock state if 1104 * there is no continuous user. 1105 */ 1106 private boolean mWantContinuousLocationUpdates; 1107 private boolean mWantSingleLocationUpdate; 1108 enableSingleLocationUpdate()1109 public void enableSingleLocationUpdate() { 1110 if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return; 1111 mWantSingleLocationUpdate = true; 1112 mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED)); 1113 } 1114 enableLocationUpdates()1115 public void enableLocationUpdates() { 1116 if (mWantSingleLocationUpdate || mWantContinuousLocationUpdates) return; 1117 mWantContinuousLocationUpdates = true; 1118 mCi.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED)); 1119 } 1120 disableSingleLocationUpdate()1121 protected void disableSingleLocationUpdate() { 1122 mWantSingleLocationUpdate = false; 1123 if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) { 1124 mCi.setLocationUpdates(false, null); 1125 } 1126 } 1127 disableLocationUpdates()1128 public void disableLocationUpdates() { 1129 mWantContinuousLocationUpdates = false; 1130 if (!mWantSingleLocationUpdate && !mWantContinuousLocationUpdates) { 1131 mCi.setLocationUpdates(false, null); 1132 } 1133 } 1134 getLteEarfcn(CellIdentity cellIdentity)1135 private int getLteEarfcn(CellIdentity cellIdentity) { 1136 int lteEarfcn = INVALID_LTE_EARFCN; 1137 if (cellIdentity != null) { 1138 switch (cellIdentity.getType()) { 1139 case CellInfoType.LTE: { 1140 lteEarfcn = ((CellIdentityLte) cellIdentity).getEarfcn(); 1141 break; 1142 } 1143 default: { 1144 break; 1145 } 1146 } 1147 } 1148 1149 return lteEarfcn; 1150 } 1151 1152 @Override handleMessage(Message msg)1153 public void handleMessage(Message msg) { 1154 AsyncResult ar; 1155 int[] ints; 1156 Message message; 1157 1158 if (VDBG) log("received event " + msg.what); 1159 switch (msg.what) { 1160 case EVENT_SET_RADIO_POWER_OFF: 1161 synchronized(this) { 1162 if (mPendingRadioPowerOffAfterDataOff && 1163 (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) { 1164 if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now."); 1165 hangupAndPowerOff(); 1166 mPendingRadioPowerOffAfterDataOffTag += 1; 1167 mPendingRadioPowerOffAfterDataOff = false; 1168 } else { 1169 log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 + 1170 "!= tag=" + mPendingRadioPowerOffAfterDataOffTag); 1171 } 1172 } 1173 break; 1174 1175 case EVENT_ICC_CHANGED: 1176 if (isSimAbsent()) { 1177 if (DBG) log("EVENT_ICC_CHANGED: SIM absent"); 1178 // cancel notifications if SIM is removed/absent 1179 cancelAllNotifications(); 1180 // clear cached values on SIM removal 1181 mMdn = null; 1182 mMin = null; 1183 mIsMinInfoReady = false; 1184 1185 // Remove the EF records that come from UICC. 1186 mCdnr.updateEfFromRuim(null /* ruim */); 1187 mCdnr.updateEfFromUsim(null /* Usim */); 1188 } 1189 onUpdateIccAvailability(); 1190 if (mUiccApplcation == null 1191 || mUiccApplcation.getState() != AppState.APPSTATE_READY) { 1192 mIsSimReady = false; 1193 updateSpnDisplay(); 1194 } 1195 break; 1196 1197 case EVENT_GET_CELL_INFO_LIST: // fallthrough 1198 case EVENT_UNSOL_CELL_INFO_LIST: { 1199 List<CellInfo> cellInfo = null; 1200 Throwable ex = null; 1201 if (msg.obj != null) { 1202 ar = (AsyncResult) msg.obj; 1203 if (ar.exception != null) { 1204 log("EVENT_GET_CELL_INFO_LIST: error ret null, e=" + ar.exception); 1205 ex = ar.exception; 1206 } else if (ar.result == null) { 1207 loge("Invalid CellInfo result"); 1208 } else { 1209 cellInfo = (List<CellInfo>) ar.result; 1210 updateOperatorNameForCellInfo(cellInfo); 1211 mLastCellInfoList = cellInfo; 1212 mPhone.notifyCellInfo(cellInfo); 1213 if (VDBG) { 1214 log("CELL_INFO_LIST: size=" + cellInfo.size() + " list=" + cellInfo); 1215 } 1216 } 1217 } else { 1218 synchronized (mPendingCellInfoRequests) { 1219 // If we receive an empty message, it's probably a timeout; if there is no 1220 // pending request, drop it. 1221 if (!mIsPendingCellInfoRequest) break; 1222 // If there is a request pending, we still need to check whether it's a 1223 // timeout for the current request of whether it's leftover from a 1224 // previous request. 1225 final long curTime = SystemClock.elapsedRealtime(); 1226 if ((curTime - mLastCellInfoReqTime) < CELL_INFO_LIST_QUERY_TIMEOUT) { 1227 break; 1228 } 1229 // We've received a legitimate timeout, so something has gone terribly 1230 // wrong. 1231 loge("Timeout waiting for CellInfo; (everybody panic)!"); 1232 mLastCellInfoList = null; 1233 // Since the timeout is applicable, fall through and update all synchronous 1234 // callers with the failure. 1235 } 1236 } 1237 synchronized (mPendingCellInfoRequests) { 1238 // If we have pending requests, then service them. Note that in case of a 1239 // timeout, we send null responses back to the callers. 1240 if (mIsPendingCellInfoRequest) { 1241 // regardless of timeout or valid response, when something arrives, 1242 mIsPendingCellInfoRequest = false; 1243 for (Message m : mPendingCellInfoRequests) { 1244 AsyncResult.forMessage(m, cellInfo, ex); 1245 m.sendToTarget(); 1246 } 1247 mPendingCellInfoRequests.clear(); 1248 } 1249 } 1250 break; 1251 } 1252 1253 case EVENT_IMS_STATE_CHANGED: // received unsol 1254 mCi.getImsRegistrationState(this.obtainMessage(EVENT_IMS_STATE_DONE)); 1255 break; 1256 1257 case EVENT_IMS_STATE_DONE: 1258 ar = (AsyncResult) msg.obj; 1259 if (ar.exception == null) { 1260 int[] responseArray = (int[])ar.result; 1261 mImsRegistered = (responseArray[0] == 1) ? true : false; 1262 } 1263 break; 1264 1265 case EVENT_RADIO_POWER_OFF_DONE: 1266 if (DBG) log("EVENT_RADIO_POWER_OFF_DONE"); 1267 if (mDeviceShuttingDown && mCi.getRadioState() 1268 != TelephonyManager.RADIO_POWER_UNAVAILABLE) { 1269 // during shutdown the modem may not send radio state changed event 1270 // as a result of radio power request 1271 // Hence, issuing shut down regardless of radio power response 1272 mCi.requestShutdown(null); 1273 } 1274 break; 1275 1276 // GSM 1277 case EVENT_SIM_READY: 1278 // Reset the mPreviousSubId so we treat a SIM power bounce 1279 // as a first boot. See b/19194287 1280 mOnSubscriptionsChangedListener.mPreviousSubId.set( 1281 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1282 mPrevSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1283 mIsSimReady = true; 1284 pollStateInternal(false); 1285 // Signal strength polling stops when radio is off 1286 queueNextSignalStrengthPoll(); 1287 break; 1288 1289 case EVENT_RADIO_STATE_CHANGED: 1290 case EVENT_PHONE_TYPE_SWITCHED: 1291 if(!mPhone.isPhoneTypeGsm() && 1292 mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) { 1293 handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource()); 1294 1295 // Signal strength polling stops when radio is off. 1296 queueNextSignalStrengthPoll(); 1297 } 1298 // This will do nothing in the 'radio not available' case 1299 setPowerStateToDesired(); 1300 // These events are modem triggered, so pollState() needs to be forced 1301 pollStateInternal(true); 1302 break; 1303 1304 case EVENT_NETWORK_STATE_CHANGED: 1305 pollStateInternal(true); 1306 break; 1307 1308 case EVENT_GET_SIGNAL_STRENGTH: 1309 // This callback is called when signal strength is polled 1310 // all by itself 1311 1312 if (!(mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON)) { 1313 // Polling will continue when radio turns back on 1314 return; 1315 } 1316 ar = (AsyncResult) msg.obj; 1317 onSignalStrengthResult(ar); 1318 queueNextSignalStrengthPoll(); 1319 1320 break; 1321 1322 case EVENT_GET_LOC_DONE: 1323 ar = (AsyncResult) msg.obj; 1324 if (ar.exception == null) { 1325 CellIdentity cellIdentity = ((NetworkRegistrationInfo) ar.result) 1326 .getCellIdentity(); 1327 updateOperatorNameForCellIdentity(cellIdentity); 1328 mCellIdentity = cellIdentity; 1329 mPhone.notifyLocationChanged(getCellIdentity()); 1330 } 1331 1332 // Release any temporary cell lock, which could have been 1333 // acquired to allow a single-shot location update. 1334 disableSingleLocationUpdate(); 1335 break; 1336 1337 case EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION: 1338 case EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION: 1339 case EVENT_POLL_STATE_PS_IWLAN_REGISTRATION: 1340 case EVENT_POLL_STATE_OPERATOR: 1341 ar = (AsyncResult) msg.obj; 1342 handlePollStateResult(msg.what, ar); 1343 break; 1344 1345 case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: 1346 if (DBG) log("EVENT_POLL_STATE_NETWORK_SELECTION_MODE"); 1347 ar = (AsyncResult) msg.obj; 1348 if (mPhone.isPhoneTypeGsm()) { 1349 handlePollStateResult(msg.what, ar); 1350 } else { 1351 if (ar.exception == null && ar.result != null) { 1352 ints = (int[])ar.result; 1353 if (ints[0] == 1) { // Manual selection. 1354 mPhone.setNetworkSelectionModeAutomatic(null); 1355 } 1356 } else { 1357 log("Unable to getNetworkSelectionMode"); 1358 } 1359 } 1360 break; 1361 1362 case EVENT_POLL_SIGNAL_STRENGTH: 1363 // Just poll signal strength...not part of pollState() 1364 1365 mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); 1366 break; 1367 1368 case EVENT_NITZ_TIME: 1369 ar = (AsyncResult) msg.obj; 1370 1371 String nitzString = (String)((Object[])ar.result)[0]; 1372 long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue(); 1373 1374 setTimeFromNITZString(nitzString, nitzReceiveTime); 1375 break; 1376 1377 case EVENT_SIGNAL_STRENGTH_UPDATE: 1378 // This is a notification from CommandsInterface.setOnSignalStrengthUpdate 1379 1380 ar = (AsyncResult) msg.obj; 1381 1382 // The radio is telling us about signal strength changes 1383 // we don't have to ask it 1384 mDontPollSignalStrength = true; 1385 1386 onSignalStrengthResult(ar); 1387 break; 1388 1389 case EVENT_SIM_RECORDS_LOADED: 1390 log("EVENT_SIM_RECORDS_LOADED: what=" + msg.what); 1391 updatePhoneObject(); 1392 updateOtaspState(); 1393 if (mPhone.isPhoneTypeGsm()) { 1394 mCdnr.updateEfFromUsim((SIMRecords) mIccRecords); 1395 updateSpnDisplay(); 1396 } 1397 break; 1398 1399 case EVENT_LOCATION_UPDATES_ENABLED: 1400 ar = (AsyncResult) msg.obj; 1401 1402 if (ar.exception == null) { 1403 mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 1404 .requestNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, 1405 obtainMessage(EVENT_GET_LOC_DONE, null)); 1406 } 1407 break; 1408 1409 case EVENT_SET_PREFERRED_NETWORK_TYPE: 1410 ar = (AsyncResult) msg.obj; 1411 // Don't care the result, only use for dereg network (COPS=2) 1412 message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj); 1413 mCi.setPreferredNetworkType(mPreferredNetworkType, message); 1414 break; 1415 1416 case EVENT_RESET_PREFERRED_NETWORK_TYPE: 1417 ar = (AsyncResult) msg.obj; 1418 if (ar.userObj != null) { 1419 AsyncResult.forMessage(((Message) ar.userObj)).exception 1420 = ar.exception; 1421 ((Message) ar.userObj).sendToTarget(); 1422 } 1423 break; 1424 1425 case EVENT_GET_PREFERRED_NETWORK_TYPE: 1426 ar = (AsyncResult) msg.obj; 1427 1428 if (ar.exception == null) { 1429 mPreferredNetworkType = ((int[])ar.result)[0]; 1430 } else { 1431 mPreferredNetworkType = RILConstants.NETWORK_MODE_GLOBAL; 1432 } 1433 1434 message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj); 1435 int toggledNetworkType = RILConstants.NETWORK_MODE_GLOBAL; 1436 1437 mCi.setPreferredNetworkType(toggledNetworkType, message); 1438 break; 1439 1440 case EVENT_CHECK_REPORT_GPRS: 1441 if (mPhone.isPhoneTypeGsm() && mSS != null && 1442 !isGprsConsistent(mSS.getDataRegistrationState(), mSS.getState())) { 1443 1444 // Can't register data service while voice service is ok 1445 // i.e. CREG is ok while CGREG is not 1446 // possible a network or baseband side error 1447 EventLog.writeEvent(EventLogTags.DATA_NETWORK_REGISTRATION_FAIL, 1448 mSS.getOperatorNumeric(), getCidFromCellIdentity(mCellIdentity)); 1449 mReportedGprsNoReg = true; 1450 } 1451 mStartedGprsRegCheck = false; 1452 break; 1453 1454 case EVENT_RESTRICTED_STATE_CHANGED: 1455 if (mPhone.isPhoneTypeGsm()) { 1456 // This is a notification from 1457 // CommandsInterface.setOnRestrictedStateChanged 1458 1459 if (DBG) log("EVENT_RESTRICTED_STATE_CHANGED"); 1460 1461 ar = (AsyncResult) msg.obj; 1462 1463 onRestrictedStateChanged(ar); 1464 } 1465 break; 1466 1467 case EVENT_ALL_DATA_DISCONNECTED: 1468 int dds = SubscriptionManager.getDefaultDataSubscriptionId(); 1469 ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this); 1470 synchronized(this) { 1471 if (mPendingRadioPowerOffAfterDataOff) { 1472 if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now."); 1473 hangupAndPowerOff(); 1474 mPendingRadioPowerOffAfterDataOff = false; 1475 } else { 1476 log("EVENT_ALL_DATA_DISCONNECTED is stale"); 1477 } 1478 } 1479 break; 1480 1481 case EVENT_CHANGE_IMS_STATE: 1482 if (DBG) log("EVENT_CHANGE_IMS_STATE:"); 1483 1484 setPowerStateToDesired(); 1485 break; 1486 1487 case EVENT_IMS_CAPABILITY_CHANGED: 1488 if (DBG) log("EVENT_IMS_CAPABILITY_CHANGED"); 1489 updateSpnDisplay(); 1490 mImsCapabilityChangedRegistrants.notifyRegistrants(); 1491 break; 1492 1493 case EVENT_IMS_SERVICE_STATE_CHANGED: 1494 if (DBG) log("EVENT_IMS_SERVICE_STATE_CHANGED"); 1495 // IMS state will only affect the merged service state if the service state of 1496 // GsmCdma phone is not STATE_IN_SERVICE. 1497 if (mSS.getState() != ServiceState.STATE_IN_SERVICE) { 1498 mPhone.notifyServiceStateChanged(mPhone.getServiceState()); 1499 } 1500 break; 1501 1502 //CDMA 1503 case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED: 1504 handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource()); 1505 break; 1506 1507 case EVENT_RUIM_READY: 1508 if (mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE) { 1509 // Subscription will be read from SIM I/O 1510 if (DBG) log("Receive EVENT_RUIM_READY"); 1511 pollStateInternal(false); 1512 } else { 1513 if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription."); 1514 getSubscriptionInfoAndStartPollingThreads(); 1515 } 1516 1517 // Only support automatic selection mode in CDMA. 1518 mCi.getNetworkSelectionMode(obtainMessage(EVENT_POLL_STATE_NETWORK_SELECTION_MODE)); 1519 1520 break; 1521 1522 case EVENT_NV_READY: 1523 updatePhoneObject(); 1524 1525 // Only support automatic selection mode in CDMA. 1526 mCi.getNetworkSelectionMode(obtainMessage(EVENT_POLL_STATE_NETWORK_SELECTION_MODE)); 1527 1528 // For Non-RUIM phones, the subscription information is stored in 1529 // Non Volatile. Here when Non-Volatile is ready, we can poll the CDMA 1530 // subscription info. 1531 getSubscriptionInfoAndStartPollingThreads(); 1532 break; 1533 1534 case EVENT_POLL_STATE_CDMA_SUBSCRIPTION: // Handle RIL_CDMA_SUBSCRIPTION 1535 if (!mPhone.isPhoneTypeGsm()) { 1536 ar = (AsyncResult) msg.obj; 1537 1538 if (ar.exception == null) { 1539 String cdmaSubscription[] = (String[]) ar.result; 1540 if (cdmaSubscription != null && cdmaSubscription.length >= 5) { 1541 mMdn = cdmaSubscription[0]; 1542 parseSidNid(cdmaSubscription[1], cdmaSubscription[2]); 1543 1544 mMin = cdmaSubscription[3]; 1545 mPrlVersion = cdmaSubscription[4]; 1546 if (DBG) log("GET_CDMA_SUBSCRIPTION: MDN=" + mMdn); 1547 1548 mIsMinInfoReady = true; 1549 1550 updateOtaspState(); 1551 // Notify apps subscription info is ready 1552 notifyCdmaSubscriptionInfoReady(); 1553 1554 if (!mIsSubscriptionFromRuim && mIccRecords != null) { 1555 if (DBG) { 1556 log("GET_CDMA_SUBSCRIPTION set imsi in mIccRecords"); 1557 } 1558 mIccRecords.setImsi(getImsi()); 1559 } else { 1560 if (DBG) { 1561 log("GET_CDMA_SUBSCRIPTION either mIccRecords is null or NV " + 1562 "type device - not setting Imsi in mIccRecords"); 1563 } 1564 } 1565 } else { 1566 if (DBG) { 1567 log("GET_CDMA_SUBSCRIPTION: error parsing cdmaSubscription " + 1568 "params num=" + cdmaSubscription.length); 1569 } 1570 } 1571 } 1572 } 1573 break; 1574 1575 case EVENT_RUIM_RECORDS_LOADED: 1576 if (!mPhone.isPhoneTypeGsm()) { 1577 log("EVENT_RUIM_RECORDS_LOADED: what=" + msg.what); 1578 mCdnr.updateEfFromRuim((RuimRecords) mIccRecords); 1579 updatePhoneObject(); 1580 if (mPhone.isPhoneTypeCdma()) { 1581 updateSpnDisplay(); 1582 } else { 1583 RuimRecords ruim = (RuimRecords) mIccRecords; 1584 if (ruim != null) { 1585 // Do not wait for RUIM to be provisioned before using mdn. Line1Number 1586 // can be queried before that and mdn may still be available. 1587 // Also note that any special casing is not done in getMdnNumber() as it 1588 // may be called on another thread, so simply doing a read operation 1589 // there. 1590 mMdn = ruim.getMdn(); 1591 if (ruim.isProvisioned()) { 1592 mMin = ruim.getMin(); 1593 parseSidNid(ruim.getSid(), ruim.getNid()); 1594 mPrlVersion = ruim.getPrlVersion(); 1595 mIsMinInfoReady = true; 1596 } 1597 updateOtaspState(); 1598 // Notify apps subscription info is ready 1599 notifyCdmaSubscriptionInfoReady(); 1600 } 1601 // SID/NID/PRL is loaded. Poll service state 1602 // again to update to the roaming state with 1603 // the latest variables. 1604 pollStateInternal(false); 1605 } 1606 } 1607 break; 1608 case EVENT_OTA_PROVISION_STATUS_CHANGE: 1609 ar = (AsyncResult)msg.obj; 1610 if (ar.exception == null) { 1611 ints = (int[]) ar.result; 1612 int otaStatus = ints[0]; 1613 if (otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED 1614 || otaStatus == Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED) { 1615 if (DBG) log("EVENT_OTA_PROVISION_STATUS_CHANGE: Complete, Reload MDN"); 1616 mCi.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION)); 1617 } 1618 } 1619 break; 1620 1621 case EVENT_CDMA_PRL_VERSION_CHANGED: 1622 ar = (AsyncResult)msg.obj; 1623 if (ar.exception == null) { 1624 ints = (int[]) ar.result; 1625 mPrlVersion = Integer.toString(ints[0]); 1626 } 1627 break; 1628 1629 case EVENT_RADIO_POWER_FROM_CARRIER: 1630 ar = (AsyncResult) msg.obj; 1631 if (ar.exception == null) { 1632 boolean enable = (boolean) ar.result; 1633 if (DBG) log("EVENT_RADIO_POWER_FROM_CARRIER: " + enable); 1634 setRadioPowerFromCarrier(enable); 1635 } 1636 break; 1637 1638 case EVENT_PHYSICAL_CHANNEL_CONFIG: 1639 ar = (AsyncResult) msg.obj; 1640 if (ar.exception == null) { 1641 List<PhysicalChannelConfig> list = (List<PhysicalChannelConfig>) ar.result; 1642 if (VDBG) { 1643 log("EVENT_PHYSICAL_CHANNEL_CONFIG: size=" + list.size() + " list=" 1644 + list); 1645 } 1646 mPhone.notifyPhysicalChannelConfiguration(list); 1647 mLastPhysicalChannelConfigList = list; 1648 boolean hasChanged = false; 1649 if (updateNrStateFromPhysicalChannelConfigs(list, mSS)) { 1650 mNrStateChangedRegistrants.notifyRegistrants(); 1651 hasChanged = true; 1652 } 1653 if (updateNrFrequencyRangeFromPhysicalChannelConfigs(list, mSS)) { 1654 mNrFrequencyChangedRegistrants.notifyRegistrants(); 1655 hasChanged = true; 1656 } 1657 hasChanged |= RatRatcheter 1658 .updateBandwidths(getBandwidthsFromConfigs(list), mSS); 1659 1660 // Notify NR frequency, NR connection status or bandwidths changed. 1661 if (hasChanged) { 1662 mPhone.notifyServiceStateChanged(mSS); 1663 TelephonyMetrics.getInstance().writeServiceStateChanged( 1664 mPhone.getPhoneId(), mSS); 1665 mPhone.getVoiceCallSessionStats().onServiceStateChanged(mSS); 1666 } 1667 } 1668 break; 1669 1670 case EVENT_CELL_LOCATION_RESPONSE: 1671 ar = (AsyncResult) msg.obj; 1672 if (ar == null) { 1673 loge("Invalid null response to getCellIdentity!"); 1674 break; 1675 } 1676 // This response means that the correct CellInfo is already cached; thus we 1677 // can rely on the last cell info to already contain any cell info that is 1678 // available, which means that we can return the result of the existing 1679 // getCellIdentity() function without any additional processing here. 1680 Message rspRspMsg = (Message) ar.userObj; 1681 AsyncResult.forMessage(rspRspMsg, getCellIdentity(), ar.exception); 1682 rspRspMsg.sendToTarget(); 1683 break; 1684 1685 case EVENT_CARRIER_CONFIG_CHANGED: 1686 onCarrierConfigChanged(); 1687 break; 1688 1689 case EVENT_POLL_STATE_REQUEST: 1690 pollStateInternal(false); 1691 break; 1692 1693 default: 1694 log("Unhandled message with number: " + msg.what); 1695 break; 1696 } 1697 } 1698 isSimAbsent()1699 private boolean isSimAbsent() { 1700 boolean simAbsent; 1701 if (mUiccController == null) { 1702 simAbsent = true; 1703 } else { 1704 UiccCard uiccCard = mUiccController.getUiccCard(mPhone.getPhoneId()); 1705 if (uiccCard == null) { 1706 simAbsent = true; 1707 } else { 1708 simAbsent = (uiccCard.getCardState() == CardState.CARDSTATE_ABSENT); 1709 } 1710 } 1711 return simAbsent; 1712 } 1713 getBandwidthsFromConfigs(List<PhysicalChannelConfig> list)1714 private int[] getBandwidthsFromConfigs(List<PhysicalChannelConfig> list) { 1715 return list.stream() 1716 .map(PhysicalChannelConfig::getCellBandwidthDownlink) 1717 .mapToInt(Integer::intValue) 1718 .toArray(); 1719 } 1720 isSidsAllZeros()1721 protected boolean isSidsAllZeros() { 1722 if (mHomeSystemId != null) { 1723 for (int i=0; i < mHomeSystemId.length; i++) { 1724 if (mHomeSystemId[i] != 0) { 1725 return false; 1726 } 1727 } 1728 } 1729 return true; 1730 } 1731 1732 /** 1733 * @return a copy of the current service state. 1734 */ getServiceState()1735 public ServiceState getServiceState() { 1736 return new ServiceState(mSS); 1737 } 1738 1739 /** 1740 * Check whether a specified system ID that matches one of the home system IDs. 1741 */ isHomeSid(int sid)1742 private boolean isHomeSid(int sid) { 1743 if (mHomeSystemId != null) { 1744 for (int i=0; i < mHomeSystemId.length; i++) { 1745 if (sid == mHomeSystemId[i]) { 1746 return true; 1747 } 1748 } 1749 } 1750 return false; 1751 } 1752 getMdnNumber()1753 public String getMdnNumber() { 1754 return mMdn; 1755 } 1756 getCdmaMin()1757 public String getCdmaMin() { 1758 return mMin; 1759 } 1760 1761 /** Returns null if NV is not yet ready */ getPrlVersion()1762 public String getPrlVersion() { 1763 return mPrlVersion; 1764 } 1765 1766 /** 1767 * Returns IMSI as MCC + MNC + MIN 1768 */ getImsi()1769 public String getImsi() { 1770 // TODO: When RUIM is enabled, IMSI will come from RUIM not build-time props. 1771 String operatorNumeric = ((TelephonyManager) mPhone.getContext() 1772 .getSystemService(Context.TELEPHONY_SERVICE)) 1773 .getSimOperatorNumericForPhone(mPhone.getPhoneId()); 1774 1775 if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) { 1776 return (operatorNumeric + getCdmaMin()); 1777 } else { 1778 return null; 1779 } 1780 } 1781 1782 /** 1783 * Check if subscription data has been assigned to mMin 1784 * 1785 * return true if MIN info is ready; false otherwise. 1786 */ isMinInfoReady()1787 public boolean isMinInfoReady() { 1788 return mIsMinInfoReady; 1789 } 1790 1791 /** 1792 * Returns OTASP_UNKNOWN, OTASP_UNINITIALIZED, OTASP_NEEDED or OTASP_NOT_NEEDED 1793 */ getOtasp()1794 public int getOtasp() { 1795 int provisioningState; 1796 // if sim is not loaded, return otasp uninitialized 1797 if(!mPhone.getIccRecordsLoaded()) { 1798 if(DBG) log("getOtasp: otasp uninitialized due to sim not loaded"); 1799 return TelephonyManager.OTASP_UNINITIALIZED; 1800 } 1801 // if voice tech is Gsm, return otasp not needed 1802 if(mPhone.isPhoneTypeGsm()) { 1803 if(DBG) log("getOtasp: otasp not needed for GSM"); 1804 return TelephonyManager.OTASP_NOT_NEEDED; 1805 } 1806 // for ruim, min is null means require otasp. 1807 if (mIsSubscriptionFromRuim && mMin == null) { 1808 return TelephonyManager.OTASP_NEEDED; 1809 } 1810 if (mMin == null || (mMin.length() < 6)) { 1811 if (DBG) log("getOtasp: bad mMin='" + mMin + "'"); 1812 provisioningState = TelephonyManager.OTASP_UNKNOWN; 1813 } else { 1814 if ((mMin.equals(UNACTIVATED_MIN_VALUE) 1815 || mMin.substring(0,6).equals(UNACTIVATED_MIN2_VALUE)) 1816 || SystemProperties.getBoolean("test_cdma_setup", false)) { 1817 provisioningState = TelephonyManager.OTASP_NEEDED; 1818 } else { 1819 provisioningState = TelephonyManager.OTASP_NOT_NEEDED; 1820 } 1821 } 1822 if (DBG) log("getOtasp: state=" + provisioningState); 1823 return provisioningState; 1824 } 1825 parseSidNid(String sidStr, String nidStr)1826 protected void parseSidNid (String sidStr, String nidStr) { 1827 if (sidStr != null) { 1828 String[] sid = sidStr.split(","); 1829 mHomeSystemId = new int[sid.length]; 1830 for (int i = 0; i < sid.length; i++) { 1831 try { 1832 mHomeSystemId[i] = Integer.parseInt(sid[i]); 1833 } catch (NumberFormatException ex) { 1834 loge("error parsing system id: " + ex); 1835 } 1836 } 1837 } 1838 if (DBG) log("CDMA_SUBSCRIPTION: SID=" + sidStr); 1839 1840 if (nidStr != null) { 1841 String[] nid = nidStr.split(","); 1842 mHomeNetworkId = new int[nid.length]; 1843 for (int i = 0; i < nid.length; i++) { 1844 try { 1845 mHomeNetworkId[i] = Integer.parseInt(nid[i]); 1846 } catch (NumberFormatException ex) { 1847 loge("CDMA_SUBSCRIPTION: error parsing network id: " + ex); 1848 } 1849 } 1850 } 1851 if (DBG) log("CDMA_SUBSCRIPTION: NID=" + nidStr); 1852 } 1853 1854 @UnsupportedAppUsage updateOtaspState()1855 protected void updateOtaspState() { 1856 int otaspMode = getOtasp(); 1857 int oldOtaspMode = mCurrentOtaspMode; 1858 mCurrentOtaspMode = otaspMode; 1859 1860 if (oldOtaspMode != mCurrentOtaspMode) { 1861 if (DBG) { 1862 log("updateOtaspState: call notifyOtaspChanged old otaspMode=" + 1863 oldOtaspMode + " new otaspMode=" + mCurrentOtaspMode); 1864 } 1865 mPhone.notifyOtaspChanged(mCurrentOtaspMode); 1866 } 1867 } 1868 onAirplaneModeChanged(boolean isAirplaneModeOn)1869 public void onAirplaneModeChanged(boolean isAirplaneModeOn) { 1870 mLastNitzData = null; 1871 mNitzState.handleAirplaneModeChanged(isAirplaneModeOn); 1872 } 1873 getPhone()1874 protected Phone getPhone() { 1875 return mPhone; 1876 } 1877 handlePollStateResult(int what, AsyncResult ar)1878 protected void handlePollStateResult(int what, AsyncResult ar) { 1879 // Ignore stale requests from last poll 1880 if (ar.userObj != mPollingContext) return; 1881 1882 if (ar.exception != null) { 1883 CommandException.Error err=null; 1884 1885 if (ar.exception instanceof IllegalStateException) { 1886 log("handlePollStateResult exception " + ar.exception); 1887 } 1888 1889 if (ar.exception instanceof CommandException) { 1890 err = ((CommandException)(ar.exception)).getCommandError(); 1891 } 1892 1893 if (err == CommandException.Error.RADIO_NOT_AVAILABLE) { 1894 // Radio has crashed or turned off 1895 cancelPollState(); 1896 return; 1897 } 1898 1899 if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) { 1900 loge("RIL implementation has returned an error where it must succeed" + 1901 ar.exception); 1902 } 1903 } else try { 1904 handlePollStateResultMessage(what, ar); 1905 } catch (RuntimeException ex) { 1906 loge("Exception while polling service state. Probably malformed RIL response." + ex); 1907 } 1908 1909 mPollingContext[0]--; 1910 1911 if (mPollingContext[0] == 0) { 1912 mNewSS.setEmergencyOnly(mEmergencyOnly); 1913 combinePsRegistrationStates(mNewSS); 1914 updateOperatorNameForServiceState(mNewSS); 1915 if (mPhone.isPhoneTypeGsm()) { 1916 updateRoamingState(); 1917 } else { 1918 boolean namMatch = false; 1919 if (!isSidsAllZeros() && isHomeSid(mNewSS.getCdmaSystemId())) { 1920 namMatch = true; 1921 } 1922 1923 // Setting SS Roaming (general) 1924 if (mIsSubscriptionFromRuim) { 1925 boolean isRoamingBetweenOperators = isRoamingBetweenOperators( 1926 mNewSS.getVoiceRoaming(), mNewSS); 1927 if (isRoamingBetweenOperators != mNewSS.getVoiceRoaming()) { 1928 log("isRoamingBetweenOperators=" + isRoamingBetweenOperators 1929 + ". Override CDMA voice roaming to " + isRoamingBetweenOperators); 1930 mNewSS.setVoiceRoaming(isRoamingBetweenOperators); 1931 } 1932 } 1933 /** 1934 * For CDMA, voice and data should have the same roaming status. 1935 * If voice is not in service, use TSB58 roaming indicator to set 1936 * data roaming status. If TSB58 roaming indicator is not in the 1937 * carrier-specified list of ERIs for home system then set roaming. 1938 */ 1939 final int dataRat = getRilDataRadioTechnologyForWwan(mNewSS); 1940 if (ServiceState.isCdma(dataRat)) { 1941 final boolean isVoiceInService = 1942 (mNewSS.getState() == ServiceState.STATE_IN_SERVICE); 1943 if (isVoiceInService) { 1944 boolean isVoiceRoaming = mNewSS.getVoiceRoaming(); 1945 if (mNewSS.getDataRoaming() != isVoiceRoaming) { 1946 log("Data roaming != Voice roaming. Override data roaming to " 1947 + isVoiceRoaming); 1948 mNewSS.setDataRoaming(isVoiceRoaming); 1949 } 1950 } else { 1951 /** 1952 * As per VoiceRegStateResult from radio types.hal the TSB58 1953 * Roaming Indicator shall be sent if device is registered 1954 * on a CDMA or EVDO system. 1955 */ 1956 boolean isRoamIndForHomeSystem = isRoamIndForHomeSystem(mRoamingIndicator); 1957 if (mNewSS.getDataRoaming() == isRoamIndForHomeSystem) { 1958 log("isRoamIndForHomeSystem=" + isRoamIndForHomeSystem 1959 + ", override data roaming to " + !isRoamIndForHomeSystem); 1960 mNewSS.setDataRoaming(!isRoamIndForHomeSystem); 1961 } 1962 } 1963 } 1964 1965 // Setting SS CdmaRoamingIndicator and CdmaDefaultRoamingIndicator 1966 mNewSS.setCdmaDefaultRoamingIndicator(mDefaultRoamingIndicator); 1967 mNewSS.setCdmaRoamingIndicator(mRoamingIndicator); 1968 boolean isPrlLoaded = true; 1969 if (TextUtils.isEmpty(mPrlVersion)) { 1970 isPrlLoaded = false; 1971 } 1972 if (!isPrlLoaded || (mNewSS.getRilVoiceRadioTechnology() 1973 == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN)) { 1974 log("Turn off roaming indicator if !isPrlLoaded or voice RAT is unknown"); 1975 mNewSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF); 1976 } else if (!isSidsAllZeros()) { 1977 if (!namMatch && !mIsInPrl) { 1978 // Use default 1979 mNewSS.setCdmaRoamingIndicator(mDefaultRoamingIndicator); 1980 } else if (namMatch && !mIsInPrl) { 1981 // TODO: remove when we handle roaming on LTE/NR on CDMA+LTE phones 1982 if (ServiceState.isPsOnlyTech(mNewSS.getRilVoiceRadioTechnology())) { 1983 log("Turn off roaming indicator as voice is LTE or NR"); 1984 mNewSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF); 1985 } else { 1986 mNewSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH); 1987 } 1988 } else if (!namMatch && mIsInPrl) { 1989 // Use the one from PRL/ERI 1990 mNewSS.setCdmaRoamingIndicator(mRoamingIndicator); 1991 } else { 1992 // It means namMatch && mIsInPrl 1993 if ((mRoamingIndicator <= 2)) { 1994 mNewSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF); 1995 } else { 1996 // Use the one from PRL/ERI 1997 mNewSS.setCdmaRoamingIndicator(mRoamingIndicator); 1998 } 1999 } 2000 } 2001 2002 int roamingIndicator = mNewSS.getCdmaRoamingIndicator(); 2003 mNewSS.setCdmaEriIconIndex(mEriManager.getCdmaEriIconIndex(roamingIndicator, 2004 mDefaultRoamingIndicator)); 2005 mNewSS.setCdmaEriIconMode(mEriManager.getCdmaEriIconMode(roamingIndicator, 2006 mDefaultRoamingIndicator)); 2007 2008 // NOTE: Some operator may require overriding mCdmaRoaming 2009 // (set by the modem), depending on the mRoamingIndicator. 2010 2011 if (DBG) { 2012 log("Set CDMA Roaming Indicator to: " + mNewSS.getCdmaRoamingIndicator() 2013 + ". voiceRoaming = " + mNewSS.getVoiceRoaming() 2014 + ". dataRoaming = " + mNewSS.getDataRoaming() 2015 + ", isPrlLoaded = " + isPrlLoaded 2016 + ". namMatch = " + namMatch + " , mIsInPrl = " + mIsInPrl 2017 + ", mRoamingIndicator = " + mRoamingIndicator 2018 + ", mDefaultRoamingIndicator= " + mDefaultRoamingIndicator); 2019 } 2020 } 2021 pollStateDone(); 2022 } 2023 2024 } 2025 2026 /** 2027 * Set roaming state when cdmaRoaming is true and ons is different from spn 2028 * @param cdmaRoaming TS 27.007 7.2 CREG registered roaming 2029 * @param s ServiceState hold current ons 2030 * @return true for roaming state set 2031 */ isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s)2032 private boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) { 2033 return cdmaRoaming && !isSameOperatorNameFromSimAndSS(s); 2034 } 2035 updateNrFrequencyRangeFromPhysicalChannelConfigs( List<PhysicalChannelConfig> physicalChannelConfigs, ServiceState ss)2036 private boolean updateNrFrequencyRangeFromPhysicalChannelConfigs( 2037 List<PhysicalChannelConfig> physicalChannelConfigs, ServiceState ss) { 2038 int newFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 2039 2040 if (physicalChannelConfigs != null) { 2041 DcTracker dcTracker = mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 2042 for (PhysicalChannelConfig config : physicalChannelConfigs) { 2043 if (isNrPhysicalChannelConfig(config)) { 2044 // Update the frequency range of the NR parameters if there is an internet data 2045 // connection associate to this NR physical channel channel config. 2046 int[] contextIds = config.getContextIds(); 2047 for (int cid : contextIds) { 2048 DataConnection dc = dcTracker.getDataConnectionByContextId(cid); 2049 if (dc != null && dc.getNetworkCapabilities().hasCapability( 2050 NetworkCapabilities.NET_CAPABILITY_INTERNET)) { 2051 newFrequencyRange = ServiceState.getBetterNRFrequencyRange( 2052 newFrequencyRange, config.getFrequencyRange()); 2053 break; 2054 } 2055 } 2056 } 2057 } 2058 } 2059 2060 boolean hasChanged = newFrequencyRange != ss.getNrFrequencyRange(); 2061 ss.setNrFrequencyRange(newFrequencyRange); 2062 return hasChanged; 2063 } 2064 updateNrStateFromPhysicalChannelConfigs( List<PhysicalChannelConfig> configs, ServiceState ss)2065 private boolean updateNrStateFromPhysicalChannelConfigs( 2066 List<PhysicalChannelConfig> configs, ServiceState ss) { 2067 NetworkRegistrationInfo regInfo = ss.getNetworkRegistrationInfo( 2068 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 2069 if (regInfo == null || configs == null) return false; 2070 2071 boolean hasNrSecondaryServingCell = false; 2072 for (PhysicalChannelConfig config : configs) { 2073 if (isNrPhysicalChannelConfig(config) && config.getConnectionStatus() 2074 == PhysicalChannelConfig.CONNECTION_SECONDARY_SERVING) { 2075 hasNrSecondaryServingCell = true; 2076 break; 2077 } 2078 } 2079 2080 int oldNrState = regInfo.getNrState(); 2081 int newNrState = oldNrState; 2082 if (hasNrSecondaryServingCell) { 2083 newNrState = NetworkRegistrationInfo.NR_STATE_CONNECTED; 2084 } else { 2085 regInfo.updateNrState(); 2086 newNrState = regInfo.getNrState(); 2087 } 2088 2089 boolean hasChanged = newNrState != oldNrState; 2090 regInfo.setNrState(newNrState); 2091 ss.addNetworkRegistrationInfo(regInfo); 2092 return hasChanged; 2093 } 2094 isNrPhysicalChannelConfig(PhysicalChannelConfig config)2095 private boolean isNrPhysicalChannelConfig(PhysicalChannelConfig config) { 2096 return config.getRat() == TelephonyManager.NETWORK_TYPE_NR; 2097 } 2098 2099 /** 2100 * This combine PS registration states from cellular and IWLAN and generates the final data 2101 * reg state and rat for backward compatibility purpose. In reality there should be two separate 2102 * registration states for cellular and IWLAN, but in legacy mode, if the device camps on IWLAN, 2103 * the IWLAN registration states overwrites the service states. This method is to simulate that 2104 * behavior. 2105 * 2106 * @param serviceState The service state having combined registration states. 2107 */ combinePsRegistrationStates(ServiceState serviceState)2108 private void combinePsRegistrationStates(ServiceState serviceState) { 2109 NetworkRegistrationInfo wlanPsRegState = serviceState.getNetworkRegistrationInfo( 2110 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WLAN); 2111 NetworkRegistrationInfo wwanPsRegState = serviceState.getNetworkRegistrationInfo( 2112 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 2113 2114 // Check if any APN is preferred on IWLAN. 2115 boolean isIwlanPreferred = mTransportManager.isAnyApnPreferredOnIwlan(); 2116 serviceState.setIwlanPreferred(isIwlanPreferred); 2117 if (wlanPsRegState != null 2118 && wlanPsRegState.getAccessNetworkTechnology() 2119 == TelephonyManager.NETWORK_TYPE_IWLAN 2120 && wlanPsRegState.getRegistrationState() 2121 == NetworkRegistrationInfo.REGISTRATION_STATE_HOME 2122 && isIwlanPreferred) { 2123 serviceState.setDataRegState(ServiceState.STATE_IN_SERVICE); 2124 } else if (wwanPsRegState != null) { 2125 // If the device is not camped on IWLAN, then we use cellular PS registration state 2126 // to compute reg state and rat. 2127 int regState = wwanPsRegState.getRegistrationState(); 2128 serviceState.setDataRegState(regCodeToServiceState(regState)); 2129 } 2130 if (DBG) { 2131 log("combinePsRegistrationStates: " + serviceState); 2132 } 2133 } 2134 handlePollStateResultMessage(int what, AsyncResult ar)2135 protected void handlePollStateResultMessage(int what, AsyncResult ar) { 2136 int ints[]; 2137 switch (what) { 2138 case EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION: { 2139 NetworkRegistrationInfo networkRegState = (NetworkRegistrationInfo) ar.result; 2140 VoiceSpecificRegistrationInfo voiceSpecificStates = 2141 networkRegState.getVoiceSpecificInfo(); 2142 2143 int registrationState = networkRegState.getRegistrationState(); 2144 int cssIndicator = voiceSpecificStates.cssSupported ? 1 : 0; 2145 int newVoiceRat = ServiceState.networkTypeToRilRadioTechnology( 2146 networkRegState.getAccessNetworkTechnology()); 2147 2148 mNewSS.setVoiceRegState(regCodeToServiceState(registrationState)); 2149 mNewSS.setCssIndicator(cssIndicator); 2150 mNewSS.addNetworkRegistrationInfo(networkRegState); 2151 setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity()); 2152 2153 //Denial reason if registrationState = 3 2154 int reasonForDenial = networkRegState.getRejectCause(); 2155 mEmergencyOnly = networkRegState.isEmergencyEnabled(); 2156 if (mPhone.isPhoneTypeGsm()) { 2157 2158 mGsmVoiceRoaming = regCodeIsRoaming(registrationState); 2159 mNewRejectCode = reasonForDenial; 2160 } else { 2161 int roamingIndicator = voiceSpecificStates.roamingIndicator; 2162 2163 //Indicates if current system is in PR 2164 int systemIsInPrl = voiceSpecificStates.systemIsInPrl; 2165 2166 //Is default roaming indicator from PRL 2167 int defaultRoamingIndicator = voiceSpecificStates.defaultRoamingIndicator; 2168 2169 mRegistrationState = registrationState; 2170 // When registration state is roaming and TSB58 2171 // roaming indicator is not in the carrier-specified 2172 // list of ERIs for home system, mCdmaRoaming is true. 2173 boolean cdmaRoaming = 2174 regCodeIsRoaming(registrationState) 2175 && !isRoamIndForHomeSystem(roamingIndicator); 2176 mNewSS.setVoiceRoaming(cdmaRoaming); 2177 mRoamingIndicator = roamingIndicator; 2178 mIsInPrl = (systemIsInPrl == 0) ? false : true; 2179 mDefaultRoamingIndicator = defaultRoamingIndicator; 2180 2181 int systemId = 0; 2182 int networkId = 0; 2183 CellIdentity cellIdentity = networkRegState.getCellIdentity(); 2184 if (cellIdentity != null && cellIdentity.getType() == CellInfoType.CDMA) { 2185 systemId = ((CellIdentityCdma) cellIdentity).getSystemId(); 2186 networkId = ((CellIdentityCdma) cellIdentity).getNetworkId(); 2187 } 2188 mNewSS.setCdmaSystemAndNetworkId(systemId, networkId); 2189 2190 if (reasonForDenial == 0) { 2191 mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_GEN; 2192 } else if (reasonForDenial == 1) { 2193 mRegistrationDeniedReason = ServiceStateTracker.REGISTRATION_DENIED_AUTH; 2194 } else { 2195 mRegistrationDeniedReason = ""; 2196 } 2197 2198 if (mRegistrationState == 3) { 2199 if (DBG) log("Registration denied, " + mRegistrationDeniedReason); 2200 } 2201 } 2202 2203 if (DBG) { 2204 log("handlePollStateResultMessage: CS cellular. " + networkRegState); 2205 } 2206 break; 2207 } 2208 2209 case EVENT_POLL_STATE_PS_IWLAN_REGISTRATION: { 2210 NetworkRegistrationInfo networkRegState = (NetworkRegistrationInfo) ar.result; 2211 mNewSS.addNetworkRegistrationInfo(networkRegState); 2212 2213 if (DBG) { 2214 log("handlePollStateResultMessage: PS IWLAN. " + networkRegState); 2215 } 2216 break; 2217 } 2218 2219 case EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION: { 2220 NetworkRegistrationInfo networkRegState = (NetworkRegistrationInfo) ar.result; 2221 mNewSS.addNetworkRegistrationInfo(networkRegState); 2222 DataSpecificRegistrationInfo dataSpecificStates = 2223 networkRegState.getDataSpecificInfo(); 2224 int registrationState = networkRegState.getRegistrationState(); 2225 int serviceState = regCodeToServiceState(registrationState); 2226 int newDataRat = ServiceState.networkTypeToRilRadioTechnology( 2227 networkRegState.getAccessNetworkTechnology()); 2228 boolean nrHasChanged = false; 2229 2230 if (DBG) { 2231 log("handlePollStateResultMessage: PS cellular. " + networkRegState); 2232 } 2233 2234 // When we receive OOS reset the PhyChanConfig list so that non-return-to-idle 2235 // implementers of PhyChanConfig unsol will not carry forward a CA report 2236 // (2 or more cells) to a new cell if they camp for emergency service only. 2237 if (serviceState == ServiceState.STATE_OUT_OF_SERVICE) { 2238 mLastPhysicalChannelConfigList = null; 2239 } 2240 nrHasChanged |= updateNrFrequencyRangeFromPhysicalChannelConfigs( 2241 mLastPhysicalChannelConfigList, mNewSS); 2242 nrHasChanged |= updateNrStateFromPhysicalChannelConfigs( 2243 mLastPhysicalChannelConfigList, mNewSS); 2244 setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity()); 2245 2246 if (nrHasChanged) { 2247 TelephonyMetrics.getInstance().writeServiceStateChanged( 2248 mPhone.getPhoneId(), mSS); 2249 mPhone.getVoiceCallSessionStats().onServiceStateChanged(mSS); 2250 } 2251 2252 if (mPhone.isPhoneTypeGsm()) { 2253 2254 mNewReasonDataDenied = networkRegState.getRejectCause(); 2255 mNewMaxDataCalls = dataSpecificStates.maxDataCalls; 2256 mGsmDataRoaming = regCodeIsRoaming(registrationState); 2257 // Save the data roaming state reported by modem registration before resource 2258 // overlay or carrier config possibly overrides it. 2259 mNewSS.setDataRoamingFromRegistration(mGsmDataRoaming); 2260 } else if (mPhone.isPhoneTypeCdma()) { 2261 boolean isDataRoaming = regCodeIsRoaming(registrationState); 2262 mNewSS.setDataRoaming(isDataRoaming); 2263 // Save the data roaming state reported by modem registration before resource 2264 // overlay or carrier config possibly overrides it. 2265 mNewSS.setDataRoamingFromRegistration(isDataRoaming); 2266 } else { 2267 2268 // If the unsolicited signal strength comes just before data RAT family changes 2269 // (i.e. from UNKNOWN to LTE/NR, CDMA to LTE/NR, LTE/NR to CDMA), the signal bar 2270 // might display the wrong information until the next unsolicited signal 2271 // strength information coming from the modem, which might take a long time to 2272 // come or even not come at all. In order to provide the best user experience, 2273 // we query the latest signal information so it will show up on the UI on time. 2274 int oldDataRAT = getRilDataRadioTechnologyForWwan(mSS); 2275 if (((oldDataRAT == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) 2276 && (newDataRat != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN)) 2277 || (ServiceState.isCdma(oldDataRAT) 2278 && ServiceState.isPsOnlyTech(newDataRat)) 2279 || (ServiceState.isPsOnlyTech(oldDataRAT) 2280 && ServiceState.isCdma(newDataRat))) { 2281 mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); 2282 } 2283 2284 // voice roaming state in done while handling EVENT_POLL_STATE_REGISTRATION_CDMA 2285 boolean isDataRoaming = regCodeIsRoaming(registrationState); 2286 mNewSS.setDataRoaming(isDataRoaming); 2287 // Save the data roaming state reported by modem registration before resource 2288 // overlay or carrier config possibly overrides it. 2289 mNewSS.setDataRoamingFromRegistration(isDataRoaming); 2290 } 2291 2292 updateServiceStateLteEarfcnBoost(mNewSS, 2293 getLteEarfcn(networkRegState.getCellIdentity())); 2294 break; 2295 } 2296 2297 case EVENT_POLL_STATE_OPERATOR: { 2298 if (mPhone.isPhoneTypeGsm()) { 2299 String opNames[] = (String[]) ar.result; 2300 2301 if (opNames != null && opNames.length >= 3) { 2302 mNewSS.setOperatorAlphaLongRaw(opNames[0]); 2303 mNewSS.setOperatorAlphaShortRaw(opNames[1]); 2304 // FIXME: Giving brandOverride higher precedence, is this desired? 2305 String brandOverride = getOperatorBrandOverride(); 2306 mCdnr.updateEfForBrandOverride(brandOverride); 2307 if (brandOverride != null) { 2308 log("EVENT_POLL_STATE_OPERATOR: use brandOverride=" + brandOverride); 2309 mNewSS.setOperatorName(brandOverride, brandOverride, opNames[2]); 2310 } else { 2311 mNewSS.setOperatorName(opNames[0], opNames[1], opNames[2]); 2312 } 2313 } 2314 } else { 2315 String opNames[] = (String[])ar.result; 2316 2317 if (opNames != null && opNames.length >= 3) { 2318 // TODO: Do we care about overriding in this case. 2319 // If the NUMERIC field isn't valid use PROPERTY_CDMA_HOME_OPERATOR_NUMERIC 2320 if ((opNames[2] == null) || (opNames[2].length() < 5) 2321 || ("00000".equals(opNames[2]))) { 2322 opNames[2] = SystemProperties.get( 2323 GsmCdmaPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, "00000"); 2324 if (DBG) { 2325 log("RIL_REQUEST_OPERATOR.response[2], the numeric, " + 2326 " is bad. Using SystemProperties '" + 2327 GsmCdmaPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC + 2328 "'= " + opNames[2]); 2329 } 2330 } 2331 2332 if (!mIsSubscriptionFromRuim) { 2333 // NV device (as opposed to CSIM) 2334 mNewSS.setOperatorName(opNames[0], opNames[1], opNames[2]); 2335 } else { 2336 String brandOverride = getOperatorBrandOverride(); 2337 mCdnr.updateEfForBrandOverride(brandOverride); 2338 if (brandOverride != null) { 2339 mNewSS.setOperatorName(brandOverride, brandOverride, opNames[2]); 2340 } else { 2341 mNewSS.setOperatorName(opNames[0], opNames[1], opNames[2]); 2342 } 2343 } 2344 } else { 2345 if (DBG) log("EVENT_POLL_STATE_OPERATOR_CDMA: error parsing opNames"); 2346 } 2347 } 2348 break; 2349 } 2350 2351 case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: { 2352 ints = (int[])ar.result; 2353 mNewSS.setIsManualSelection(ints[0] == 1); 2354 if ((ints[0] == 1) && (mPhone.shouldForceAutoNetworkSelect())) { 2355 /* 2356 * modem is currently in manual selection but manual 2357 * selection is not allowed in the current mode so 2358 * switch to automatic registration 2359 */ 2360 mPhone.setNetworkSelectionModeAutomatic (null); 2361 log(" Forcing Automatic Network Selection, " + 2362 "manual selection is not allowed"); 2363 } 2364 break; 2365 } 2366 2367 default: 2368 loge("handlePollStateResultMessage: Unexpected RIL response received: " + what); 2369 } 2370 } 2371 isValidLteBandwidthKhz(int bandwidth)2372 private static boolean isValidLteBandwidthKhz(int bandwidth) { 2373 // Valid bandwidths, see 3gpp 36.101 sec. 5.6 2374 switch (bandwidth) { 2375 case 1400: 2376 case 3000: 2377 case 5000: 2378 case 10000: 2379 case 15000: 2380 case 20000: 2381 return true; 2382 default: 2383 return false; 2384 } 2385 } 2386 2387 /** 2388 * Extract the CID/CI for GSM/UTRA/EUTRA 2389 * 2390 * @returns the cell ID (unique within a PLMN for a given tech) or -1 if invalid 2391 */ getCidFromCellIdentity(CellIdentity id)2392 private static long getCidFromCellIdentity(CellIdentity id) { 2393 if (id == null) return -1; 2394 long cid = -1; 2395 switch(id.getType()) { 2396 case CellInfo.TYPE_GSM: cid = ((CellIdentityGsm) id).getCid(); break; 2397 case CellInfo.TYPE_WCDMA: cid = ((CellIdentityWcdma) id).getCid(); break; 2398 case CellInfo.TYPE_TDSCDMA: cid = ((CellIdentityTdscdma) id).getCid(); break; 2399 case CellInfo.TYPE_LTE: cid = ((CellIdentityLte) id).getCi(); break; 2400 case CellInfo.TYPE_NR: cid = ((CellIdentityNr) id).getNci(); break; 2401 default: break; 2402 } 2403 // If the CID is unreported 2404 if (cid == (id.getType() == CellInfo.TYPE_NR 2405 ? CellInfo.UNAVAILABLE_LONG : CellInfo.UNAVAILABLE)) { 2406 cid = -1; 2407 } 2408 2409 return cid; 2410 } 2411 setPhyCellInfoFromCellIdentity(ServiceState ss, CellIdentity cellIdentity)2412 private void setPhyCellInfoFromCellIdentity(ServiceState ss, CellIdentity cellIdentity) { 2413 if (cellIdentity == null) { 2414 if (DBG) { 2415 log("Could not set ServiceState channel number. CellIdentity null"); 2416 } 2417 return; 2418 } 2419 2420 ss.setChannelNumber(cellIdentity.getChannelNumber()); 2421 if (VDBG) { 2422 log("Setting channel number: " + cellIdentity.getChannelNumber()); 2423 } 2424 2425 if (cellIdentity instanceof CellIdentityLte) { 2426 CellIdentityLte cl = (CellIdentityLte) cellIdentity; 2427 int[] bandwidths = null; 2428 // Prioritize the PhysicalChannelConfig list because we might already be in carrier 2429 // aggregation by the time poll state is performed. 2430 if (!ArrayUtils.isEmpty(mLastPhysicalChannelConfigList)) { 2431 bandwidths = getBandwidthsFromConfigs(mLastPhysicalChannelConfigList); 2432 for (int bw : bandwidths) { 2433 if (!isValidLteBandwidthKhz(bw)) { 2434 loge("Invalid LTE Bandwidth in RegistrationState, " + bw); 2435 bandwidths = null; 2436 break; 2437 } 2438 } 2439 } 2440 // If we don't have a PhysicalChannelConfig[] list, then pull from CellIdentityLte. 2441 // This is normal if we're in idle mode and the PhysicalChannelConfig[] has already 2442 // been updated. This is also a fallback in case the PhysicalChannelConfig info 2443 // is invalid (ie, broken). 2444 // Also, for vendor implementations that do not report return-to-idle, we should 2445 // prioritize the bandwidth report in the CellIdentity, because the physical channel 2446 // config report may be stale in the case where a single carrier was used previously 2447 // and we transition to camped-for-emergency (since we never have a physical 2448 // channel active). In the normal case of single-carrier non-return-to-idle, the 2449 // values *must* be the same, so it doesn't matter which is chosen. 2450 if (bandwidths == null || bandwidths.length == 1) { 2451 final int cbw = cl.getBandwidth(); 2452 if (isValidLteBandwidthKhz(cbw)) { 2453 bandwidths = new int[] {cbw}; 2454 } else if (cbw == Integer.MAX_VALUE) { 2455 // Bandwidth is unreported; c'est la vie. This is not an error because 2456 // pre-1.2 HAL implementations do not support bandwidth reporting. 2457 } else { 2458 loge("Invalid LTE Bandwidth in RegistrationState, " + cbw); 2459 } 2460 } 2461 if (bandwidths != null) { 2462 ss.setCellBandwidths(bandwidths); 2463 } 2464 } else { 2465 if (VDBG) log("Skipping bandwidth update for Non-LTE cell."); 2466 } 2467 } 2468 2469 /** 2470 * Determine whether a roaming indicator is in the carrier-specified list of ERIs for 2471 * home system 2472 * 2473 * @param roamInd roaming indicator 2474 * @return true if the roamInd is in the carrier-specified list of ERIs for home network 2475 */ isRoamIndForHomeSystem(int roamInd)2476 private boolean isRoamIndForHomeSystem(int roamInd) { 2477 // retrieve the carrier-specified list of ERIs for home system 2478 final PersistableBundle config = getCarrierConfig(); 2479 int[] homeRoamIndicators = config.getIntArray(CarrierConfigManager 2480 .KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY); 2481 2482 log("isRoamIndForHomeSystem: homeRoamIndicators=" + Arrays.toString(homeRoamIndicators)); 2483 2484 if (homeRoamIndicators != null) { 2485 // searches through the comma-separated list for a match, 2486 // return true if one is found. 2487 for (int homeRoamInd : homeRoamIndicators) { 2488 if (homeRoamInd == roamInd) { 2489 return true; 2490 } 2491 } 2492 // no matches found against the list! 2493 log("isRoamIndForHomeSystem: No match found against list for roamInd=" + roamInd); 2494 return false; 2495 } 2496 2497 // no system property found for the roaming indicators for home system 2498 log("isRoamIndForHomeSystem: No list found"); 2499 return false; 2500 } 2501 2502 /** 2503 * Query the carrier configuration to determine if there any network overrides 2504 * for roaming or not roaming for the current service state. 2505 */ 2506 @UnsupportedAppUsage updateRoamingState()2507 protected void updateRoamingState() { 2508 PersistableBundle bundle = getCarrierConfig(); 2509 2510 if (mPhone.isPhoneTypeGsm()) { 2511 /** 2512 * Since the roaming state of gsm service (from +CREG) and 2513 * data service (from +CGREG) could be different, the new SS 2514 * is set to roaming when either is true. 2515 * 2516 * There are exceptions for the above rule. 2517 * The new SS is not set as roaming while gsm service or 2518 * data service reports roaming but indeed it is same 2519 * operator. And the operator is considered non roaming. 2520 * 2521 * The test for the operators is to handle special roaming 2522 * agreements and MVNO's. 2523 */ 2524 boolean roaming = (mGsmVoiceRoaming || mGsmDataRoaming); 2525 2526 if (roaming && !isOperatorConsideredRoaming(mNewSS) 2527 && (isSameNamedOperators(mNewSS) || isOperatorConsideredNonRoaming(mNewSS))) { 2528 log("updateRoamingState: resource override set non roaming.isSameNamedOperators=" 2529 + isSameNamedOperators(mNewSS) + ",isOperatorConsideredNonRoaming=" 2530 + isOperatorConsideredNonRoaming(mNewSS)); 2531 roaming = false; 2532 } 2533 2534 if (alwaysOnHomeNetwork(bundle)) { 2535 log("updateRoamingState: carrier config override always on home network"); 2536 roaming = false; 2537 } else if (isNonRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric())) { 2538 log("updateRoamingState: carrier config override set non roaming:" 2539 + mNewSS.getOperatorNumeric()); 2540 roaming = false; 2541 } else if (isRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric())) { 2542 log("updateRoamingState: carrier config override set roaming:" 2543 + mNewSS.getOperatorNumeric()); 2544 roaming = true; 2545 } 2546 2547 mNewSS.setRoaming(roaming); 2548 } else { 2549 String systemId = Integer.toString(mNewSS.getCdmaSystemId()); 2550 2551 if (alwaysOnHomeNetwork(bundle)) { 2552 log("updateRoamingState: carrier config override always on home network"); 2553 setRoamingOff(); 2554 } else if (isNonRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric()) 2555 || isNonRoamingInCdmaNetwork(bundle, systemId)) { 2556 log("updateRoamingState: carrier config override set non-roaming:" 2557 + mNewSS.getOperatorNumeric() + ", " + systemId); 2558 setRoamingOff(); 2559 } else if (isRoamingInGsmNetwork(bundle, mNewSS.getOperatorNumeric()) 2560 || isRoamingInCdmaNetwork(bundle, systemId)) { 2561 log("updateRoamingState: carrier config override set roaming:" 2562 + mNewSS.getOperatorNumeric() + ", " + systemId); 2563 setRoamingOn(); 2564 } 2565 2566 if (TelephonyUtils.IS_DEBUGGABLE 2567 && SystemProperties.getBoolean(PROP_FORCE_ROAMING, false)) { 2568 mNewSS.setRoaming(true); 2569 } 2570 } 2571 } 2572 setRoamingOn()2573 private void setRoamingOn() { 2574 mNewSS.setRoaming(true); 2575 mNewSS.setCdmaEriIconIndex(EriInfo.ROAMING_INDICATOR_ON); 2576 mNewSS.setCdmaEriIconMode(EriInfo.ROAMING_ICON_MODE_NORMAL); 2577 } 2578 setRoamingOff()2579 private void setRoamingOff() { 2580 mNewSS.setRoaming(false); 2581 mNewSS.setCdmaEriIconIndex(EriInfo.ROAMING_INDICATOR_OFF); 2582 } 2583 updateOperatorNameFromCarrierConfig()2584 private void updateOperatorNameFromCarrierConfig() { 2585 // Brand override gets a priority over carrier config. If brand override is not available, 2586 // override the operator name in home network. Also do this only for CDMA. This is temporary 2587 // and should be fixed in a proper way in a later release. 2588 if (!mPhone.isPhoneTypeGsm() && !mSS.getRoaming()) { 2589 boolean hasBrandOverride = mUiccController.getUiccCard(getPhoneId()) != null 2590 && mUiccController.getUiccCard(getPhoneId()).getOperatorBrandOverride() != null; 2591 if (!hasBrandOverride) { 2592 PersistableBundle config = getCarrierConfig(); 2593 if (config.getBoolean( 2594 CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL)) { 2595 String operator = config.getString( 2596 CarrierConfigManager.KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING); 2597 log("updateOperatorNameFromCarrierConfig: changing from " 2598 + mSS.getOperatorAlpha() + " to " + operator); 2599 // override long and short operator name, keeping numeric the same 2600 mSS.setOperatorName(operator, operator, mSS.getOperatorNumeric()); 2601 } 2602 } 2603 } 2604 } 2605 notifySpnDisplayUpdate(CarrierDisplayNameData data)2606 private void notifySpnDisplayUpdate(CarrierDisplayNameData data) { 2607 int subId = mPhone.getSubId(); 2608 // Update ACTION_SERVICE_PROVIDERS_UPDATED IFF any value changes 2609 if (mSubId != subId 2610 || data.shouldShowPlmn() != mCurShowPlmn 2611 || data.shouldShowSpn() != mCurShowSpn 2612 || !TextUtils.equals(data.getSpn(), mCurSpn) 2613 || !TextUtils.equals(data.getDataSpn(), mCurDataSpn) 2614 || !TextUtils.equals(data.getPlmn(), mCurPlmn)) { 2615 2616 final String log = String.format("updateSpnDisplay: changed sending intent, " 2617 + "rule=%d, showPlmn='%b', plmn='%s', showSpn='%b', spn='%s', " 2618 + "dataSpn='%s', subId='%d'", 2619 getCarrierNameDisplayBitmask(mSS), 2620 data.shouldShowPlmn(), 2621 data.getPlmn(), 2622 data.shouldShowSpn(), 2623 data.getSpn(), 2624 data.getDataSpn(), 2625 subId); 2626 mCdnrLogs.log(log); 2627 if (DBG) log("updateSpnDisplay: " + log); 2628 2629 Intent intent = new Intent(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED); 2630 intent.putExtra(TelephonyManager.EXTRA_SHOW_SPN, data.shouldShowSpn()); 2631 intent.putExtra(TelephonyManager.EXTRA_SPN, data.getSpn()); 2632 intent.putExtra(TelephonyManager.EXTRA_DATA_SPN, data.getDataSpn()); 2633 intent.putExtra(TelephonyManager.EXTRA_SHOW_PLMN, data.shouldShowPlmn()); 2634 intent.putExtra(TelephonyManager.EXTRA_PLMN, data.getPlmn()); 2635 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId()); 2636 mPhone.getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL); 2637 2638 if (!mSubscriptionController.setPlmnSpn(mPhone.getPhoneId(), 2639 data.shouldShowPlmn(), data.getPlmn(), data.shouldShowSpn(), data.getSpn())) { 2640 mSpnUpdatePending = true; 2641 } 2642 } 2643 2644 mSubId = subId; 2645 mCurShowSpn = data.shouldShowSpn(); 2646 mCurShowPlmn = data.shouldShowPlmn(); 2647 mCurSpn = data.getSpn(); 2648 mCurDataSpn = data.getDataSpn(); 2649 mCurPlmn = data.getPlmn(); 2650 } 2651 updateSpnDisplayCdnr()2652 private void updateSpnDisplayCdnr() { 2653 log("updateSpnDisplayCdnr+"); 2654 CarrierDisplayNameData data = mCdnr.getCarrierDisplayNameData(); 2655 notifySpnDisplayUpdate(data); 2656 log("updateSpnDisplayCdnr-"); 2657 } 2658 2659 @UnsupportedAppUsage 2660 @VisibleForTesting updateSpnDisplay()2661 public void updateSpnDisplay() { 2662 PersistableBundle config = getCarrierConfig(); 2663 if (config.getBoolean(CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL)) { 2664 updateSpnDisplayCdnr(); 2665 } else { 2666 updateSpnDisplayLegacy(); 2667 } 2668 } 2669 updateSpnDisplayLegacy()2670 private void updateSpnDisplayLegacy() { 2671 log("updateSpnDisplayLegacy+"); 2672 2673 String spn = null; 2674 String dataSpn = null; 2675 boolean showSpn = false; 2676 String plmn = null; 2677 boolean showPlmn = false; 2678 2679 String wfcVoiceSpnFormat = null; 2680 String wfcDataSpnFormat = null; 2681 String wfcFlightSpnFormat = null; 2682 int combinedRegState = getCombinedRegState(mSS); 2683 if (mPhone.getImsPhone() != null && mPhone.getImsPhone().isWifiCallingEnabled() 2684 && (combinedRegState == ServiceState.STATE_IN_SERVICE)) { 2685 // In Wi-Fi Calling mode show SPN or PLMN + WiFi Calling 2686 // 2687 // 1) Show SPN + Wi-Fi Calling If SIM has SPN and SPN display condition 2688 // is satisfied or SPN override is enabled for this carrier 2689 // 2690 // 2) Show PLMN + Wi-Fi Calling if there is no valid SPN in case 1 2691 2692 int voiceIdx = 0; 2693 int dataIdx = 0; 2694 int flightModeIdx = -1; 2695 boolean useRootLocale = false; 2696 2697 PersistableBundle bundle = getCarrierConfig(); 2698 2699 voiceIdx = bundle.getInt(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT); 2700 dataIdx = bundle.getInt( 2701 CarrierConfigManager.KEY_WFC_DATA_SPN_FORMAT_IDX_INT); 2702 flightModeIdx = bundle.getInt( 2703 CarrierConfigManager.KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT); 2704 useRootLocale = 2705 bundle.getBoolean(CarrierConfigManager.KEY_WFC_SPN_USE_ROOT_LOCALE); 2706 2707 String[] wfcSpnFormats = SubscriptionManager.getResourcesForSubId(mPhone.getContext(), 2708 mPhone.getSubId(), useRootLocale) 2709 .getStringArray(com.android.internal.R.array.wfcSpnFormats); 2710 2711 if (voiceIdx < 0 || voiceIdx >= wfcSpnFormats.length) { 2712 loge("updateSpnDisplay: KEY_WFC_SPN_FORMAT_IDX_INT out of bounds: " + voiceIdx); 2713 voiceIdx = 0; 2714 } 2715 if (dataIdx < 0 || dataIdx >= wfcSpnFormats.length) { 2716 loge("updateSpnDisplay: KEY_WFC_DATA_SPN_FORMAT_IDX_INT out of bounds: " 2717 + dataIdx); 2718 dataIdx = 0; 2719 } 2720 if (flightModeIdx < 0 || flightModeIdx >= wfcSpnFormats.length) { 2721 // KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT out of bounds. Use the value from 2722 // voiceIdx. 2723 flightModeIdx = voiceIdx; 2724 } 2725 2726 wfcVoiceSpnFormat = wfcSpnFormats[voiceIdx]; 2727 wfcDataSpnFormat = wfcSpnFormats[dataIdx]; 2728 wfcFlightSpnFormat = wfcSpnFormats[flightModeIdx]; 2729 } 2730 2731 if (mPhone.isPhoneTypeGsm()) { 2732 // The values of plmn/showPlmn change in different scenarios. 2733 // 1) No service but emergency call allowed -> expected 2734 // to show "Emergency call only" 2735 // EXTRA_SHOW_PLMN = true 2736 // EXTRA_PLMN = "Emergency call only" 2737 2738 // 2) No service at all --> expected to show "No service" 2739 // EXTRA_SHOW_PLMN = true 2740 // EXTRA_PLMN = "No service" 2741 2742 // 3) Normal operation in either home or roaming service 2743 // EXTRA_SHOW_PLMN = depending on IccRecords rule 2744 // EXTRA_PLMN = plmn 2745 2746 // 4) No service due to power off, aka airplane mode 2747 // EXTRA_SHOW_PLMN = true 2748 // EXTRA_PLMN = null 2749 2750 IccRecords iccRecords = mIccRecords; 2751 int rule = getCarrierNameDisplayBitmask(mSS); 2752 boolean noService = false; 2753 if (combinedRegState == ServiceState.STATE_OUT_OF_SERVICE 2754 || combinedRegState == ServiceState.STATE_EMERGENCY_ONLY) { 2755 showPlmn = true; 2756 2757 // Force display no service 2758 final boolean forceDisplayNoService = shouldForceDisplayNoService() && !mIsSimReady; 2759 if (!forceDisplayNoService && Phone.isEmergencyCallOnly()) { 2760 // No service but emergency call allowed 2761 plmn = Resources.getSystem() 2762 .getText(com.android.internal.R.string.emergency_calls_only).toString(); 2763 } else { 2764 // No service at all 2765 plmn = Resources.getSystem() 2766 .getText( 2767 com.android.internal.R.string.lockscreen_carrier_default) 2768 .toString(); 2769 noService = true; 2770 } 2771 if (DBG) log("updateSpnDisplay: radio is on but out " + 2772 "of service, set plmn='" + plmn + "'"); 2773 } else if (combinedRegState == ServiceState.STATE_IN_SERVICE) { 2774 // In either home or roaming service 2775 plmn = mSS.getOperatorAlpha(); 2776 showPlmn = !TextUtils.isEmpty(plmn) && 2777 ((rule & CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN) 2778 == CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN); 2779 if (DBG) log("updateSpnDisplay: rawPlmn = " + plmn); 2780 } else { 2781 // Power off state, such as airplane mode, show plmn as null 2782 showPlmn = true; 2783 plmn = null; 2784 if (DBG) log("updateSpnDisplay: radio is off w/ showPlmn=" 2785 + showPlmn + " plmn=" + plmn); 2786 } 2787 2788 // The value of spn/showSpn are same in different scenarios. 2789 // EXTRA_SHOW_SPN = depending on IccRecords rule and radio/IMS state 2790 // EXTRA_SPN = spn 2791 // EXTRA_DATA_SPN = dataSpn 2792 spn = getServiceProviderName(); 2793 dataSpn = spn; 2794 showSpn = !noService && !TextUtils.isEmpty(spn) 2795 && ((rule & CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN) 2796 == CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN); 2797 if (DBG) log("updateSpnDisplay: rawSpn = " + spn); 2798 2799 if (!TextUtils.isEmpty(spn) && !TextUtils.isEmpty(wfcVoiceSpnFormat) && 2800 !TextUtils.isEmpty(wfcDataSpnFormat)) { 2801 // Show SPN + Wi-Fi Calling If SIM has SPN and SPN display condition 2802 // is satisfied or SPN override is enabled for this carrier. 2803 2804 // Handle Flight Mode 2805 if (mSS.getState() == ServiceState.STATE_POWER_OFF) { 2806 wfcVoiceSpnFormat = wfcFlightSpnFormat; 2807 } 2808 2809 String originalSpn = spn.trim(); 2810 spn = String.format(wfcVoiceSpnFormat, originalSpn); 2811 dataSpn = String.format(wfcDataSpnFormat, originalSpn); 2812 showSpn = true; 2813 showPlmn = false; 2814 } else if (!TextUtils.isEmpty(plmn) && !TextUtils.isEmpty(wfcVoiceSpnFormat)) { 2815 // Show PLMN + Wi-Fi Calling if there is no valid SPN in the above case 2816 String originalPlmn = plmn.trim(); 2817 2818 PersistableBundle config = getCarrierConfig(); 2819 if (mIccRecords != null && config.getBoolean( 2820 CarrierConfigManager.KEY_WFC_CARRIER_NAME_OVERRIDE_BY_PNN_BOOL)) { 2821 originalPlmn = mIccRecords.getPnnHomeName(); 2822 } 2823 2824 plmn = String.format(wfcVoiceSpnFormat, originalPlmn); 2825 } else if (mSS.getState() == ServiceState.STATE_POWER_OFF 2826 || (showPlmn && TextUtils.equals(spn, plmn))) { 2827 // airplane mode or spn equals plmn, do not show spn 2828 spn = null; 2829 showSpn = false; 2830 } 2831 } else { 2832 String eriText = getOperatorNameFromEri(); 2833 if (eriText != null) mSS.setOperatorAlphaLong(eriText); 2834 2835 // carrier config gets a priority over ERI 2836 updateOperatorNameFromCarrierConfig(); 2837 2838 // mOperatorAlpha contains the ERI text 2839 plmn = mSS.getOperatorAlpha(); 2840 if (DBG) log("updateSpnDisplay: cdma rawPlmn = " + plmn); 2841 2842 showPlmn = plmn != null; 2843 2844 if (!TextUtils.isEmpty(plmn) && !TextUtils.isEmpty(wfcVoiceSpnFormat)) { 2845 // In Wi-Fi Calling mode show SPN+WiFi 2846 String originalPlmn = plmn.trim(); 2847 plmn = String.format(wfcVoiceSpnFormat, originalPlmn); 2848 } else if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) { 2849 // todo: temporary hack; should have a better fix. This is to avoid using operator 2850 // name from ServiceState (populated in processIwlanRegistrationInfo()) until 2851 // wifi calling is actually enabled 2852 log("updateSpnDisplay: overwriting plmn from " + plmn + " to null as radio " + 2853 "state is off"); 2854 plmn = null; 2855 } 2856 2857 if (combinedRegState == ServiceState.STATE_OUT_OF_SERVICE) { 2858 plmn = Resources.getSystem().getText(com.android.internal.R.string 2859 .lockscreen_carrier_default).toString(); 2860 if (DBG) { 2861 log("updateSpnDisplay: radio is on but out of svc, set plmn='" + plmn + "'"); 2862 } 2863 } 2864 2865 } 2866 2867 notifySpnDisplayUpdate(new CarrierDisplayNameData.Builder() 2868 .setSpn(spn) 2869 .setDataSpn(dataSpn) 2870 .setShowSpn(showSpn) 2871 .setPlmn(plmn) 2872 .setShowPlmn(showPlmn) 2873 .build()); 2874 log("updateSpnDisplayLegacy-"); 2875 } 2876 2877 /** 2878 * Returns whether out-of-service will be displayed as "no service" to the user. 2879 */ shouldForceDisplayNoService()2880 public boolean shouldForceDisplayNoService() { 2881 String[] countriesWithNoService = mPhone.getContext().getResources().getStringArray( 2882 com.android.internal.R.array.config_display_no_service_when_sim_unready); 2883 if (ArrayUtils.isEmpty(countriesWithNoService)) { 2884 return false; 2885 } 2886 mLastKnownNetworkCountry = mLocaleTracker.getLastKnownCountryIso(); 2887 for (String country : countriesWithNoService) { 2888 if (country.equalsIgnoreCase(mLastKnownNetworkCountry)) { 2889 return true; 2890 } 2891 } 2892 return false; 2893 } 2894 setPowerStateToDesired()2895 protected void setPowerStateToDesired() { 2896 setPowerStateToDesired(false, false, false); 2897 } 2898 setPowerStateToDesired(boolean forEmergencyCall, boolean isSelectedPhoneForEmergencyCall, boolean forceApply)2899 protected void setPowerStateToDesired(boolean forEmergencyCall, 2900 boolean isSelectedPhoneForEmergencyCall, boolean forceApply) { 2901 if (DBG) { 2902 String tmpLog = "mDeviceShuttingDown=" + mDeviceShuttingDown + 2903 ", mDesiredPowerState=" + mDesiredPowerState + 2904 ", getRadioState=" + mCi.getRadioState() + 2905 ", mPowerOffDelayNeed=" + mPowerOffDelayNeed + 2906 ", mAlarmSwitch=" + mAlarmSwitch + 2907 ", mRadioDisabledByCarrier=" + mRadioDisabledByCarrier; 2908 log(tmpLog); 2909 mRadioPowerLog.log(tmpLog); 2910 } 2911 2912 if (mPhone.isPhoneTypeGsm() && mAlarmSwitch) { 2913 if(DBG) log("mAlarmSwitch == true"); 2914 Context context = mPhone.getContext(); 2915 AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 2916 am.cancel(mRadioOffIntent); 2917 mAlarmSwitch = false; 2918 } 2919 2920 // If we want it on and it's off, turn it on 2921 if (mDesiredPowerState && !mRadioDisabledByCarrier 2922 && (forceApply || mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF)) { 2923 mCi.setRadioPower(true, forEmergencyCall, isSelectedPhoneForEmergencyCall, null); 2924 } else if ((!mDesiredPowerState || mRadioDisabledByCarrier) && mCi.getRadioState() 2925 == TelephonyManager.RADIO_POWER_ON) { 2926 // If it's on and available and we want it off gracefully 2927 if (mPhone.isPhoneTypeGsm() && mPowerOffDelayNeed) { 2928 if (mImsRegistrationOnOff && !mAlarmSwitch) { 2929 if(DBG) log("mImsRegistrationOnOff == true"); 2930 Context context = mPhone.getContext(); 2931 AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 2932 2933 Intent intent = new Intent(ACTION_RADIO_OFF); 2934 mRadioOffIntent = PendingIntent.getBroadcast( 2935 context, 0, intent, PendingIntent.FLAG_IMMUTABLE); 2936 2937 mAlarmSwitch = true; 2938 if (DBG) log("Alarm setting"); 2939 am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 2940 SystemClock.elapsedRealtime() + 3000, mRadioOffIntent); 2941 } else { 2942 powerOffRadioSafely(); 2943 } 2944 } else { 2945 powerOffRadioSafely(); 2946 } 2947 } else if (mDeviceShuttingDown 2948 && (mCi.getRadioState() != TelephonyManager.RADIO_POWER_UNAVAILABLE)) { 2949 mCi.requestShutdown(null); 2950 } 2951 } 2952 onUpdateIccAvailability()2953 protected void onUpdateIccAvailability() { 2954 if (mUiccController == null ) { 2955 return; 2956 } 2957 2958 UiccCardApplication newUiccApplication = getUiccCardApplication(); 2959 2960 if (mUiccApplcation != newUiccApplication) { 2961 2962 // Remove the EF records that come from UICC 2963 if (mIccRecords instanceof SIMRecords) { 2964 mCdnr.updateEfFromUsim(null /* usim */); 2965 } else if (mIccRecords instanceof RuimRecords) { 2966 mCdnr.updateEfFromRuim(null /* ruim */); 2967 } 2968 2969 if (mUiccApplcation != null) { 2970 log("Removing stale icc objects."); 2971 mUiccApplcation.unregisterForReady(this); 2972 if (mIccRecords != null) { 2973 mIccRecords.unregisterForRecordsLoaded(this); 2974 } 2975 mIccRecords = null; 2976 mUiccApplcation = null; 2977 } 2978 if (newUiccApplication != null) { 2979 log("New card found"); 2980 mUiccApplcation = newUiccApplication; 2981 mIccRecords = mUiccApplcation.getIccRecords(); 2982 if (mPhone.isPhoneTypeGsm()) { 2983 mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null); 2984 if (mIccRecords != null) { 2985 mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); 2986 } 2987 } else if (mIsSubscriptionFromRuim) { 2988 mUiccApplcation.registerForReady(this, EVENT_RUIM_READY, null); 2989 if (mIccRecords != null) { 2990 mIccRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null); 2991 } 2992 } 2993 } 2994 } 2995 } 2996 logRoamingChange()2997 private void logRoamingChange() { 2998 mRoamingLog.log(mSS.toString()); 2999 } 3000 logAttachChange()3001 private void logAttachChange() { 3002 mAttachLog.log(mSS.toString()); 3003 } 3004 logPhoneTypeChange()3005 private void logPhoneTypeChange() { 3006 mPhoneTypeLog.log(Integer.toString(mPhone.getPhoneType())); 3007 } 3008 logRatChange()3009 private void logRatChange() { 3010 mRatLog.log(mSS.toString()); 3011 } 3012 3013 @UnsupportedAppUsage log(String s)3014 protected final void log(String s) { 3015 Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + s); 3016 } 3017 3018 @UnsupportedAppUsage loge(String s)3019 protected final void loge(String s) { 3020 Rlog.e(LOG_TAG, "[" + mPhone.getPhoneId() + "] " + s); 3021 } 3022 3023 /** 3024 * @return The current GPRS state. IN_SERVICE is the same as "attached" 3025 * and OUT_OF_SERVICE is the same as detached. 3026 */ 3027 @UnsupportedAppUsage getCurrentDataConnectionState()3028 public int getCurrentDataConnectionState() { 3029 return mSS.getDataRegistrationState(); 3030 } 3031 3032 /** 3033 * @return true if phone is camping on a technology (eg UMTS) 3034 * that could support voice and data simultaneously. 3035 */ 3036 @UnsupportedAppUsage isConcurrentVoiceAndDataAllowed()3037 public boolean isConcurrentVoiceAndDataAllowed() { 3038 if (mSS.getCssIndicator() == 1) { 3039 // Checking the Concurrent Service Supported flag first for all phone types. 3040 return true; 3041 } else if (mPhone.isPhoneTypeGsm()) { 3042 int radioTechnology = mSS.getRilDataRadioTechnology(); 3043 // There are cases where we we would setup data connection even data is not yet 3044 // attached. In these cases we check voice rat. 3045 if (radioTechnology == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN 3046 && mSS.getDataRegistrationState() != ServiceState.STATE_IN_SERVICE) { 3047 radioTechnology = mSS.getRilVoiceRadioTechnology(); 3048 } 3049 // Concurrent voice and data is not allowed for 2G technologies. It's allowed in other 3050 // rats e.g. UMTS, LTE, etc. 3051 return radioTechnology != ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN 3052 && ServiceState.rilRadioTechnologyToAccessNetworkType(radioTechnology) 3053 != AccessNetworkType.GERAN; 3054 } else { 3055 return false; 3056 } 3057 } 3058 3059 /** Called when the service state of ImsPhone is changed. */ onImsServiceStateChanged()3060 public void onImsServiceStateChanged() { 3061 sendMessage(obtainMessage(EVENT_IMS_SERVICE_STATE_CHANGED)); 3062 } 3063 setImsRegistrationState(boolean registered)3064 public void setImsRegistrationState(boolean registered) { 3065 log("ImsRegistrationState - registered : " + registered); 3066 3067 if (mImsRegistrationOnOff && !registered) { 3068 if (mAlarmSwitch) { 3069 mImsRegistrationOnOff = registered; 3070 3071 Context context = mPhone.getContext(); 3072 AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 3073 am.cancel(mRadioOffIntent); 3074 mAlarmSwitch = false; 3075 3076 sendMessage(obtainMessage(EVENT_CHANGE_IMS_STATE)); 3077 return; 3078 } 3079 } 3080 mImsRegistrationOnOff = registered; 3081 } 3082 onImsCapabilityChanged()3083 public void onImsCapabilityChanged() { 3084 sendMessage(obtainMessage(EVENT_IMS_CAPABILITY_CHANGED)); 3085 } 3086 isRadioOn()3087 public boolean isRadioOn() { 3088 return mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON; 3089 } 3090 3091 /** 3092 * A complete "service state" from our perspective is 3093 * composed of a handful of separate requests to the radio. 3094 * 3095 * We make all of these requests at once, but then abandon them 3096 * and start over again if the radio notifies us that some 3097 * event has changed 3098 */ 3099 @UnsupportedAppUsage pollState()3100 public void pollState() { 3101 sendEmptyMessage(EVENT_POLL_STATE_REQUEST); 3102 } 3103 pollStateInternal(boolean modemTriggered)3104 private void pollStateInternal(boolean modemTriggered) { 3105 mPollingContext = new int[1]; 3106 mPollingContext[0] = 0; 3107 3108 log("pollState: modemTriggered=" + modemTriggered); 3109 3110 switch (mCi.getRadioState()) { 3111 case TelephonyManager.RADIO_POWER_UNAVAILABLE: 3112 mNewSS.setStateOutOfService(); 3113 setSignalStrengthDefaultValues(); 3114 mLastNitzData = null; 3115 mNitzState.handleNetworkUnavailable(); 3116 pollStateDone(); 3117 break; 3118 3119 case TelephonyManager.RADIO_POWER_OFF: 3120 mNewSS.setStateOff(); 3121 setSignalStrengthDefaultValues(); 3122 mLastNitzData = null; 3123 mNitzState.handleNetworkUnavailable(); 3124 // don't poll when device is shutting down or the poll was not modemTrigged 3125 // (they sent us new radio data) and current network is not IWLAN 3126 if (mDeviceShuttingDown || 3127 (!modemTriggered && ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN 3128 != mSS.getRilDataRadioTechnology())) { 3129 pollStateDone(); 3130 break; 3131 } 3132 3133 default: 3134 // Issue all poll-related commands at once then count down the responses, which 3135 // are allowed to arrive out-of-order 3136 mPollingContext[0]++; 3137 mCi.getOperator(obtainMessage(EVENT_POLL_STATE_OPERATOR, mPollingContext)); 3138 3139 mPollingContext[0]++; 3140 mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3141 .requestNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, 3142 obtainMessage(EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION, 3143 mPollingContext)); 3144 3145 mPollingContext[0]++; 3146 mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3147 .requestNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS, 3148 obtainMessage(EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION, mPollingContext)); 3149 3150 if (mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) != null) { 3151 mPollingContext[0]++; 3152 mRegStateManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 3153 .requestNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, 3154 obtainMessage(EVENT_POLL_STATE_PS_IWLAN_REGISTRATION, 3155 mPollingContext)); 3156 } 3157 3158 if (mPhone.isPhoneTypeGsm()) { 3159 mPollingContext[0]++; 3160 mCi.getNetworkSelectionMode(obtainMessage( 3161 EVENT_POLL_STATE_NETWORK_SELECTION_MODE, mPollingContext)); 3162 } 3163 break; 3164 } 3165 } 3166 3167 /** 3168 * Get the highest-priority CellIdentity for a provided ServiceState. 3169 * 3170 * Choose a CellIdentity for ServiceState using the following rules: 3171 * 1) WWAN only (WLAN is excluded) 3172 * 2) Registered > Camped 3173 * 3) CS > PS 3174 * 3175 * @param ss a Non-Null ServiceState object 3176 * 3177 * @return a list of CellIdentity objects in *decreasing* order of preference. 3178 */ getPrioritizedCellIdentities( @onNull final ServiceState ss)3179 @VisibleForTesting public static @NonNull List<CellIdentity> getPrioritizedCellIdentities( 3180 @NonNull final ServiceState ss) { 3181 final List<NetworkRegistrationInfo> regInfos = ss.getNetworkRegistrationInfoList(); 3182 if (regInfos.isEmpty()) return Collections.emptyList(); 3183 3184 return regInfos.stream() 3185 .filter(nri -> nri.getCellIdentity() != null) 3186 .filter(nri -> nri.getTransportType() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3187 .sorted(Comparator 3188 .comparing(NetworkRegistrationInfo::isRegistered) 3189 .thenComparing((nri) -> nri.getDomain() & NetworkRegistrationInfo.DOMAIN_CS) 3190 .reversed()) 3191 .map(nri -> nri.getCellIdentity()) 3192 .distinct() 3193 .collect(Collectors.toList()); 3194 } 3195 pollStateDone()3196 private void pollStateDone() { 3197 if (!mPhone.isPhoneTypeGsm()) { 3198 updateRoamingState(); 3199 } 3200 3201 if (TelephonyUtils.IS_DEBUGGABLE 3202 && SystemProperties.getBoolean(PROP_FORCE_ROAMING, false)) { 3203 mNewSS.setRoaming(true); 3204 } 3205 useDataRegStateForDataOnlyDevices(); 3206 processIwlanRegistrationInfo(); 3207 3208 if (TelephonyUtils.IS_DEBUGGABLE && mPhone.mTelephonyTester != null) { 3209 mPhone.mTelephonyTester.overrideServiceState(mNewSS); 3210 } 3211 3212 if (DBG) { 3213 log("Poll ServiceState done: " 3214 + " oldSS=[" + mSS + "] newSS=[" + mNewSS + "]" 3215 + " oldMaxDataCalls=" + mMaxDataCalls 3216 + " mNewMaxDataCalls=" + mNewMaxDataCalls 3217 + " oldReasonDataDenied=" + mReasonDataDenied 3218 + " mNewReasonDataDenied=" + mNewReasonDataDenied); 3219 } 3220 3221 boolean hasRegistered = 3222 mSS.getState() != ServiceState.STATE_IN_SERVICE 3223 && mNewSS.getState() == ServiceState.STATE_IN_SERVICE; 3224 3225 boolean hasDeregistered = 3226 mSS.getState() == ServiceState.STATE_IN_SERVICE 3227 && mNewSS.getState() != ServiceState.STATE_IN_SERVICE; 3228 3229 boolean hasAirplaneModeOnChanged = 3230 mSS.getState() != ServiceState.STATE_POWER_OFF 3231 && mNewSS.getState() == ServiceState.STATE_POWER_OFF; 3232 3233 SparseBooleanArray hasDataAttached = new SparseBooleanArray( 3234 mTransportManager.getAvailableTransports().length); 3235 SparseBooleanArray hasDataDetached = new SparseBooleanArray( 3236 mTransportManager.getAvailableTransports().length); 3237 SparseBooleanArray hasRilDataRadioTechnologyChanged = new SparseBooleanArray( 3238 mTransportManager.getAvailableTransports().length); 3239 SparseBooleanArray hasDataRegStateChanged = new SparseBooleanArray( 3240 mTransportManager.getAvailableTransports().length); 3241 boolean anyDataRegChanged = false; 3242 boolean anyDataRatChanged = false; 3243 boolean hasAlphaRawChanged = 3244 !TextUtils.equals(mSS.getOperatorAlphaLongRaw(), mNewSS.getOperatorAlphaLongRaw()) 3245 || !TextUtils.equals(mSS.getOperatorAlphaShortRaw(), 3246 mNewSS.getOperatorAlphaShortRaw()); 3247 3248 for (int transport : mTransportManager.getAvailableTransports()) { 3249 NetworkRegistrationInfo oldNrs = mSS.getNetworkRegistrationInfo( 3250 NetworkRegistrationInfo.DOMAIN_PS, transport); 3251 NetworkRegistrationInfo newNrs = mNewSS.getNetworkRegistrationInfo( 3252 NetworkRegistrationInfo.DOMAIN_PS, transport); 3253 3254 // If the previously it was not in service, and now it's in service, trigger the 3255 // attached event. Also if airplane mode was just turned on, and data is already in 3256 // service, we need to trigger the attached event again so that DcTracker can setup 3257 // data on all connectable APNs again (because we've already torn down all data 3258 // connections just before airplane mode turned on) 3259 boolean changed = (oldNrs == null || !oldNrs.isInService() || hasAirplaneModeOnChanged) 3260 && (newNrs != null && newNrs.isInService()); 3261 hasDataAttached.put(transport, changed); 3262 3263 changed = (oldNrs != null && oldNrs.isInService()) 3264 && (newNrs == null || !newNrs.isInService()); 3265 hasDataDetached.put(transport, changed); 3266 3267 int oldRAT = oldNrs != null ? oldNrs.getAccessNetworkTechnology() 3268 : TelephonyManager.NETWORK_TYPE_UNKNOWN; 3269 int newRAT = newNrs != null ? newNrs.getAccessNetworkTechnology() 3270 : TelephonyManager.NETWORK_TYPE_UNKNOWN; 3271 3272 boolean isOldCA = oldNrs != null ? (oldNrs.getDataSpecificInfo() != null 3273 ? oldNrs.getDataSpecificInfo().isUsingCarrierAggregation() : false) : false; 3274 boolean isNewCA = newNrs != null ? (newNrs.getDataSpecificInfo() != null 3275 ? newNrs.getDataSpecificInfo().isUsingCarrierAggregation() : false) : false; 3276 3277 // If the carrier enable KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING and the operator name 3278 // match this pattern, the data rat display LteAdvanced indicator. 3279 hasRilDataRadioTechnologyChanged.put(transport, 3280 oldRAT != newRAT || isOldCA != isNewCA || hasAlphaRawChanged); 3281 if (oldRAT != newRAT) { 3282 anyDataRatChanged = true; 3283 } 3284 3285 int oldRegState = oldNrs != null ? oldNrs.getRegistrationState() 3286 : NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN; 3287 int newRegState = newNrs != null ? newNrs.getRegistrationState() 3288 : NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN; 3289 hasDataRegStateChanged.put(transport, oldRegState != newRegState); 3290 if (oldRegState != newRegState) { 3291 anyDataRegChanged = true; 3292 } 3293 } 3294 3295 // Filter out per transport data RAT changes, only want to track changes based on 3296 // transport preference changes (WWAN to WLAN, for example). 3297 boolean hasDataTransportPreferenceChanged = !anyDataRatChanged 3298 && (mSS.getRilDataRadioTechnology() != mNewSS.getRilDataRadioTechnology()); 3299 3300 boolean hasVoiceRegStateChanged = 3301 mSS.getState() != mNewSS.getState(); 3302 3303 boolean hasNrFrequencyRangeChanged = 3304 mSS.getNrFrequencyRange() != mNewSS.getNrFrequencyRange(); 3305 3306 boolean hasNrStateChanged = mSS.getNrState() != mNewSS.getNrState(); 3307 3308 final List<CellIdentity> prioritizedCids = getPrioritizedCellIdentities(mNewSS); 3309 3310 final CellIdentity primaryCellIdentity = prioritizedCids.isEmpty() 3311 ? null : prioritizedCids.get(0); 3312 3313 boolean hasLocationChanged = mCellIdentity == null 3314 ? primaryCellIdentity != null : !mCellIdentity.isSameCell(primaryCellIdentity); 3315 3316 // ratchet the new tech up through its rat family but don't drop back down 3317 // until cell change or device is OOS 3318 boolean isDataInService = mNewSS.getDataRegistrationState() 3319 == ServiceState.STATE_IN_SERVICE; 3320 if (isDataInService) { 3321 mRatRatcheter.ratchet(mSS, mNewSS, hasLocationChanged); 3322 } 3323 3324 boolean hasRilVoiceRadioTechnologyChanged = 3325 mSS.getRilVoiceRadioTechnology() != mNewSS.getRilVoiceRadioTechnology(); 3326 3327 boolean hasChanged = !mNewSS.equals(mSS); 3328 3329 boolean hasVoiceRoamingOn = !mSS.getVoiceRoaming() && mNewSS.getVoiceRoaming(); 3330 3331 boolean hasVoiceRoamingOff = mSS.getVoiceRoaming() && !mNewSS.getVoiceRoaming(); 3332 3333 boolean hasDataRoamingOn = !mSS.getDataRoaming() && mNewSS.getDataRoaming(); 3334 3335 boolean hasDataRoamingOff = mSS.getDataRoaming() && !mNewSS.getDataRoaming(); 3336 3337 boolean hasRejectCauseChanged = mRejectCode != mNewRejectCode; 3338 3339 boolean hasCssIndicatorChanged = (mSS.getCssIndicator() != mNewSS.getCssIndicator()); 3340 3341 boolean has4gHandoff = false; 3342 boolean hasMultiApnSupport = false; 3343 boolean hasLostMultiApnSupport = false; 3344 if (mPhone.isPhoneTypeCdmaLte()) { 3345 final int wwanDataRat = getRilDataRadioTechnologyForWwan(mSS); 3346 final int newWwanDataRat = getRilDataRadioTechnologyForWwan(mNewSS); 3347 has4gHandoff = mNewSS.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE 3348 && ((ServiceState.isPsOnlyTech(wwanDataRat) 3349 && (newWwanDataRat == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) 3350 || ((wwanDataRat == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD) 3351 && ServiceState.isPsOnlyTech(newWwanDataRat))); 3352 3353 hasMultiApnSupport = ((ServiceState.isPsOnlyTech(newWwanDataRat) 3354 || (newWwanDataRat == ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD)) 3355 && (!ServiceState.isPsOnlyTech(wwanDataRat) 3356 && (wwanDataRat != ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD))); 3357 3358 hasLostMultiApnSupport = ((newWwanDataRat >= ServiceState.RIL_RADIO_TECHNOLOGY_IS95A) 3359 && (newWwanDataRat <= ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)); 3360 } 3361 3362 if (DBG) { 3363 log("pollStateDone:" 3364 + " hasRegistered = " + hasRegistered 3365 + " hasDeregistered = " + hasDeregistered 3366 + " hasDataAttached = " + hasDataAttached 3367 + " hasDataDetached = " + hasDataDetached 3368 + " hasDataRegStateChanged = " + hasDataRegStateChanged 3369 + " hasRilVoiceRadioTechnologyChanged = " + hasRilVoiceRadioTechnologyChanged 3370 + " hasRilDataRadioTechnologyChanged = " + hasRilDataRadioTechnologyChanged 3371 + " hasDataTransportPreferenceChanged = " + hasDataTransportPreferenceChanged 3372 + " hasChanged = " + hasChanged 3373 + " hasVoiceRoamingOn = " + hasVoiceRoamingOn 3374 + " hasVoiceRoamingOff = " + hasVoiceRoamingOff 3375 + " hasDataRoamingOn =" + hasDataRoamingOn 3376 + " hasDataRoamingOff = " + hasDataRoamingOff 3377 + " hasLocationChanged = " + hasLocationChanged 3378 + " has4gHandoff = " + has4gHandoff 3379 + " hasMultiApnSupport = " + hasMultiApnSupport 3380 + " hasLostMultiApnSupport = " + hasLostMultiApnSupport 3381 + " hasCssIndicatorChanged = " + hasCssIndicatorChanged 3382 + " hasNrFrequencyRangeChanged = " + hasNrFrequencyRangeChanged 3383 + " hasNrStateChanged = " + hasNrStateChanged 3384 + " hasAirplaneModeOnlChanged = " + hasAirplaneModeOnChanged); 3385 } 3386 3387 // Add an event log when connection state changes 3388 if (hasVoiceRegStateChanged || anyDataRegChanged) { 3389 EventLog.writeEvent(mPhone.isPhoneTypeGsm() ? EventLogTags.GSM_SERVICE_STATE_CHANGE : 3390 EventLogTags.CDMA_SERVICE_STATE_CHANGE, 3391 mSS.getState(), mSS.getDataRegistrationState(), 3392 mNewSS.getState(), mNewSS.getDataRegistrationState()); 3393 } 3394 3395 if (mPhone.isPhoneTypeGsm()) { 3396 // Add an event log when network type switched 3397 // TODO: we may add filtering to reduce the event logged, 3398 // i.e. check preferred network setting, only switch to 2G, etc 3399 if (hasRilVoiceRadioTechnologyChanged) { 3400 long cid = getCidFromCellIdentity(primaryCellIdentity); 3401 // NOTE: this code was previously located after mSS and mNewSS are swapped, so 3402 // existing logs were incorrectly using the new state for "network_from" 3403 // and STATE_OUT_OF_SERVICE for "network_to". To avoid confusion, use a new log tag 3404 // to record the correct states. 3405 EventLog.writeEvent(EventLogTags.GSM_RAT_SWITCHED_NEW, cid, 3406 mSS.getRilVoiceRadioTechnology(), 3407 mNewSS.getRilVoiceRadioTechnology()); 3408 if (DBG) { 3409 log("RAT switched " 3410 + ServiceState.rilRadioTechnologyToString( 3411 mSS.getRilVoiceRadioTechnology()) 3412 + " -> " 3413 + ServiceState.rilRadioTechnologyToString( 3414 mNewSS.getRilVoiceRadioTechnology()) + " at cell " + cid); 3415 } 3416 } 3417 3418 mReasonDataDenied = mNewReasonDataDenied; 3419 mMaxDataCalls = mNewMaxDataCalls; 3420 mRejectCode = mNewRejectCode; 3421 } 3422 3423 if (hasCssIndicatorChanged) { 3424 mPhone.notifyAllActiveDataConnections(); 3425 } 3426 3427 ServiceState oldMergedSS = new ServiceState(mPhone.getServiceState()); 3428 3429 // swap mSS and mNewSS to put new state in mSS 3430 ServiceState tss = mSS; 3431 mSS = mNewSS; 3432 mNewSS = tss; 3433 // clean slate for next time 3434 mNewSS.setStateOutOfService(); 3435 3436 mCellIdentity = primaryCellIdentity; 3437 3438 if (hasRilVoiceRadioTechnologyChanged) { 3439 updatePhoneObject(); 3440 } 3441 3442 TelephonyManager tm = (TelephonyManager) mPhone.getContext().getSystemService( 3443 Context.TELEPHONY_SERVICE); 3444 if (anyDataRatChanged) { 3445 tm.setDataNetworkTypeForPhone(mPhone.getPhoneId(), mSS.getRilDataRadioTechnology()); 3446 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_RADIO_TECHNOLOGY_CHANGED, 3447 ServiceState.rilRadioTechnologyToNetworkType( 3448 mSS.getRilDataRadioTechnology()), mPhone.getPhoneId()); 3449 } 3450 3451 if (hasRegistered) { 3452 mNetworkAttachedRegistrants.notifyRegistrants(); 3453 } 3454 3455 if (hasDeregistered) { 3456 mNetworkDetachedRegistrants.notifyRegistrants(); 3457 } 3458 3459 if (hasRejectCauseChanged) { 3460 setNotification(CS_REJECT_CAUSE_ENABLED); 3461 } 3462 3463 String eriText = mPhone.getCdmaEriText(); 3464 boolean hasEriChanged = !TextUtils.equals(mEriText, eriText); 3465 mEriText = eriText; 3466 // Trigger updateSpnDisplay when 3467 // 1. Service state is changed. 3468 // 2. phone type is Cdma or CdmaLte and ERI text has changed. 3469 if (hasChanged || (!mPhone.isPhoneTypeGsm() && hasEriChanged)) { 3470 updateSpnDisplay(); 3471 } 3472 3473 if (hasChanged) { 3474 tm.setNetworkOperatorNameForPhone(mPhone.getPhoneId(), mSS.getOperatorAlpha()); 3475 String operatorNumeric = mSS.getOperatorNumeric(); 3476 3477 if (!mPhone.isPhoneTypeGsm()) { 3478 // try to fix the invalid Operator Numeric 3479 if (isInvalidOperatorNumeric(operatorNumeric)) { 3480 int sid = mSS.getCdmaSystemId(); 3481 operatorNumeric = fixUnknownMcc(operatorNumeric, sid); 3482 } 3483 } 3484 3485 tm.setNetworkOperatorNumericForPhone(mPhone.getPhoneId(), operatorNumeric); 3486 3487 // If the OPERATOR command hasn't returned a valid operator or the device is on IWLAN ( 3488 // because operatorNumeric would be SIM's mcc/mnc when device is on IWLAN), but if the 3489 // device has camped on a cell either to attempt registration or for emergency services, 3490 // then for purposes of setting the locale, we don't care if registration fails or is 3491 // incomplete. 3492 // CellIdentity can return a null MCC and MNC in CDMA 3493 String localeOperator = operatorNumeric; 3494 if (isInvalidOperatorNumeric(operatorNumeric) 3495 || mSS.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN) { 3496 for (CellIdentity cid : prioritizedCids) { 3497 if (!TextUtils.isEmpty(cid.getPlmn())) { 3498 localeOperator = cid.getPlmn(); 3499 break; 3500 } 3501 } 3502 } 3503 3504 if (isInvalidOperatorNumeric(localeOperator)) { 3505 if (DBG) log("localeOperator " + localeOperator + " is invalid"); 3506 // Passing empty string is important for the first update. The initial value of 3507 // operator numeric in locale tracker is null. The async update will allow getting 3508 // cell info from the modem instead of using the cached one. 3509 mLocaleTracker.updateOperatorNumeric(""); 3510 } else { 3511 if (!mPhone.isPhoneTypeGsm()) { 3512 setOperatorIdd(localeOperator); 3513 } 3514 mLocaleTracker.updateOperatorNumeric(localeOperator); 3515 } 3516 3517 tm.setNetworkRoamingForPhone(mPhone.getPhoneId(), 3518 mPhone.isPhoneTypeGsm() ? mSS.getVoiceRoaming() : 3519 (mSS.getVoiceRoaming() || mSS.getDataRoaming())); 3520 3521 setRoamingType(mSS); 3522 log("Broadcasting ServiceState : " + mSS); 3523 // notify using PhoneStateListener and the legacy intent ACTION_SERVICE_STATE_CHANGED 3524 // notify service state changed only if the merged service state is changed. 3525 if (!oldMergedSS.equals(mPhone.getServiceState())) { 3526 mPhone.notifyServiceStateChanged(mPhone.getServiceState()); 3527 } 3528 3529 // insert into ServiceStateProvider. This will trigger apps to wake through JobScheduler 3530 mPhone.getContext().getContentResolver() 3531 .insert(getUriForSubscriptionId(mPhone.getSubId()), 3532 getContentValuesForServiceState(mSS)); 3533 } 3534 3535 if (hasChanged || hasNrStateChanged) { 3536 TelephonyMetrics.getInstance().writeServiceStateChanged(mPhone.getPhoneId(), mSS); 3537 mPhone.getVoiceCallSessionStats().onServiceStateChanged(mSS); 3538 } 3539 3540 boolean shouldLogAttachedChange = false; 3541 boolean shouldLogRatChange = false; 3542 3543 if (hasRegistered || hasDeregistered) { 3544 shouldLogAttachedChange = true; 3545 } 3546 3547 if (has4gHandoff) { 3548 mAttachedRegistrants.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3549 .notifyRegistrants(); 3550 shouldLogAttachedChange = true; 3551 } 3552 3553 if (hasRilVoiceRadioTechnologyChanged) { 3554 shouldLogRatChange = true; 3555 notifySignalStrength(); 3556 } 3557 3558 for (int transport : mTransportManager.getAvailableTransports()) { 3559 if (hasRilDataRadioTechnologyChanged.get(transport)) { 3560 shouldLogRatChange = true; 3561 notifySignalStrength(); 3562 } 3563 3564 if (hasDataRegStateChanged.get(transport) 3565 || hasRilDataRadioTechnologyChanged.get(transport) 3566 // Update all transports if preference changed so that consumers can be notified 3567 // that ServiceState#getRilDataRadioTechnology has changed. 3568 || hasDataTransportPreferenceChanged) { 3569 setDataNetworkTypeForPhone(mSS.getRilDataRadioTechnology()); 3570 notifyDataRegStateRilRadioTechnologyChanged(transport); 3571 mPhone.notifyAllActiveDataConnections(); 3572 } 3573 3574 if (hasDataAttached.get(transport)) { 3575 shouldLogAttachedChange = true; 3576 if (mAttachedRegistrants.get(transport) != null) { 3577 mAttachedRegistrants.get(transport).notifyRegistrants(); 3578 } 3579 } 3580 if (hasDataDetached.get(transport)) { 3581 shouldLogAttachedChange = true; 3582 if (mDetachedRegistrants.get(transport) != null) { 3583 mDetachedRegistrants.get(transport).notifyRegistrants(); 3584 } 3585 } 3586 } 3587 3588 if (shouldLogAttachedChange) { 3589 logAttachChange(); 3590 } 3591 if (shouldLogRatChange) { 3592 logRatChange(); 3593 } 3594 3595 if (hasVoiceRegStateChanged || hasRilVoiceRadioTechnologyChanged) { 3596 notifyVoiceRegStateRilRadioTechnologyChanged(); 3597 } 3598 3599 if (hasVoiceRoamingOn || hasVoiceRoamingOff || hasDataRoamingOn || hasDataRoamingOff) { 3600 logRoamingChange(); 3601 } 3602 3603 if (hasVoiceRoamingOn) { 3604 mVoiceRoamingOnRegistrants.notifyRegistrants(); 3605 } 3606 3607 if (hasVoiceRoamingOff) { 3608 mVoiceRoamingOffRegistrants.notifyRegistrants(); 3609 } 3610 3611 if (hasDataRoamingOn) { 3612 mDataRoamingOnRegistrants.notifyRegistrants(); 3613 } 3614 3615 if (hasDataRoamingOff) { 3616 mDataRoamingOffRegistrants.notifyRegistrants(); 3617 } 3618 3619 if (hasLocationChanged) { 3620 mPhone.notifyLocationChanged(getCellIdentity()); 3621 } 3622 3623 if (hasNrStateChanged) { 3624 mNrStateChangedRegistrants.notifyRegistrants(); 3625 } 3626 3627 if (hasNrFrequencyRangeChanged) { 3628 mNrFrequencyChangedRegistrants.notifyRegistrants(); 3629 } 3630 3631 if (mPhone.isPhoneTypeGsm()) { 3632 if (!isGprsConsistent(mSS.getDataRegistrationState(), mSS.getState())) { 3633 if (!mStartedGprsRegCheck && !mReportedGprsNoReg) { 3634 mStartedGprsRegCheck = true; 3635 3636 int check_period = Settings.Global.getInt( 3637 mPhone.getContext().getContentResolver(), 3638 Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS, 3639 DEFAULT_GPRS_CHECK_PERIOD_MILLIS); 3640 sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS), 3641 check_period); 3642 } 3643 } else { 3644 mReportedGprsNoReg = false; 3645 } 3646 } 3647 } 3648 getOperatorNameFromEri()3649 private String getOperatorNameFromEri() { 3650 String eriText = null; 3651 if (mPhone.isPhoneTypeCdma()) { 3652 if ((mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) 3653 && (!mIsSubscriptionFromRuim)) { 3654 // Now the Phone sees the new ServiceState so it can get the new ERI text 3655 if (mSS.getState() == ServiceState.STATE_IN_SERVICE) { 3656 eriText = mPhone.getCdmaEriText(); 3657 } else { 3658 // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used for 3659 // mRegistrationState 0,2,3 and 4 3660 eriText = mPhone.getContext().getText( 3661 com.android.internal.R.string.roamingTextSearching).toString(); 3662 } 3663 } 3664 } else if (mPhone.isPhoneTypeCdmaLte()) { 3665 boolean hasBrandOverride = mUiccController.getUiccCard(getPhoneId()) != null && 3666 mUiccController.getUiccCard(getPhoneId()).getOperatorBrandOverride() != null; 3667 if (!hasBrandOverride && (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) 3668 && (mEriManager.isEriFileLoaded()) 3669 && (!ServiceState.isPsOnlyTech(mSS.getRilVoiceRadioTechnology()) 3670 || mPhone.getContext().getResources().getBoolean(com.android.internal.R 3671 .bool.config_LTE_eri_for_network_name))) { 3672 // Only when CDMA is in service, ERI will take effect 3673 eriText = mSS.getOperatorAlpha(); 3674 // Now the Phone sees the new ServiceState so it can get the new ERI text 3675 if (mSS.getState() == ServiceState.STATE_IN_SERVICE) { 3676 eriText = mPhone.getCdmaEriText(); 3677 } else if (mSS.getState() == ServiceState.STATE_POWER_OFF) { 3678 eriText = getServiceProviderName(); 3679 if (TextUtils.isEmpty(eriText)) { 3680 // Sets operator alpha property by retrieving from 3681 // build-time system property 3682 eriText = SystemProperties.get("ro.cdma.home.operator.alpha"); 3683 } 3684 } else if (mSS.getDataRegistrationState() != ServiceState.STATE_IN_SERVICE) { 3685 // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used 3686 // for mRegistrationState 0,2,3 and 4 3687 eriText = mPhone.getContext() 3688 .getText(com.android.internal.R.string.roamingTextSearching).toString(); 3689 } 3690 } 3691 3692 if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY && 3693 mIccRecords != null && getCombinedRegState(mSS) == ServiceState.STATE_IN_SERVICE 3694 && !ServiceState.isPsOnlyTech(mSS.getRilVoiceRadioTechnology())) { 3695 // SIM is found on the device. If ERI roaming is OFF, and SID/NID matches 3696 // one configured in SIM, use operator name from CSIM record. Note that ERI, SID, 3697 // and NID are CDMA only, not applicable to LTE. 3698 boolean showSpn = 3699 ((RuimRecords) mIccRecords).getCsimSpnDisplayCondition(); 3700 int iconIndex = mSS.getCdmaEriIconIndex(); 3701 3702 if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) 3703 && isInHomeSidNid(mSS.getCdmaSystemId(), mSS.getCdmaNetworkId()) 3704 && mIccRecords != null) { 3705 eriText = getServiceProviderName(); 3706 } 3707 } 3708 } 3709 return eriText; 3710 } 3711 3712 /** 3713 * Get the service provider name with highest priority among various source. 3714 * @return service provider name. 3715 */ getServiceProviderName()3716 public String getServiceProviderName() { 3717 // BrandOverride has higher priority than the carrier config 3718 String operatorBrandOverride = getOperatorBrandOverride(); 3719 if (!TextUtils.isEmpty(operatorBrandOverride)) { 3720 return operatorBrandOverride; 3721 } 3722 3723 String carrierName = mIccRecords != null ? mIccRecords.getServiceProviderName() : ""; 3724 PersistableBundle config = getCarrierConfig(); 3725 if (config.getBoolean(CarrierConfigManager.KEY_CARRIER_NAME_OVERRIDE_BOOL) 3726 || TextUtils.isEmpty(carrierName)) { 3727 return config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING); 3728 } 3729 3730 return carrierName; 3731 } 3732 3733 /** 3734 * Get the resolved carrier name display condition bitmask. 3735 * 3736 * <p> Show service provider name if only if {@link #CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN} 3737 * is set. 3738 * 3739 * <p> Show PLMN network name if only if {@link #CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN} is set. 3740 * 3741 * @param ss service state 3742 * @return carrier name display bitmask. 3743 */ 3744 @CarrierNameDisplayBitmask getCarrierNameDisplayBitmask(ServiceState ss)3745 public int getCarrierNameDisplayBitmask(ServiceState ss) { 3746 PersistableBundle config = getCarrierConfig(); 3747 if (!TextUtils.isEmpty(getOperatorBrandOverride())) { 3748 // If the operator has been overridden, all PLMNs will be considered HOME PLMNs, only 3749 // show SPN. 3750 return CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN; 3751 } else if (TextUtils.isEmpty(getServiceProviderName())) { 3752 // If SPN is null or empty, we should show plmn. 3753 // This is a hack from IccRecords#getServiceProviderName(). 3754 return CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN; 3755 } else { 3756 boolean useRoamingFromServiceState = config.getBoolean( 3757 CarrierConfigManager.KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL); 3758 int carrierDisplayNameConditionFromSim = 3759 mIccRecords == null ? 0 : mIccRecords.getCarrierNameDisplayCondition(); 3760 3761 boolean isRoaming; 3762 if (useRoamingFromServiceState) { 3763 isRoaming = ss.getRoaming(); 3764 } else { 3765 String[] hplmns = mIccRecords != null ? mIccRecords.getHomePlmns() : null; 3766 isRoaming = !ArrayUtils.contains(hplmns, ss.getOperatorNumeric()); 3767 } 3768 int rule; 3769 if (isRoaming) { 3770 // Show PLMN when roaming. 3771 rule = CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN; 3772 3773 // Check if show SPN is required when roaming. 3774 if ((carrierDisplayNameConditionFromSim 3775 & CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN) 3776 == CARRIER_NAME_DISPLAY_CONDITION_BITMASK_SPN) { 3777 rule |= CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN; 3778 } 3779 } else { 3780 // Show SPN when not roaming. 3781 rule = CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN; 3782 3783 // Check if show PLMN is required when not roaming. 3784 if ((carrierDisplayNameConditionFromSim 3785 & CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN) 3786 == CARRIER_NAME_DISPLAY_CONDITION_BITMASK_PLMN) { 3787 rule |= CARRIER_NAME_DISPLAY_BITMASK_SHOW_PLMN; 3788 } 3789 } 3790 return rule; 3791 } 3792 } 3793 getOperatorBrandOverride()3794 private String getOperatorBrandOverride() { 3795 UiccCard card = mPhone.getUiccCard(); 3796 if (card == null) return null; 3797 UiccProfile profile = card.getUiccProfile(); 3798 if (profile == null) return null; 3799 return profile.getOperatorBrandOverride(); 3800 } 3801 3802 /** 3803 * Check whether the specified SID and NID pair appears in the HOME SID/NID list 3804 * read from NV or SIM. 3805 * 3806 * @return true if provided sid/nid pair belongs to operator's home network. 3807 */ 3808 @UnsupportedAppUsage isInHomeSidNid(int sid, int nid)3809 private boolean isInHomeSidNid(int sid, int nid) { 3810 // if SID/NID is not available, assume this is home network. 3811 if (isSidsAllZeros()) return true; 3812 3813 // length of SID/NID shold be same 3814 if (mHomeSystemId.length != mHomeNetworkId.length) return true; 3815 3816 if (sid == 0) return true; 3817 3818 for (int i = 0; i < mHomeSystemId.length; i++) { 3819 // Use SID only if NID is a reserved value. 3820 // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2) 3821 if ((mHomeSystemId[i] == sid) && 3822 ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) || 3823 (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) { 3824 return true; 3825 } 3826 } 3827 // SID/NID are not in the list. So device is not in home network 3828 return false; 3829 } 3830 3831 @UnsupportedAppUsage setOperatorIdd(String operatorNumeric)3832 protected void setOperatorIdd(String operatorNumeric) { 3833 if (mPhone.getUnitTestMode()) { 3834 return; 3835 } 3836 3837 // Retrieve the current country information 3838 // with the MCC got from operatorNumeric. 3839 String idd = mHbpcdUtils.getIddByMcc( 3840 Integer.parseInt(operatorNumeric.substring(0,3))); 3841 if (idd != null && !idd.isEmpty()) { 3842 TelephonyProperties.operator_idp_string(idd); 3843 } else { 3844 // use default "+", since we don't know the current IDP 3845 TelephonyProperties.operator_idp_string("+"); 3846 } 3847 } 3848 3849 @UnsupportedAppUsage isInvalidOperatorNumeric(String operatorNumeric)3850 private boolean isInvalidOperatorNumeric(String operatorNumeric) { 3851 return operatorNumeric == null || operatorNumeric.length() < 5 || 3852 operatorNumeric.startsWith(INVALID_MCC); 3853 } 3854 3855 @UnsupportedAppUsage fixUnknownMcc(String operatorNumeric, int sid)3856 private String fixUnknownMcc(String operatorNumeric, int sid) { 3857 if (sid <= 0) { 3858 // no cdma information is available, do nothing 3859 return operatorNumeric; 3860 } 3861 3862 // resolve the mcc from sid, using time zone information from the latest NITZ signal when 3863 // available. 3864 int utcOffsetHours = 0; 3865 boolean isDst = false; 3866 boolean isNitzTimeZone = false; 3867 NitzData lastNitzData = mLastNitzData; 3868 if (lastNitzData != null) { 3869 utcOffsetHours = lastNitzData.getLocalOffsetMillis() / MS_PER_HOUR; 3870 Integer dstAdjustmentMillis = lastNitzData.getDstAdjustmentMillis(); 3871 isDst = (dstAdjustmentMillis != null) && (dstAdjustmentMillis != 0); 3872 isNitzTimeZone = true; 3873 } 3874 int mcc = mHbpcdUtils.getMcc(sid, utcOffsetHours, (isDst ? 1 : 0), isNitzTimeZone); 3875 if (mcc > 0) { 3876 operatorNumeric = mcc + DEFAULT_MNC; 3877 } 3878 return operatorNumeric; 3879 } 3880 3881 /** 3882 * Check if GPRS got registered while voice is registered. 3883 * 3884 * @param dataRegState i.e. CGREG in GSM 3885 * @param voiceRegState i.e. CREG in GSM 3886 * @return false if device only register to voice but not gprs 3887 */ 3888 @UnsupportedAppUsage isGprsConsistent(int dataRegState, int voiceRegState)3889 private boolean isGprsConsistent(int dataRegState, int voiceRegState) { 3890 return !((voiceRegState == ServiceState.STATE_IN_SERVICE) && 3891 (dataRegState != ServiceState.STATE_IN_SERVICE)); 3892 } 3893 3894 /** convert ServiceState registration code 3895 * to service state */ regCodeToServiceState(int code)3896 private int regCodeToServiceState(int code) { 3897 switch (code) { 3898 case NetworkRegistrationInfo.REGISTRATION_STATE_HOME: 3899 case NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING: 3900 return ServiceState.STATE_IN_SERVICE; 3901 default: 3902 return ServiceState.STATE_OUT_OF_SERVICE; 3903 } 3904 } 3905 3906 /** 3907 * code is registration state 0-5 from TS 27.007 7.2 3908 * returns true if registered roam, false otherwise 3909 */ regCodeIsRoaming(int code)3910 private boolean regCodeIsRoaming (int code) { 3911 return NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING == code; 3912 } 3913 isSameOperatorNameFromSimAndSS(ServiceState s)3914 private boolean isSameOperatorNameFromSimAndSS(ServiceState s) { 3915 String spn = ((TelephonyManager) mPhone.getContext(). 3916 getSystemService(Context.TELEPHONY_SERVICE)). 3917 getSimOperatorNameForPhone(getPhoneId()); 3918 3919 // NOTE: in case of RUIM we should completely ignore the ERI data file and 3920 // mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS) 3921 String onsl = s.getOperatorAlphaLong(); 3922 String onss = s.getOperatorAlphaShort(); 3923 3924 boolean equalsOnsl = !TextUtils.isEmpty(spn) && spn.equalsIgnoreCase(onsl); 3925 boolean equalsOnss = !TextUtils.isEmpty(spn) && spn.equalsIgnoreCase(onss); 3926 3927 return (equalsOnsl || equalsOnss); 3928 } 3929 3930 /** 3931 * Set roaming state if operator mcc is the same as sim mcc 3932 * and ons is not different from spn 3933 * 3934 * @param s ServiceState hold current ons 3935 * @return true if same operator 3936 */ isSameNamedOperators(ServiceState s)3937 private boolean isSameNamedOperators(ServiceState s) { 3938 return currentMccEqualsSimMcc(s) && isSameOperatorNameFromSimAndSS(s); 3939 } 3940 3941 /** 3942 * Compare SIM MCC with Operator MCC 3943 * 3944 * @param s ServiceState hold current ons 3945 * @return true if both are same 3946 */ currentMccEqualsSimMcc(ServiceState s)3947 private boolean currentMccEqualsSimMcc(ServiceState s) { 3948 String simNumeric = ((TelephonyManager) mPhone.getContext(). 3949 getSystemService(Context.TELEPHONY_SERVICE)). 3950 getSimOperatorNumericForPhone(getPhoneId()); 3951 String operatorNumeric = s.getOperatorNumeric(); 3952 boolean equalsMcc = true; 3953 3954 try { 3955 equalsMcc = simNumeric.substring(0, 3). 3956 equals(operatorNumeric.substring(0, 3)); 3957 } catch (Exception e){ 3958 } 3959 return equalsMcc; 3960 } 3961 3962 /** 3963 * Do not set roaming state in case of oprators considered non-roaming. 3964 * 3965 * Can use mcc or mcc+mnc as item of 3966 * {@link CarrierConfigManager#KEY_NON_ROAMING_OPERATOR_STRING_ARRAY}. 3967 * For example, 302 or 21407. If mcc or mcc+mnc match with operator, 3968 * don't set roaming state. 3969 * 3970 * @param s ServiceState hold current ons 3971 * @return false for roaming state set 3972 */ isOperatorConsideredNonRoaming(ServiceState s)3973 private boolean isOperatorConsideredNonRoaming(ServiceState s) { 3974 String operatorNumeric = s.getOperatorNumeric(); 3975 3976 PersistableBundle config = getCarrierConfig(); 3977 String[] numericArray = config.getStringArray( 3978 CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY); 3979 3980 if (ArrayUtils.isEmpty(numericArray) || operatorNumeric == null) { 3981 return false; 3982 } 3983 3984 for (String numeric : numericArray) { 3985 if (!TextUtils.isEmpty(numeric) && operatorNumeric.startsWith(numeric)) { 3986 return true; 3987 } 3988 } 3989 return false; 3990 } 3991 isOperatorConsideredRoaming(ServiceState s)3992 private boolean isOperatorConsideredRoaming(ServiceState s) { 3993 String operatorNumeric = s.getOperatorNumeric(); 3994 PersistableBundle config = getCarrierConfig(); 3995 String[] numericArray = config.getStringArray( 3996 CarrierConfigManager.KEY_ROAMING_OPERATOR_STRING_ARRAY); 3997 if (ArrayUtils.isEmpty(numericArray) || operatorNumeric == null) { 3998 return false; 3999 } 4000 4001 for (String numeric : numericArray) { 4002 if (!TextUtils.isEmpty(numeric) && operatorNumeric.startsWith(numeric)) { 4003 return true; 4004 } 4005 } 4006 return false; 4007 } 4008 4009 /** 4010 * Set restricted state based on the OnRestrictedStateChanged notification 4011 * If any voice or packet restricted state changes, trigger a UI 4012 * notification and notify registrants when sim is ready. 4013 * 4014 * @param ar an int value of RIL_RESTRICTED_STATE_* 4015 */ onRestrictedStateChanged(AsyncResult ar)4016 private void onRestrictedStateChanged(AsyncResult ar) { 4017 RestrictedState newRs = new RestrictedState(); 4018 4019 if (DBG) log("onRestrictedStateChanged: E rs "+ mRestrictedState); 4020 4021 if (ar.exception == null && ar.result != null) { 4022 int state = (int)ar.result; 4023 4024 newRs.setCsEmergencyRestricted( 4025 ((state & RILConstants.RIL_RESTRICTED_STATE_CS_EMERGENCY) != 0) || 4026 ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) ); 4027 //ignore the normal call and data restricted state before SIM READY 4028 if (mUiccApplcation != null && mUiccApplcation.getState() == AppState.APPSTATE_READY) { 4029 newRs.setCsNormalRestricted( 4030 ((state & RILConstants.RIL_RESTRICTED_STATE_CS_NORMAL) != 0) || 4031 ((state & RILConstants.RIL_RESTRICTED_STATE_CS_ALL) != 0) ); 4032 newRs.setPsRestricted( 4033 (state & RILConstants.RIL_RESTRICTED_STATE_PS_ALL)!= 0); 4034 } 4035 4036 if (DBG) log("onRestrictedStateChanged: new rs "+ newRs); 4037 4038 if (!mRestrictedState.isPsRestricted() && newRs.isPsRestricted()) { 4039 mPsRestrictEnabledRegistrants.notifyRegistrants(); 4040 setNotification(PS_ENABLED); 4041 } else if (mRestrictedState.isPsRestricted() && !newRs.isPsRestricted()) { 4042 mPsRestrictDisabledRegistrants.notifyRegistrants(); 4043 setNotification(PS_DISABLED); 4044 } 4045 4046 /** 4047 * There are two kind of cs restriction, normal and emergency. So 4048 * there are 4 x 4 combinations in current and new restricted states 4049 * and we only need to notify when state is changed. 4050 */ 4051 if (mRestrictedState.isCsRestricted()) { 4052 if (!newRs.isAnyCsRestricted()) { 4053 // remove all restriction 4054 setNotification(CS_DISABLED); 4055 } else if (!newRs.isCsNormalRestricted()) { 4056 // remove normal restriction 4057 setNotification(CS_EMERGENCY_ENABLED); 4058 } else if (!newRs.isCsEmergencyRestricted()) { 4059 // remove emergency restriction 4060 setNotification(CS_NORMAL_ENABLED); 4061 } 4062 } else if (mRestrictedState.isCsEmergencyRestricted() && 4063 !mRestrictedState.isCsNormalRestricted()) { 4064 if (!newRs.isAnyCsRestricted()) { 4065 // remove all restriction 4066 setNotification(CS_DISABLED); 4067 } else if (newRs.isCsRestricted()) { 4068 // enable all restriction 4069 setNotification(CS_ENABLED); 4070 } else if (newRs.isCsNormalRestricted()) { 4071 // remove emergency restriction and enable normal restriction 4072 setNotification(CS_NORMAL_ENABLED); 4073 } 4074 } else if (!mRestrictedState.isCsEmergencyRestricted() && 4075 mRestrictedState.isCsNormalRestricted()) { 4076 if (!newRs.isAnyCsRestricted()) { 4077 // remove all restriction 4078 setNotification(CS_DISABLED); 4079 } else if (newRs.isCsRestricted()) { 4080 // enable all restriction 4081 setNotification(CS_ENABLED); 4082 } else if (newRs.isCsEmergencyRestricted()) { 4083 // remove normal restriction and enable emergency restriction 4084 setNotification(CS_EMERGENCY_ENABLED); 4085 } 4086 } else { 4087 if (newRs.isCsRestricted()) { 4088 // enable all restriction 4089 setNotification(CS_ENABLED); 4090 } else if (newRs.isCsEmergencyRestricted()) { 4091 // enable emergency restriction 4092 setNotification(CS_EMERGENCY_ENABLED); 4093 } else if (newRs.isCsNormalRestricted()) { 4094 // enable normal restriction 4095 setNotification(CS_NORMAL_ENABLED); 4096 } 4097 } 4098 4099 mRestrictedState = newRs; 4100 } 4101 log("onRestrictedStateChanged: X rs "+ mRestrictedState); 4102 } 4103 4104 /** 4105 * Get CellIdentity from the ServiceState if available or guess from cached 4106 * 4107 * Get the CellIdentity by first checking if ServiceState has a current CID. If so 4108 * then return that info. Otherwise, check the latest List<CellInfo> and return the first GSM or 4109 * WCDMA result that appears. If no GSM or WCDMA results, then return an LTE result. The 4110 * behavior is kept consistent for backwards compatibility; (do not apply logic to determine 4111 * why the behavior is this way). 4112 * 4113 * @return the current cell location if known or a non-null "empty" cell location 4114 */ 4115 @NonNull getCellIdentity()4116 public CellIdentity getCellIdentity() { 4117 if (mCellIdentity != null) return mCellIdentity; 4118 4119 CellIdentity ci = getCellIdentityFromCellInfo(getAllCellInfo()); 4120 if (ci != null) return ci; 4121 4122 return mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA 4123 ? new CellIdentityCdma() : new CellIdentityGsm(); 4124 } 4125 4126 /** 4127 * Get CellIdentity from the ServiceState if available or guess from CellInfo 4128 * 4129 * Get the CellLocation by first checking if ServiceState has a current CID. If so 4130 * then return that info. Otherwise, query AllCellInfo and return the first GSM or 4131 * WCDMA result that appears. If no GSM or WCDMA results, then return an LTE result. 4132 * The behavior is kept consistent for backwards compatibility; (do not apply logic 4133 * to determine why the behavior is this way). 4134 * 4135 * @param workSource calling WorkSource 4136 * @param rspMsg the response message which must be non-null 4137 */ requestCellIdentity(WorkSource workSource, Message rspMsg)4138 public void requestCellIdentity(WorkSource workSource, Message rspMsg) { 4139 if (mCellIdentity != null) { 4140 AsyncResult.forMessage(rspMsg, mCellIdentity, null); 4141 rspMsg.sendToTarget(); 4142 return; 4143 } 4144 4145 Message cellLocRsp = obtainMessage(EVENT_CELL_LOCATION_RESPONSE, rspMsg); 4146 requestAllCellInfo(workSource, cellLocRsp); 4147 } 4148 4149 /* Find and return a CellIdentity from CellInfo 4150 * 4151 * This method returns the first GSM or WCDMA result that appears in List<CellInfo>. If no GSM 4152 * or WCDMA results are found, then it returns an LTE result. The behavior is kept consistent 4153 * for backwards compatibility; (do not apply logic to determine why the behavior is this way). 4154 * 4155 * @return the current CellIdentity from CellInfo or null 4156 */ getCellIdentityFromCellInfo(List<CellInfo> info)4157 private static CellIdentity getCellIdentityFromCellInfo(List<CellInfo> info) { 4158 CellIdentity cl = null; 4159 if (info != null && info.size() > 0) { 4160 CellIdentity fallbackLteCid = null; // We prefer not to use LTE 4161 for (CellInfo ci : info) { 4162 CellIdentity c = ci.getCellIdentity(); 4163 if (c instanceof CellIdentityLte && fallbackLteCid == null) { 4164 if (getCidFromCellIdentity(c) != -1) fallbackLteCid = c; 4165 continue; 4166 } 4167 if (getCidFromCellIdentity(c) != -1) { 4168 cl = c; 4169 break; 4170 } 4171 } 4172 if (cl == null && fallbackLteCid != null) { 4173 cl = fallbackLteCid; 4174 } 4175 } 4176 return cl; 4177 } 4178 4179 /** 4180 * nitzReceiveTime is time_t that the NITZ time was posted 4181 */ setTimeFromNITZString(String nitzString, long nitzReceiveTime)4182 private void setTimeFromNITZString(String nitzString, long nitzReceiveTime) { 4183 long start = SystemClock.elapsedRealtime(); 4184 if (DBG) { 4185 Rlog.d(LOG_TAG, "NITZ: " + nitzString + "," + nitzReceiveTime 4186 + " start=" + start + " delay=" + (start - nitzReceiveTime)); 4187 } 4188 NitzData newNitzData = NitzData.parse(nitzString); 4189 mLastNitzData = newNitzData; 4190 if (newNitzData != null) { 4191 try { 4192 TimestampedValue<NitzData> nitzSignal = 4193 new TimestampedValue<>(nitzReceiveTime, newNitzData); 4194 mNitzState.handleNitzReceived(nitzSignal); 4195 } finally { 4196 if (DBG) { 4197 long end = SystemClock.elapsedRealtime(); 4198 Rlog.d(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start)); 4199 } 4200 } 4201 } 4202 } 4203 4204 /** 4205 * Cancels all notifications posted to NotificationManager for this subId. These notifications 4206 * for restricted state and rejection cause for cs registration are no longer valid after the 4207 * SIM has been removed. 4208 */ cancelAllNotifications()4209 private void cancelAllNotifications() { 4210 if (DBG) log("cancelAllNotifications: mPrevSubId=" + mPrevSubId); 4211 NotificationManager notificationManager = (NotificationManager) 4212 mPhone.getContext().getSystemService(Context.NOTIFICATION_SERVICE); 4213 if (SubscriptionManager.isValidSubscriptionId(mPrevSubId)) { 4214 notificationManager.cancel(Integer.toString(mPrevSubId), PS_NOTIFICATION); 4215 notificationManager.cancel(Integer.toString(mPrevSubId), CS_NOTIFICATION); 4216 notificationManager.cancel(Integer.toString(mPrevSubId), CS_REJECT_CAUSE_NOTIFICATION); 4217 4218 // Cancel Emergency call warning and network preference notifications 4219 notificationManager.cancel( 4220 CarrierServiceStateTracker.EMERGENCY_NOTIFICATION_TAG, mPrevSubId); 4221 notificationManager.cancel( 4222 CarrierServiceStateTracker.PREF_NETWORK_NOTIFICATION_TAG, mPrevSubId); 4223 } 4224 } 4225 4226 /** 4227 * Post a notification to NotificationManager for restricted state and 4228 * rejection cause for cs registration 4229 * 4230 * @param notifyType is one state of PS/CS_*_ENABLE/DISABLE 4231 */ 4232 @VisibleForTesting setNotification(int notifyType)4233 public void setNotification(int notifyType) { 4234 if (DBG) log("setNotification: create notification " + notifyType); 4235 4236 if (!SubscriptionManager.isValidSubscriptionId(mSubId)) { 4237 // notifications are posted per-sub-id, so return if current sub-id is invalid 4238 loge("cannot setNotification on invalid subid mSubId=" + mSubId); 4239 return; 4240 } 4241 Context context = mPhone.getContext(); 4242 4243 SubscriptionInfo info = mSubscriptionController 4244 .getActiveSubscriptionInfo(mPhone.getSubId(), context.getOpPackageName(), 4245 context.getAttributionTag()); 4246 4247 //if subscription is part of a group and non-primary, suppress all notifications 4248 if (info == null || (info.isOpportunistic() && info.getGroupUuid() != null)) { 4249 log("cannot setNotification on invisible subid mSubId=" + mSubId); 4250 return; 4251 } 4252 4253 // Needed because sprout RIL sends these when they shouldn't? 4254 boolean isSetNotification = context.getResources().getBoolean( 4255 com.android.internal.R.bool.config_user_notification_of_restrictied_mobile_access); 4256 if (!isSetNotification) { 4257 if (DBG) log("Ignore all the notifications"); 4258 return; 4259 } 4260 4261 boolean autoCancelCsRejectNotification = false; 4262 4263 PersistableBundle bundle = getCarrierConfig(); 4264 boolean disableVoiceBarringNotification = bundle.getBoolean( 4265 CarrierConfigManager.KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false); 4266 if (disableVoiceBarringNotification && (notifyType == CS_ENABLED 4267 || notifyType == CS_NORMAL_ENABLED 4268 || notifyType == CS_EMERGENCY_ENABLED)) { 4269 if (DBG) log("Voice/emergency call barred notification disabled"); 4270 return; 4271 } 4272 autoCancelCsRejectNotification = bundle.getBoolean( 4273 CarrierConfigManager.KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); 4274 4275 CharSequence details = ""; 4276 CharSequence title = ""; 4277 int notificationId = CS_NOTIFICATION; 4278 int icon = com.android.internal.R.drawable.stat_sys_warning; 4279 4280 final boolean multipleSubscriptions = (((TelephonyManager) mPhone.getContext() 4281 .getSystemService(Context.TELEPHONY_SERVICE)).getPhoneCount() > 1); 4282 final int simNumber = mSubscriptionController.getSlotIndex(mSubId) + 1; 4283 4284 switch (notifyType) { 4285 case PS_ENABLED: 4286 long dataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); 4287 if (dataSubId != mPhone.getSubId()) { 4288 return; 4289 } 4290 notificationId = PS_NOTIFICATION; 4291 title = context.getText(com.android.internal.R.string.RestrictedOnDataTitle); 4292 details = multipleSubscriptions 4293 ? context.getString( 4294 com.android.internal.R.string.RestrictedStateContentMsimTemplate, 4295 simNumber) : 4296 context.getText(com.android.internal.R.string.RestrictedStateContent); 4297 break; 4298 case PS_DISABLED: 4299 notificationId = PS_NOTIFICATION; 4300 break; 4301 case CS_ENABLED: 4302 title = context.getText(com.android.internal.R.string.RestrictedOnAllVoiceTitle); 4303 details = multipleSubscriptions 4304 ? context.getString( 4305 com.android.internal.R.string.RestrictedStateContentMsimTemplate, 4306 simNumber) : 4307 context.getText(com.android.internal.R.string.RestrictedStateContent); 4308 break; 4309 case CS_NORMAL_ENABLED: 4310 title = context.getText(com.android.internal.R.string.RestrictedOnNormalTitle); 4311 details = multipleSubscriptions 4312 ? context.getString( 4313 com.android.internal.R.string.RestrictedStateContentMsimTemplate, 4314 simNumber) : 4315 context.getText(com.android.internal.R.string.RestrictedStateContent); 4316 break; 4317 case CS_EMERGENCY_ENABLED: 4318 title = context.getText(com.android.internal.R.string.RestrictedOnEmergencyTitle); 4319 details = multipleSubscriptions 4320 ? context.getString( 4321 com.android.internal.R.string.RestrictedStateContentMsimTemplate, 4322 simNumber) : 4323 context.getText(com.android.internal.R.string.RestrictedStateContent); 4324 break; 4325 case CS_DISABLED: 4326 // do nothing and cancel the notification later 4327 break; 4328 case CS_REJECT_CAUSE_ENABLED: 4329 notificationId = CS_REJECT_CAUSE_NOTIFICATION; 4330 int resId = selectResourceForRejectCode(mRejectCode, multipleSubscriptions); 4331 if (0 == resId) { 4332 if (autoCancelCsRejectNotification) { 4333 notifyType = CS_REJECT_CAUSE_DISABLED; 4334 } else { 4335 loge("setNotification: mRejectCode=" + mRejectCode + " is not handled."); 4336 return; 4337 } 4338 } else { 4339 icon = com.android.internal.R.drawable.stat_notify_mmcc_indication_icn; 4340 // if using the single SIM resource, simNumber will be ignored 4341 title = context.getString(resId, simNumber); 4342 details = null; 4343 } 4344 break; 4345 } 4346 4347 if (DBG) { 4348 log("setNotification, create notification, notifyType: " + notifyType 4349 + ", title: " + title + ", details: " + details + ", subId: " + mSubId); 4350 } 4351 4352 mNotification = new Notification.Builder(context) 4353 .setWhen(System.currentTimeMillis()) 4354 .setAutoCancel(true) 4355 .setSmallIcon(icon) 4356 .setTicker(title) 4357 .setColor(context.getResources().getColor( 4358 com.android.internal.R.color.system_notification_accent_color)) 4359 .setContentTitle(title) 4360 .setStyle(new Notification.BigTextStyle().bigText(details)) 4361 .setContentText(details) 4362 .setChannelId(NotificationChannelController.CHANNEL_ID_ALERT) 4363 .build(); 4364 4365 NotificationManager notificationManager = (NotificationManager) 4366 context.getSystemService(Context.NOTIFICATION_SERVICE); 4367 4368 if (notifyType == PS_DISABLED || notifyType == CS_DISABLED 4369 || notifyType == CS_REJECT_CAUSE_DISABLED) { 4370 // cancel previous post notification 4371 notificationManager.cancel(Integer.toString(mSubId), notificationId); 4372 } else { 4373 boolean show = false; 4374 if (mSS.isEmergencyOnly() && notifyType == CS_EMERGENCY_ENABLED) { 4375 // if reg state is emergency only, always show restricted emergency notification. 4376 show = true; 4377 } else if (notifyType == CS_REJECT_CAUSE_ENABLED) { 4378 // always show notification due to CS reject irrespective of service state. 4379 show = true; 4380 } else if (mSS.getState() == ServiceState.STATE_IN_SERVICE) { 4381 // for non in service states, we have system UI and signal bar to indicate limited 4382 // service. No need to show notification again. This also helps to mitigate the 4383 // issue if phone go to OOS and camp to other networks and received restricted ind. 4384 show = true; 4385 } 4386 // update restricted state notification for this subId 4387 if (show) { 4388 notificationManager.notify(Integer.toString(mSubId), notificationId, mNotification); 4389 } 4390 } 4391 } 4392 4393 /** 4394 * Selects the resource ID, which depends on rejection cause that is sent by the network when CS 4395 * registration is rejected. 4396 * 4397 * @param rejCode should be compatible with TS 24.008. 4398 */ selectResourceForRejectCode(int rejCode, boolean multipleSubscriptions)4399 private int selectResourceForRejectCode(int rejCode, boolean multipleSubscriptions) { 4400 int rejResourceId = 0; 4401 switch (rejCode) { 4402 case 1:// Authentication reject 4403 rejResourceId = multipleSubscriptions 4404 ? com.android.internal.R.string.mmcc_authentication_reject_msim_template : 4405 com.android.internal.R.string.mmcc_authentication_reject; 4406 break; 4407 case 2:// IMSI unknown in HLR 4408 rejResourceId = multipleSubscriptions 4409 ? com.android.internal.R.string.mmcc_imsi_unknown_in_hlr_msim_template : 4410 com.android.internal.R.string.mmcc_imsi_unknown_in_hlr; 4411 break; 4412 case 3:// Illegal MS 4413 rejResourceId = multipleSubscriptions 4414 ? com.android.internal.R.string.mmcc_illegal_ms_msim_template : 4415 com.android.internal.R.string.mmcc_illegal_ms; 4416 break; 4417 case 6:// Illegal ME 4418 rejResourceId = multipleSubscriptions 4419 ? com.android.internal.R.string.mmcc_illegal_me_msim_template : 4420 com.android.internal.R.string.mmcc_illegal_me; 4421 break; 4422 default: 4423 // The other codes are not defined or not required by operators till now. 4424 break; 4425 } 4426 return rejResourceId; 4427 } 4428 getUiccCardApplication()4429 private UiccCardApplication getUiccCardApplication() { 4430 if (mPhone.isPhoneTypeGsm()) { 4431 return mUiccController.getUiccCardApplication(mPhone.getPhoneId(), 4432 UiccController.APP_FAM_3GPP); 4433 } else { 4434 return mUiccController.getUiccCardApplication(mPhone.getPhoneId(), 4435 UiccController.APP_FAM_3GPP2); 4436 } 4437 } 4438 queueNextSignalStrengthPoll()4439 private void queueNextSignalStrengthPoll() { 4440 if (mDontPollSignalStrength) { 4441 // The radio is telling us about signal strength changes 4442 // we don't have to ask it 4443 return; 4444 } 4445 4446 // if there is no SIM present, do not poll signal strength 4447 UiccCard uiccCard = UiccController.getInstance().getUiccCard(getPhoneId()); 4448 if (uiccCard == null || uiccCard.getCardState() == CardState.CARDSTATE_ABSENT) { 4449 log("Not polling signal strength due to absence of SIM"); 4450 return; 4451 } 4452 4453 Message msg; 4454 4455 msg = obtainMessage(); 4456 msg.what = EVENT_POLL_SIGNAL_STRENGTH; 4457 4458 long nextTime; 4459 4460 // TODO Don't poll signal strength if screen is off 4461 sendMessageDelayed(msg, POLL_PERIOD_MILLIS); 4462 } 4463 notifyCdmaSubscriptionInfoReady()4464 private void notifyCdmaSubscriptionInfoReady() { 4465 if (mCdmaForSubscriptionInfoReadyRegistrants != null) { 4466 if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()"); 4467 mCdmaForSubscriptionInfoReadyRegistrants.notifyRegistrants(); 4468 } 4469 } 4470 4471 /** 4472 * Registration point for transition into DataConnection attached. 4473 * @param transport Transport type 4474 * @param h handler to notify 4475 * @param what what code of message when delivered 4476 * @param obj placed in Message.obj 4477 */ registerForDataConnectionAttached(@ransportType int transport, Handler h, int what, Object obj)4478 public void registerForDataConnectionAttached(@TransportType int transport, Handler h, int what, 4479 Object obj) { 4480 Registrant r = new Registrant(h, what, obj); 4481 if (mAttachedRegistrants.get(transport) == null) { 4482 mAttachedRegistrants.put(transport, new RegistrantList()); 4483 } 4484 mAttachedRegistrants.get(transport).add(r); 4485 4486 if (mSS != null) { 4487 NetworkRegistrationInfo netRegState = mSS.getNetworkRegistrationInfo( 4488 NetworkRegistrationInfo.DOMAIN_PS, transport); 4489 if (netRegState == null || netRegState.isInService()) { 4490 r.notifyRegistrant(); 4491 } 4492 } 4493 } 4494 4495 /** 4496 * Unregister for data attached event 4497 * 4498 * @param transport Transport type 4499 * @param h Handler to notify 4500 */ unregisterForDataConnectionAttached(@ransportType int transport, Handler h)4501 public void unregisterForDataConnectionAttached(@TransportType int transport, Handler h) { 4502 if (mAttachedRegistrants.get(transport) != null) { 4503 mAttachedRegistrants.get(transport).remove(h); 4504 } 4505 } 4506 4507 /** 4508 * Registration point for transition into DataConnection detached. 4509 * @param transport Transport type 4510 * @param h handler to notify 4511 * @param what what code of message when delivered 4512 * @param obj placed in Message.obj 4513 */ registerForDataConnectionDetached(@ransportType int transport, Handler h, int what, Object obj)4514 public void registerForDataConnectionDetached(@TransportType int transport, Handler h, int what, 4515 Object obj) { 4516 Registrant r = new Registrant(h, what, obj); 4517 if (mDetachedRegistrants.get(transport) == null) { 4518 mDetachedRegistrants.put(transport, new RegistrantList()); 4519 } 4520 mDetachedRegistrants.get(transport).add(r); 4521 4522 if (mSS != null) { 4523 NetworkRegistrationInfo netRegState = mSS.getNetworkRegistrationInfo( 4524 NetworkRegistrationInfo.DOMAIN_PS, transport); 4525 if (netRegState != null && !netRegState.isInService()) { 4526 r.notifyRegistrant(); 4527 } 4528 } 4529 } 4530 4531 /** 4532 * Unregister for data detatched event 4533 * 4534 * @param transport Transport type 4535 * @param h Handler to notify 4536 */ unregisterForDataConnectionDetached(@ransportType int transport, Handler h)4537 public void unregisterForDataConnectionDetached(@TransportType int transport, Handler h) { 4538 if (mDetachedRegistrants.get(transport) != null) { 4539 mDetachedRegistrants.get(transport).remove(h); 4540 } 4541 } 4542 4543 /** 4544 * Registration for RIL Voice Radio Technology changing. The 4545 * new radio technology will be returned AsyncResult#result as an Integer Object. 4546 * The AsyncResult will be in the notification Message#obj. 4547 * 4548 * @param h handler to notify 4549 * @param what what code of message when delivered 4550 * @param obj placed in Message.obj 4551 */ registerForVoiceRegStateOrRatChanged(Handler h, int what, Object obj)4552 public void registerForVoiceRegStateOrRatChanged(Handler h, int what, Object obj) { 4553 Registrant r = new Registrant(h, what, obj); 4554 mVoiceRegStateOrRatChangedRegistrants.add(r); 4555 notifyVoiceRegStateRilRadioTechnologyChanged(); 4556 } 4557 unregisterForVoiceRegStateOrRatChanged(Handler h)4558 public void unregisterForVoiceRegStateOrRatChanged(Handler h) { 4559 mVoiceRegStateOrRatChangedRegistrants.remove(h); 4560 } 4561 4562 /** 4563 * Registration for DataConnection RIL Data Radio Technology changing. The 4564 * new radio technology will be returned AsyncResult#result as an Integer Object. 4565 * The AsyncResult will be in the notification Message#obj. 4566 * 4567 * @param transport Transport 4568 * @param h handler to notify 4569 * @param what what code of message when delivered 4570 * @param obj placed in Message.obj 4571 */ registerForDataRegStateOrRatChanged(@ransportType int transport, Handler h, int what, Object obj)4572 public void registerForDataRegStateOrRatChanged(@TransportType int transport, Handler h, 4573 int what, Object obj) { 4574 Registrant r = new Registrant(h, what, obj); 4575 if (mDataRegStateOrRatChangedRegistrants.get(transport) == null) { 4576 mDataRegStateOrRatChangedRegistrants.put(transport, new RegistrantList()); 4577 } 4578 mDataRegStateOrRatChangedRegistrants.get(transport).add(r); 4579 Pair<Integer, Integer> registrationInfo = getRegistrationInfo(transport); 4580 if (registrationInfo != null) { 4581 r.notifyResult(registrationInfo); 4582 } 4583 } 4584 4585 /** 4586 * Unregister for data registration state changed or RAT changed event 4587 * 4588 * @param transport Transport 4589 * @param h The handler 4590 */ unregisterForDataRegStateOrRatChanged(@ransportType int transport, Handler h)4591 public void unregisterForDataRegStateOrRatChanged(@TransportType int transport, Handler h) { 4592 if (mDataRegStateOrRatChangedRegistrants.get(transport) != null) { 4593 mDataRegStateOrRatChangedRegistrants.get(transport).remove(h); 4594 } 4595 } 4596 4597 /** 4598 * Registration point for transition into network attached. 4599 * @param h handler to notify 4600 * @param what what code of message when delivered 4601 * @param obj in Message.obj 4602 */ registerForNetworkAttached(Handler h, int what, Object obj)4603 public void registerForNetworkAttached(Handler h, int what, Object obj) { 4604 Registrant r = new Registrant(h, what, obj); 4605 4606 mNetworkAttachedRegistrants.add(r); 4607 if (mSS.getState() == ServiceState.STATE_IN_SERVICE) { 4608 r.notifyRegistrant(); 4609 } 4610 } 4611 unregisterForNetworkAttached(Handler h)4612 public void unregisterForNetworkAttached(Handler h) { 4613 mNetworkAttachedRegistrants.remove(h); 4614 } 4615 4616 /** 4617 * Registration point for transition into network detached. 4618 * @param h handler to notify 4619 * @param what what code of message when delivered 4620 * @param obj in Message.obj 4621 */ registerForNetworkDetached(Handler h, int what, Object obj)4622 public void registerForNetworkDetached(Handler h, int what, Object obj) { 4623 Registrant r = new Registrant(h, what, obj); 4624 4625 mNetworkDetachedRegistrants.add(r); 4626 if (mSS.getState() != ServiceState.STATE_IN_SERVICE) { 4627 r.notifyRegistrant(); 4628 } 4629 } 4630 unregisterForNetworkDetached(Handler h)4631 public void unregisterForNetworkDetached(Handler h) { 4632 mNetworkDetachedRegistrants.remove(h); 4633 } 4634 4635 /** 4636 * Registration point for transition into packet service restricted zone. 4637 * @param h handler to notify 4638 * @param what what code of message when delivered 4639 * @param obj placed in Message.obj 4640 */ registerForPsRestrictedEnabled(Handler h, int what, Object obj)4641 public void registerForPsRestrictedEnabled(Handler h, int what, Object obj) { 4642 Registrant r = new Registrant(h, what, obj); 4643 mPsRestrictEnabledRegistrants.add(r); 4644 4645 if (mRestrictedState.isPsRestricted()) { 4646 r.notifyRegistrant(); 4647 } 4648 } 4649 unregisterForPsRestrictedEnabled(Handler h)4650 public void unregisterForPsRestrictedEnabled(Handler h) { 4651 mPsRestrictEnabledRegistrants.remove(h); 4652 } 4653 4654 /** 4655 * Registration point for transition out of packet service restricted zone. 4656 * @param h handler to notify 4657 * @param what what code of message when delivered 4658 * @param obj placed in Message.obj 4659 */ registerForPsRestrictedDisabled(Handler h, int what, Object obj)4660 public void registerForPsRestrictedDisabled(Handler h, int what, Object obj) { 4661 Registrant r = new Registrant(h, what, obj); 4662 mPsRestrictDisabledRegistrants.add(r); 4663 4664 if (mRestrictedState.isPsRestricted()) { 4665 r.notifyRegistrant(); 4666 } 4667 } 4668 unregisterForPsRestrictedDisabled(Handler h)4669 public void unregisterForPsRestrictedDisabled(Handler h) { 4670 mPsRestrictDisabledRegistrants.remove(h); 4671 } 4672 4673 /** 4674 * Registers for IMS capability changed. 4675 * @param h handler to notify 4676 * @param what what code of message when delivered 4677 * @param obj placed in Message.obj 4678 */ registerForImsCapabilityChanged(Handler h, int what, Object obj)4679 public void registerForImsCapabilityChanged(Handler h, int what, Object obj) { 4680 Registrant r = new Registrant(h, what, obj); 4681 mImsCapabilityChangedRegistrants.add(r); 4682 } 4683 4684 /** 4685 * Unregisters for IMS capability changed. 4686 * @param h handler to notify 4687 */ unregisterForImsCapabilityChanged(Handler h)4688 public void unregisterForImsCapabilityChanged(Handler h) { 4689 mImsCapabilityChangedRegistrants.remove(h); 4690 } 4691 4692 /** 4693 * Clean up existing voice and data connection then turn off radio power. 4694 * 4695 * Hang up the existing voice calls to decrease call drop rate. 4696 */ powerOffRadioSafely()4697 public void powerOffRadioSafely() { 4698 synchronized (this) { 4699 if (!mPendingRadioPowerOffAfterDataOff) { 4700 int dds = SubscriptionManager.getDefaultDataSubscriptionId(); 4701 // To minimize race conditions we call cleanUpAllConnections on 4702 // both if else paths instead of before this isDisconnected test. 4703 if (mPhone.areAllDataDisconnected() 4704 && (dds == mPhone.getSubId() 4705 || (dds != mPhone.getSubId() 4706 && ProxyController.getInstance().areAllDataDisconnected(dds)))) { 4707 // To minimize race conditions we do this after isDisconnected 4708 for (int transport : mTransportManager.getAvailableTransports()) { 4709 if (mPhone.getDcTracker(transport) != null) { 4710 mPhone.getDcTracker(transport).cleanUpAllConnections( 4711 Phone.REASON_RADIO_TURNED_OFF); 4712 } 4713 } 4714 if (DBG) log("Data disconnected, turn off radio right away."); 4715 hangupAndPowerOff(); 4716 } else { 4717 // hang up all active voice calls first 4718 if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) { 4719 mPhone.mCT.mRingingCall.hangupIfAlive(); 4720 mPhone.mCT.mBackgroundCall.hangupIfAlive(); 4721 mPhone.mCT.mForegroundCall.hangupIfAlive(); 4722 } 4723 for (int transport : mTransportManager.getAvailableTransports()) { 4724 if (mPhone.getDcTracker(transport) != null) { 4725 mPhone.getDcTracker(transport).cleanUpAllConnections( 4726 Phone.REASON_RADIO_TURNED_OFF); 4727 } 4728 } 4729 4730 if (dds != mPhone.getSubId() 4731 && !ProxyController.getInstance().areAllDataDisconnected(dds)) { 4732 if (DBG) log("Data is active on DDS. Wait for all data disconnect"); 4733 // Data is not disconnected on DDS. Wait for the data disconnect complete 4734 // before sending the RADIO_POWER off. 4735 ProxyController.getInstance().registerForAllDataDisconnected(dds, this, 4736 EVENT_ALL_DATA_DISCONNECTED); 4737 mPendingRadioPowerOffAfterDataOff = true; 4738 } 4739 Message msg = Message.obtain(this); 4740 msg.what = EVENT_SET_RADIO_POWER_OFF; 4741 msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag; 4742 if (sendMessageDelayed(msg, 30000)) { 4743 if (DBG) log("Wait upto 30s for data to disconnect, then turn off radio."); 4744 mPendingRadioPowerOffAfterDataOff = true; 4745 } else { 4746 log("Cannot send delayed Msg, turn off radio right away."); 4747 hangupAndPowerOff(); 4748 mPendingRadioPowerOffAfterDataOff = false; 4749 } 4750 } 4751 } 4752 } 4753 } 4754 4755 /** 4756 * process the pending request to turn radio off after data is disconnected 4757 * 4758 * return true if there is pending request to process; false otherwise. 4759 */ processPendingRadioPowerOffAfterDataOff()4760 public boolean processPendingRadioPowerOffAfterDataOff() { 4761 synchronized(this) { 4762 if (mPendingRadioPowerOffAfterDataOff) { 4763 if (DBG) log("Process pending request to turn radio off."); 4764 mPendingRadioPowerOffAfterDataOffTag += 1; 4765 hangupAndPowerOff(); 4766 mPendingRadioPowerOffAfterDataOff = false; 4767 return true; 4768 } 4769 return false; 4770 } 4771 } 4772 4773 /** 4774 * Checks if the provided earfcn falls withing the range of earfcns. 4775 * 4776 * return true if earfcn falls within the provided range; false otherwise. 4777 */ containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList, int earfcn)4778 private boolean containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList, 4779 int earfcn) { 4780 if (earfcnPairList != null) { 4781 for (Pair<Integer, Integer> earfcnPair : earfcnPairList) { 4782 if ((earfcn >= earfcnPair.first) && (earfcn <= earfcnPair.second)) { 4783 return true; 4784 } 4785 } 4786 } 4787 4788 return false; 4789 } 4790 4791 /** 4792 * Convert the earfcnStringArray to list of pairs. 4793 * 4794 * Format of the earfcnsList is expected to be {"erafcn1_start-earfcn1_end", 4795 * "earfcn2_start-earfcn2_end" ... } 4796 */ convertEarfcnStringArrayToPairList(String[] earfcnsList)4797 ArrayList<Pair<Integer, Integer>> convertEarfcnStringArrayToPairList(String[] earfcnsList) { 4798 ArrayList<Pair<Integer, Integer>> earfcnPairList = new ArrayList<Pair<Integer, Integer>>(); 4799 4800 if (earfcnsList != null) { 4801 int earfcnStart; 4802 int earfcnEnd; 4803 for (int i = 0; i < earfcnsList.length; i++) { 4804 try { 4805 String[] earfcns = earfcnsList[i].split("-"); 4806 if (earfcns.length != 2) { 4807 if (VDBG) { 4808 log("Invalid earfcn range format"); 4809 } 4810 return null; 4811 } 4812 4813 earfcnStart = Integer.parseInt(earfcns[0]); 4814 earfcnEnd = Integer.parseInt(earfcns[1]); 4815 4816 if (earfcnStart > earfcnEnd) { 4817 if (VDBG) { 4818 log("Invalid earfcn range format"); 4819 } 4820 return null; 4821 } 4822 4823 earfcnPairList.add(new Pair<Integer, Integer>(earfcnStart, earfcnEnd)); 4824 } catch (PatternSyntaxException pse) { 4825 if (VDBG) { 4826 log("Invalid earfcn range format"); 4827 } 4828 return null; 4829 } catch (NumberFormatException nfe) { 4830 if (VDBG) { 4831 log("Invalid earfcn number format"); 4832 } 4833 return null; 4834 } 4835 } 4836 } 4837 4838 return earfcnPairList; 4839 } 4840 onCarrierConfigChanged()4841 private void onCarrierConfigChanged() { 4842 PersistableBundle config = getCarrierConfig(); 4843 log("CarrierConfigChange " + config); 4844 4845 // Load the ERI based on carrier config. Carrier might have their specific ERI. 4846 mEriManager.loadEriFile(); 4847 mCdnr.updateEfForEri(getOperatorNameFromEri()); 4848 4849 updateLteEarfcnLists(config); 4850 updateReportingCriteria(config); 4851 updateOperatorNamePattern(config); 4852 mCdnr.updateEfFromCarrierConfig(config); 4853 4854 // Sometimes the network registration information comes before carrier config is ready. 4855 // For some cases like roaming/non-roaming overriding, we need carrier config. So it's 4856 // important to poll state again when carrier config is ready. 4857 pollStateInternal(false); 4858 } 4859 updateLteEarfcnLists(PersistableBundle config)4860 private void updateLteEarfcnLists(PersistableBundle config) { 4861 synchronized (mLteRsrpBoostLock) { 4862 mLteRsrpBoost = config.getInt(CarrierConfigManager.KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0); 4863 String[] earfcnsStringArrayForRsrpBoost = config.getStringArray( 4864 CarrierConfigManager.KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY); 4865 mEarfcnPairListForRsrpBoost = convertEarfcnStringArrayToPairList( 4866 earfcnsStringArrayForRsrpBoost); 4867 } 4868 } 4869 updateReportingCriteria(PersistableBundle config)4870 private void updateReportingCriteria(PersistableBundle config) { 4871 int lteMeasurementEnabled = config.getInt(CarrierConfigManager 4872 .KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT, CellSignalStrengthLte.USE_RSRP); 4873 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSRP, 4874 config.getIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY), 4875 AccessNetworkType.EUTRAN, 4876 (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRP) != 0); 4877 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSCP, 4878 config.getIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY), 4879 AccessNetworkType.UTRAN, true); 4880 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSI, 4881 config.getIntArray(CarrierConfigManager.KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY), 4882 AccessNetworkType.GERAN, true); 4883 4884 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) { 4885 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSRQ, 4886 config.getIntArray(CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY), 4887 AccessNetworkType.EUTRAN, 4888 (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRQ) != 0); 4889 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_RSSNR, 4890 config.getIntArray(CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY), 4891 AccessNetworkType.EUTRAN, 4892 (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSSNR) != 0); 4893 4894 int measurementEnabled = config.getInt(CarrierConfigManager 4895 .KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, CellSignalStrengthNr.USE_SSRSRP); 4896 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSRSRP, 4897 config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY), 4898 AccessNetworkType.NGRAN, 4899 (measurementEnabled & CellSignalStrengthNr.USE_SSRSRP) != 0); 4900 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSRSRQ, 4901 config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY), 4902 AccessNetworkType.NGRAN, 4903 (measurementEnabled & CellSignalStrengthNr.USE_SSRSRQ) != 0); 4904 mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_SSSINR, 4905 config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY), 4906 AccessNetworkType.NGRAN, 4907 (measurementEnabled & CellSignalStrengthNr.USE_SSSINR) != 0); 4908 } 4909 } 4910 updateServiceStateLteEarfcnBoost(ServiceState serviceState, int lteEarfcn)4911 private void updateServiceStateLteEarfcnBoost(ServiceState serviceState, int lteEarfcn) { 4912 synchronized (mLteRsrpBoostLock) { 4913 if ((lteEarfcn != INVALID_LTE_EARFCN) 4914 && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost, lteEarfcn)) { 4915 serviceState.setLteEarfcnRsrpBoost(mLteRsrpBoost); 4916 } else { 4917 serviceState.setLteEarfcnRsrpBoost(0); 4918 } 4919 } 4920 } 4921 4922 /** 4923 * send signal-strength-changed notification if changed Called both for 4924 * solicited and unsolicited signal strength updates 4925 * 4926 * @return true if the signal strength changed and a notification was sent. 4927 */ onSignalStrengthResult(AsyncResult ar)4928 protected boolean onSignalStrengthResult(AsyncResult ar) { 4929 4930 // This signal is used for both voice and data radio signal so parse 4931 // all fields 4932 4933 if ((ar.exception == null) && (ar.result != null)) { 4934 mSignalStrength = (SignalStrength) ar.result; 4935 4936 PersistableBundle config = getCarrierConfig(); 4937 mSignalStrength.updateLevel(config, mSS); 4938 } else { 4939 log("onSignalStrengthResult() Exception from RIL : " + ar.exception); 4940 mSignalStrength = new SignalStrength(); 4941 } 4942 mSignalStrengthUpdatedTime = System.currentTimeMillis(); 4943 4944 boolean ssChanged = notifySignalStrength(); 4945 4946 return ssChanged; 4947 } 4948 4949 /** 4950 * Hang up all voice call and turn off radio. Implemented by derived class. 4951 */ hangupAndPowerOff()4952 protected void hangupAndPowerOff() { 4953 // hang up all active voice calls 4954 if (!mPhone.isPhoneTypeGsm() || mPhone.isInCall()) { 4955 mPhone.mCT.mRingingCall.hangupIfAlive(); 4956 mPhone.mCT.mBackgroundCall.hangupIfAlive(); 4957 mPhone.mCT.mForegroundCall.hangupIfAlive(); 4958 } 4959 4960 mCi.setRadioPower(false, obtainMessage(EVENT_RADIO_POWER_OFF_DONE)); 4961 4962 } 4963 4964 /** Cancel a pending (if any) pollState() operation */ cancelPollState()4965 protected void cancelPollState() { 4966 // This will effectively cancel the rest of the poll requests. 4967 mPollingContext = new int[1]; 4968 } 4969 4970 /** 4971 * Return true if the network operator's country code changed. 4972 */ networkCountryIsoChanged(String newCountryIsoCode, String prevCountryIsoCode)4973 private boolean networkCountryIsoChanged(String newCountryIsoCode, String prevCountryIsoCode) { 4974 // Return false if the new ISO code isn't valid as we don't know where we are. 4975 // Return true if the previous ISO code wasn't valid, or if it was and the new one differs. 4976 4977 // If newCountryIsoCode is invalid then we'll return false 4978 if (TextUtils.isEmpty(newCountryIsoCode)) { 4979 if (DBG) { 4980 log("countryIsoChanged: no new country ISO code"); 4981 } 4982 return false; 4983 } 4984 4985 if (TextUtils.isEmpty(prevCountryIsoCode)) { 4986 if (DBG) { 4987 log("countryIsoChanged: no previous country ISO code"); 4988 } 4989 return true; 4990 } 4991 return !newCountryIsoCode.equals(prevCountryIsoCode); 4992 } 4993 4994 // Determine if the Icc card exists iccCardExists()4995 private boolean iccCardExists() { 4996 boolean iccCardExist = false; 4997 if (mUiccApplcation != null) { 4998 iccCardExist = mUiccApplcation.getState() != AppState.APPSTATE_UNKNOWN; 4999 } 5000 return iccCardExist; 5001 } 5002 5003 @UnsupportedAppUsage getSystemProperty(String property, String defValue)5004 public String getSystemProperty(String property, String defValue) { 5005 return TelephonyManager.getTelephonyProperty(mPhone.getPhoneId(), property, defValue); 5006 } 5007 getAllCellInfo()5008 public List<CellInfo> getAllCellInfo() { 5009 return mLastCellInfoList; 5010 } 5011 5012 /** Set the minimum time between CellInfo requests to the modem, in milliseconds */ setCellInfoMinInterval(int interval)5013 public void setCellInfoMinInterval(int interval) { 5014 mCellInfoMinIntervalMs = interval; 5015 } 5016 5017 /** 5018 * Request the latest CellInfo from the modem. 5019 * 5020 * If sufficient time has elapsed, then this request will be sent to the modem. Otherwise 5021 * the latest cached List<CellInfo> will be returned. 5022 * 5023 * @param workSource of the caller for power accounting 5024 * @param rspMsg an optional response message to get the response to the CellInfo request. If 5025 * the rspMsg is not provided, then CellInfo will still be requested from the modem and 5026 * cached locally for future lookup. 5027 */ requestAllCellInfo(WorkSource workSource, Message rspMsg)5028 public void requestAllCellInfo(WorkSource workSource, Message rspMsg) { 5029 if (VDBG) log("SST.requestAllCellInfo(): E"); 5030 if (mCi.getRilVersion() < 8) { 5031 AsyncResult.forMessage(rspMsg); 5032 rspMsg.sendToTarget(); 5033 if (DBG) log("SST.requestAllCellInfo(): not implemented"); 5034 return; 5035 } 5036 synchronized (mPendingCellInfoRequests) { 5037 // If there are pending requests, then we already have a request active, so add this 5038 // request to the response queue without initiating a new request. 5039 if (mIsPendingCellInfoRequest) { 5040 if (rspMsg != null) mPendingCellInfoRequests.add(rspMsg); 5041 return; 5042 } 5043 // Check to see whether the elapsed time is sufficient for a new request; if not, then 5044 // return the result of the last request (if expected). 5045 final long curTime = SystemClock.elapsedRealtime(); 5046 if ((curTime - mLastCellInfoReqTime) < mCellInfoMinIntervalMs) { 5047 if (rspMsg != null) { 5048 if (DBG) log("SST.requestAllCellInfo(): return last, back to back calls"); 5049 AsyncResult.forMessage(rspMsg, mLastCellInfoList, null); 5050 rspMsg.sendToTarget(); 5051 } 5052 return; 5053 } 5054 // If this request needs an explicit response (it's a synchronous request), then queue 5055 // the response message. 5056 if (rspMsg != null) mPendingCellInfoRequests.add(rspMsg); 5057 // Update the timeout window so that we don't delay based on slow responses 5058 mLastCellInfoReqTime = curTime; 5059 // Set a flag to remember that we have a pending cell info request 5060 mIsPendingCellInfoRequest = true; 5061 // Send a cell info request and also chase it with a timeout message 5062 Message msg = obtainMessage(EVENT_GET_CELL_INFO_LIST); 5063 mCi.getCellInfoList(msg, workSource); 5064 // This message will arrive TIMEOUT ms later and ensure that we don't wait forever for 5065 // a CELL_INFO response. 5066 sendMessageDelayed( 5067 obtainMessage(EVENT_GET_CELL_INFO_LIST), CELL_INFO_LIST_QUERY_TIMEOUT); 5068 } 5069 } 5070 5071 /** 5072 * @return signal strength 5073 */ getSignalStrength()5074 public SignalStrength getSignalStrength() { 5075 if (shouldRefreshSignalStrength()) { 5076 log("SST.getSignalStrength() refreshing signal strength."); 5077 obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget(); 5078 } 5079 return mSignalStrength; 5080 } 5081 shouldRefreshSignalStrength()5082 private boolean shouldRefreshSignalStrength() { 5083 long curTime = System.currentTimeMillis(); 5084 5085 // If last signal strength is older than 10 seconds, or somehow if curTime is smaller 5086 // than mSignalStrengthUpdatedTime (system time update), it's considered stale. 5087 boolean isStale = (mSignalStrengthUpdatedTime > curTime) 5088 || (curTime - mSignalStrengthUpdatedTime > SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS); 5089 if (!isStale) return false; 5090 5091 List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance() 5092 .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(), 5093 mPhone.getContext().getAttributionTag()); 5094 5095 if (!ArrayUtils.isEmpty(subInfoList)) { 5096 for (SubscriptionInfo info : subInfoList) { 5097 // If we have an active opportunistic subscription whose data is IN_SERVICE, 5098 // we need to get signal strength to decide data switching threshold. In this case, 5099 // we poll latest signal strength from modem. 5100 if (info.isOpportunistic()) { 5101 TelephonyManager tm = TelephonyManager.from(mPhone.getContext()) 5102 .createForSubscriptionId(info.getSubscriptionId()); 5103 ServiceState ss = tm.getServiceState(); 5104 if (ss != null 5105 && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) { 5106 return true; 5107 } 5108 } 5109 } 5110 } 5111 5112 return false; 5113 } 5114 5115 /** 5116 * Registration point for subscription info ready 5117 * @param h handler to notify 5118 * @param what what code of message when delivered 5119 * @param obj placed in Message.obj 5120 */ registerForSubscriptionInfoReady(Handler h, int what, Object obj)5121 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 5122 Registrant r = new Registrant(h, what, obj); 5123 mCdmaForSubscriptionInfoReadyRegistrants.add(r); 5124 5125 if (isMinInfoReady()) { 5126 r.notifyRegistrant(); 5127 } 5128 } 5129 unregisterForSubscriptionInfoReady(Handler h)5130 public void unregisterForSubscriptionInfoReady(Handler h) { 5131 mCdmaForSubscriptionInfoReadyRegistrants.remove(h); 5132 } 5133 5134 /** 5135 * Save current source of cdma subscription 5136 * @param source - 1 for NV, 0 for RUIM 5137 */ saveCdmaSubscriptionSource(int source)5138 private void saveCdmaSubscriptionSource(int source) { 5139 log("Storing cdma subscription source: " + source); 5140 Settings.Global.putInt(mPhone.getContext().getContentResolver(), 5141 Settings.Global.CDMA_SUBSCRIPTION_MODE, 5142 source); 5143 log("Read from settings: " + Settings.Global.getInt(mPhone.getContext().getContentResolver(), 5144 Settings.Global.CDMA_SUBSCRIPTION_MODE, -1)); 5145 } 5146 getSubscriptionInfoAndStartPollingThreads()5147 private void getSubscriptionInfoAndStartPollingThreads() { 5148 mCi.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION)); 5149 5150 // Get Registration Information 5151 pollStateInternal(false); 5152 } 5153 handleCdmaSubscriptionSource(int newSubscriptionSource)5154 private void handleCdmaSubscriptionSource(int newSubscriptionSource) { 5155 log("Subscription Source : " + newSubscriptionSource); 5156 mIsSubscriptionFromRuim = 5157 (newSubscriptionSource == CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM); 5158 log("isFromRuim: " + mIsSubscriptionFromRuim); 5159 saveCdmaSubscriptionSource(newSubscriptionSource); 5160 if (!mIsSubscriptionFromRuim) { 5161 // NV is ready when subscription source is NV 5162 sendMessage(obtainMessage(EVENT_NV_READY)); 5163 } 5164 } 5165 dumpEarfcnPairList(PrintWriter pw)5166 private void dumpEarfcnPairList(PrintWriter pw) { 5167 pw.print(" mEarfcnPairListForRsrpBoost={"); 5168 if (mEarfcnPairListForRsrpBoost != null) { 5169 int i = mEarfcnPairListForRsrpBoost.size(); 5170 for (Pair<Integer, Integer> earfcnPair : mEarfcnPairListForRsrpBoost) { 5171 pw.print("("); 5172 pw.print(earfcnPair.first); 5173 pw.print(","); 5174 pw.print(earfcnPair.second); 5175 pw.print(")"); 5176 if ((--i) != 0) { 5177 pw.print(","); 5178 } 5179 } 5180 } 5181 pw.println("}"); 5182 } 5183 dumpCellInfoList(PrintWriter pw)5184 private void dumpCellInfoList(PrintWriter pw) { 5185 pw.print(" mLastCellInfoList={"); 5186 if(mLastCellInfoList != null) { 5187 boolean first = true; 5188 for(CellInfo info : mLastCellInfoList) { 5189 if(first == false) { 5190 pw.print(","); 5191 } 5192 first = false; 5193 pw.print(info.toString()); 5194 } 5195 } 5196 pw.println("}"); 5197 } 5198 dump(FileDescriptor fd, PrintWriter pw, String[] args)5199 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 5200 pw.println("ServiceStateTracker:"); 5201 pw.println(" mSubId=" + mSubId); 5202 pw.println(" mSS=" + mSS); 5203 pw.println(" mNewSS=" + mNewSS); 5204 pw.println(" mVoiceCapable=" + mVoiceCapable); 5205 pw.println(" mRestrictedState=" + mRestrictedState); 5206 pw.println(" mPollingContext=" + mPollingContext + " - " + 5207 (mPollingContext != null ? mPollingContext[0] : "")); 5208 pw.println(" mDesiredPowerState=" + mDesiredPowerState); 5209 pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength); 5210 pw.println(" mSignalStrength=" + mSignalStrength); 5211 pw.println(" mLastSignalStrength=" + mLastSignalStrength); 5212 pw.println(" mRestrictedState=" + mRestrictedState); 5213 pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff); 5214 pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag); 5215 pw.println(" mCellIdentity=" + Rlog.pii(VDBG, mCellIdentity)); 5216 pw.println(" mLastCellInfoReqTime=" + mLastCellInfoReqTime); 5217 dumpCellInfoList(pw); 5218 pw.flush(); 5219 pw.println(" mPreferredNetworkType=" + mPreferredNetworkType); 5220 pw.println(" mMaxDataCalls=" + mMaxDataCalls); 5221 pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls); 5222 pw.println(" mReasonDataDenied=" + mReasonDataDenied); 5223 pw.println(" mNewReasonDataDenied=" + mNewReasonDataDenied); 5224 pw.println(" mGsmVoiceRoaming=" + mGsmVoiceRoaming); 5225 pw.println(" mGsmDataRoaming=" + mGsmDataRoaming); 5226 pw.println(" mEmergencyOnly=" + mEmergencyOnly); 5227 pw.flush(); 5228 mNitzState.dumpState(pw); 5229 pw.println(" mLastNitzData=" + mLastNitzData); 5230 pw.flush(); 5231 pw.println(" mStartedGprsRegCheck=" + mStartedGprsRegCheck); 5232 pw.println(" mReportedGprsNoReg=" + mReportedGprsNoReg); 5233 pw.println(" mNotification=" + mNotification); 5234 pw.println(" mCurSpn=" + mCurSpn); 5235 pw.println(" mCurDataSpn=" + mCurDataSpn); 5236 pw.println(" mCurShowSpn=" + mCurShowSpn); 5237 pw.println(" mCurPlmn=" + mCurPlmn); 5238 pw.println(" mCurShowPlmn=" + mCurShowPlmn); 5239 pw.flush(); 5240 pw.println(" mCurrentOtaspMode=" + mCurrentOtaspMode); 5241 pw.println(" mRoamingIndicator=" + mRoamingIndicator); 5242 pw.println(" mIsInPrl=" + mIsInPrl); 5243 pw.println(" mDefaultRoamingIndicator=" + mDefaultRoamingIndicator); 5244 pw.println(" mRegistrationState=" + mRegistrationState); 5245 pw.println(" mMdn=" + mMdn); 5246 pw.println(" mHomeSystemId=" + mHomeSystemId); 5247 pw.println(" mHomeNetworkId=" + mHomeNetworkId); 5248 pw.println(" mMin=" + mMin); 5249 pw.println(" mPrlVersion=" + mPrlVersion); 5250 pw.println(" mIsMinInfoReady=" + mIsMinInfoReady); 5251 pw.println(" mIsEriTextLoaded=" + mIsEriTextLoaded); 5252 pw.println(" mIsSubscriptionFromRuim=" + mIsSubscriptionFromRuim); 5253 pw.println(" mCdmaSSM=" + mCdmaSSM); 5254 pw.println(" mRegistrationDeniedReason=" + mRegistrationDeniedReason); 5255 pw.println(" mCurrentCarrier=" + mCurrentCarrier); 5256 pw.flush(); 5257 pw.println(" mImsRegistered=" + mImsRegistered); 5258 pw.println(" mImsRegistrationOnOff=" + mImsRegistrationOnOff); 5259 pw.println(" mAlarmSwitch=" + mAlarmSwitch); 5260 pw.println(" mRadioDisabledByCarrier" + mRadioDisabledByCarrier); 5261 pw.println(" mPowerOffDelayNeed=" + mPowerOffDelayNeed); 5262 pw.println(" mDeviceShuttingDown=" + mDeviceShuttingDown); 5263 pw.println(" mSpnUpdatePending=" + mSpnUpdatePending); 5264 pw.println(" mLteRsrpBoost=" + mLteRsrpBoost); 5265 pw.println(" mCellInfoMinIntervalMs=" + mCellInfoMinIntervalMs); 5266 pw.println(" mEriManager=" + mEriManager); 5267 dumpEarfcnPairList(pw); 5268 5269 mLocaleTracker.dump(fd, pw, args); 5270 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 5271 5272 mCdnr.dump(ipw); 5273 5274 ipw.println(" Carrier Display Name update records:"); 5275 ipw.increaseIndent(); 5276 mCdnrLogs.dump(fd, ipw, args); 5277 ipw.decreaseIndent(); 5278 5279 ipw.println(" Roaming Log:"); 5280 ipw.increaseIndent(); 5281 mRoamingLog.dump(fd, ipw, args); 5282 ipw.decreaseIndent(); 5283 5284 ipw.println(" Attach Log:"); 5285 ipw.increaseIndent(); 5286 mAttachLog.dump(fd, ipw, args); 5287 ipw.decreaseIndent(); 5288 5289 ipw.println(" Phone Change Log:"); 5290 ipw.increaseIndent(); 5291 mPhoneTypeLog.dump(fd, ipw, args); 5292 ipw.decreaseIndent(); 5293 5294 ipw.println(" Rat Change Log:"); 5295 ipw.increaseIndent(); 5296 mRatLog.dump(fd, ipw, args); 5297 ipw.decreaseIndent(); 5298 5299 ipw.println(" Radio power Log:"); 5300 ipw.increaseIndent(); 5301 mRadioPowerLog.dump(fd, ipw, args); 5302 ipw.decreaseIndent(); 5303 5304 mNitzState.dumpLogs(fd, ipw, args); 5305 5306 ipw.flush(); 5307 } 5308 5309 @UnsupportedAppUsage isImsRegistered()5310 public boolean isImsRegistered() { 5311 return mImsRegistered; 5312 } 5313 /** 5314 * Verifies the current thread is the same as the thread originally 5315 * used in the initialization of this instance. Throws RuntimeException 5316 * if not. 5317 * 5318 * @exception RuntimeException if the current thread is not 5319 * the thread that originally obtained this Phone instance. 5320 */ checkCorrectThread()5321 protected void checkCorrectThread() { 5322 if (Thread.currentThread() != getLooper().getThread()) { 5323 throw new RuntimeException( 5324 "ServiceStateTracker must be used from within one thread"); 5325 } 5326 } 5327 isCallerOnDifferentThread()5328 protected boolean isCallerOnDifferentThread() { 5329 boolean value = Thread.currentThread() != getLooper().getThread(); 5330 if (VDBG) log("isCallerOnDifferentThread: " + value); 5331 return value; 5332 } 5333 5334 /** 5335 * Check ISO country by MCC to see if phone is roaming in same registered country 5336 */ inSameCountry(String operatorNumeric)5337 protected boolean inSameCountry(String operatorNumeric) { 5338 if (TextUtils.isEmpty(operatorNumeric) || (operatorNumeric.length() < 5)) { 5339 // Not a valid network 5340 return false; 5341 } 5342 final String homeNumeric = getHomeOperatorNumeric(); 5343 if (TextUtils.isEmpty(homeNumeric) || (homeNumeric.length() < 5)) { 5344 // Not a valid SIM MCC 5345 return false; 5346 } 5347 boolean inSameCountry = true; 5348 final String networkMCC = operatorNumeric.substring(0, 3); 5349 final String homeMCC = homeNumeric.substring(0, 3); 5350 final String networkCountry = MccTable.countryCodeForMcc(networkMCC); 5351 final String homeCountry = MccTable.countryCodeForMcc(homeMCC); 5352 if (networkCountry.isEmpty() || homeCountry.isEmpty()) { 5353 // Not a valid country 5354 return false; 5355 } 5356 inSameCountry = homeCountry.equals(networkCountry); 5357 if (inSameCountry) { 5358 return inSameCountry; 5359 } 5360 // special same country cases 5361 if ("us".equals(homeCountry) && "vi".equals(networkCountry)) { 5362 inSameCountry = true; 5363 } else if ("vi".equals(homeCountry) && "us".equals(networkCountry)) { 5364 inSameCountry = true; 5365 } 5366 return inSameCountry; 5367 } 5368 5369 /** 5370 * Set both voice and data roaming type, 5371 * judging from the ISO country of SIM VS network. 5372 */ 5373 @UnsupportedAppUsage setRoamingType(ServiceState currentServiceState)5374 protected void setRoamingType(ServiceState currentServiceState) { 5375 final boolean isVoiceInService = 5376 (currentServiceState.getState() == ServiceState.STATE_IN_SERVICE); 5377 if (isVoiceInService) { 5378 if (currentServiceState.getVoiceRoaming()) { 5379 if (mPhone.isPhoneTypeGsm()) { 5380 // check roaming type by MCC 5381 if (inSameCountry(currentServiceState.getOperatorNumeric())) { 5382 currentServiceState.setVoiceRoamingType( 5383 ServiceState.ROAMING_TYPE_DOMESTIC); 5384 } else { 5385 currentServiceState.setVoiceRoamingType( 5386 ServiceState.ROAMING_TYPE_INTERNATIONAL); 5387 } 5388 } else { 5389 // some carrier defines international roaming by indicator 5390 int[] intRoamingIndicators = mPhone.getContext().getResources().getIntArray( 5391 com.android.internal.R.array 5392 .config_cdma_international_roaming_indicators); 5393 if ((intRoamingIndicators != null) && (intRoamingIndicators.length > 0)) { 5394 // It's domestic roaming at least now 5395 currentServiceState.setVoiceRoamingType(ServiceState.ROAMING_TYPE_DOMESTIC); 5396 int curRoamingIndicator = currentServiceState.getCdmaRoamingIndicator(); 5397 for (int i = 0; i < intRoamingIndicators.length; i++) { 5398 if (curRoamingIndicator == intRoamingIndicators[i]) { 5399 currentServiceState.setVoiceRoamingType( 5400 ServiceState.ROAMING_TYPE_INTERNATIONAL); 5401 break; 5402 } 5403 } 5404 } else { 5405 // check roaming type by MCC 5406 if (inSameCountry(currentServiceState.getOperatorNumeric())) { 5407 currentServiceState.setVoiceRoamingType( 5408 ServiceState.ROAMING_TYPE_DOMESTIC); 5409 } else { 5410 currentServiceState.setVoiceRoamingType( 5411 ServiceState.ROAMING_TYPE_INTERNATIONAL); 5412 } 5413 } 5414 } 5415 } else { 5416 currentServiceState.setVoiceRoamingType(ServiceState.ROAMING_TYPE_NOT_ROAMING); 5417 } 5418 } 5419 final boolean isDataInService = 5420 (currentServiceState.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE); 5421 final int dataRegType = getRilDataRadioTechnologyForWwan(currentServiceState); 5422 if (isDataInService) { 5423 if (!currentServiceState.getDataRoaming()) { 5424 currentServiceState.setDataRoamingType(ServiceState.ROAMING_TYPE_NOT_ROAMING); 5425 } else { 5426 if (mPhone.isPhoneTypeGsm()) { 5427 if (ServiceState.isGsm(dataRegType)) { 5428 if (isVoiceInService) { 5429 // GSM data should have the same state as voice 5430 currentServiceState.setDataRoamingType(currentServiceState 5431 .getVoiceRoamingType()); 5432 } else { 5433 // we can not decide GSM data roaming type without voice 5434 currentServiceState.setDataRoamingType(ServiceState.ROAMING_TYPE_UNKNOWN); 5435 } 5436 } else { 5437 // we can not decide 3gpp2 roaming state here 5438 currentServiceState.setDataRoamingType(ServiceState.ROAMING_TYPE_UNKNOWN); 5439 } 5440 } else { 5441 if (ServiceState.isCdma(dataRegType)) { 5442 if (isVoiceInService) { 5443 // CDMA data should have the same state as voice 5444 currentServiceState.setDataRoamingType(currentServiceState 5445 .getVoiceRoamingType()); 5446 } else { 5447 // we can not decide CDMA data roaming type without voice 5448 // set it as same as last time 5449 currentServiceState.setDataRoamingType(ServiceState.ROAMING_TYPE_UNKNOWN); 5450 } 5451 } else { 5452 // take it as 3GPP roaming 5453 if (inSameCountry(currentServiceState.getOperatorNumeric())) { 5454 currentServiceState.setDataRoamingType(ServiceState.ROAMING_TYPE_DOMESTIC); 5455 } else { 5456 currentServiceState.setDataRoamingType( 5457 ServiceState.ROAMING_TYPE_INTERNATIONAL); 5458 } 5459 } 5460 } 5461 } 5462 } 5463 } 5464 5465 @UnsupportedAppUsage setSignalStrengthDefaultValues()5466 private void setSignalStrengthDefaultValues() { 5467 mSignalStrength = new SignalStrength(); 5468 mSignalStrengthUpdatedTime = System.currentTimeMillis(); 5469 } 5470 getHomeOperatorNumeric()5471 protected String getHomeOperatorNumeric() { 5472 String numeric = ((TelephonyManager) mPhone.getContext(). 5473 getSystemService(Context.TELEPHONY_SERVICE)). 5474 getSimOperatorNumericForPhone(mPhone.getPhoneId()); 5475 if (!mPhone.isPhoneTypeGsm() && TextUtils.isEmpty(numeric)) { 5476 numeric = SystemProperties.get(GsmCdmaPhone.PROPERTY_CDMA_HOME_OPERATOR_NUMERIC, ""); 5477 } 5478 return numeric; 5479 } 5480 5481 @UnsupportedAppUsage getPhoneId()5482 protected int getPhoneId() { 5483 return mPhone.getPhoneId(); 5484 } 5485 5486 /* Reset Service state when IWLAN is enabled as polling in airplane mode 5487 * causes state to go to OUT_OF_SERVICE state instead of STATE_OFF 5488 */ 5489 5490 5491 /** 5492 * This method adds IWLAN registration info for legacy mode devices camped on IWLAN. It also 5493 * makes some adjustments when the device camps on IWLAN in airplane mode. 5494 */ processIwlanRegistrationInfo()5495 private void processIwlanRegistrationInfo() { 5496 if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) { 5497 boolean resetIwlanRatVal = false; 5498 log("set service state as POWER_OFF"); 5499 if (ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN 5500 == mNewSS.getRilDataRadioTechnology()) { 5501 log("pollStateDone: mNewSS = " + mNewSS); 5502 log("pollStateDone: reset iwlan RAT value"); 5503 resetIwlanRatVal = true; 5504 } 5505 // operator info should be kept in SS 5506 String operator = mNewSS.getOperatorAlphaLong(); 5507 mNewSS.setStateOff(); 5508 if (resetIwlanRatVal) { 5509 mNewSS.setDataRegState(ServiceState.STATE_IN_SERVICE); 5510 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder() 5511 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 5512 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 5513 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN) 5514 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME) 5515 .build(); 5516 mNewSS.addNetworkRegistrationInfo(nri); 5517 if (mTransportManager.isInLegacyMode()) { 5518 // If in legacy mode, simulate the behavior that IWLAN registration info 5519 // is reported through WWAN transport. 5520 nri = new NetworkRegistrationInfo.Builder() 5521 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 5522 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 5523 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN) 5524 .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME) 5525 .build(); 5526 mNewSS.addNetworkRegistrationInfo(nri); 5527 } 5528 mNewSS.setOperatorAlphaLong(operator); 5529 // Since it's in airplane mode, cellular must be out of service. The only possible 5530 // transport for data to go through is the IWLAN transport. Setting this to true 5531 // so that ServiceState.getDataNetworkType can report the right RAT. 5532 mNewSS.setIwlanPreferred(true); 5533 log("pollStateDone: mNewSS = " + mNewSS); 5534 } 5535 return; 5536 } 5537 5538 // If the device operates in legacy mode and camps on IWLAN, modem reports IWLAN as a RAT 5539 // through WWAN registration info. To be consistent with the behavior with AP-assisted mode, 5540 // we manually make a WLAN registration info for clients to consume. In this scenario, 5541 // both WWAN and WLAN registration info are the IWLAN registration info and that's the 5542 // unfortunate limitation we have when the device operates in legacy mode. In AP-assisted 5543 // mode, the WWAN registration will correctly report the actual cellular registration info 5544 // when the device camps on IWLAN. 5545 if (mTransportManager.isInLegacyMode()) { 5546 NetworkRegistrationInfo wwanNri = mNewSS.getNetworkRegistrationInfo( 5547 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 5548 if (wwanNri != null && wwanNri.getAccessNetworkTechnology() 5549 == TelephonyManager.NETWORK_TYPE_IWLAN) { 5550 NetworkRegistrationInfo wlanNri = new NetworkRegistrationInfo.Builder() 5551 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN) 5552 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 5553 .setRegistrationState(wwanNri.getRegistrationState()) 5554 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN) 5555 .setRejectCause(wwanNri.getRejectCause()) 5556 .setEmergencyOnly(wwanNri.isEmergencyEnabled()) 5557 .setAvailableServices(wwanNri.getAvailableServices()) 5558 .build(); 5559 mNewSS.addNetworkRegistrationInfo(wlanNri); 5560 } 5561 } 5562 } 5563 5564 /** 5565 * Check if device is non-roaming and always on home network. 5566 * 5567 * @param b carrier config bundle obtained from CarrierConfigManager 5568 * @return true if network is always on home network, false otherwise 5569 * @see CarrierConfigManager 5570 */ alwaysOnHomeNetwork(BaseBundle b)5571 protected final boolean alwaysOnHomeNetwork(BaseBundle b) { 5572 return b.getBoolean(CarrierConfigManager.KEY_FORCE_HOME_NETWORK_BOOL); 5573 } 5574 5575 /** 5576 * Check if the network identifier has membership in the set of 5577 * network identifiers stored in the carrier config bundle. 5578 * 5579 * @param b carrier config bundle obtained from CarrierConfigManager 5580 * @param network The network identifier to check network existence in bundle 5581 * @param key The key to index into the bundle presenting a string array of 5582 * networks to check membership 5583 * @return true if network has membership in bundle networks, false otherwise 5584 * @see CarrierConfigManager 5585 */ isInNetwork(BaseBundle b, String network, String key)5586 private boolean isInNetwork(BaseBundle b, String network, String key) { 5587 String[] networks = b.getStringArray(key); 5588 5589 if (networks != null && Arrays.asList(networks).contains(network)) { 5590 return true; 5591 } 5592 return false; 5593 } 5594 isRoamingInGsmNetwork(BaseBundle b, String network)5595 protected final boolean isRoamingInGsmNetwork(BaseBundle b, String network) { 5596 return isInNetwork(b, network, CarrierConfigManager.KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY); 5597 } 5598 isNonRoamingInGsmNetwork(BaseBundle b, String network)5599 protected final boolean isNonRoamingInGsmNetwork(BaseBundle b, String network) { 5600 return isInNetwork(b, network, CarrierConfigManager.KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY); 5601 } 5602 isRoamingInCdmaNetwork(BaseBundle b, String network)5603 protected final boolean isRoamingInCdmaNetwork(BaseBundle b, String network) { 5604 return isInNetwork(b, network, CarrierConfigManager.KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY); 5605 } 5606 isNonRoamingInCdmaNetwork(BaseBundle b, String network)5607 protected final boolean isNonRoamingInCdmaNetwork(BaseBundle b, String network) { 5608 return isInNetwork(b, network, CarrierConfigManager.KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY); 5609 } 5610 5611 /** Check if the device is shutting down. */ isDeviceShuttingDown()5612 public boolean isDeviceShuttingDown() { 5613 return mDeviceShuttingDown; 5614 } 5615 5616 /** 5617 * Consider dataRegState if voiceRegState is OOS to determine SPN to be displayed. 5618 * If dataRegState is in service on IWLAN, also check for wifi calling enabled. 5619 * @param ss service state. 5620 */ getCombinedRegState(ServiceState ss)5621 protected int getCombinedRegState(ServiceState ss) { 5622 int regState = ss.getState(); 5623 int dataRegState = ss.getDataRegistrationState(); 5624 if ((regState == ServiceState.STATE_OUT_OF_SERVICE 5625 || regState == ServiceState.STATE_POWER_OFF) 5626 && (dataRegState == ServiceState.STATE_IN_SERVICE)) { 5627 if (ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN) { 5628 if (mPhone.getImsPhone() != null && mPhone.getImsPhone().isWifiCallingEnabled()) { 5629 log("getCombinedRegState: return STATE_IN_SERVICE for IWLAN as " 5630 + "Data is in service and WFC is enabled"); 5631 regState = dataRegState; 5632 } 5633 } else { 5634 log("getCombinedRegState: return STATE_IN_SERVICE as Data is in service"); 5635 regState = dataRegState; 5636 } 5637 } 5638 return regState; 5639 } 5640 5641 /** 5642 * Gets the carrier configuration values for a particular subscription. 5643 * 5644 * @return A {@link PersistableBundle} containing the config for the given subId, 5645 * or default values for an invalid subId. 5646 */ 5647 @NonNull getCarrierConfig()5648 private PersistableBundle getCarrierConfig() { 5649 CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext() 5650 .getSystemService(Context.CARRIER_CONFIG_SERVICE); 5651 if (configManager != null) { 5652 // If an invalid subId is used, this bundle will contain default values. 5653 PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId()); 5654 if (config != null) { 5655 return config; 5656 } 5657 } 5658 // Return static default defined in CarrierConfigManager. 5659 return CarrierConfigManager.getDefaultConfig(); 5660 } 5661 getLocaleTracker()5662 public LocaleTracker getLocaleTracker() { 5663 return mLocaleTracker; 5664 } 5665 getCdmaEriText(int roamInd, int defRoamInd)5666 String getCdmaEriText(int roamInd, int defRoamInd) { 5667 return mEriManager.getCdmaEriText(roamInd, defRoamInd); 5668 } 5669 updateOperatorNamePattern(PersistableBundle config)5670 private void updateOperatorNamePattern(PersistableBundle config) { 5671 String operatorNamePattern = config.getString( 5672 CarrierConfigManager.KEY_OPERATOR_NAME_FILTER_PATTERN_STRING); 5673 if (!TextUtils.isEmpty(operatorNamePattern)) { 5674 mOperatorNameStringPattern = Pattern.compile(operatorNamePattern); 5675 if (DBG) { 5676 log("mOperatorNameStringPattern: " + mOperatorNameStringPattern.toString()); 5677 } 5678 } 5679 } 5680 updateOperatorNameForServiceState(ServiceState servicestate)5681 private void updateOperatorNameForServiceState(ServiceState servicestate) { 5682 if (servicestate == null) { 5683 return; 5684 } 5685 5686 servicestate.setOperatorName( 5687 filterOperatorNameByPattern(servicestate.getOperatorAlphaLong()), 5688 filterOperatorNameByPattern(servicestate.getOperatorAlphaShort()), 5689 servicestate.getOperatorNumeric()); 5690 5691 List<NetworkRegistrationInfo> networkRegistrationInfos = 5692 servicestate.getNetworkRegistrationInfoList(); 5693 5694 for (int i = 0; i < networkRegistrationInfos.size(); i++) { 5695 if (networkRegistrationInfos.get(i) != null) { 5696 updateOperatorNameForCellIdentity( 5697 networkRegistrationInfos.get(i).getCellIdentity()); 5698 servicestate.addNetworkRegistrationInfo(networkRegistrationInfos.get(i)); 5699 } 5700 } 5701 } 5702 updateOperatorNameForCellIdentity(CellIdentity cellIdentity)5703 private void updateOperatorNameForCellIdentity(CellIdentity cellIdentity) { 5704 if (cellIdentity == null) { 5705 return; 5706 } 5707 cellIdentity.setOperatorAlphaLong( 5708 filterOperatorNameByPattern((String) cellIdentity.getOperatorAlphaLong())); 5709 cellIdentity.setOperatorAlphaShort( 5710 filterOperatorNameByPattern((String) cellIdentity.getOperatorAlphaShort())); 5711 } 5712 5713 /** 5714 * To modify the operator name of CellInfo by pattern. 5715 * 5716 * @param cellInfos List of CellInfo{@link CellInfo}. 5717 */ updateOperatorNameForCellInfo(List<CellInfo> cellInfos)5718 public void updateOperatorNameForCellInfo(List<CellInfo> cellInfos) { 5719 if (cellInfos == null || cellInfos.isEmpty()) { 5720 return; 5721 } 5722 for (CellInfo cellInfo : cellInfos) { 5723 if (cellInfo.isRegistered()) { 5724 updateOperatorNameForCellIdentity(cellInfo.getCellIdentity()); 5725 } 5726 } 5727 } 5728 5729 /** 5730 * To modify the operator name by pattern. 5731 * 5732 * @param operatorName Registered operator name 5733 * @return An operator name. 5734 */ filterOperatorNameByPattern(String operatorName)5735 public String filterOperatorNameByPattern(String operatorName) { 5736 if (mOperatorNameStringPattern == null || TextUtils.isEmpty(operatorName)) { 5737 return operatorName; 5738 } 5739 Matcher matcher = mOperatorNameStringPattern.matcher(operatorName); 5740 if (matcher.find()) { 5741 if (matcher.groupCount() > 0) { 5742 operatorName = matcher.group(1); 5743 } else { 5744 log("filterOperatorNameByPattern: pattern no group"); 5745 } 5746 } 5747 return operatorName; 5748 } 5749 5750 @RilRadioTechnology getRilDataRadioTechnologyForWwan(ServiceState ss)5751 private static int getRilDataRadioTechnologyForWwan(ServiceState ss) { 5752 NetworkRegistrationInfo regInfo = ss.getNetworkRegistrationInfo( 5753 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); 5754 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 5755 if (regInfo != null) { 5756 networkType = regInfo.getAccessNetworkTechnology(); 5757 } 5758 return ServiceState.networkTypeToRilRadioTechnology(networkType); 5759 } 5760 5761 /** 5762 * Registers for 5G NR state changed. 5763 * @param h handler to notify 5764 * @param what what code of message when delivered 5765 * @param obj placed in Message.obj 5766 */ registerForNrStateChanged(Handler h, int what, Object obj)5767 public void registerForNrStateChanged(Handler h, int what, Object obj) { 5768 Registrant r = new Registrant(h, what, obj); 5769 mNrStateChangedRegistrants.add(r); 5770 } 5771 5772 /** 5773 * Unregisters for 5G NR state changed. 5774 * @param h handler to notify 5775 */ unregisterForNrStateChanged(Handler h)5776 public void unregisterForNrStateChanged(Handler h) { 5777 mNrStateChangedRegistrants.remove(h); 5778 } 5779 5780 /** 5781 * Registers for 5G NR frequency changed. 5782 * @param h handler to notify 5783 * @param what what code of message when delivered 5784 * @param obj placed in Message.obj 5785 */ registerForNrFrequencyChanged(Handler h, int what, Object obj)5786 public void registerForNrFrequencyChanged(Handler h, int what, Object obj) { 5787 Registrant r = new Registrant(h, what, obj); 5788 mNrFrequencyChangedRegistrants.add(r); 5789 } 5790 5791 /** 5792 * Unregisters for 5G NR frequency changed. 5793 * @param h handler to notify 5794 */ unregisterForNrFrequencyChanged(Handler h)5795 public void unregisterForNrFrequencyChanged(Handler h) { 5796 mNrFrequencyChangedRegistrants.remove(h); 5797 } 5798 5799 /** 5800 * Get the NR data connection context ids. 5801 * 5802 * @return data connection context ids. 5803 */ 5804 @NonNull getNrContextIds()5805 public Set<Integer> getNrContextIds() { 5806 Set<Integer> idSet = new HashSet<>(); 5807 5808 if (!ArrayUtils.isEmpty(mLastPhysicalChannelConfigList)) { 5809 for (PhysicalChannelConfig config : mLastPhysicalChannelConfigList) { 5810 if (isNrPhysicalChannelConfig(config)) { 5811 for (int id : config.getContextIds()) { 5812 idSet.add(id); 5813 } 5814 } 5815 } 5816 } 5817 5818 return idSet; 5819 } 5820 setDataNetworkTypeForPhone(int type)5821 private void setDataNetworkTypeForPhone(int type) { 5822 if (mPhone.getUnitTestMode()) { 5823 return; 5824 } 5825 TelephonyManager tm = (TelephonyManager) mPhone.getContext().getSystemService( 5826 Context.TELEPHONY_SERVICE); 5827 tm.setDataNetworkTypeForPhone(mPhone.getPhoneId(), type); 5828 } 5829 5830 /** 5831 * Used to insert a ServiceState into the ServiceStateProvider as a ContentValues instance. 5832 * 5833 * Copied from packages/services/Telephony/src/com/android/phone/ServiceStateProvider.java 5834 * 5835 * @param state the ServiceState to convert into ContentValues 5836 * @return the convertedContentValues instance 5837 */ getContentValuesForServiceState(ServiceState state)5838 private ContentValues getContentValuesForServiceState(ServiceState state) { 5839 ContentValues values = new ContentValues(); 5840 final Parcel p = Parcel.obtain(); 5841 state.writeToParcel(p, 0); 5842 // Turn the parcel to byte array. Safe to do this because the content values were never 5843 // written into a persistent storage. ServiceStateProvider keeps values in the memory. 5844 values.put(SERVICE_STATE, p.marshall()); 5845 return values; 5846 } 5847 } 5848