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