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