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