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