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