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