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