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.phone;
18 
19 import android.annotation.IntDef;
20 import android.annotation.Nullable;
21 import android.app.Activity;
22 import android.app.KeyguardManager;
23 import android.app.ProgressDialog;
24 import android.content.BroadcastReceiver;
25 import android.content.ContentResolver;
26 import android.content.Context;
27 import android.content.ContextWrapper;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.content.pm.PackageManager;
31 import android.content.res.XmlResourceParser;
32 import android.media.AudioManager;
33 import android.net.ConnectivityManager;
34 import android.net.Uri;
35 import android.os.AsyncResult;
36 import android.os.Handler;
37 import android.os.Message;
38 import android.os.PersistableBundle;
39 import android.os.PowerManager;
40 import android.os.SystemProperties;
41 import android.preference.PreferenceManager;
42 import android.provider.Settings;
43 import android.sysprop.TelephonyProperties;
44 import android.telecom.TelecomManager;
45 import android.telephony.AnomalyReporter;
46 import android.telephony.CarrierConfigManager;
47 import android.telephony.ServiceState;
48 import android.telephony.SubscriptionInfo;
49 import android.telephony.SubscriptionManager;
50 import android.telephony.TelephonyCallback;
51 import android.telephony.TelephonyLocalConnection;
52 import android.telephony.TelephonyManager;
53 import android.text.TextUtils;
54 import android.util.ArraySet;
55 import android.util.LocalLog;
56 import android.util.Log;
57 import android.widget.Toast;
58 
59 import com.android.ims.ImsFeatureBinderRepository;
60 import com.android.internal.os.BinderCallsStats;
61 import com.android.internal.telephony.CallManager;
62 import com.android.internal.telephony.IccCardConstants;
63 import com.android.internal.telephony.MmiCode;
64 import com.android.internal.telephony.Phone;
65 import com.android.internal.telephony.PhoneConfigurationManager;
66 import com.android.internal.telephony.PhoneConstants;
67 import com.android.internal.telephony.PhoneFactory;
68 import com.android.internal.telephony.SettingsObserver;
69 import com.android.internal.telephony.TelephonyCapabilities;
70 import com.android.internal.telephony.TelephonyComponentFactory;
71 import com.android.internal.telephony.TelephonyIntents;
72 import com.android.internal.telephony.data.DataEvaluation.DataDisallowedReason;
73 import com.android.internal.telephony.domainselection.DomainSelectionResolver;
74 import com.android.internal.telephony.emergency.EmergencyStateTracker;
75 import com.android.internal.telephony.flags.FeatureFlags;
76 import com.android.internal.telephony.flags.FeatureFlagsImpl;
77 import com.android.internal.telephony.ims.ImsResolver;
78 import com.android.internal.telephony.imsphone.ImsPhone;
79 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
80 import com.android.internal.telephony.satellite.SatelliteController;
81 import com.android.internal.telephony.subscription.SubscriptionManagerService;
82 import com.android.internal.telephony.uicc.UiccPort;
83 import com.android.internal.telephony.uicc.UiccProfile;
84 import com.android.internal.util.IndentingPrintWriter;
85 import com.android.phone.settings.SettingsConstants;
86 import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
87 import com.android.services.telephony.domainselection.DynamicRoutingController;
88 import com.android.services.telephony.rcs.TelephonyRcsService;
89 
90 import java.io.FileDescriptor;
91 import java.io.PrintWriter;
92 import java.lang.annotation.Retention;
93 import java.lang.annotation.RetentionPolicy;
94 import java.util.List;
95 import java.util.concurrent.atomic.AtomicBoolean;
96 
97 /**
98  * Global state for the telephony subsystem when running in the primary
99  * phone process.
100  */
101 public class PhoneGlobals extends ContextWrapper {
102     public static final String LOG_TAG = "PhoneGlobals";
103 
104     /**
105      * Phone app-wide debug level:
106      *   0 - no debug logging
107      *   1 - normal debug logging if ro.debuggable is set (which is true in
108      *       "eng" and "userdebug" builds but not "user" builds)
109      *   2 - ultra-verbose debug logging
110      *
111      * Most individual classes in the phone app have a local DBG constant,
112      * typically set to
113      *   (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1)
114      * or else
115      *   (PhoneApp.DBG_LEVEL >= 2)
116      * depending on the desired verbosity.
117      *
118      * ***** DO NOT SUBMIT WITH DBG_LEVEL > 0 *************
119      */
120     public static final int DBG_LEVEL = 0;
121 
122     private static final boolean DBG =
123             (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
124     private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
125 
126     // Message codes; see mHandler below.
127     private static final int EVENT_SIM_NETWORK_LOCKED = 3;
128     private static final int EVENT_SIM_STATE_CHANGED = 8;
129     private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
130     private static final int EVENT_DATA_ROAMING_CONNECTED = 11;
131     private static final int EVENT_DATA_ROAMING_OK = 12;
132     private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 13;
133     private static final int EVENT_DATA_ROAMING_SETTINGS_CHANGED = 15;
134     private static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 16;
135     private static final int EVENT_CARRIER_CONFIG_CHANGED = 17;
136     private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 18;
137 
138     // The MMI codes are also used by the InCallScreen.
139     public static final int MMI_INITIATE = 51;
140     public static final int MMI_COMPLETE = 52;
141     public static final int MMI_CANCEL = 53;
142     // Don't use message codes larger than 99 here; those are reserved for
143     // the individual Activities of the Phone UI.
144 
145     public static final int AIRPLANE_ON = 1;
146     public static final int AIRPLANE_OFF = 0;
147 
148     /**
149      * Allowable values for the wake lock code.
150      *   SLEEP means the device can be put to sleep.
151      *   PARTIAL means wake the processor, but we display can be kept off.
152      *   FULL means wake both the processor and the display.
153      */
154     public enum WakeState {
155         SLEEP,
156         PARTIAL,
157         FULL
158     }
159 
160     private static PhoneGlobals sMe;
161 
162     CallManager mCM;
163     CallNotifier notifier;
164     NotificationMgr notificationMgr;
165     TelephonyRcsService mTelephonyRcsService;
166     public PhoneInterfaceManager phoneMgr;
167     public ImsRcsController imsRcsController;
168     public ImsStateCallbackController mImsStateCallbackController;
169     public ImsProvisioningController mImsProvisioningController;
170     CarrierConfigLoader configLoader;
171 
172     private Phone phoneInEcm;
173 
174     static boolean sVoiceCapable = true;
175 
176     // TODO: Remove, no longer used.
177     CdmaPhoneCallState cdmaPhoneCallState;
178 
179     // The currently-active PUK entry activity and progress dialog.
180     // Normally, these are the Emergency Dialer and the subsequent
181     // progress dialog.  null if there is are no such objects in
182     // the foreground.
183     private Activity mPUKEntryActivity;
184     private ProgressDialog mPUKEntryProgressDialog;
185 
186     /** @hide */
187     @Retention(RetentionPolicy.SOURCE)
188     @IntDef(prefix = {"ROAMING_NOTIFICATION_REASON_"},
189             value = {
190                     ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED,
191                     ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED,
192                     ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED,
193                     ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED,
194                     ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED,
195                     ROAMING_NOTIFICATION_REASON_DISCONNECTED_SINGLE_NETWORK})
196     public @interface RoamingNotificationReason {}
197     private static final int ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED = 0;
198     private static final int ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED = 1;
199     private static final int ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED = 2;
200     private static final int ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED = 3;
201     private static final int ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED = 4;
202     private static final int ROAMING_NOTIFICATION_REASON_DISCONNECTED_SINGLE_NETWORK = 5;
203 
204     /** @hide */
205     @Retention(RetentionPolicy.SOURCE)
206     @IntDef(prefix = {"ROAMING_NOTIFICATION_"},
207             value = {
208                     ROAMING_NOTIFICATION_NO_NOTIFICATION,
209                     ROAMING_NOTIFICATION_CONNECTED,
210                     ROAMING_NOTIFICATION_DISCONNECTED})
211     public @interface RoamingNotification {}
212 
213     private static final int ROAMING_NOTIFICATION_NO_NOTIFICATION = 0;
214     private static final int ROAMING_NOTIFICATION_CONNECTED       = 1;
215     private static final int ROAMING_NOTIFICATION_DISCONNECTED    = 2;
216 
217     @RoamingNotification
218     private int mCurrentRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
219 
220     /**
221      * If true, update roaming notifications after the Internet is completely disconnected. If
222      * carrier allows only a single data network, wait until the Internet connection is completely
223      * disconnected and then update the roaming notification once more to check if
224      * ONLY_ALLOWED_SINGLE_NETWORK disallow reason is disappeared.
225      */
226     private AtomicBoolean mWaitForInternetDisconnection = new AtomicBoolean(false);
227 
228     /**
229      * Reasons that have already shown notification to prevent duplicate shows for the same reason.
230      */
231     private ArraySet<String> mShownNotificationReasons = new ArraySet<>();
232 
233     // For reorganize_roaming_notification feature disabled.
234     @RoamingNotification
235     private int mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
236 
237     // For reorganize_roaming_notification feature disabled.
238     /** Operator numerics for which we've shown is-roaming notifications. **/
239     private ArraySet<String> mPrevRoamingOperatorNumerics = new ArraySet<>();
240 
241     private WakeState mWakeState = WakeState.SLEEP;
242 
243     private PowerManager mPowerManager;
244     private PowerManager.WakeLock mWakeLock;
245     private PowerManager.WakeLock mPartialWakeLock;
246     private KeyguardManager mKeyguardManager;
247 
248     private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
249     private final LocalLog mDataRoamingNotifLog = new LocalLog(50);
250 
251     // Broadcast receiver for various intent broadcasts (see onCreate())
252     private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
253 
254     private final CarrierVvmPackageInstalledReceiver mCarrierVvmPackageInstalledReceiver =
255             new CarrierVvmPackageInstalledReceiver();
256 
257     private SettingsObserver mSettingsObserver;
258     private BinderCallsStats.SettingsObserver mBinderCallsSettingsObserver;
259 
260     // Mapping of phone ID to the associated TelephonyCallback. These should be registered without
261     // fine or coarse location since we only use ServiceState for
262     private PhoneAppCallback[] mTelephonyCallbacks;
263 
264     private FeatureFlags mFeatureFlags = new FeatureFlagsImpl();
265 
266     private class PhoneAppCallback extends TelephonyCallback implements
267             TelephonyCallback.ServiceStateListener,
268             TelephonyCallback.DataConnectionStateListener {
269         private final int mSubId;
270 
PhoneAppCallback(int subId)271         PhoneAppCallback(int subId) {
272             mSubId = subId;
273         }
274 
275         @Override
onServiceStateChanged(ServiceState serviceState)276         public void onServiceStateChanged(ServiceState serviceState) {
277             // Note when registering that we should be registering with INCLUDE_LOCATION_DATA_NONE.
278             // PhoneGlobals only uses the state and roaming status, which does not require location.
279             handleServiceStateChanged(serviceState, mSubId);
280         }
281 
282         @Override
onDataConnectionStateChanged(int state, int networkType)283         public void onDataConnectionStateChanged(int state, int networkType) {
284             if (mSubId == mDefaultDataSubId && state == TelephonyManager.DATA_DISCONNECTED) {
285                 // onDataConnectionStateChanged is an event about the state of exact DataNetwork,
286                 // but since the DataNetwork of internet may not have been completely removed from
287                 // the DataNetworkController list, The post handler event expects the internet data
288                 // network to be completely removed from the DataNetworkController list.
289                 mHandler.post(() -> {
290                     if (mWaitForInternetDisconnection.compareAndSet(true, false)) {
291                         Log.d(LOG_TAG, "onDisconnectedInternetDataNetwork.");
292                         updateDataRoamingStatus(
293                                 ROAMING_NOTIFICATION_REASON_DISCONNECTED_SINGLE_NETWORK);
294                     }
295                 });
296             }
297         }
298 
getSubId()299         public int getSubId() {
300             return mSubId;
301         }
302     }
303 
304     private static class EventSimStateChangedBag {
305         final int mPhoneId;
306         final String mIccStatus;
307 
EventSimStateChangedBag(int phoneId, String iccStatus)308         EventSimStateChangedBag(int phoneId, String iccStatus) {
309             mPhoneId = phoneId;
310             mIccStatus = iccStatus;
311         }
312     }
313 
314     // Some carrier config settings disable the network lock screen, so we call handleSimLock
315     // when either SIM_LOCK or CARRIER_CONFIG changes so that no matter which one happens first,
316     // we still do the right thing
handleSimLock(int subType, Phone phone)317     private void handleSimLock(int subType, Phone phone) {
318         PersistableBundle cc = getCarrierConfigForSubId(phone.getSubId());
319         if (!CarrierConfigManager.isConfigForIdentifiedCarrier(cc)) {
320             // If we only have the default carrier config just return, to avoid popping up the
321             // the SIM lock screen when it's disabled by the carrier.
322             Log.i(LOG_TAG, "Not showing 'SIM network unlock' screen. Carrier config not loaded");
323             return;
324         }
325         if (cc.getBoolean(CarrierConfigManager.KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL)) {
326             // Some products don't have the concept of a "SIM network lock"
327             Log.i(LOG_TAG, "Not showing 'SIM network unlock' screen. Disabled by carrier config");
328             return;
329         }
330 
331         // if passed in subType is unknown, retrieve it here.
332         if (subType == -1) {
333             final UiccPort uiccPort = phone.getUiccPort();
334             if (uiccPort == null) {
335                 Log.e(LOG_TAG,
336                         "handleSimLock: uiccPort for phone " + phone.getPhoneId() + " is null");
337                 return;
338             }
339             final UiccProfile uiccProfile = uiccPort.getUiccProfile();
340             if (uiccProfile == null) {
341                 Log.e(LOG_TAG,
342                         "handleSimLock: uiccProfile for phone " + phone.getPhoneId() + " is null");
343                 return;
344             }
345             subType = uiccProfile.getApplication(
346                     uiccProfile.mCurrentAppType).getPersoSubState().ordinal();
347         }
348         // Normal case: show the "SIM network unlock" PIN entry screen.
349         // The user won't be able to do anything else until
350         // they enter a valid SIM network PIN.
351         Log.i(LOG_TAG, "show sim depersonal panel");
352         IccNetworkDepersonalizationPanel.showDialog(phone, subType);
353     }
354 
isSimLocked(Phone phone)355     private boolean isSimLocked(Phone phone) {
356         TelephonyManager tm = getSystemService(TelephonyManager.class);
357         return tm.createForSubscriptionId(phone.getSubId()).getSimState()
358                 == TelephonyManager.SIM_STATE_NETWORK_LOCKED;
359     }
360 
361     Handler mHandler = new Handler() {
362         @Override
363         public void handleMessage(Message msg) {
364             PhoneConstants.State phoneState;
365             if (VDBG) Log.v(LOG_TAG, "event=" + msg.what);
366             switch (msg.what) {
367                 // TODO: This event should be handled by the lock screen, just
368                 // like the "SIM missing" and "Sim locked" cases (bug 1804111).
369                 case EVENT_SIM_NETWORK_LOCKED:
370                     int subType = (Integer) ((AsyncResult) msg.obj).result;
371                     Phone phone = (Phone) ((AsyncResult) msg.obj).userObj;
372                     handleSimLock(subType, phone);
373                     break;
374 
375                 case EVENT_DATA_ROAMING_DISCONNECTED:
376                     if (SubscriptionManagerService.getInstance()
377                             .isEsimBootStrapProvisioningActiveForSubId(msg.arg1)) {
378                         Log.i(LOG_TAG,
379                                 "skip notification/warnings during esim bootstrap activation");
380                     } else {
381                         notificationMgr.showDataRoamingNotification(msg.arg1, false);
382                     }
383                     break;
384 
385                 case EVENT_DATA_ROAMING_CONNECTED:
386                     if (SubscriptionManagerService.getInstance()
387                             .isEsimBootStrapProvisioningActiveForSubId(msg.arg1)) {
388                         Log.i(LOG_TAG,
389                                 "skip notification/warnings during esim bootstrap activation");
390                     } else {
391                         notificationMgr.showDataRoamingNotification(msg.arg1, true);
392                     }
393                     break;
394 
395                 case EVENT_DATA_ROAMING_OK:
396                     notificationMgr.hideDataRoamingNotification();
397                     break;
398 
399                 case MMI_COMPLETE:
400                     onMMIComplete((AsyncResult) msg.obj);
401                     break;
402 
403                 case MMI_CANCEL:
404                     PhoneUtils.cancelMmiCode(mCM.getFgPhone());
405                     break;
406 
407                 case EVENT_SIM_STATE_CHANGED:
408                     EventSimStateChangedBag bag = (EventSimStateChangedBag)msg.obj;
409                     // Dismiss the "No services" notification if the SIM is removed.
410                     if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(bag.mIccStatus)) {
411                         notificationMgr.dismissNetworkSelectionNotificationForInactiveSubId();
412                     }
413 
414                     // Marks the event where the SIM goes into ready state.
415                     // Right now, this is only used for the PUK-unlocking process.
416                     if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(bag.mIccStatus)
417                             || IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(bag.mIccStatus)
418                             || IccCardConstants.INTENT_VALUE_ICC_NOT_READY.equals(bag.mIccStatus)
419                             || IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(bag.mIccStatus)) {
420                         // When the right event is triggered and there are UI objects in the
421                         // foreground, we close them to display the lock panel.
422                         if (mPUKEntryActivity != null) {
423                             Log.i(LOG_TAG, "Dismiss puk entry activity");
424                             mPUKEntryActivity.finish();
425                             mPUKEntryActivity = null;
426                         }
427                         if (mPUKEntryProgressDialog != null) {
428                             Log.i(LOG_TAG, "Dismiss puk progress dialog");
429                             mPUKEntryProgressDialog.dismiss();
430                             mPUKEntryProgressDialog = null;
431                         }
432                         Log.i(LOG_TAG, "Dismissing depersonal panel" + (bag.mIccStatus));
433                         IccNetworkDepersonalizationPanel.dialogDismiss(bag.mPhoneId);
434                     }
435                     break;
436 
437                 case EVENT_UNSOL_CDMA_INFO_RECORD:
438                     //TODO: handle message here;
439                     break;
440                 case EVENT_DATA_ROAMING_SETTINGS_CHANGED:
441                     if (mFeatureFlags.reorganizeRoamingNotification()) {
442                         updateDataRoamingStatus(
443                                 ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED);
444                     } else {
445                         updateDataRoamingStatusForFeatureDisabled(null);
446                     }
447                     break;
448                 case EVENT_MOBILE_DATA_SETTINGS_CHANGED:
449                     if (mFeatureFlags.reorganizeRoamingNotification()) {
450                         updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED);
451                     } else {
452                         updateDataRoamingStatusForFeatureDisabled(null);
453                     }
454                     break;
455                 case EVENT_CARRIER_CONFIG_CHANGED:
456                     int subId = (Integer) msg.obj;
457                     // The voicemail number could be overridden by carrier config, so need to
458                     // refresh the message waiting (voicemail) indicator.
459                     refreshMwiIndicator(subId);
460                     phone = getPhone(subId);
461                     if (phone != null) {
462                         if (isSimLocked(phone)) {
463                             // pass in subType=-1 so handleSimLock can find the actual subType if
464                             // needed. This is safe as valid values for subType are >= 0
465                             handleSimLock(-1, phone);
466                         }
467                         TelephonyManager tm = getSystemService(TelephonyManager.class);
468                         PhoneAppCallback callback = mTelephonyCallbacks[phone.getPhoneId()];
469                         // TODO: We may need to figure out a way to unregister if subId is invalid
470                         tm.createForSubscriptionId(callback.getSubId())
471                                 .unregisterTelephonyCallback(callback);
472                         callback = new PhoneAppCallback(subId);
473                         tm.createForSubscriptionId(subId).registerTelephonyCallback(
474                                 TelephonyManager.INCLUDE_LOCATION_DATA_COARSE, mHandler::post,
475                                 callback);
476                         mTelephonyCallbacks[phone.getPhoneId()] = callback;
477                     }
478                     break;
479                 case EVENT_MULTI_SIM_CONFIG_CHANGED:
480                     int activeModems = (int) ((AsyncResult) msg.obj).result;
481                     TelephonyManager tm = getSystemService(TelephonyManager.class);
482                     // Unregister all previous callbacks
483                     for (int phoneId = 0; phoneId < mTelephonyCallbacks.length; phoneId++) {
484                         PhoneAppCallback callback = mTelephonyCallbacks[phoneId];
485                         if (callback != null) {
486                             tm.createForSubscriptionId(callback.getSubId())
487                                     .unregisterTelephonyCallback(callback);
488                             mTelephonyCallbacks[phoneId] = null;
489                         }
490                     }
491                     // Register callbacks for all active modems
492                     for (int phoneId = 0; phoneId < activeModems; phoneId++) {
493                         int sub = PhoneFactory.getPhone(phoneId).getSubId();
494                         PhoneAppCallback callback = new PhoneAppCallback(sub);
495                         tm.createForSubscriptionId(sub).registerTelephonyCallback(
496                                 TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mHandler::post,
497                                 callback);
498                         mTelephonyCallbacks[phoneId] = callback;
499                     }
500                     break;
501             }
502         }
503     };
504 
PhoneGlobals(Context context)505     public PhoneGlobals(Context context) {
506         super(context);
507         sMe = this;
508         if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()) {
509             if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
510                 mSettingsObserver = new SettingsObserver(context, mHandler);
511             }
512         } else {
513             mSettingsObserver = new SettingsObserver(context, mHandler);
514         }
515     }
516 
onCreate()517     public void onCreate() {
518         if (VDBG) Log.v(LOG_TAG, "onCreate()...");
519 
520         ContentResolver resolver = getContentResolver();
521 
522         if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
523                 && !getResources().getBoolean(
524                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
525             if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
526                 Log.v(LOG_TAG, "onCreate()... but not defined FEATURE_TELEPHONY");
527                 return;
528             }
529         }
530 
531         // Initialize the shim from frameworks/opt/telephony into packages/services/Telephony.
532         TelephonyLocalConnection.setInstance(new LocalConnectionImpl(this));
533 
534         TelephonyManager tm = getSystemService(TelephonyManager.class);
535         // Cache the "voice capable" flag.
536         // This flag currently comes from a resource (which is
537         // overrideable on a per-product basis):
538         sVoiceCapable = tm.isVoiceCapable();
539         // ...but this might eventually become a PackageManager "system
540         // feature" instead, in which case we'd do something like:
541         // sVoiceCapable =
542         //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
543 
544         if (mCM == null) {
545             // Initialize AnomalyReporter early so that it can be used
546             AnomalyReporter.initialize(this);
547 
548             // Inject telephony component factory if configured using other jars.
549             XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection);
550             TelephonyComponentFactory.getInstance().injectTheComponentFactory(parser);
551 
552             // Create DomainSelectionResolver always, but it MUST be initialized only when
553             // the device supports AOSP domain selection architecture and
554             // has new IRadio that supports its related HAL APIs.
555             String dssComponentName = getResources().getString(
556                     R.string.config_domain_selection_service_component_name);
557             DomainSelectionResolver.make(this, dssComponentName);
558 
559             // Initialize the telephony framework
560             PhoneFactory.makeDefaultPhones(this, mFeatureFlags);
561 
562             // Initialize the DomainSelectionResolver after creating the Phone instance
563             // to check the Radio HAL version.
564             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
565                 DomainSelectionResolver.getInstance().initialize();
566                 // Initialize EmergencyStateTracker if domain selection is supported
567                 boolean isSuplDdsSwitchRequiredForEmergencyCall = getResources()
568                         .getBoolean(R.bool.config_gnss_supl_requires_default_data_for_emergency);
569                 EmergencyStateTracker.make(this, isSuplDdsSwitchRequiredForEmergencyCall);
570                 DynamicRoutingController.getInstance().initialize(this);
571             }
572 
573             // Only bring up ImsResolver if the device supports having an IMS stack.
574             if (getPackageManager().hasSystemFeature(
575                     PackageManager.FEATURE_TELEPHONY_IMS)) {
576                 // Get the package name of the default IMS implementation.
577                 String defaultImsMmtelPackage = getResources().getString(
578                         R.string.config_ims_mmtel_package);
579                 String defaultImsRcsPackage = getResources().getString(
580                         R.string.config_ims_rcs_package);
581                 ImsResolver.make(this, defaultImsMmtelPackage,
582                         defaultImsRcsPackage, PhoneFactory.getPhones().length,
583                         new ImsFeatureBinderRepository(), mFeatureFlags);
584                 ImsResolver.getInstance().initialize();
585 
586                 // With the IMS phone created, load static config.xml values from the phone process
587                 // so that it can be provided to the ImsPhoneCallTracker.
588                 for (Phone p : PhoneFactory.getPhones()) {
589                     Phone imsPhone = p.getImsPhone();
590                     if (imsPhone != null && imsPhone instanceof ImsPhone) {
591                         ImsPhone theImsPhone = (ImsPhone) imsPhone;
592                         if (theImsPhone.getCallTracker() instanceof ImsPhoneCallTracker) {
593                             ImsPhoneCallTracker ict = (ImsPhoneCallTracker)
594                                     theImsPhone.getCallTracker();
595 
596                             ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
597                             config.isD2DCommunicationSupported = getResources().getBoolean(
598                                     R.bool.config_use_device_to_device_communication);
599                             ict.setConfig(config);
600                         }
601                     }
602                 }
603                 RcsProvisioningMonitor.make(this);
604             }
605 
606             // Start TelephonyDebugService After the default phone is created.
607             Intent intent = new Intent(this, TelephonyDebugService.class);
608             startService(intent);
609 
610             mCM = CallManager.getInstance();
611 
612             // Create the NotificationMgr singleton, which is used to display
613             // status bar icons and control other status bar behavior.
614             notificationMgr = NotificationMgr.init(this);
615 
616             // Create the SatelliteController singleton, which acts as a backend service for
617             // {@link android.telephony.satellite.SatelliteManager}.
618             SatelliteController.make(this, mFeatureFlags);
619 
620             // Create an instance of CdmaPhoneCallState and initialize it to IDLE
621             cdmaPhoneCallState = new CdmaPhoneCallState();
622             cdmaPhoneCallState.CdmaPhoneCallStateInit();
623 
624             // before registering for phone state changes
625             mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
626             mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG);
627             // lock used to keep the processor awake, when we don't care for the display.
628             mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
629                     | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
630 
631             mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
632 
633             phoneMgr = PhoneInterfaceManager.init(this, mFeatureFlags);
634 
635             imsRcsController = ImsRcsController.init(this, mFeatureFlags);
636 
637             configLoader = CarrierConfigLoader.init(this, mFeatureFlags);
638 
639             if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
640                 mImsStateCallbackController =
641                         ImsStateCallbackController.make(this, PhoneFactory.getPhones().length);
642                 mTelephonyRcsService = new TelephonyRcsService(this,
643                         PhoneFactory.getPhones().length, mFeatureFlags);
644                 mTelephonyRcsService.initialize();
645                 imsRcsController.setRcsService(mTelephonyRcsService);
646                 mImsProvisioningController =
647                         ImsProvisioningController.make(this, PhoneFactory.getPhones().length,
648                                 mFeatureFlags);
649             }
650 
651             // Create the CallNotifier singleton, which handles
652             // asynchronous events from the telephony layer (like
653             // launching the incoming-call UI when an incoming call comes
654             // in.)
655             notifier = CallNotifier.init(this);
656 
657             PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED);
658 
659             // register for MMI/USSD
660             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
661 
662             // Initialize cell status using current airplane mode.
663             handleAirplaneModeChange(
664                     Settings.Global.getInt(
665                                     getContentResolver(),
666                                     Settings.Global.AIRPLANE_MODE_ON,
667                                     AIRPLANE_OFF)
668                             == AIRPLANE_ON);
669 
670             // Register for misc other intent broadcasts.
671             IntentFilter intentFilter =
672                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
673             intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
674             intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
675             intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
676             intentFilter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
677             intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
678             registerReceiver(mReceiver, intentFilter);
679             int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
680             if (SubscriptionManager.isValidSubscriptionId(defaultDataSubId)) {
681                 if (VDBG) {
682                     Log.v(LOG_TAG, "Loaded initial default data sub: " + defaultDataSubId);
683                 }
684                 mDefaultDataSubId = defaultDataSubId;
685                 registerSettingsObserver();
686                 updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED);
687             }
688 
689             PhoneConfigurationManager.registerForMultiSimConfigChange(
690                     mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
691 
692             mTelephonyCallbacks = new PhoneAppCallback[tm.getSupportedModemCount()];
693             if (tm.getSupportedModemCount() > 0) {
694                 for (Phone phone : PhoneFactory.getPhones()) {
695                     int subId = phone.getSubId();
696                     PhoneAppCallback callback = new PhoneAppCallback(subId);
697                     tm.createForSubscriptionId(subId).registerTelephonyCallback(
698                             TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mHandler::post, callback);
699                     mTelephonyCallbacks[phone.getPhoneId()] = callback;
700                 }
701             }
702             mCarrierVvmPackageInstalledReceiver.register(this);
703 
704             //set the default values for the preferences in the phone.
705             PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
706         }
707 
708         // XXX pre-load the SimProvider so that it's ready
709         resolver.getType(Uri.parse("content://icc/adn"));
710 
711         // TODO: Register for Cdma Information Records
712         // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null);
713 
714         // Read HAC settings and configure audio hardware
715         if (getResources().getBoolean(R.bool.hac_enabled)) {
716             int hac = android.provider.Settings.System.getInt(
717                     getContentResolver(),
718                     android.provider.Settings.System.HEARING_AID,
719                     0);
720             AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
721             audioManager.setParameters(
722                     SettingsConstants.HAC_KEY + "=" + (hac == SettingsConstants.HAC_ENABLED
723                             ? SettingsConstants.HAC_VAL_ON : SettingsConstants.HAC_VAL_OFF));
724         }
725 
726         // Start tracking Binder latency for the phone process.
727         mBinderCallsSettingsObserver = new BinderCallsStats.SettingsObserver(
728             getApplicationContext(),
729             new BinderCallsStats(
730                     new BinderCallsStats.Injector(),
731                     com.android.internal.os.BinderLatencyProto.Dims.TELEPHONY));
732     }
733 
734     /**
735      * Returns the singleton instance of the PhoneApp.
736      */
getInstance()737     public static PhoneGlobals getInstance() {
738         if (sMe == null) {
739             throw new IllegalStateException("No PhoneGlobals here!");
740         }
741         return sMe;
742     }
743 
744     /**
745      * Returns the default phone.
746      *
747      * WARNING: This method should be used carefully, now that there may be multiple phones.
748      */
getPhone()749     public static Phone getPhone() {
750         return PhoneFactory.getDefaultPhone();
751     }
752 
getPhone(int subId)753     public static Phone getPhone(int subId) {
754         return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
755     }
756 
getCallManager()757     /* package */ CallManager getCallManager() {
758         return mCM;
759     }
760 
getCarrierConfig()761     public PersistableBundle getCarrierConfig() {
762         return getCarrierConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
763     }
764 
getCarrierConfigForSubId(int subId)765     public PersistableBundle getCarrierConfigForSubId(int subId) {
766         return configLoader.getConfigForSubIdWithFeature(subId, getOpPackageName(),
767                 getAttributionTag());
768     }
769 
registerSettingsObserver()770     private void registerSettingsObserver() {
771         mSettingsObserver.unobserve();
772         String dataRoamingSetting = Settings.Global.DATA_ROAMING;
773         String mobileDataSetting = Settings.Global.MOBILE_DATA;
774         if (TelephonyManager.getDefault().getSimCount() > 1) {
775             int subId = mDefaultDataSubId;
776             if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
777                 dataRoamingSetting += subId;
778                 mobileDataSetting += subId;
779             }
780         }
781 
782         // Listen for user data roaming setting changed event
783         mSettingsObserver.observe(Settings.Global.getUriFor(dataRoamingSetting),
784                 EVENT_DATA_ROAMING_SETTINGS_CHANGED);
785 
786         // Listen for mobile data setting changed event
787         mSettingsObserver.observe(Settings.Global.getUriFor(mobileDataSetting),
788                 EVENT_MOBILE_DATA_SETTINGS_CHANGED);
789     }
790 
791     /**
792      * Sets the activity responsible for un-PUK-blocking the device
793      * so that we may close it when we receive a positive result.
794      * mPUKEntryActivity is also used to indicate to the device that
795      * we are trying to un-PUK-lock the phone. In other words, iff
796      * it is NOT null, then we are trying to unlock and waiting for
797      * the SIM to move to READY state.
798      *
799      * @param activity is the activity to close when PUK has
800      * finished unlocking. Can be set to null to indicate the unlock
801      * or SIM READYing process is over.
802      */
setPukEntryActivity(Activity activity)803     void setPukEntryActivity(Activity activity) {
804         Log.i(LOG_TAG, "setPukEntryActivity - set to " + (activity == null ? "null" : "activity"));
805         mPUKEntryActivity = activity;
806     }
807 
getPUKEntryActivity()808     Activity getPUKEntryActivity() {
809         return mPUKEntryActivity;
810     }
811 
812     /**
813      * Sets the dialog responsible for notifying the user of un-PUK-
814      * blocking - SIM READYing progress, so that we may dismiss it
815      * when we receive a positive result.
816      *
817      * @param dialog indicates the progress dialog informing the user
818      * of the state of the device.  Dismissed upon completion of
819      * READYing process
820      */
setPukEntryProgressDialog(ProgressDialog dialog)821     void setPukEntryProgressDialog(ProgressDialog dialog) {
822         Log.i(LOG_TAG, "setPukEntryProgressDialog - set to "
823                 + (dialog == null ? "null" : "activity"));
824         mPUKEntryProgressDialog = dialog;
825     }
826 
getKeyguardManager()827     KeyguardManager getKeyguardManager() {
828         return mKeyguardManager;
829     }
830 
onMMIComplete(AsyncResult r)831     private void onMMIComplete(AsyncResult r) {
832         if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
833         MmiCode mmiCode = (MmiCode) r.result;
834         PhoneUtils.displayMMIComplete(mmiCode.getPhone(), getInstance(), mmiCode, null, null);
835     }
836 
initForNewRadioTechnology()837     private void initForNewRadioTechnology() {
838         if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
839         notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
840     }
841 
handleAirplaneModeChange(boolean isAirplaneNewlyOn)842     private void handleAirplaneModeChange(boolean isAirplaneNewlyOn) {
843         Log.i(LOG_TAG, "handleAirplaneModeChange: isAirplaneNewlyOn=" + isAirplaneNewlyOn);
844         int cellState =
845                 Settings.Global.getInt(
846                         getContentResolver(), Settings.Global.CELL_ON, PhoneConstants.CELL_ON_FLAG);
847         switch (cellState) {
848             case PhoneConstants.CELL_OFF_FLAG:
849                 // Airplane mode does not affect the cell radio if user has turned it off.
850                 Log.i(LOG_TAG, "Ignore airplane mode change due to cell off.");
851                 break;
852             case PhoneConstants.CELL_ON_FLAG:
853                 maybeTurnCellOff(isAirplaneNewlyOn);
854                 break;
855             case PhoneConstants.CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG:
856                 maybeTurnCellOn(isAirplaneNewlyOn);
857                 break;
858         }
859         for (Phone phone : PhoneFactory.getPhones()) {
860             phone.getServiceStateTracker().onAirplaneModeChanged(isAirplaneNewlyOn);
861         }
862     }
863 
864     /*
865      * Returns true if the radio must be turned off when entering airplane mode.
866      */
isCellOffInAirplaneMode()867     private boolean isCellOffInAirplaneMode() {
868         String airplaneModeRadios =
869                 Settings.Global.getString(
870                         getContentResolver(), Settings.Global.AIRPLANE_MODE_RADIOS);
871         return airplaneModeRadios == null
872                 || airplaneModeRadios.contains(Settings.Global.RADIO_CELL);
873     }
874 
setRadioPowerOff()875     private void setRadioPowerOff() {
876         Log.i(LOG_TAG, "Turning radio off - airplane");
877         Settings.Global.putInt(
878                 getContentResolver(),
879                 Settings.Global.CELL_ON,
880                 PhoneConstants.CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG);
881         Settings.Global.putInt(getContentResolver(), Settings.Global.ENABLE_CELLULAR_ON_BOOT, 0);
882         TelephonyProperties.airplane_mode_on(true); // true means int value 1
883         PhoneUtils.setRadioPower(false);
884         clearCacheOnRadioOff();
885     }
886 
887     /** Clear fields on power off radio **/
clearCacheOnRadioOff()888     private void clearCacheOnRadioOff() {
889         // Re-show is-roaming notifications after APM mode
890         if (mFeatureFlags.reorganizeRoamingNotification()) {
891             mShownNotificationReasons.clear();
892         } else {
893             mPrevRoamingOperatorNumerics.clear();
894         }
895     }
896 
setRadioPowerOn()897     private void setRadioPowerOn() {
898         Log.i(LOG_TAG, "Turning radio on - airplane");
899         Settings.Global.putInt(
900                 getContentResolver(), Settings.Global.CELL_ON, PhoneConstants.CELL_ON_FLAG);
901         Settings.Global.putInt(getContentResolver(), Settings.Global.ENABLE_CELLULAR_ON_BOOT, 1);
902         TelephonyProperties.airplane_mode_on(false); // false means int value 0
903         PhoneUtils.setRadioPower(true);
904     }
905 
maybeTurnCellOff(boolean isAirplaneNewlyOn)906     private void maybeTurnCellOff(boolean isAirplaneNewlyOn) {
907         if (isAirplaneNewlyOn) {
908             // If we are trying to turn off the radio, make sure there are no active
909             // emergency calls.  If there are, switch airplane mode back to off.
910             TelecomManager tm = (TelecomManager) getSystemService(TELECOM_SERVICE);
911 
912             if (tm != null && tm.isInEmergencyCall()) {
913                 // Switch airplane mode back to off.
914                 ConnectivityManager cm =
915                         (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
916                 cm.setAirplaneMode(false);
917                 Toast.makeText(this, R.string.radio_off_during_emergency_call, Toast.LENGTH_LONG)
918                         .show();
919                 Log.i(LOG_TAG, "Ignoring airplane mode: emergency call. Turning airplane off");
920             } else if (isCellOffInAirplaneMode()) {
921                 setRadioPowerOff();
922             } else {
923                 Log.i(LOG_TAG, "Ignoring airplane mode: settings prevent cell radio power off");
924             }
925         } else {
926             Log.i(LOG_TAG, "Ignoring airplane mode: not newly on");
927         }
928     }
929 
maybeTurnCellOn(boolean isAirplaneNewlyOn)930     private void maybeTurnCellOn(boolean isAirplaneNewlyOn) {
931         if (!isAirplaneNewlyOn) {
932             setRadioPowerOn();
933         } else {
934             Log.i(LOG_TAG, "Ignoring airplane mode off: radio is already on.");
935         }
936     }
937 
938     /**
939      * Receiver for misc intent broadcasts the Phone app cares about.
940      */
941     private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
942         @Override
onReceive(Context context, Intent intent)943         public void onReceive(Context context, Intent intent) {
944             String action = intent.getAction();
945             if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
946                 boolean airplaneMode = intent.getBooleanExtra("state", false);
947                 handleAirplaneModeChange(airplaneMode);
948             } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
949                 // re-register as it may be a new IccCard
950                 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY,
951                         SubscriptionManager.INVALID_PHONE_INDEX);
952                 if (SubscriptionManager.isValidPhoneId(phoneId)) {
953                     PhoneUtils.unregisterIccStatus(mHandler, phoneId);
954                     PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED, phoneId);
955                 }
956                 String iccStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
957                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
958                         new EventSimStateChangedBag(phoneId, iccStatus)));
959             } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
960                 String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
961                 Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
962                 initForNewRadioTechnology();
963             } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
964                 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
965                 phoneInEcm = PhoneFactory.getPhone(phoneId);
966                 Log.d(LOG_TAG, "Emergency Callback Mode. phoneId:" + phoneId);
967                 if (phoneInEcm != null) {
968                     if (TelephonyCapabilities.supportsEcm(phoneInEcm)) {
969                         Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp.");
970                         // Start Emergency Callback Mode service
971                         if (intent.getBooleanExtra(
972                                 TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false)) {
973                             context.startService(new Intent(context,
974                                     EmergencyCallbackModeService.class));
975                         } else {
976                             phoneInEcm = null;
977                         }
978                     } else {
979                         // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
980                         // on a device that doesn't support ECM in the first place.
981                         Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, but "
982                                 + "ECM isn't supported for phone: " + phoneInEcm.getPhoneName());
983                         phoneInEcm = null;
984                     }
985                 } else {
986                     Log.w(LOG_TAG, "phoneInEcm is null.");
987                 }
988             } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
989                 // Roaming status could be overridden by carrier config, so we need to update it.
990                 if (VDBG) Log.v(LOG_TAG, "carrier config changed.");
991                 if (mFeatureFlags.reorganizeRoamingNotification()) {
992                     updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED);
993                 } else {
994                     updateDataRoamingStatusForFeatureDisabled(null);
995                 }
996                 updateLimitedSimFunctionForDualSim();
997                 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
998                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
999                 if (SubscriptionManager.isValidSubscriptionId(subId)) {
1000                     mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_CONFIG_CHANGED,
1001                             new Integer(subId)));
1002                 }
1003             } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
1004                 // We also need to pay attention when default data subscription changes.
1005                 if (VDBG) Log.v(LOG_TAG, "default data sub changed.");
1006                 mDefaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
1007                 registerSettingsObserver();
1008                 Phone phone = getPhone(mDefaultDataSubId);
1009                 if (phone != null) {
1010                     if (mFeatureFlags.reorganizeRoamingNotification()) {
1011                         updateDataRoamingStatus(
1012                                 ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED);
1013                     } else {
1014                         updateDataRoamingStatusForFeatureDisabled(null);
1015                     }
1016                 }
1017             }
1018         }
1019     }
1020 
handleServiceStateChanged(ServiceState serviceState, int subId)1021     private void handleServiceStateChanged(ServiceState serviceState, int subId) {
1022         if (VDBG) Log.v(LOG_TAG, "handleServiceStateChanged");
1023         int state = serviceState.getState();
1024         notificationMgr.updateNetworkSelection(state, subId);
1025 
1026         if (VDBG) {
1027             Log.v(LOG_TAG, "subId=" + subId + ", mDefaultDataSubId="
1028                     + mDefaultDataSubId + ", ss roaming=" + serviceState.getDataRoaming());
1029         }
1030         if (subId == mDefaultDataSubId) {
1031             if (mFeatureFlags.reorganizeRoamingNotification()) {
1032                 updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED);
1033             } else {
1034                 updateDataRoamingStatusForFeatureDisabled(serviceState.getOperatorNumeric());
1035             }
1036         }
1037     }
1038 
1039     /**
1040      * When roaming, if mobile data cannot be established due to data roaming not enabled, we need
1041      * to notify the user so they can enable it through settings. Vise versa if the condition
1042      * changes, we need to dismiss the notification.
1043      * @param notificationReason to inform which event is called for notification update.
1044      */
updateDataRoamingStatus(@oamingNotificationReason int notificationReason)1045     private void updateDataRoamingStatus(@RoamingNotificationReason int notificationReason) {
1046         Phone phone = getPhone(mDefaultDataSubId);
1047         if (phone == null) {
1048             Log.w(LOG_TAG, "Can't get phone with sub id = " + mDefaultDataSubId);
1049             return;
1050         }
1051 
1052         ServiceState serviceState = phone.getServiceState();
1053         if (serviceState == null) {
1054             Log.e(LOG_TAG, "updateDataRoamingStatus: serviceState is null");
1055             return;
1056         }
1057 
1058         List<DataDisallowedReason> disallowReasons = phone.getDataNetworkController()
1059                 .getInternetDataDisallowedReasons();
1060 
1061         if (mFeatureFlags.roamingNotificationForSingleDataNetwork()) {
1062             if (disallowReasons.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)
1063                     && disallowReasons.contains(DataDisallowedReason.ROAMING_DISABLED)
1064                     && (notificationReason == ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED
1065                             || notificationReason
1066                                     == ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED)) {
1067                 // If the ONLY_ALLOWED_SINGLE_NETWORK disallow reason has not yet been removed due
1068                 // to a change in mobile_data (including roaming_data) settings, update roaming
1069                 // notification again after the Internet is completely disconnected to check
1070                 // ONLY_ALLOWED_SINGLE_NETWORK disallow reason is removed.
1071                 mWaitForInternetDisconnection.set(true);
1072                 Log.d(LOG_TAG, "updateDataRoamingStatus,"
1073                         + " wait for internet disconnection for single data network");
1074             } else if (!disallowReasons.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)
1075                     && mWaitForInternetDisconnection.compareAndSet(true, false)) {
1076                 // If the ONLY_ALLOWED_SINGLE_NETWORK disallow reason has been removed,
1077                 // no longer wait for Internet disconnection.
1078                 Log.d(LOG_TAG, "updateDataRoamingStatus,"
1079                         + " cancel to wait for internet disconnection for single data network");
1080             }
1081         }
1082 
1083         updateDataRoamingStatus(notificationReason, disallowReasons, serviceState);
1084     }
1085 
1086     /**
1087      * When roaming, if mobile data cannot be established due to data roaming not enabled, we need
1088      * to notify the user so they can enable it through settings. Vise versa if the condition
1089      * changes, we need to dismiss the notification.
1090      * @param notificationReason to inform which event is called for notification update.
1091      * @param disallowReasons List of reasons why internet data is not allowed. An empty list if
1092      *                       internet is allowed.
1093      * @param serviceState Service state from phone
1094      */
updateDataRoamingStatus(@oamingNotificationReason int notificationReason, List<DataDisallowedReason> disallowReasons, ServiceState serviceState)1095     private void updateDataRoamingStatus(@RoamingNotificationReason int notificationReason,
1096             List<DataDisallowedReason> disallowReasons, ServiceState serviceState) {
1097 
1098         if (VDBG) Log.v(LOG_TAG, "updateDataRoamingStatus");
1099         String roamingNumeric = serviceState.getOperatorNumeric();
1100         String roamingNumericReason = "RoamingNumeric=" + roamingNumeric;
1101         String callingReason = "CallingReason=" + notificationReason;
1102         boolean dataIsNowRoaming = serviceState.getDataRoaming();
1103         boolean dataAllowed;
1104         boolean notAllowedDueToRoamingOff;
1105         dataAllowed = disallowReasons.isEmpty();
1106         notAllowedDueToRoamingOff = (disallowReasons.size() == 1
1107                 && disallowReasons.contains(DataDisallowedReason.ROAMING_DISABLED));
1108         StringBuilder sb = new StringBuilder("updateDataRoamingStatus");
1109         sb.append(" dataAllowed=").append(dataAllowed);
1110         sb.append(", disallowReasons=").append(disallowReasons);
1111         sb.append(", dataIsNowRoaming=").append(dataIsNowRoaming);
1112         sb.append(", ").append(roamingNumericReason);
1113         sb.append(", ").append(callingReason);
1114         mDataRoamingNotifLog.log(sb.toString());
1115         if (VDBG) {
1116             Log.v(LOG_TAG, sb.toString());
1117         }
1118 
1119         // Determine if a given roaming numeric has never been shown.
1120         boolean shownInThisNumeric = false;
1121         if (notificationReason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED
1122                 || notificationReason == ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED) {
1123             shownInThisNumeric = mShownNotificationReasons.contains(roamingNumericReason);
1124         }
1125         // Determine if a notification has never been shown by given calling reason.
1126         boolean shownForThisReason = mShownNotificationReasons.contains(callingReason);
1127 
1128         if (!dataAllowed && notAllowedDueToRoamingOff) {
1129             if (!shownInThisNumeric && roamingNumeric != null) {
1130                 mShownNotificationReasons.add(roamingNumericReason);
1131             }
1132             if (!shownForThisReason
1133                     && notificationReason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED) {
1134                 mShownNotificationReasons.add(callingReason);
1135             }
1136             // No need to show it again if we never cancelled it explicitly.
1137             if (getCurrentRoamingNotification() == ROAMING_NOTIFICATION_DISCONNECTED) {
1138                 return;
1139             }
1140 
1141             // If the only reason of no data is data roaming disabled, then we notify the user
1142             // so the user can turn on data roaming.
1143             if (!shownInThisNumeric && !shownForThisReason) {
1144                 updateDataRoamingNotification(ROAMING_NOTIFICATION_DISCONNECTED);
1145             } else {
1146                 // Don't show roaming notification if we've already shown for this MccMnc
1147                 Log.d(LOG_TAG, "Skip roaming disconnected notification since already"
1148                         + " shownInThisNumeric=" + shownInThisNumeric
1149                         + " shownForThisReason=" + shownForThisReason);
1150                 // Dismiss notification if the other notification is shown.
1151                 if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
1152                     updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION);
1153                 }
1154             }
1155         } else if (dataAllowed && dataIsNowRoaming) {
1156             if (!shownInThisNumeric && roamingNumeric != null) {
1157                 mShownNotificationReasons.add(roamingNumericReason);
1158             }
1159             if (!shownForThisReason
1160                     && notificationReason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED) {
1161                 mShownNotificationReasons.add(callingReason);
1162             }
1163             boolean shouldShowRoamingNotification = shouldShowRoamingNotification(roamingNumeric);
1164             // No need to show it again if we never cancelled it explicitly.
1165             if (getCurrentRoamingNotification() == ROAMING_NOTIFICATION_CONNECTED) {
1166                 return;
1167             }
1168 
1169             // Inform users that roaming charges may apply.
1170             if (!shownInThisNumeric && !shownForThisReason && shouldShowRoamingNotification) {
1171                 updateDataRoamingNotification(ROAMING_NOTIFICATION_CONNECTED);
1172             } else {
1173                 // Don't show roaming notification if we've already shown for this MccMnc or
1174                 // disabled from carrier config.
1175                 Log.d(LOG_TAG, "Skip roaming connected notification since already"
1176                         + " shownInThisNumeric:" + shownInThisNumeric
1177                         + " shownForThisReason:" + shownForThisReason
1178                         + " shouldShowRoamingNotification:" + shouldShowRoamingNotification);
1179                 // Dismiss notification if the other notification is shown.
1180                 if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
1181                     updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION);
1182                 }
1183             }
1184         } else if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
1185             // Otherwise we either 1) we are not roaming or 2) roaming is off but ROAMING_DISABLED
1186             // is not the only data disable reason. In this case we dismiss the notification we
1187             // showed earlier.
1188             updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION);
1189         }
1190     }
1191 
updateDataRoamingNotification(@oamingNotification int roamingNotification)1192     private void updateDataRoamingNotification(@RoamingNotification int roamingNotification) {
1193         int event;
1194         switch (roamingNotification) {
1195             case ROAMING_NOTIFICATION_NO_NOTIFICATION:
1196                 Log.d(LOG_TAG, "Dismiss roaming notification");
1197                 mDataRoamingNotifLog.log("Hide roaming.");
1198                 event = EVENT_DATA_ROAMING_OK;
1199                 break;
1200             case ROAMING_NOTIFICATION_CONNECTED:
1201                 Log.d(LOG_TAG, "Show roaming connected notification");
1202                 mDataRoamingNotifLog.log("Show roaming on.");
1203                 event = EVENT_DATA_ROAMING_CONNECTED;
1204                 break;
1205             case ROAMING_NOTIFICATION_DISCONNECTED:
1206                 Log.d(LOG_TAG, "Show roaming disconnected notification");
1207                 mDataRoamingNotifLog.log("Show roaming off.");
1208                 event = EVENT_DATA_ROAMING_DISCONNECTED;
1209                 break;
1210             default:
1211                 Log.d(LOG_TAG, "Should never reach here.");
1212                 mDataRoamingNotifLog.log("Should never reach here.");
1213                 return;
1214         }
1215         mCurrentRoamingNotification = roamingNotification;
1216         mHandler.obtainMessage(event, mDefaultDataSubId, 0).sendToTarget();
1217     }
1218 
getCurrentRoamingNotification()1219     private @RoamingNotification int getCurrentRoamingNotification() {
1220         return mCurrentRoamingNotification;
1221     }
1222 
1223     // For reorganize_roaming_notification feature disabled.
1224     /**
1225      * When roaming, if mobile data cannot be established due to data roaming not enabled, we need
1226      * to notify the user so they can enable it through settings. Vise versa if the condition
1227      * changes, we need to dismiss the notification.
1228      * @param roamingOperatorNumeric The operator numeric for the current roaming. {@code null} if
1229      *                               the current roaming operator numeric didn't change.
1230      */
updateDataRoamingStatusForFeatureDisabled( @ullable String roamingOperatorNumeric)1231     private void updateDataRoamingStatusForFeatureDisabled(
1232             @Nullable String roamingOperatorNumeric) {
1233         if (VDBG) Log.v(LOG_TAG, "updateDataRoamingStatusForFeatureDisabled");
1234         Phone phone = getPhone(mDefaultDataSubId);
1235         if (phone == null) {
1236             Log.w(LOG_TAG, "Can't get phone with sub id = " + mDefaultDataSubId);
1237             return;
1238         }
1239 
1240         boolean dataAllowed;
1241         boolean notAllowedDueToRoamingOff;
1242         List<DataDisallowedReason> reasons = phone.getDataNetworkController()
1243                 .getInternetDataDisallowedReasons();
1244         dataAllowed = reasons.isEmpty();
1245         notAllowedDueToRoamingOff = (reasons.size() == 1
1246                 && reasons.contains(DataDisallowedReason.ROAMING_DISABLED));
1247         mDataRoamingNotifLog.log("dataAllowed=" + dataAllowed + ", reasons=" + reasons
1248                 + ", roamingOperatorNumeric=" + roamingOperatorNumeric);
1249         if (VDBG) {
1250             Log.v(LOG_TAG, "dataAllowed=" + dataAllowed + ", reasons=" + reasons
1251                     + ", roamingOperatorNumeric=" + roamingOperatorNumeric);
1252         }
1253 
1254         if (!dataAllowed && notAllowedDueToRoamingOff) {
1255             // Don't show roaming notification if we've already shown for this MccMnc
1256             if (roamingOperatorNumeric != null
1257                     && !mPrevRoamingOperatorNumerics.add(roamingOperatorNumeric)) {
1258                 Log.d(LOG_TAG, "Skip roaming disconnected notification since already shown in "
1259                         + "MccMnc " + roamingOperatorNumeric);
1260                 return;
1261             }
1262             // No need to show it again if we never cancelled it explicitly.
1263             if (mPrevRoamingNotification == ROAMING_NOTIFICATION_DISCONNECTED) return;
1264             // If the only reason of no data is data roaming disabled, then we notify the user
1265             // so the user can turn on data roaming.
1266             mPrevRoamingNotification = ROAMING_NOTIFICATION_DISCONNECTED;
1267             Log.d(LOG_TAG, "Show roaming disconnected notification");
1268             mDataRoamingNotifLog.log("Show roaming off.");
1269             Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_DISCONNECTED);
1270             msg.arg1 = mDefaultDataSubId;
1271             msg.sendToTarget();
1272         } else if (dataAllowed && dataIsNowRoaming(mDefaultDataSubId)) {
1273             if (!shouldShowRoamingNotification(roamingOperatorNumeric != null
1274                         ? roamingOperatorNumeric : phone.getServiceState().getOperatorNumeric())) {
1275                 Log.d(LOG_TAG, "Skip showing roaming connected notification.");
1276                 return;
1277             }
1278             // Don't show roaming notification if we've already shown for this MccMnc
1279             if (roamingOperatorNumeric != null
1280                     && !mPrevRoamingOperatorNumerics.add(roamingOperatorNumeric)) {
1281                 Log.d(LOG_TAG, "Skip roaming connected notification since already shown in "
1282                         + "MccMnc " + roamingOperatorNumeric);
1283                 return;
1284             }
1285             // No need to show it again if we never cancelled it explicitly, or carrier config
1286             // indicates this is not needed.
1287             if (mPrevRoamingNotification == ROAMING_NOTIFICATION_CONNECTED) return;
1288             mPrevRoamingNotification = ROAMING_NOTIFICATION_CONNECTED;
1289             Log.d(LOG_TAG, "Show roaming connected notification");
1290             mDataRoamingNotifLog.log("Show roaming on.");
1291             Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_CONNECTED);
1292             msg.arg1 = mDefaultDataSubId;
1293             msg.sendToTarget();
1294         } else if (mPrevRoamingNotification != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
1295             // Otherwise we either 1) we are not roaming or 2) roaming is off but ROAMING_DISABLED
1296             // is not the only data disable reason. In this case we dismiss the notification we
1297             // showed earlier.
1298             mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
1299             Log.d(LOG_TAG, "Dismiss roaming notification");
1300             mDataRoamingNotifLog.log("Hide. data allowed=" + dataAllowed);
1301             mHandler.sendEmptyMessage(EVENT_DATA_ROAMING_OK);
1302         }
1303     }
1304 
1305     /**
1306      *
1307      * @param subId to check roaming on
1308      * @return whether we have transitioned to dataRoaming
1309      */
dataIsNowRoaming(int subId)1310     private boolean dataIsNowRoaming(int subId) {
1311         return getPhone(subId).getServiceState().getDataRoaming();
1312     }
1313 
shouldShowRoamingNotification(String roamingNumeric)1314     private boolean shouldShowRoamingNotification(String roamingNumeric) {
1315         PersistableBundle config = getCarrierConfigForSubId(mDefaultDataSubId);
1316         boolean showRoamingNotification = config.getBoolean(
1317                 CarrierConfigManager.KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL);
1318 
1319         if (TextUtils.isEmpty(roamingNumeric) || !mFeatureFlags.hideRoamingIcon()) {
1320             Log.d(LOG_TAG, "shouldShowRoamingNotification: roamingNumeric=" + roamingNumeric
1321                     + ", hideRoaming=" + mFeatureFlags.hideRoamingIcon());
1322             return showRoamingNotification;
1323         }
1324 
1325         String[] includedMccMncs = config.getStringArray(CarrierConfigManager
1326                 .KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY);
1327         if (includedMccMncs != null) {
1328             for (String mccMnc : includedMccMncs) {
1329                 if (roamingNumeric.equals(mccMnc)) {
1330                     Log.d(LOG_TAG, "shouldShowRoamingNotification: show for MCC/MNC " + mccMnc);
1331                     return showRoamingNotification;
1332                 }
1333             }
1334         }
1335 
1336         String[] excludedMccs = config.getStringArray(CarrierConfigManager
1337                 .KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY);
1338         String roamingMcc = roamingNumeric.length() < 3 ? "" : roamingNumeric.substring(0, 3);
1339         if (excludedMccs != null && !TextUtils.isEmpty(roamingMcc)) {
1340             for (String mcc : excludedMccs) {
1341                 if (roamingMcc.equals(mcc)) {
1342                     Log.d(LOG_TAG, "shouldShowRoamingNotification: ignore for MCC " + mcc);
1343                     return false;
1344                 }
1345             }
1346         }
1347 
1348         if (showRoamingNotification) {
1349             Log.d(LOG_TAG, "shouldShowRoamingNotification: show for numeric " + roamingNumeric);
1350         }
1351         return showRoamingNotification;
1352     }
1353 
1354     private void updateLimitedSimFunctionForDualSim() {
1355         if (DBG) Log.d(LOG_TAG, "updateLimitedSimFunctionForDualSim");
1356         // check conditions to display limited SIM function notification under dual SIM
1357         SubscriptionManager subMgr = (SubscriptionManager) getSystemService(
1358                 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
1359         List<SubscriptionInfo> subList = subMgr.getActiveSubscriptionInfoList(false);
1360         if (subList != null && subList.size() > 1) {
1361             CarrierConfigManager configMgr = (CarrierConfigManager)
1362                     getSystemService(Context.CARRIER_CONFIG_SERVICE);
1363             for (SubscriptionInfo info : subList) {
1364                 PersistableBundle b = configMgr.getConfigForSubId(info.getSubscriptionId());
1365                 if (b != null) {
1366                     if (b.getBoolean(CarrierConfigManager
1367                             .KEY_LIMITED_SIM_FUNCTION_NOTIFICATION_FOR_DSDS_BOOL)) {
1368                         notificationMgr.showLimitedSimFunctionWarningNotification(
1369                                 info.getSubscriptionId(),
1370                                 info.getDisplayName().toString());
1371                     } else {
1372                         notificationMgr.dismissLimitedSimFunctionWarningNotification(
1373                                 info.getSubscriptionId());
1374                     }
1375                 }
1376             }
1377         } else {
1378             // cancel notifications for all subs
1379             notificationMgr.dismissLimitedSimFunctionWarningNotification(
1380                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1381         }
1382         notificationMgr.dismissLimitedSimFunctionWarningNotificationForInactiveSubs();
1383 
1384     }
1385 
getPhoneInEcm()1386     public Phone getPhoneInEcm() {
1387         return phoneInEcm;
1388     }
1389 
1390     /**
1391      * Triggers a refresh of the message waiting (voicemail) indicator.
1392      *
1393      * @param subId the subscription id we should refresh the notification for.
1394      */
refreshMwiIndicator(int subId)1395     public void refreshMwiIndicator(int subId) {
1396         notificationMgr.refreshMwi(subId);
1397     }
1398 
1399     /**
1400      * Called when the network selection on the subscription {@code subId} is changed by the user.
1401      *
1402      * @param subId the subscription id.
1403      */
onNetworkSelectionChanged(int subId)1404     public void onNetworkSelectionChanged(int subId) {
1405         Phone phone = getPhone(subId);
1406         if (phone != null) {
1407             notificationMgr.updateNetworkSelection(phone.getServiceState().getState(), subId);
1408         } else {
1409             Log.w(LOG_TAG, "onNetworkSelectionChanged on null phone, subId: " + subId);
1410         }
1411     }
1412 
1413     /**
1414      * @return whether the device supports RCS User Capability Exchange or not.
1415      */
getDeviceUceEnabled()1416     public boolean getDeviceUceEnabled() {
1417         return (mTelephonyRcsService == null) ? false : mTelephonyRcsService.isDeviceUceEnabled();
1418     }
1419 
1420     /**
1421      * Set the device supports RCS User Capability Exchange.
1422      * @param isEnabled true if the device supports UCE.
1423      */
setDeviceUceEnabled(boolean isEnabled)1424     public void setDeviceUceEnabled(boolean isEnabled) {
1425         if (mTelephonyRcsService != null) {
1426             mTelephonyRcsService.setDeviceUceEnabled(isEnabled);
1427         }
1428     }
1429 
1430     /**
1431      * Dump the state of the object, add calls to other objects as desired.
1432      *
1433      * @param fd File descriptor
1434      * @param printWriter Print writer
1435      * @param args Arguments
1436      */
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)1437     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
1438         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
1439         pw.println("------- PhoneGlobals -------");
1440         pw.increaseIndent();
1441         pw.println("FeatureFlags:");
1442         pw.increaseIndent();
1443         pw.println("reorganizeRoamingNotification="
1444                 + mFeatureFlags.reorganizeRoamingNotification());
1445         pw.println("dismissNetworkSelectionNotificationOnSimDisable="
1446                 + mFeatureFlags.dismissNetworkSelectionNotificationOnSimDisable());
1447         pw.decreaseIndent();
1448         if (mFeatureFlags.reorganizeRoamingNotification()) {
1449             pw.println("mCurrentRoamingNotification=" + mCurrentRoamingNotification);
1450         } else {
1451             pw.println("mPrevRoamingNotification=" + mPrevRoamingNotification);
1452         }
1453         pw.println("mDefaultDataSubId=" + mDefaultDataSubId);
1454         pw.println("isSmsCapable=" + TelephonyManager.from(this).isSmsCapable());
1455         pw.println("mDataRoamingNotifLog:");
1456         pw.increaseIndent();
1457         mDataRoamingNotifLog.dump(fd, pw, args);
1458         pw.decreaseIndent();
1459         pw.println("ImsResolver:");
1460         pw.increaseIndent();
1461         try {
1462             if (ImsResolver.getInstance() != null) ImsResolver.getInstance().dump(fd, pw, args);
1463         } catch (Exception e) {
1464             e.printStackTrace();
1465         }
1466         pw.decreaseIndent();
1467         pw.println("RcsService:");
1468         try {
1469             if (mTelephonyRcsService != null) mTelephonyRcsService.dump(fd, pw, args);
1470         } catch (Exception e) {
1471             e.printStackTrace();
1472         }
1473         pw.println("ImsStateCallbackController:");
1474         try {
1475             if (mImsStateCallbackController != null) mImsStateCallbackController.dump(pw);
1476         } catch (Exception e) {
1477             e.printStackTrace();
1478         }
1479         pw.println("DomainSelectionResolver:");
1480         pw.increaseIndent();
1481         try {
1482             if (DomainSelectionResolver.getInstance() != null) {
1483                 DomainSelectionResolver.getInstance().dump(fd, pw, args);
1484             }
1485         } catch (Exception e) {
1486             e.printStackTrace();
1487         }
1488         pw.decreaseIndent();
1489         pw.decreaseIndent();
1490         if (mFeatureFlags.reorganizeRoamingNotification()) {
1491             pw.println("mShownNotificationReasons=" + mShownNotificationReasons);
1492         } else {
1493             pw.println("mPrevRoamingOperatorNumerics:" + mPrevRoamingOperatorNumerics);
1494         }
1495         pw.println("------- End PhoneGlobals -------");
1496     }
1497 }
1498