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