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