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