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