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