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