• 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.phone;
18 
19 import android.annotation.IntDef;
20 import android.app.Activity;
21 import android.app.KeyguardManager;
22 import android.app.ProgressDialog;
23 import android.content.BroadcastReceiver;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.ContextWrapper;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.pm.PackageManager;
30 import android.content.res.XmlResourceParser;
31 import android.media.AudioManager;
32 import android.net.ConnectivityManager;
33 import android.net.Uri;
34 import android.net.sip.SipManager;
35 import android.os.AsyncResult;
36 import android.os.Bundle;
37 import android.os.Handler;
38 import android.os.Message;
39 import android.os.PersistableBundle;
40 import android.os.PowerManager;
41 import android.os.SystemProperties;
42 import android.os.UserManager;
43 import android.preference.PreferenceManager;
44 import android.provider.Settings;
45 import android.sysprop.TelephonyProperties;
46 import android.telecom.TelecomManager;
47 import android.telephony.AnomalyReporter;
48 import android.telephony.CarrierConfigManager;
49 import android.telephony.ServiceState;
50 import android.telephony.SubscriptionInfo;
51 import android.telephony.SubscriptionManager;
52 import android.telephony.TelephonyLocalConnection;
53 import android.telephony.TelephonyManager;
54 import android.telephony.data.ApnSetting;
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.PhoneConstants;
66 import com.android.internal.telephony.PhoneFactory;
67 import com.android.internal.telephony.SettingsObserver;
68 import com.android.internal.telephony.TelephonyCapabilities;
69 import com.android.internal.telephony.TelephonyComponentFactory;
70 import com.android.internal.telephony.TelephonyIntents;
71 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
72 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
73 import com.android.internal.telephony.ims.ImsResolver;
74 import com.android.internal.telephony.imsphone.ImsPhone;
75 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
76 import com.android.internal.telephony.uicc.UiccCard;
77 import com.android.internal.telephony.uicc.UiccProfile;
78 import com.android.internal.util.IndentingPrintWriter;
79 import com.android.phone.settings.SettingsConstants;
80 import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
81 import com.android.services.telephony.rcs.TelephonyRcsService;
82 import com.android.services.telephony.sip.SipAccountRegistry;
83 import com.android.services.telephony.sip.SipUtil;
84 
85 import java.io.FileDescriptor;
86 import java.io.PrintWriter;
87 import java.lang.annotation.Retention;
88 import java.lang.annotation.RetentionPolicy;
89 import java.util.List;
90 
91 /**
92  * Global state for the telephony subsystem when running in the primary
93  * phone process.
94  */
95 public class PhoneGlobals extends ContextWrapper {
96     public static final String LOG_TAG = "PhoneGlobals";
97 
98     /**
99      * Phone app-wide debug level:
100      *   0 - no debug logging
101      *   1 - normal debug logging if ro.debuggable is set (which is true in
102      *       "eng" and "userdebug" builds but not "user" builds)
103      *   2 - ultra-verbose debug logging
104      *
105      * Most individual classes in the phone app have a local DBG constant,
106      * typically set to
107      *   (PhoneApp.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1)
108      * or else
109      *   (PhoneApp.DBG_LEVEL >= 2)
110      * depending on the desired verbosity.
111      *
112      * ***** DO NOT SUBMIT WITH DBG_LEVEL > 0 *************
113      */
114     public static final int DBG_LEVEL = 0;
115 
116     private static final boolean DBG =
117             (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
118     private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);
119 
120     // Message codes; see mHandler below.
121     private static final int EVENT_SIM_NETWORK_LOCKED = 3;
122     private static final int EVENT_SIM_STATE_CHANGED = 8;
123     private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
124     private static final int EVENT_DATA_ROAMING_CONNECTED = 11;
125     private static final int EVENT_DATA_ROAMING_OK = 12;
126     private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 13;
127     private static final int EVENT_RESTART_SIP = 14;
128     private static final int EVENT_DATA_ROAMING_SETTINGS_CHANGED = 15;
129     private static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 16;
130     private static final int EVENT_CARRIER_CONFIG_CHANGED = 17;
131 
132     // The MMI codes are also used by the InCallScreen.
133     public static final int MMI_INITIATE = 51;
134     public static final int MMI_COMPLETE = 52;
135     public static final int MMI_CANCEL = 53;
136     // Don't use message codes larger than 99 here; those are reserved for
137     // the individual Activities of the Phone UI.
138 
139     public static final int AIRPLANE_ON = 1;
140     public static final int AIRPLANE_OFF = 0;
141 
142     /**
143      * Allowable values for the wake lock code.
144      *   SLEEP means the device can be put to sleep.
145      *   PARTIAL means wake the processor, but we display can be kept off.
146      *   FULL means wake both the processor and the display.
147      */
148     public enum WakeState {
149         SLEEP,
150         PARTIAL,
151         FULL
152     }
153 
154     private static PhoneGlobals sMe;
155 
156     CallManager mCM;
157     CallNotifier notifier;
158     CallerInfoCache callerInfoCache;
159     NotificationMgr notificationMgr;
160     TelephonyRcsService mTelephonyRcsService;
161     public PhoneInterfaceManager phoneMgr;
162     public ImsRcsController imsRcsController;
163     CarrierConfigLoader configLoader;
164 
165     private Phone phoneInEcm;
166 
167     static boolean sVoiceCapable = true;
168 
169     // TODO: Remove, no longer used.
170     CdmaPhoneCallState cdmaPhoneCallState;
171 
172     // The currently-active PUK entry activity and progress dialog.
173     // Normally, these are the Emergency Dialer and the subsequent
174     // progress dialog.  null if there is are no such objects in
175     // the foreground.
176     private Activity mPUKEntryActivity;
177     private ProgressDialog mPUKEntryProgressDialog;
178 
179     /** @hide */
180     @Retention(RetentionPolicy.SOURCE)
181     @IntDef(prefix = {"ROAMING_NOTIFICATION_"},
182             value = {
183                     ROAMING_NOTIFICATION_NO_NOTIFICATION,
184                     ROAMING_NOTIFICATION_CONNECTED,
185                     ROAMING_NOTIFICATION_DISCONNECTED})
186     public @interface RoamingNotification {}
187 
188     private static final int ROAMING_NOTIFICATION_NO_NOTIFICATION = 0;
189     private static final int ROAMING_NOTIFICATION_CONNECTED       = 1;
190     private static final int ROAMING_NOTIFICATION_DISCONNECTED    = 2;
191 
192     @RoamingNotification
193     private int mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
194 
195     private WakeState mWakeState = WakeState.SLEEP;
196 
197     private PowerManager mPowerManager;
198     private PowerManager.WakeLock mWakeLock;
199     private PowerManager.WakeLock mPartialWakeLock;
200     private KeyguardManager mKeyguardManager;
201 
202     private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
203     private final LocalLog mDataRoamingNotifLog = new LocalLog(50);
204 
205     // Broadcast receiver for various intent broadcasts (see onCreate())
206     private final BroadcastReceiver mReceiver = new PhoneAppBroadcastReceiver();
207     // Broadcast receiver for SIP based intents (see onCreate())
208     private final SipReceiver mSipReceiver = new SipReceiver();
209 
210     private final CarrierVvmPackageInstalledReceiver mCarrierVvmPackageInstalledReceiver =
211             new CarrierVvmPackageInstalledReceiver();
212 
213     private final SettingsObserver mSettingsObserver;
214     private BinderCallsStats.SettingsObserver mBinderCallsSettingsObserver;
215 
216     private static class EventSimStateChangedBag {
217         final int mPhoneId;
218         final String mIccStatus;
219 
EventSimStateChangedBag(int phoneId, String iccStatus)220         EventSimStateChangedBag(int phoneId, String iccStatus) {
221             mPhoneId = phoneId;
222             mIccStatus = iccStatus;
223         }
224     }
225 
226     // Some carrier config settings disable the network lock screen, so we call handleSimLock
227     // when either SIM_LOCK or CARRIER_CONFIG changes so that no matter which one happens first,
228     // we still do the right thing
handleSimLock(int subType, Phone phone)229     private void handleSimLock(int subType, Phone phone) {
230         PersistableBundle cc = getCarrierConfigForSubId(phone.getSubId());
231         if (!CarrierConfigManager.isConfigForIdentifiedCarrier(cc)) {
232             // If we only have the default carrier config just return, to avoid popping up the
233             // the SIM lock screen when it's disabled by the carrier.
234             Log.i(LOG_TAG, "Not showing 'SIM network unlock' screen. Carrier config not loaded");
235             return;
236         }
237         if (cc.getBoolean(CarrierConfigManager.KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL)) {
238             // Some products don't have the concept of a "SIM network lock"
239             Log.i(LOG_TAG, "Not showing 'SIM network unlock' screen. Disabled by carrier config");
240             return;
241         }
242 
243         // if passed in subType is unknown, retrieve it here.
244         if (subType == -1) {
245             final UiccCard uiccCard = phone.getUiccCard();
246             if (uiccCard == null) {
247                 Log.e(LOG_TAG,
248                         "handleSimLock: uiccCard for phone " + phone.getPhoneId() + " is null");
249                 return;
250             }
251             final UiccProfile uiccProfile = uiccCard.getUiccProfile();
252             if (uiccProfile == null) {
253                 Log.e(LOG_TAG,
254                         "handleSimLock: uiccProfile for phone " + phone.getPhoneId() + " is null");
255                 return;
256             }
257             subType = uiccProfile.getApplication(
258                     uiccProfile.mCurrentAppType).getPersoSubState().ordinal();
259         }
260         // Normal case: show the "SIM network unlock" PIN entry screen.
261         // The user won't be able to do anything else until
262         // they enter a valid SIM network PIN.
263         Log.i(LOG_TAG, "show sim depersonal panel");
264         IccNetworkDepersonalizationPanel.showDialog(phone, subType);
265     }
266 
isSimLocked(Phone phone)267     private boolean isSimLocked(Phone phone) {
268         TelephonyManager tm = getSystemService(TelephonyManager.class);
269         return tm.createForSubscriptionId(phone.getSubId()).getSimState()
270                 == TelephonyManager.SIM_STATE_NETWORK_LOCKED;
271     }
272 
273     Handler mHandler = new Handler() {
274         @Override
275         public void handleMessage(Message msg) {
276             PhoneConstants.State phoneState;
277             if (VDBG) Log.v(LOG_TAG, "event=" + msg.what);
278             switch (msg.what) {
279                 // TODO: This event should be handled by the lock screen, just
280                 // like the "SIM missing" and "Sim locked" cases (bug 1804111).
281                 case EVENT_SIM_NETWORK_LOCKED:
282                     int subType = (Integer) ((AsyncResult) msg.obj).result;
283                     Phone phone = (Phone) ((AsyncResult) msg.obj).userObj;
284                     handleSimLock(subType, phone);
285                     break;
286 
287                 case EVENT_DATA_ROAMING_DISCONNECTED:
288                     notificationMgr.showDataRoamingNotification(msg.arg1, false);
289                     break;
290 
291                 case EVENT_DATA_ROAMING_CONNECTED:
292                     notificationMgr.showDataRoamingNotification(msg.arg1, true);
293                     break;
294 
295                 case EVENT_DATA_ROAMING_OK:
296                     notificationMgr.hideDataRoamingNotification();
297                     break;
298 
299                 case MMI_COMPLETE:
300                     onMMIComplete((AsyncResult) msg.obj);
301                     break;
302 
303                 case MMI_CANCEL:
304                     PhoneUtils.cancelMmiCode(mCM.getFgPhone());
305                     break;
306 
307                 case EVENT_SIM_STATE_CHANGED:
308                     // Marks the event where the SIM goes into ready state.
309                     // Right now, this is only used for the PUK-unlocking
310                     // process.
311                     EventSimStateChangedBag bag = (EventSimStateChangedBag)msg.obj;
312                     if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(bag.mIccStatus)
313                             || IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(bag.mIccStatus)
314                             || IccCardConstants.INTENT_VALUE_ICC_NOT_READY.equals(bag.mIccStatus)
315                             || IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(bag.mIccStatus)) {
316                         // when the right event is triggered and there
317                         // are UI objects in the foreground, we close
318                         // them to display the lock panel.
319                         if (mPUKEntryActivity != null) {
320                             Log.i(LOG_TAG, "Dismiss puk entry activity");
321                             mPUKEntryActivity.finish();
322                             mPUKEntryActivity = null;
323                         }
324                         if (mPUKEntryProgressDialog != null) {
325                             Log.i(LOG_TAG, "Dismiss puk progress dialog");
326                             mPUKEntryProgressDialog.dismiss();
327                             mPUKEntryProgressDialog = null;
328                         }
329                         Log.i(LOG_TAG, "Dismissing depersonal panel" + (bag.mIccStatus));
330                         IccNetworkDepersonalizationPanel.dialogDismiss(bag.mPhoneId);
331                     }
332                     break;
333 
334                 case EVENT_UNSOL_CDMA_INFO_RECORD:
335                     //TODO: handle message here;
336                     break;
337                 case EVENT_RESTART_SIP:
338                     // This should only run if the Phone process crashed and was restarted. We do
339                     // not want this running if the device is still in the FBE encrypted state.
340                     // This is the same procedure that is triggered in the SipIncomingCallReceiver
341                     // upon BOOT_COMPLETED.
342                     UserManager userManager =
343                             (UserManager) sMe.getSystemService(Context.USER_SERVICE);
344                     if (userManager != null && userManager.isUserUnlocked()) {
345                         SipUtil.startSipService();
346                     }
347                     break;
348                 case EVENT_DATA_ROAMING_SETTINGS_CHANGED:
349                 case EVENT_MOBILE_DATA_SETTINGS_CHANGED:
350                     updateDataRoamingStatus();
351                     break;
352                 case EVENT_CARRIER_CONFIG_CHANGED:
353                     int subId = (Integer) msg.obj;
354                     // The voicemail number could be overridden by carrier config, so need to
355                     // refresh the message waiting (voicemail) indicator.
356                     refreshMwiIndicator(subId);
357                     phone = getPhone(subId);
358                     if (phone != null && isSimLocked(phone)) {
359                         // pass in subType=-1 so handleSimLock can find the actual subType if
360                         // needed. This is safe as valid values for subType are >= 0
361                         handleSimLock(-1, phone);
362                     }
363                     break;
364             }
365         }
366     };
367 
PhoneGlobals(Context context)368     public PhoneGlobals(Context context) {
369         super(context);
370         sMe = this;
371         mSettingsObserver = new SettingsObserver(context, mHandler);
372     }
373 
onCreate()374     public void onCreate() {
375         if (VDBG) Log.v(LOG_TAG, "onCreate()...");
376 
377         ContentResolver resolver = getContentResolver();
378 
379         // Initialize the shim from frameworks/opt/telephony into packages/services/Telephony.
380         TelephonyLocalConnection.setInstance(new LocalConnectionImpl(this));
381 
382         // Cache the "voice capable" flag.
383         // This flag currently comes from a resource (which is
384         // overrideable on a per-product basis):
385         sVoiceCapable = ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE))
386                 .isVoiceCapable();
387         // ...but this might eventually become a PackageManager "system
388         // feature" instead, in which case we'd do something like:
389         // sVoiceCapable =
390         //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
391 
392         if (mCM == null) {
393             // Initialize AnomalyReporter early so that it can be used
394             AnomalyReporter.initialize(this);
395 
396             // Inject telephony component factory if configured using other jars.
397             XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection);
398             TelephonyComponentFactory.getInstance().injectTheComponentFactory(parser);
399             // Initialize the telephony framework
400             PhoneFactory.makeDefaultPhones(this);
401 
402             // Only bring up ImsResolver if the device supports having an IMS stack.
403             if (getPackageManager().hasSystemFeature(
404                     PackageManager.FEATURE_TELEPHONY_IMS)) {
405                 // Get the package name of the default IMS implementation.
406                 String defaultImsMmtelPackage = getResources().getString(
407                         R.string.config_ims_mmtel_package);
408                 String defaultImsRcsPackage = getResources().getString(
409                         R.string.config_ims_rcs_package);
410                 ImsResolver.make(this, defaultImsMmtelPackage,
411                         defaultImsRcsPackage, PhoneFactory.getPhones().length,
412                         new ImsFeatureBinderRepository());
413                 ImsResolver.getInstance().initialize();
414 
415                 // With the IMS phone created, load static config.xml values from the phone process
416                 // so that it can be provided to the ImsPhoneCallTracker.
417                 for (Phone p : PhoneFactory.getPhones()) {
418                     Phone imsPhone = p.getImsPhone();
419                     if (imsPhone != null && imsPhone instanceof ImsPhone) {
420                         ImsPhone theImsPhone = (ImsPhone) imsPhone;
421                         if (theImsPhone.getCallTracker() instanceof ImsPhoneCallTracker) {
422                             ImsPhoneCallTracker ict = (ImsPhoneCallTracker)
423                                     theImsPhone.getCallTracker();
424 
425                             ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
426                             config.isD2DCommunicationSupported = getResources().getBoolean(
427                                     R.bool.config_use_device_to_device_communication);
428                             ict.setConfig(config);
429                         }
430                     }
431                 }
432                 RcsProvisioningMonitor.make(this);
433             }
434 
435             // Start TelephonyDebugService After the default phone is created.
436             Intent intent = new Intent(this, TelephonyDebugService.class);
437             startService(intent);
438 
439             mCM = CallManager.getInstance();
440 
441             // Create the NotificationMgr singleton, which is used to display
442             // status bar icons and control other status bar behavior.
443             notificationMgr = NotificationMgr.init(this);
444 
445             // If PhoneGlobals has crashed and is being restarted, then restart.
446             mHandler.sendEmptyMessage(EVENT_RESTART_SIP);
447 
448             // Create an instance of CdmaPhoneCallState and initialize it to IDLE
449             cdmaPhoneCallState = new CdmaPhoneCallState();
450             cdmaPhoneCallState.CdmaPhoneCallStateInit();
451 
452             // before registering for phone state changes
453             mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
454             mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG);
455             // lock used to keep the processor awake, when we don't care for the display.
456             mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK
457                     | PowerManager.ON_AFTER_RELEASE, LOG_TAG);
458 
459             mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
460 
461             // Create the CallerInfoCache singleton, which remembers custom ring tone and
462             // send-to-voicemail settings.
463             //
464             // The asynchronous caching will start just after this call.
465             callerInfoCache = CallerInfoCache.init(this);
466 
467             phoneMgr = PhoneInterfaceManager.init(this);
468 
469             imsRcsController = ImsRcsController.init(this);
470 
471             if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
472                 mTelephonyRcsService = new TelephonyRcsService(this,
473                         PhoneFactory.getPhones().length);
474                 mTelephonyRcsService.initialize();
475                 imsRcsController.setRcsService(mTelephonyRcsService);
476             }
477 
478             configLoader = CarrierConfigLoader.init(this);
479 
480             // Create the CallNotifier singleton, which handles
481             // asynchronous events from the telephony layer (like
482             // launching the incoming-call UI when an incoming call comes
483             // in.)
484             notifier = CallNotifier.init(this);
485 
486             PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED);
487 
488             // register for MMI/USSD
489             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
490 
491             // Initialize cell status using current airplane mode.
492             handleAirplaneModeChange(this, Settings.Global.getInt(getContentResolver(),
493                     Settings.Global.AIRPLANE_MODE_ON, AIRPLANE_OFF));
494 
495             // Register for misc other intent broadcasts.
496             IntentFilter intentFilter =
497                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
498             intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
499             intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
500             intentFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
501             intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
502             intentFilter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
503             intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
504             registerReceiver(mReceiver, intentFilter);
505 
506             IntentFilter sipIntentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
507             sipIntentFilter.addAction(SipManager.ACTION_SIP_SERVICE_UP);
508             sipIntentFilter.addAction(SipManager.ACTION_SIP_CALL_OPTION_CHANGED);
509             sipIntentFilter.addAction(SipManager.ACTION_SIP_REMOVE_PROFILE);
510             registerReceiver(mSipReceiver, sipIntentFilter);
511 
512             mCarrierVvmPackageInstalledReceiver.register(this);
513 
514             //set the default values for the preferences in the phone.
515             PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false);
516         }
517 
518         // XXX pre-load the SimProvider so that it's ready
519         resolver.getType(Uri.parse("content://icc/adn"));
520 
521         // TODO: Register for Cdma Information Records
522         // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null);
523 
524         // Read HAC settings and configure audio hardware
525         if (getResources().getBoolean(R.bool.hac_enabled)) {
526             int hac = android.provider.Settings.System.getInt(
527                     getContentResolver(),
528                     android.provider.Settings.System.HEARING_AID,
529                     0);
530             AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
531             audioManager.setParameters(
532                     SettingsConstants.HAC_KEY + "=" + (hac == SettingsConstants.HAC_ENABLED
533                             ? SettingsConstants.HAC_VAL_ON : SettingsConstants.HAC_VAL_OFF));
534         }
535 
536         // Start tracking Binder latency for the phone process.
537         mBinderCallsSettingsObserver = new BinderCallsStats.SettingsObserver(
538             getApplicationContext(),
539             new BinderCallsStats(
540                     new BinderCallsStats.Injector(),
541                     com.android.internal.os.BinderLatencyProto.Dims.TELEPHONY));
542     }
543 
544     /**
545      * Returns the singleton instance of the PhoneApp.
546      */
getInstance()547     public static PhoneGlobals getInstance() {
548         if (sMe == null) {
549             throw new IllegalStateException("No PhoneGlobals here!");
550         }
551         return sMe;
552     }
553 
554     /**
555      * Returns the default phone.
556      *
557      * WARNING: This method should be used carefully, now that there may be multiple phones.
558      */
getPhone()559     public static Phone getPhone() {
560         return PhoneFactory.getDefaultPhone();
561     }
562 
getPhone(int subId)563     public static Phone getPhone(int subId) {
564         return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
565     }
566 
getCallManager()567     /* package */ CallManager getCallManager() {
568         return mCM;
569     }
570 
getCarrierConfig()571     public PersistableBundle getCarrierConfig() {
572         return getCarrierConfigForSubId(SubscriptionManager.getDefaultSubscriptionId());
573     }
574 
getCarrierConfigForSubId(int subId)575     public PersistableBundle getCarrierConfigForSubId(int subId) {
576         return configLoader.getConfigForSubIdWithFeature(subId, getOpPackageName(),
577                 getAttributionTag());
578     }
579 
registerSettingsObserver()580     private void registerSettingsObserver() {
581         mSettingsObserver.unobserve();
582         String dataRoamingSetting = Settings.Global.DATA_ROAMING;
583         String mobileDataSetting = Settings.Global.MOBILE_DATA;
584         if (TelephonyManager.getDefault().getSimCount() > 1) {
585             int subId = mDefaultDataSubId;
586             if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
587                 dataRoamingSetting += subId;
588                 mobileDataSetting += subId;
589             }
590         }
591 
592         // Listen for user data roaming setting changed event
593         mSettingsObserver.observe(Settings.Global.getUriFor(dataRoamingSetting),
594                 EVENT_DATA_ROAMING_SETTINGS_CHANGED);
595 
596         // Listen for mobile data setting changed event
597         mSettingsObserver.observe(Settings.Global.getUriFor(mobileDataSetting),
598                 EVENT_MOBILE_DATA_SETTINGS_CHANGED);
599     }
600 
601     /**
602      * Sets the activity responsible for un-PUK-blocking the device
603      * so that we may close it when we receive a positive result.
604      * mPUKEntryActivity is also used to indicate to the device that
605      * we are trying to un-PUK-lock the phone. In other words, iff
606      * it is NOT null, then we are trying to unlock and waiting for
607      * the SIM to move to READY state.
608      *
609      * @param activity is the activity to close when PUK has
610      * finished unlocking. Can be set to null to indicate the unlock
611      * or SIM READYing process is over.
612      */
setPukEntryActivity(Activity activity)613     void setPukEntryActivity(Activity activity) {
614         Log.i(LOG_TAG, "setPukEntryActivity - set to " + (activity == null ? "null" : "activity"));
615         mPUKEntryActivity = activity;
616     }
617 
getPUKEntryActivity()618     Activity getPUKEntryActivity() {
619         return mPUKEntryActivity;
620     }
621 
622     /**
623      * Sets the dialog responsible for notifying the user of un-PUK-
624      * blocking - SIM READYing progress, so that we may dismiss it
625      * when we receive a positive result.
626      *
627      * @param dialog indicates the progress dialog informing the user
628      * of the state of the device.  Dismissed upon completion of
629      * READYing process
630      */
setPukEntryProgressDialog(ProgressDialog dialog)631     void setPukEntryProgressDialog(ProgressDialog dialog) {
632         Log.i(LOG_TAG, "setPukEntryProgressDialog - set to "
633                 + (dialog == null ? "null" : "activity"));
634         mPUKEntryProgressDialog = dialog;
635     }
636 
getKeyguardManager()637     KeyguardManager getKeyguardManager() {
638         return mKeyguardManager;
639     }
640 
onMMIComplete(AsyncResult r)641     private void onMMIComplete(AsyncResult r) {
642         if (VDBG) Log.d(LOG_TAG, "onMMIComplete()...");
643         MmiCode mmiCode = (MmiCode) r.result;
644         PhoneUtils.displayMMIComplete(mmiCode.getPhone(), getInstance(), mmiCode, null, null);
645     }
646 
initForNewRadioTechnology()647     private void initForNewRadioTechnology() {
648         if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology...");
649         notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
650     }
651 
handleAirplaneModeChange(Context context, int newMode)652     private void handleAirplaneModeChange(Context context, int newMode) {
653         int cellState = Settings.Global.getInt(context.getContentResolver(),
654                 Settings.Global.CELL_ON, PhoneConstants.CELL_ON_FLAG);
655         boolean isAirplaneNewlyOn = (newMode == 1);
656         switch (cellState) {
657             case PhoneConstants.CELL_OFF_FLAG:
658                 // Airplane mode does not affect the cell radio if user
659                 // has turned it off.
660                 break;
661             case PhoneConstants.CELL_ON_FLAG:
662                 maybeTurnCellOff(context, isAirplaneNewlyOn);
663                 break;
664             case PhoneConstants.CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG:
665                 maybeTurnCellOn(context, isAirplaneNewlyOn);
666                 break;
667         }
668         for (Phone phone : PhoneFactory.getPhones()) {
669             phone.getServiceStateTracker().onAirplaneModeChanged(isAirplaneNewlyOn);
670         }
671     }
672 
673     /*
674      * Returns true if the radio must be turned off when entering airplane mode.
675      */
isCellOffInAirplaneMode(Context context)676     private boolean isCellOffInAirplaneMode(Context context) {
677         String airplaneModeRadios = Settings.Global.getString(context.getContentResolver(),
678                 Settings.Global.AIRPLANE_MODE_RADIOS);
679         return airplaneModeRadios == null
680                 || airplaneModeRadios.contains(Settings.Global.RADIO_CELL);
681     }
682 
setRadioPowerOff(Context context)683     private void setRadioPowerOff(Context context) {
684         Log.i(LOG_TAG, "Turning radio off - airplane");
685         Settings.Global.putInt(context.getContentResolver(), Settings.Global.CELL_ON,
686                  PhoneConstants.CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG);
687         TelephonyProperties.airplane_mode_on(true); // true means int value 1
688         Settings.Global.putInt(getContentResolver(), Settings.Global.ENABLE_CELLULAR_ON_BOOT, 0);
689         PhoneUtils.setRadioPower(false);
690     }
691 
setRadioPowerOn(Context context)692     private void setRadioPowerOn(Context context) {
693         Log.i(LOG_TAG, "Turning radio on - airplane");
694         Settings.Global.putInt(context.getContentResolver(), Settings.Global.CELL_ON,
695                 PhoneConstants.CELL_ON_FLAG);
696         Settings.Global.putInt(getContentResolver(), Settings.Global.ENABLE_CELLULAR_ON_BOOT,
697                 1);
698         TelephonyProperties.airplane_mode_on(false); // false means int value 0
699         PhoneUtils.setRadioPower(true);
700     }
701 
maybeTurnCellOff(Context context, boolean isAirplaneNewlyOn)702     private void maybeTurnCellOff(Context context, boolean isAirplaneNewlyOn) {
703         if (isAirplaneNewlyOn) {
704             // If we are trying to turn off the radio, make sure there are no active
705             // emergency calls.  If there are, switch airplane mode back to off.
706             TelecomManager tm = (TelecomManager) context.getSystemService(TELECOM_SERVICE);
707 
708             if (tm != null && tm.isInEmergencyCall()) {
709                 // Switch airplane mode back to off.
710                 ConnectivityManager cm =
711                         (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
712                 cm.setAirplaneMode(false);
713                 Toast.makeText(this, R.string.radio_off_during_emergency_call, Toast.LENGTH_LONG)
714                         .show();
715                 Log.i(LOG_TAG, "Ignoring airplane mode: emergency call. Turning airplane off");
716             } else if (isCellOffInAirplaneMode(context)) {
717                 setRadioPowerOff(context);
718             } else {
719                 Log.i(LOG_TAG, "Ignoring airplane mode: settings prevent cell radio power off");
720             }
721         }
722     }
723 
maybeTurnCellOn(Context context, boolean isAirplaneNewlyOn)724     private void maybeTurnCellOn(Context context, boolean isAirplaneNewlyOn) {
725         if (!isAirplaneNewlyOn) {
726             setRadioPowerOn(context);
727         }
728     }
729 
730     /**
731      * Receiver for misc intent broadcasts the Phone app cares about.
732      */
733     private class PhoneAppBroadcastReceiver extends BroadcastReceiver {
734         @Override
onReceive(Context context, Intent intent)735         public void onReceive(Context context, Intent intent) {
736             String action = intent.getAction();
737             if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
738                 int airplaneMode = Settings.Global.getInt(getContentResolver(),
739                         Settings.Global.AIRPLANE_MODE_ON, AIRPLANE_OFF);
740                 // Treat any non-OFF values as ON.
741                 if (airplaneMode != AIRPLANE_OFF) {
742                     airplaneMode = AIRPLANE_ON;
743                 }
744                 handleAirplaneModeChange(context, airplaneMode);
745             } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
746                 // re-register as it may be a new IccCard
747                 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY,
748                         SubscriptionManager.INVALID_PHONE_INDEX);
749                 if (SubscriptionManager.isValidPhoneId(phoneId)) {
750                     PhoneUtils.unregisterIccStatus(mHandler, phoneId);
751                     PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED, phoneId);
752                 }
753                 String iccStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
754                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED,
755                         new EventSimStateChangedBag(phoneId, iccStatus)));
756             } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) {
757                 String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY);
758                 Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active.");
759                 initForNewRadioTechnology();
760             } else if (action.equals(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED)) {
761                 handleServiceStateChanged(intent);
762             } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
763                 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
764                 phoneInEcm = PhoneFactory.getPhone(phoneId);
765                 Log.d(LOG_TAG, "Emergency Callback Mode. phoneId:" + phoneId);
766                 if (phoneInEcm != null) {
767                     if (TelephonyCapabilities.supportsEcm(phoneInEcm)) {
768                         Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp.");
769                         // Start Emergency Callback Mode service
770                         if (intent.getBooleanExtra(
771                                 TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false)) {
772                             context.startService(new Intent(context,
773                                     EmergencyCallbackModeService.class));
774                         } else {
775                             phoneInEcm = null;
776                         }
777                     } else {
778                         // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
779                         // on a device that doesn't support ECM in the first place.
780                         Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, but "
781                                 + "ECM isn't supported for phone: " + phoneInEcm.getPhoneName());
782                         phoneInEcm = null;
783                     }
784                 } else {
785                     Log.w(LOG_TAG, "phoneInEcm is null.");
786                 }
787             } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
788                 // Roaming status could be overridden by carrier config, so we need to update it.
789                 if (VDBG) Log.v(LOG_TAG, "carrier config changed.");
790                 updateDataRoamingStatus();
791                 updateLimitedSimFunctionForDualSim();
792                 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
793                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
794                 if (SubscriptionManager.isValidSubscriptionId(subId)) {
795                     mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_CONFIG_CHANGED,
796                             new Integer(subId)));
797                 }
798             } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
799                 // We also need to pay attention when default data subscription changes.
800                 if (VDBG) Log.v(LOG_TAG, "default data sub changed.");
801                 mDefaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
802                 registerSettingsObserver();
803                 Phone phone = getPhone(mDefaultDataSubId);
804                 if (phone != null) {
805                     updateDataRoamingStatus();
806                 }
807             }
808         }
809     }
810 
811     private class SipReceiver extends BroadcastReceiver {
812 
813         @Override
onReceive(Context context, Intent intent)814         public void onReceive(Context context, Intent intent) {
815             String action = intent.getAction();
816 
817             SipAccountRegistry sipAccountRegistry = SipAccountRegistry.getInstance();
818             if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
819                 SipUtil.startSipService();
820             } else if (action.equals(SipManager.ACTION_SIP_SERVICE_UP)
821                     || action.equals(SipManager.ACTION_SIP_CALL_OPTION_CHANGED)) {
822                 sipAccountRegistry.setup(context);
823             } else if (action.equals(SipManager.ACTION_SIP_REMOVE_PROFILE)) {
824                 if (DBG) {
825                     Log.d(LOG_TAG, "SIP_REMOVE_PHONE "
826                             + intent.getStringExtra(SipManager.EXTRA_LOCAL_URI));
827                 }
828                 sipAccountRegistry.removeSipProfile(intent.getStringExtra(
829                         SipManager.EXTRA_LOCAL_URI));
830             } else {
831                 if (DBG) Log.d(LOG_TAG, "onReceive, action not processed: " + action);
832             }
833         }
834     }
835 
handleServiceStateChanged(Intent intent)836     private void handleServiceStateChanged(Intent intent) {
837         /**
838          * This used to handle updating EriTextWidgetProvider this routine
839          * and and listening for ACTION_SERVICE_STATE_CHANGED intents could
840          * be removed. But leaving just in case it might be needed in the near
841          * future.
842          */
843 
844         if (VDBG) Log.v(LOG_TAG, "handleServiceStateChanged");
845         // If service just returned, start sending out the queued messages
846         Bundle extras = intent.getExtras();
847         if (extras != null) {
848             ServiceState ss = ServiceState.newFromBundle(extras);
849             if (ss != null) {
850                 int state = ss.getState();
851                 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
852                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
853                 notificationMgr.updateNetworkSelection(state, subId);
854 
855                 if (VDBG) {
856                     Log.v(LOG_TAG, "subId=" + subId + ",mDefaultDataSubId="
857                             + mDefaultDataSubId + ",ss roaming=" + ss.getDataRoaming());
858                 }
859                 if (subId == mDefaultDataSubId) {
860                     updateDataRoamingStatus();
861                 }
862             }
863         }
864     }
865 
866     /**
867      * @return whether or not we should show a notification when connecting to data roaming if the
868      * user has data roaming enabled
869      */
shouldShowDataConnectedRoaming(int subId)870     private boolean shouldShowDataConnectedRoaming(int subId) {
871         PersistableBundle config = getCarrierConfigForSubId(subId);
872         return config.getBoolean(CarrierConfigManager
873                 .KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL);
874     }
875 
876     /**
877      * When roaming, if mobile data cannot be established due to data roaming not enabled, we need
878      * to notify the user so they can enable it through settings. Vise versa if the condition
879      * changes, we need to dismiss the notification.
880      */
updateDataRoamingStatus()881     private void updateDataRoamingStatus() {
882         if (VDBG) Log.v(LOG_TAG, "updateDataRoamingStatus");
883         Phone phone = getPhone(mDefaultDataSubId);
884         if (phone == null) {
885             Log.w(LOG_TAG, "Can't get phone with sub id = " + mDefaultDataSubId);
886             return;
887         }
888 
889         DataConnectionReasons reasons = new DataConnectionReasons();
890         boolean dataAllowed = phone.isDataAllowed(ApnSetting.TYPE_DEFAULT, reasons);
891         mDataRoamingNotifLog.log("dataAllowed=" + dataAllowed + ", reasons=" + reasons);
892         if (VDBG) Log.v(LOG_TAG, "dataAllowed=" + dataAllowed + ", reasons=" + reasons);
893         if (!dataAllowed && reasons.containsOnly(DataDisallowedReasonType.ROAMING_DISABLED)) {
894             // No need to show it again if we never cancelled it explicitly.
895             if (mPrevRoamingNotification == ROAMING_NOTIFICATION_DISCONNECTED) return;
896             // If the only reason of no data is data roaming disabled, then we notify the user
897             // so the user can turn on data roaming.
898             mPrevRoamingNotification = ROAMING_NOTIFICATION_DISCONNECTED;
899             Log.d(LOG_TAG, "Show roaming disconnected notification");
900             mDataRoamingNotifLog.log("Show roaming off.");
901             Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_DISCONNECTED);
902             msg.arg1 = mDefaultDataSubId;
903             msg.sendToTarget();
904         } else if (dataAllowed && dataIsNowRoaming(mDefaultDataSubId)
905                 && shouldShowDataConnectedRoaming(mDefaultDataSubId)) {
906             // No need to show it again if we never cancelled it explicitly, or carrier config
907             // indicates this is not needed.
908             if (mPrevRoamingNotification == ROAMING_NOTIFICATION_CONNECTED) return;
909             mPrevRoamingNotification = ROAMING_NOTIFICATION_CONNECTED;
910             Log.d(LOG_TAG, "Show roaming connected notification");
911             mDataRoamingNotifLog.log("Show roaming on.");
912             Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_CONNECTED);
913             msg.arg1 = mDefaultDataSubId;
914             msg.sendToTarget();
915         } else if (mPrevRoamingNotification != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
916             // Otherwise we either 1) we are not roaming or 2) roaming is off but ROAMING_DISABLED
917             // is not the only data disable reason. In this case we dismiss the notification we
918             // showed earlier.
919             mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
920             Log.d(LOG_TAG, "Dismiss roaming notification");
921             mDataRoamingNotifLog.log("Hide. data allowed=" + dataAllowed + ", reasons=" + reasons);
922             mHandler.sendEmptyMessage(EVENT_DATA_ROAMING_OK);
923         }
924     }
925 
926     /**
927      *
928      * @param subId to check roaming on
929      * @return whether we have transitioned to dataRoaming
930      */
dataIsNowRoaming(int subId)931     private boolean dataIsNowRoaming(int subId) {
932         return getPhone(subId).getServiceState().getDataRoaming();
933     }
934 
updateLimitedSimFunctionForDualSim()935     private void updateLimitedSimFunctionForDualSim() {
936         if (DBG) Log.d(LOG_TAG, "updateLimitedSimFunctionForDualSim");
937         // check conditions to display limited SIM function notification under dual SIM
938         SubscriptionManager subMgr = (SubscriptionManager) getSystemService(
939                 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
940         List<SubscriptionInfo> subList = subMgr.getActiveSubscriptionInfoList(false);
941         if (subList != null && subList.size() > 1) {
942             CarrierConfigManager configMgr = (CarrierConfigManager)
943                     getSystemService(Context.CARRIER_CONFIG_SERVICE);
944             for (SubscriptionInfo info : subList) {
945                 PersistableBundle b = configMgr.getConfigForSubId(info.getSubscriptionId());
946                 if (b != null) {
947                     if (b.getBoolean(CarrierConfigManager
948                             .KEY_LIMITED_SIM_FUNCTION_NOTIFICATION_FOR_DSDS_BOOL)) {
949                         notificationMgr.showLimitedSimFunctionWarningNotification(
950                                 info.getSubscriptionId(),
951                                 info.getDisplayName().toString());
952                     } else {
953                         notificationMgr.dismissLimitedSimFunctionWarningNotification(
954                                 info.getSubscriptionId());
955                     }
956                 }
957             }
958         } else {
959             // cancel notifications for all subs
960             notificationMgr.dismissLimitedSimFunctionWarningNotification(
961                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
962         }
963         notificationMgr.dismissLimitedSimFunctionWarningNotificationForInactiveSubs();
964 
965     }
966 
getPhoneInEcm()967     public Phone getPhoneInEcm() {
968         return phoneInEcm;
969     }
970 
971     /**
972      * Triggers a refresh of the message waiting (voicemail) indicator.
973      *
974      * @param subId the subscription id we should refresh the notification for.
975      */
refreshMwiIndicator(int subId)976     public void refreshMwiIndicator(int subId) {
977         notificationMgr.refreshMwi(subId);
978     }
979 
980     /**
981      * Called when the network selection on the subscription {@code subId} is changed by the user.
982      *
983      * @param subId the subscription id.
984      */
onNetworkSelectionChanged(int subId)985     public void onNetworkSelectionChanged(int subId) {
986         Phone phone = getPhone(subId);
987         if (phone != null) {
988             notificationMgr.updateNetworkSelection(phone.getServiceState().getState(), subId);
989         } else {
990             Log.w(LOG_TAG, "onNetworkSelectionChanged on null phone, subId: " + subId);
991         }
992     }
993 
994     /**
995      * @return whether the device supports RCS User Capability Exchange or not.
996      */
getDeviceUceEnabled()997     public boolean getDeviceUceEnabled() {
998         return (mTelephonyRcsService == null) ? false : mTelephonyRcsService.isDeviceUceEnabled();
999     }
1000 
1001     /**
1002      * Set the device supports RCS User Capability Exchange.
1003      * @param isEnabled true if the device supports UCE.
1004      */
setDeviceUceEnabled(boolean isEnabled)1005     public void setDeviceUceEnabled(boolean isEnabled) {
1006         if (mTelephonyRcsService != null) {
1007             mTelephonyRcsService.setDeviceUceEnabled(isEnabled);
1008         }
1009     }
1010 
1011     /**
1012      * Dump the state of the object, add calls to other objects as desired.
1013      *
1014      * @param fd File descriptor
1015      * @param printWriter Print writer
1016      * @param args Arguments
1017      */
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)1018     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
1019         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
1020         pw.println("------- PhoneGlobals -------");
1021         pw.increaseIndent();
1022         pw.println("mPrevRoamingNotification=" + mPrevRoamingNotification);
1023         pw.println("mDefaultDataSubId=" + mDefaultDataSubId);
1024         pw.println("mDataRoamingNotifLog:");
1025         pw.println("isSmsCapable=" + TelephonyManager.from(this).isSmsCapable());
1026         pw.increaseIndent();
1027         mDataRoamingNotifLog.dump(fd, pw, args);
1028         pw.decreaseIndent();
1029         pw.println("ImsResolver:");
1030         pw.increaseIndent();
1031         try {
1032             if (ImsResolver.getInstance() != null) ImsResolver.getInstance().dump(fd, pw, args);
1033         } catch (Exception e) {
1034             e.printStackTrace();
1035         }
1036         pw.decreaseIndent();
1037         pw.println("RcsService:");
1038         try {
1039             if (mTelephonyRcsService != null) mTelephonyRcsService.dump(fd, pw, args);
1040         } catch (Exception e) {
1041             e.printStackTrace();
1042         }
1043         pw.decreaseIndent();
1044         pw.println("------- End PhoneGlobals -------");
1045     }
1046 }
1047