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