1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.phone; 18 19 import android.annotation.IntDef; 20 import android.app.Activity; 21 import android.app.KeyguardManager; 22 import android.app.ProgressDialog; 23 import android.content.BroadcastReceiver; 24 import android.content.ContentResolver; 25 import android.content.Context; 26 import android.content.ContextWrapper; 27 import android.content.Intent; 28 import android.content.IntentFilter; 29 import android.content.pm.PackageManager; 30 import android.content.res.XmlResourceParser; 31 import android.media.AudioManager; 32 import android.net.ConnectivityManager; 33 import android.net.Uri; 34 import android.os.AsyncResult; 35 import android.os.Handler; 36 import android.os.Message; 37 import android.os.PersistableBundle; 38 import android.os.PowerManager; 39 import android.os.SystemProperties; 40 import android.preference.PreferenceManager; 41 import android.provider.Settings; 42 import android.sysprop.TelephonyProperties; 43 import android.telecom.TelecomManager; 44 import android.telephony.AnomalyReporter; 45 import android.telephony.CarrierConfigManager; 46 import android.telephony.NetworkRegistrationInfo; 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 Log.d(LOG_TAG, "EVENT_DATA_ROAMING_DISCONNECTED"); 377 if (SubscriptionManagerService.getInstance() 378 .isEsimBootStrapProvisioningActiveForSubId(msg.arg1)) { 379 Log.i(LOG_TAG, 380 "skip notification/warnings during esim bootstrap activation"); 381 } else if (skipDataRoamingDisconnectedNotificationInSatelliteMode((msg.arg1))) { 382 Log.i(LOG_TAG, "skip data roaming disconnected notification when device is " 383 + "connected to satellite network that does not support data."); 384 } else { 385 notificationMgr.showDataRoamingNotification((msg.arg1), false); 386 } 387 break; 388 389 case EVENT_DATA_ROAMING_CONNECTED: 390 if (SubscriptionManagerService.getInstance() 391 .isEsimBootStrapProvisioningActiveForSubId(msg.arg1)) { 392 Log.i(LOG_TAG, 393 "skip notification/warnings during esim bootstrap activation"); 394 } else { 395 notificationMgr.showDataRoamingNotification(msg.arg1, true); 396 } 397 break; 398 399 case EVENT_DATA_ROAMING_OK: 400 notificationMgr.hideDataRoamingNotification(); 401 break; 402 403 case MMI_COMPLETE: 404 onMMIComplete((AsyncResult) msg.obj); 405 break; 406 407 case MMI_CANCEL: 408 PhoneUtils.cancelMmiCode(mCM.getFgPhone()); 409 break; 410 411 case EVENT_SIM_STATE_CHANGED: 412 EventSimStateChangedBag bag = (EventSimStateChangedBag)msg.obj; 413 // Dismiss the "No services" notification if the SIM is removed. 414 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(bag.mIccStatus)) { 415 notificationMgr.dismissNetworkSelectionNotificationForInactiveSubId(); 416 } 417 418 // Marks the event where the SIM goes into ready state. 419 // Right now, this is only used for the PUK-unlocking process. 420 if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(bag.mIccStatus) 421 || IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(bag.mIccStatus) 422 || IccCardConstants.INTENT_VALUE_ICC_NOT_READY.equals(bag.mIccStatus) 423 || IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(bag.mIccStatus)) { 424 // When the right event is triggered and there are UI objects in the 425 // foreground, we close them to display the lock panel. 426 if (mPUKEntryActivity != null) { 427 Log.i(LOG_TAG, "Dismiss puk entry activity"); 428 mPUKEntryActivity.finish(); 429 mPUKEntryActivity = null; 430 } 431 if (mPUKEntryProgressDialog != null) { 432 Log.i(LOG_TAG, "Dismiss puk progress dialog"); 433 mPUKEntryProgressDialog.dismiss(); 434 mPUKEntryProgressDialog = null; 435 } 436 Log.i(LOG_TAG, "Dismissing depersonal panel" + (bag.mIccStatus)); 437 IccNetworkDepersonalizationPanel.dialogDismiss(bag.mPhoneId); 438 } 439 break; 440 441 case EVENT_UNSOL_CDMA_INFO_RECORD: 442 //TODO: handle message here; 443 break; 444 case EVENT_DATA_ROAMING_SETTINGS_CHANGED: 445 updateDataRoamingStatus( 446 ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED); 447 break; 448 case EVENT_MOBILE_DATA_SETTINGS_CHANGED: 449 updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED); 450 break; 451 case EVENT_CARRIER_CONFIG_CHANGED: 452 int subId = (Integer) msg.obj; 453 // The voicemail number could be overridden by carrier config, so need to 454 // refresh the message waiting (voicemail) indicator. 455 refreshMwiIndicator(subId); 456 phone = getPhone(subId); 457 if (phone != null) { 458 if (isSimLocked(phone)) { 459 // pass in subType=-1 so handleSimLock can find the actual subType if 460 // needed. This is safe as valid values for subType are >= 0 461 handleSimLock(-1, phone); 462 } 463 TelephonyManager tm = getSystemService(TelephonyManager.class); 464 PhoneAppCallback callback = mTelephonyCallbacks[phone.getPhoneId()]; 465 // TODO: We may need to figure out a way to unregister if subId is invalid 466 tm.createForSubscriptionId(callback.getSubId()) 467 .unregisterTelephonyCallback(callback); 468 callback = new PhoneAppCallback(subId); 469 tm.createForSubscriptionId(subId).registerTelephonyCallback( 470 TelephonyManager.INCLUDE_LOCATION_DATA_COARSE, mHandler::post, 471 callback); 472 mTelephonyCallbacks[phone.getPhoneId()] = callback; 473 } 474 break; 475 case EVENT_MULTI_SIM_CONFIG_CHANGED: 476 int activeModems = (int) ((AsyncResult) msg.obj).result; 477 TelephonyManager tm = getSystemService(TelephonyManager.class); 478 // Unregister all previous callbacks 479 for (int phoneId = 0; phoneId < mTelephonyCallbacks.length; phoneId++) { 480 PhoneAppCallback callback = mTelephonyCallbacks[phoneId]; 481 if (callback != null) { 482 tm.createForSubscriptionId(callback.getSubId()) 483 .unregisterTelephonyCallback(callback); 484 mTelephonyCallbacks[phoneId] = null; 485 } 486 } 487 // Register callbacks for all active modems 488 for (int phoneId = 0; phoneId < activeModems; phoneId++) { 489 int sub = PhoneFactory.getPhone(phoneId).getSubId(); 490 PhoneAppCallback callback = new PhoneAppCallback(sub); 491 tm.createForSubscriptionId(sub).registerTelephonyCallback( 492 TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mHandler::post, 493 callback); 494 mTelephonyCallbacks[phoneId] = callback; 495 } 496 break; 497 } 498 } 499 }; 500 PhoneGlobals(Context context)501 public PhoneGlobals(Context context) { 502 super(context); 503 sMe = this; 504 if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 505 mSettingsObserver = new SettingsObserver(context, mHandler); 506 } 507 } 508 onCreate()509 public void onCreate() { 510 if (VDBG) Log.v(LOG_TAG, "onCreate()..."); 511 512 ContentResolver resolver = getContentResolver(); 513 514 if (!getResources().getBoolean( 515 com.android.internal.R.bool.config_force_phone_globals_creation)) { 516 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) { 517 Log.v(LOG_TAG, "onCreate()... but not defined FEATURE_TELEPHONY"); 518 return; 519 } 520 } 521 522 // Initialize the shim from frameworks/opt/telephony into packages/services/Telephony. 523 TelephonyLocalConnection.setInstance(new LocalConnectionImpl(this)); 524 525 TelephonyManager tm = getSystemService(TelephonyManager.class); 526 // Cache the "voice capable" flag. 527 // This flag currently comes from a resource (which is 528 // overrideable on a per-product basis): 529 sVoiceCapable = tm.isVoiceCapable(); 530 // ...but this might eventually become a PackageManager "system 531 // feature" instead, in which case we'd do something like: 532 // sVoiceCapable = 533 // getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS); 534 535 if (mCM == null) { 536 // Initialize AnomalyReporter early so that it can be used 537 AnomalyReporter.initialize(this); 538 539 // Inject telephony component factory if configured using other jars. 540 XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection); 541 TelephonyComponentFactory.getInstance().injectTheComponentFactory(parser); 542 543 // Create DomainSelectionResolver always, but it MUST be initialized only when 544 // the device supports AOSP domain selection architecture and 545 // has new IRadio that supports its related HAL APIs. 546 String dssComponentName = getResources().getString( 547 R.string.config_domain_selection_service_component_name); 548 DomainSelectionResolver.make(this, dssComponentName); 549 550 // Initialize the telephony framework 551 PhoneFactory.makeDefaultPhones(this, mFeatureFlags); 552 553 // Initialize the DomainSelectionResolver after creating the Phone instance 554 // to check the Radio HAL version. 555 if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) { 556 DomainSelectionResolver.getInstance().initialize(); 557 // Initialize EmergencyStateTracker if domain selection is supported 558 boolean isSuplDdsSwitchRequiredForEmergencyCall = getResources() 559 .getBoolean(R.bool.config_gnss_supl_requires_default_data_for_emergency); 560 int inServiceWaitTimeWhenDialEccInApm = getResources().getInteger(R.integer 561 .config_in_service_wait_timer_when_dialing_emergency_routing_ecc_in_apm); 562 boolean turnOffOemEnabledSatelliteDuringEmergencyCall = getResources().getBoolean( 563 R.bool.config_turn_off_oem_enabled_satellite_during_emergency_call); 564 boolean turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall = getResources() 565 .getBoolean(R.bool 566 .config_turn_off_non_emergency_nb_iot_ntn_satellite_for_emergency_call); 567 EmergencyStateTracker.make(this, isSuplDdsSwitchRequiredForEmergencyCall, 568 inServiceWaitTimeWhenDialEccInApm, 569 turnOffOemEnabledSatelliteDuringEmergencyCall, 570 turnOffNonEmergencyNbIotNtnSatelliteForEmergencyCall, 571 mFeatureFlags); 572 DynamicRoutingController.getInstance().initialize(this); 573 } 574 575 // Only bring up ImsResolver if the device supports having an IMS stack. 576 if (getPackageManager().hasSystemFeature( 577 PackageManager.FEATURE_TELEPHONY_IMS)) { 578 // Get the package name of the default IMS implementation. 579 String defaultImsMmtelPackage = getResources().getString( 580 R.string.config_ims_mmtel_package); 581 String defaultImsRcsPackage = getResources().getString( 582 R.string.config_ims_rcs_package); 583 ImsResolver.make(this, defaultImsMmtelPackage, 584 defaultImsRcsPackage, PhoneFactory.getPhones().length, 585 new ImsFeatureBinderRepository(), mFeatureFlags); 586 ImsResolver.getInstance().initialize(); 587 588 // With the IMS phone created, load static config.xml values from the phone process 589 // so that it can be provided to the ImsPhoneCallTracker. 590 for (Phone p : PhoneFactory.getPhones()) { 591 Phone imsPhone = p.getImsPhone(); 592 if (imsPhone != null && imsPhone instanceof ImsPhone) { 593 ImsPhone theImsPhone = (ImsPhone) imsPhone; 594 if (theImsPhone.getCallTracker() instanceof ImsPhoneCallTracker) { 595 ImsPhoneCallTracker ict = (ImsPhoneCallTracker) 596 theImsPhone.getCallTracker(); 597 598 ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config(); 599 config.isD2DCommunicationSupported = getResources().getBoolean( 600 R.bool.config_use_device_to_device_communication); 601 ict.setConfig(config); 602 } 603 } 604 } 605 RcsProvisioningMonitor.make(this, mFeatureFlags); 606 } 607 608 // Start TelephonyDebugService After the default phone is created. 609 Intent intent = new Intent(this, TelephonyDebugService.class); 610 startService(intent); 611 612 mCM = CallManager.getInstance(); 613 614 // Create the NotificationMgr singleton, which is used to display 615 // status bar icons and control other status bar behavior. 616 notificationMgr = NotificationMgr.init(this); 617 618 // Create the SatelliteController singleton, which acts as a backend service for 619 // {@link android.telephony.satellite.SatelliteManager}. 620 SatelliteController.make(this, mFeatureFlags); 621 622 if (!mFeatureFlags.phoneTypeCleanup()) { 623 // Create an instance of CdmaPhoneCallState and initialize it to IDLE 624 cdmaPhoneCallState = new CdmaPhoneCallState(); 625 cdmaPhoneCallState.CdmaPhoneCallStateInit(); 626 } 627 628 // before registering for phone state changes 629 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 630 mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG); 631 // lock used to keep the processor awake, when we don't care for the display. 632 mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK 633 | PowerManager.ON_AFTER_RELEASE, LOG_TAG); 634 635 mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); 636 637 phoneMgr = PhoneInterfaceManager.init(this, mFeatureFlags); 638 639 imsRcsController = ImsRcsController.init(this, mFeatureFlags); 640 641 configLoader = CarrierConfigLoader.init(this, mFeatureFlags); 642 643 if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) { 644 mImsStateCallbackController = 645 ImsStateCallbackController.make(this, PhoneFactory.getPhones().length, 646 mFeatureFlags); 647 mTelephonyRcsService = new TelephonyRcsService(this, 648 PhoneFactory.getPhones().length, mFeatureFlags); 649 mTelephonyRcsService.initialize(); 650 imsRcsController.setRcsService(mTelephonyRcsService); 651 mImsProvisioningController = 652 ImsProvisioningController.make(this, PhoneFactory.getPhones().length, 653 mFeatureFlags); 654 } 655 656 // Create the CallNotifier singleton, which handles 657 // asynchronous events from the telephony layer (like 658 // launching the incoming-call UI when an incoming call comes 659 // in.) 660 notifier = CallNotifier.init(this); 661 662 PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED); 663 664 // register for MMI/USSD 665 mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null); 666 667 // Initialize cell status using current airplane mode. 668 handleAirplaneModeChange( 669 Settings.Global.getInt( 670 getContentResolver(), 671 Settings.Global.AIRPLANE_MODE_ON, 672 AIRPLANE_OFF) 673 == AIRPLANE_ON); 674 675 // Register for misc other intent broadcasts. 676 IntentFilter intentFilter = 677 new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); 678 intentFilter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); 679 intentFilter.addAction(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED); 680 intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); 681 intentFilter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); 682 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); 683 registerReceiver(mReceiver, intentFilter); 684 int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); 685 if (SubscriptionManager.isValidSubscriptionId(defaultDataSubId)) { 686 if (VDBG) { 687 Log.v(LOG_TAG, "Loaded initial default data sub: " + defaultDataSubId); 688 } 689 mDefaultDataSubId = defaultDataSubId; 690 registerSettingsObserver(); 691 updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED); 692 } 693 694 PhoneConfigurationManager.registerForMultiSimConfigChange( 695 mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null); 696 697 mTelephonyCallbacks = new PhoneAppCallback[tm.getSupportedModemCount()]; 698 if (tm.getSupportedModemCount() > 0) { 699 for (Phone phone : PhoneFactory.getPhones()) { 700 int subId = phone.getSubId(); 701 PhoneAppCallback callback = new PhoneAppCallback(subId); 702 tm.createForSubscriptionId(subId).registerTelephonyCallback( 703 TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mHandler::post, callback); 704 mTelephonyCallbacks[phone.getPhoneId()] = callback; 705 } 706 } 707 mCarrierVvmPackageInstalledReceiver.register(this); 708 709 //set the default values for the preferences in the phone. 710 PreferenceManager.setDefaultValues(this, R.xml.call_feature_setting, false); 711 } 712 713 // XXX pre-load the SimProvider so that it's ready 714 resolver.getType(Uri.parse("content://icc/adn")); 715 716 // TODO: Register for Cdma Information Records 717 // phone.registerCdmaInformationRecord(mHandler, EVENT_UNSOL_CDMA_INFO_RECORD, null); 718 719 // Read HAC settings and configure audio hardware 720 if (getResources().getBoolean(R.bool.hac_enabled)) { 721 int hac = android.provider.Settings.System.getInt( 722 getContentResolver(), 723 android.provider.Settings.System.HEARING_AID, 724 0); 725 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 726 audioManager.setParameters( 727 SettingsConstants.HAC_KEY + "=" + (hac == SettingsConstants.HAC_ENABLED 728 ? SettingsConstants.HAC_VAL_ON : SettingsConstants.HAC_VAL_OFF)); 729 } 730 731 // Start tracking Binder latency for the phone process. 732 mBinderCallsSettingsObserver = new BinderCallsStats.SettingsObserver( 733 getApplicationContext(), 734 new BinderCallsStats( 735 new BinderCallsStats.Injector(), 736 com.android.internal.os.BinderLatencyProto.Dims.TELEPHONY)); 737 } 738 739 /** 740 * Returns the singleton instance of the PhoneApp. 741 */ getInstance()742 public static PhoneGlobals getInstance() { 743 if (sMe == null) { 744 throw new IllegalStateException("No PhoneGlobals here!"); 745 } 746 return sMe; 747 } 748 749 /** 750 * Returns the default phone. 751 * 752 * WARNING: This method should be used carefully, now that there may be multiple phones. 753 */ getPhone()754 public static Phone getPhone() { 755 return PhoneFactory.getDefaultPhone(); 756 } 757 getPhone(int subId)758 public static Phone getPhone(int subId) { 759 return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId)); 760 } 761 getCallManager()762 /* package */ CallManager getCallManager() { 763 return mCM; 764 } 765 getCarrierConfig()766 public PersistableBundle getCarrierConfig() { 767 return getCarrierConfigForSubId(SubscriptionManager.getDefaultSubscriptionId()); 768 } 769 getCarrierConfigForSubId(int subId)770 public PersistableBundle getCarrierConfigForSubId(int subId) { 771 return configLoader.getConfigForSubIdWithFeature(subId, getOpPackageName(), 772 getAttributionTag()); 773 } 774 registerSettingsObserver()775 private void registerSettingsObserver() { 776 mSettingsObserver.unobserve(); 777 String dataRoamingSetting = Settings.Global.DATA_ROAMING; 778 String mobileDataSetting = Settings.Global.MOBILE_DATA; 779 if (TelephonyManager.getDefault().getSimCount() > 1) { 780 int subId = mDefaultDataSubId; 781 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 782 dataRoamingSetting += subId; 783 mobileDataSetting += subId; 784 } 785 } 786 787 // Listen for user data roaming setting changed event 788 mSettingsObserver.observe(Settings.Global.getUriFor(dataRoamingSetting), 789 EVENT_DATA_ROAMING_SETTINGS_CHANGED); 790 791 // Listen for mobile data setting changed event 792 mSettingsObserver.observe(Settings.Global.getUriFor(mobileDataSetting), 793 EVENT_MOBILE_DATA_SETTINGS_CHANGED); 794 } 795 796 /** 797 * Sets the activity responsible for un-PUK-blocking the device 798 * so that we may close it when we receive a positive result. 799 * mPUKEntryActivity is also used to indicate to the device that 800 * we are trying to un-PUK-lock the phone. In other words, iff 801 * it is NOT null, then we are trying to unlock and waiting for 802 * the SIM to move to READY state. 803 * 804 * @param activity is the activity to close when PUK has 805 * finished unlocking. Can be set to null to indicate the unlock 806 * or SIM READYing process is over. 807 */ setPukEntryActivity(Activity activity)808 void setPukEntryActivity(Activity activity) { 809 Log.i(LOG_TAG, "setPukEntryActivity - set to " + (activity == null ? "null" : "activity")); 810 mPUKEntryActivity = activity; 811 } 812 getPUKEntryActivity()813 Activity getPUKEntryActivity() { 814 return mPUKEntryActivity; 815 } 816 817 /** 818 * Sets the dialog responsible for notifying the user of un-PUK- 819 * blocking - SIM READYing progress, so that we may dismiss it 820 * when we receive a positive result. 821 * 822 * @param dialog indicates the progress dialog informing the user 823 * of the state of the device. Dismissed upon completion of 824 * READYing process 825 */ setPukEntryProgressDialog(ProgressDialog dialog)826 void setPukEntryProgressDialog(ProgressDialog dialog) { 827 Log.i(LOG_TAG, "setPukEntryProgressDialog - set to " 828 + (dialog == null ? "null" : "activity")); 829 mPUKEntryProgressDialog = dialog; 830 } 831 getKeyguardManager()832 KeyguardManager getKeyguardManager() { 833 return mKeyguardManager; 834 } 835 onMMIComplete(AsyncResult r)836 private void onMMIComplete(AsyncResult r) { 837 if (VDBG) Log.d(LOG_TAG, "onMMIComplete()..."); 838 MmiCode mmiCode = (MmiCode) r.result; 839 PhoneUtils.displayMMIComplete(mmiCode.getPhone(), getInstance(), mmiCode, null, null); 840 } 841 initForNewRadioTechnology()842 private void initForNewRadioTechnology() { 843 if (DBG) Log.d(LOG_TAG, "initForNewRadioTechnology..."); 844 notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange(); 845 } 846 handleAirplaneModeChange(boolean isAirplaneNewlyOn)847 private void handleAirplaneModeChange(boolean isAirplaneNewlyOn) { 848 Log.i(LOG_TAG, "handleAirplaneModeChange: isAirplaneNewlyOn=" + isAirplaneNewlyOn); 849 int cellState = 850 Settings.Global.getInt( 851 getContentResolver(), Settings.Global.CELL_ON, PhoneConstants.CELL_ON_FLAG); 852 switch (cellState) { 853 case PhoneConstants.CELL_OFF_FLAG: 854 // Airplane mode does not affect the cell radio if user has turned it off. 855 Log.i(LOG_TAG, "Ignore airplane mode change due to cell off."); 856 break; 857 case PhoneConstants.CELL_ON_FLAG: 858 maybeTurnCellOff(isAirplaneNewlyOn); 859 break; 860 case PhoneConstants.CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG: 861 maybeTurnCellOn(isAirplaneNewlyOn); 862 break; 863 } 864 for (Phone phone : PhoneFactory.getPhones()) { 865 phone.getServiceStateTracker().onAirplaneModeChanged(isAirplaneNewlyOn); 866 } 867 } 868 869 /* 870 * Returns true if the radio must be turned off when entering airplane mode. 871 */ isCellOffInAirplaneMode()872 private boolean isCellOffInAirplaneMode() { 873 String airplaneModeRadios = 874 Settings.Global.getString( 875 getContentResolver(), Settings.Global.AIRPLANE_MODE_RADIOS); 876 return airplaneModeRadios == null 877 || airplaneModeRadios.contains(Settings.Global.RADIO_CELL); 878 } 879 setRadioPowerOff()880 private void setRadioPowerOff() { 881 Log.i(LOG_TAG, "Turning radio off - airplane"); 882 Settings.Global.putInt( 883 getContentResolver(), 884 Settings.Global.CELL_ON, 885 PhoneConstants.CELL_OFF_DUE_TO_AIRPLANE_MODE_FLAG); 886 Settings.Global.putInt(getContentResolver(), Settings.Global.ENABLE_CELLULAR_ON_BOOT, 0); 887 TelephonyProperties.airplane_mode_on(true); // true means int value 1 888 PhoneUtils.setRadioPower(false); 889 clearCacheOnRadioOff(); 890 } 891 892 /** Clear fields on power off radio **/ clearCacheOnRadioOff()893 private void clearCacheOnRadioOff() { 894 // Re-show is-roaming notifications after APM mode 895 mShownNotificationReasons.clear(); 896 } 897 setRadioPowerOn()898 private void setRadioPowerOn() { 899 Log.i(LOG_TAG, "Turning radio on - airplane"); 900 Settings.Global.putInt( 901 getContentResolver(), Settings.Global.CELL_ON, PhoneConstants.CELL_ON_FLAG); 902 Settings.Global.putInt(getContentResolver(), Settings.Global.ENABLE_CELLULAR_ON_BOOT, 1); 903 TelephonyProperties.airplane_mode_on(false); // false means int value 0 904 PhoneUtils.setRadioPower(true); 905 } 906 maybeTurnCellOff(boolean isAirplaneNewlyOn)907 private void maybeTurnCellOff(boolean isAirplaneNewlyOn) { 908 if (isAirplaneNewlyOn) { 909 // If we are trying to turn off the radio, make sure there are no active 910 // emergency calls. If there are, switch airplane mode back to off. 911 TelecomManager tm = (TelecomManager) getSystemService(TELECOM_SERVICE); 912 913 if (tm != null && tm.isInEmergencyCall()) { 914 // Switch airplane mode back to off. 915 ConnectivityManager cm = 916 (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); 917 cm.setAirplaneMode(false); 918 Toast.makeText(this, R.string.radio_off_during_emergency_call, Toast.LENGTH_LONG) 919 .show(); 920 Log.i(LOG_TAG, "Ignoring airplane mode: emergency call. Turning airplane off"); 921 } else if (isCellOffInAirplaneMode()) { 922 setRadioPowerOff(); 923 } else { 924 Log.i(LOG_TAG, "Ignoring airplane mode: settings prevent cell radio power off"); 925 } 926 } else { 927 Log.i(LOG_TAG, "Ignoring airplane mode: not newly on"); 928 } 929 } 930 maybeTurnCellOn(boolean isAirplaneNewlyOn)931 private void maybeTurnCellOn(boolean isAirplaneNewlyOn) { 932 if (!isAirplaneNewlyOn) { 933 setRadioPowerOn(); 934 } else { 935 Log.i(LOG_TAG, "Ignoring airplane mode off: radio is already on."); 936 } 937 } 938 939 /** 940 * Receiver for misc intent broadcasts the Phone app cares about. 941 */ 942 private class PhoneAppBroadcastReceiver extends BroadcastReceiver { 943 @Override onReceive(Context context, Intent intent)944 public void onReceive(Context context, Intent intent) { 945 String action = intent.getAction(); 946 if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { 947 boolean airplaneMode = intent.getBooleanExtra("state", false); 948 handleAirplaneModeChange(airplaneMode); 949 } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { 950 // re-register as it may be a new IccCard 951 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 952 SubscriptionManager.INVALID_PHONE_INDEX); 953 if (SubscriptionManager.isValidPhoneId(phoneId)) { 954 PhoneUtils.unregisterIccStatus(mHandler, phoneId); 955 PhoneUtils.registerIccStatus(mHandler, EVENT_SIM_NETWORK_LOCKED, phoneId); 956 } 957 String iccStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE); 958 mHandler.sendMessage(mHandler.obtainMessage(EVENT_SIM_STATE_CHANGED, 959 new EventSimStateChangedBag(phoneId, iccStatus))); 960 } else if (action.equals(TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED)) { 961 String newPhone = intent.getStringExtra(PhoneConstants.PHONE_NAME_KEY); 962 Log.d(LOG_TAG, "Radio technology switched. Now " + newPhone + " is active."); 963 initForNewRadioTechnology(); 964 } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) { 965 int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0); 966 phoneInEcm = PhoneFactory.getPhone(phoneId); 967 Log.d(LOG_TAG, "Emergency Callback Mode. phoneId:" + phoneId); 968 if (phoneInEcm != null) { 969 if (TelephonyCapabilities.supportsEcm(phoneInEcm)) { 970 Log.d(LOG_TAG, "Emergency Callback Mode arrived in PhoneApp."); 971 // Start Emergency Callback Mode service 972 if (intent.getBooleanExtra( 973 TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false)) { 974 context.startService(new Intent(context, 975 EmergencyCallbackModeService.class)); 976 } else { 977 phoneInEcm = null; 978 } 979 } else { 980 // It doesn't make sense to get ACTION_EMERGENCY_CALLBACK_MODE_CHANGED 981 // on a device that doesn't support ECM in the first place. 982 Log.e(LOG_TAG, "Got ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, but " 983 + "ECM isn't supported for phone: " + phoneInEcm.getPhoneName()); 984 phoneInEcm = null; 985 } 986 } else { 987 Log.w(LOG_TAG, "phoneInEcm is null."); 988 } 989 } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) { 990 // Roaming status could be overridden by carrier config, so we need to update it. 991 if (VDBG) Log.v(LOG_TAG, "carrier config changed."); 992 updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED); 993 updateLimitedSimFunctionForDualSim(); 994 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 995 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 996 if (SubscriptionManager.isValidSubscriptionId(subId)) { 997 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARRIER_CONFIG_CHANGED, 998 new Integer(subId))); 999 } 1000 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) { 1001 // We also need to pay attention when default data subscription changes. 1002 if (VDBG) Log.v(LOG_TAG, "default data sub changed."); 1003 mDefaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); 1004 registerSettingsObserver(); 1005 Phone phone = getPhone(mDefaultDataSubId); 1006 if (phone != null) { 1007 updateDataRoamingStatus( 1008 ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED); 1009 } 1010 } 1011 } 1012 } 1013 handleServiceStateChanged(ServiceState serviceState, int subId)1014 private void handleServiceStateChanged(ServiceState serviceState, int subId) { 1015 if (VDBG) Log.v(LOG_TAG, "handleServiceStateChanged"); 1016 int state = serviceState.getState(); 1017 notificationMgr.updateNetworkSelection(state, subId); 1018 1019 if (VDBG) { 1020 Log.v(LOG_TAG, "subId=" + subId + ", mDefaultDataSubId=" 1021 + mDefaultDataSubId + ", ss roaming=" + serviceState.getDataRoaming()); 1022 } 1023 if (subId == mDefaultDataSubId) { 1024 updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED); 1025 } 1026 } 1027 1028 /** 1029 * When roaming, if mobile data cannot be established due to data roaming not enabled, we need 1030 * to notify the user so they can enable it through settings. Vise versa if the condition 1031 * changes, we need to dismiss the notification. 1032 * @param notificationReason to inform which event is called for notification update. 1033 */ updateDataRoamingStatus(@oamingNotificationReason int notificationReason)1034 private void updateDataRoamingStatus(@RoamingNotificationReason int notificationReason) { 1035 Phone phone = getPhone(mDefaultDataSubId); 1036 if (phone == null) { 1037 Log.w(LOG_TAG, "Can't get phone with sub id = " + mDefaultDataSubId); 1038 return; 1039 } 1040 1041 ServiceState serviceState = phone.getServiceState(); 1042 if (serviceState == null) { 1043 Log.e(LOG_TAG, "updateDataRoamingStatus: serviceState is null"); 1044 return; 1045 } 1046 1047 List<DataDisallowedReason> disallowReasons = phone.getDataNetworkController() 1048 .getInternetDataDisallowedReasons(); 1049 1050 if (disallowReasons.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK) 1051 && disallowReasons.contains(DataDisallowedReason.ROAMING_DISABLED) 1052 && (notificationReason == ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED 1053 || notificationReason 1054 == ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED)) { 1055 // If the ONLY_ALLOWED_SINGLE_NETWORK disallow reason has not yet been removed due 1056 // to a change in mobile_data (including roaming_data) settings, update roaming 1057 // notification again after the Internet is completely disconnected to check 1058 // ONLY_ALLOWED_SINGLE_NETWORK disallow reason is removed. 1059 mWaitForInternetDisconnection.set(true); 1060 Log.d(LOG_TAG, "updateDataRoamingStatus," 1061 + " wait for internet disconnection for single data network"); 1062 } else if (!disallowReasons.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK) 1063 && mWaitForInternetDisconnection.compareAndSet(true, false)) { 1064 // If the ONLY_ALLOWED_SINGLE_NETWORK disallow reason has been removed, 1065 // no longer wait for Internet disconnection. 1066 Log.d(LOG_TAG, "updateDataRoamingStatus," 1067 + " cancel to wait for internet disconnection for single data network"); 1068 } 1069 1070 updateDataRoamingStatus(notificationReason, disallowReasons, serviceState); 1071 } 1072 1073 /** 1074 * When roaming, if mobile data cannot be established due to data roaming not enabled, we need 1075 * to notify the user so they can enable it through settings. Vise versa if the condition 1076 * changes, we need to dismiss the notification. 1077 * @param notificationReason to inform which event is called for notification update. 1078 * @param disallowReasons List of reasons why internet data is not allowed. An empty list if 1079 * internet is allowed. 1080 * @param serviceState Service state from phone 1081 */ updateDataRoamingStatus(@oamingNotificationReason int notificationReason, List<DataDisallowedReason> disallowReasons, ServiceState serviceState)1082 private void updateDataRoamingStatus(@RoamingNotificationReason int notificationReason, 1083 List<DataDisallowedReason> disallowReasons, ServiceState serviceState) { 1084 1085 if (VDBG) Log.v(LOG_TAG, "updateDataRoamingStatus"); 1086 String roamingNumeric = serviceState.getOperatorNumeric(); 1087 String roamingNumericReason = "RoamingNumeric=" + roamingNumeric; 1088 String callingReason = "CallingReason=" + notificationReason; 1089 boolean dataIsNowRoaming = serviceState.getDataRoaming(); 1090 boolean dataAllowed; 1091 boolean notAllowedDueToRoamingOff; 1092 dataAllowed = disallowReasons.isEmpty(); 1093 notAllowedDueToRoamingOff = (disallowReasons.size() == 1 1094 && disallowReasons.contains(DataDisallowedReason.ROAMING_DISABLED)); 1095 StringBuilder sb = new StringBuilder("updateDataRoamingStatus"); 1096 sb.append(" dataAllowed=").append(dataAllowed); 1097 sb.append(", disallowReasons=").append(disallowReasons); 1098 sb.append(", dataIsNowRoaming=").append(dataIsNowRoaming); 1099 sb.append(", ").append(roamingNumericReason); 1100 sb.append(", ").append(callingReason); 1101 mDataRoamingNotifLog.log(sb.toString()); 1102 if (VDBG) { 1103 Log.v(LOG_TAG, sb.toString()); 1104 } 1105 1106 // Determine if a given roaming numeric has never been shown. 1107 boolean shownInThisNumeric = false; 1108 if (notificationReason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED 1109 || notificationReason == ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED) { 1110 shownInThisNumeric = mShownNotificationReasons.contains(roamingNumericReason); 1111 } 1112 // Determine if a notification has never been shown by given calling reason. 1113 boolean shownForThisReason = mShownNotificationReasons.contains(callingReason); 1114 1115 if (!dataAllowed && notAllowedDueToRoamingOff) { 1116 if (!shownInThisNumeric && roamingNumeric != null) { 1117 mShownNotificationReasons.add(roamingNumericReason); 1118 } 1119 if (!shownForThisReason 1120 && notificationReason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED) { 1121 mShownNotificationReasons.add(callingReason); 1122 } 1123 // No need to show it again if we never cancelled it explicitly. 1124 if (getCurrentRoamingNotification() == ROAMING_NOTIFICATION_DISCONNECTED) { 1125 return; 1126 } 1127 1128 // If the only reason of no data is data roaming disabled, then we notify the user 1129 // so the user can turn on data roaming. 1130 if (!shownInThisNumeric && !shownForThisReason) { 1131 updateDataRoamingNotification(ROAMING_NOTIFICATION_DISCONNECTED); 1132 } else { 1133 // Don't show roaming notification if we've already shown for this MccMnc 1134 Log.d(LOG_TAG, "Skip roaming disconnected notification since already" 1135 + " shownInThisNumeric=" + shownInThisNumeric 1136 + " shownForThisReason=" + shownForThisReason); 1137 // Dismiss notification if the other notification is shown. 1138 if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) { 1139 updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION); 1140 } 1141 } 1142 } else if (dataAllowed && dataIsNowRoaming) { 1143 if (!shownInThisNumeric && roamingNumeric != null) { 1144 mShownNotificationReasons.add(roamingNumericReason); 1145 } 1146 if (!shownForThisReason 1147 && notificationReason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED) { 1148 mShownNotificationReasons.add(callingReason); 1149 } 1150 boolean shouldShowRoamingNotification = shouldShowRoamingNotification(roamingNumeric); 1151 // No need to show it again if we never cancelled it explicitly. 1152 if (getCurrentRoamingNotification() == ROAMING_NOTIFICATION_CONNECTED) { 1153 return; 1154 } 1155 1156 // Inform users that roaming charges may apply. 1157 if (!shownInThisNumeric && !shownForThisReason && shouldShowRoamingNotification) { 1158 updateDataRoamingNotification(ROAMING_NOTIFICATION_CONNECTED); 1159 } else { 1160 // Don't show roaming notification if we've already shown for this MccMnc or 1161 // disabled from carrier config. 1162 Log.d(LOG_TAG, "Skip roaming connected notification since already" 1163 + " shownInThisNumeric:" + shownInThisNumeric 1164 + " shownForThisReason:" + shownForThisReason 1165 + " shouldShowRoamingNotification:" + shouldShowRoamingNotification); 1166 // Dismiss notification if the other notification is shown. 1167 if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) { 1168 updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION); 1169 } 1170 } 1171 } else if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) { 1172 // Otherwise we either 1) we are not roaming or 2) roaming is off but ROAMING_DISABLED 1173 // is not the only data disable reason. In this case we dismiss the notification we 1174 // showed earlier. 1175 updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION); 1176 } 1177 } 1178 updateDataRoamingNotification(@oamingNotification int roamingNotification)1179 private void updateDataRoamingNotification(@RoamingNotification int roamingNotification) { 1180 int event; 1181 switch (roamingNotification) { 1182 case ROAMING_NOTIFICATION_NO_NOTIFICATION: 1183 Log.d(LOG_TAG, "Dismiss roaming notification"); 1184 mDataRoamingNotifLog.log("Hide roaming."); 1185 event = EVENT_DATA_ROAMING_OK; 1186 break; 1187 case ROAMING_NOTIFICATION_CONNECTED: 1188 Log.d(LOG_TAG, "Show roaming connected notification"); 1189 mDataRoamingNotifLog.log("Show roaming on."); 1190 event = EVENT_DATA_ROAMING_CONNECTED; 1191 break; 1192 case ROAMING_NOTIFICATION_DISCONNECTED: 1193 Log.d(LOG_TAG, "Show roaming disconnected notification"); 1194 mDataRoamingNotifLog.log("Show roaming off."); 1195 event = EVENT_DATA_ROAMING_DISCONNECTED; 1196 break; 1197 default: 1198 Log.d(LOG_TAG, "Should never reach here."); 1199 mDataRoamingNotifLog.log("Should never reach here."); 1200 return; 1201 } 1202 mCurrentRoamingNotification = roamingNotification; 1203 mHandler.obtainMessage(event, mDefaultDataSubId, 0).sendToTarget(); 1204 } 1205 getCurrentRoamingNotification()1206 private @RoamingNotification int getCurrentRoamingNotification() { 1207 return mCurrentRoamingNotification; 1208 } 1209 1210 /** 1211 * 1212 * @param subId to check roaming on 1213 * @return whether we have transitioned to dataRoaming 1214 */ dataIsNowRoaming(int subId)1215 private boolean dataIsNowRoaming(int subId) { 1216 return getPhone(subId).getServiceState().getDataRoaming(); 1217 } 1218 shouldShowRoamingNotification(String roamingNumeric)1219 private boolean shouldShowRoamingNotification(String roamingNumeric) { 1220 PersistableBundle config = getCarrierConfigForSubId(mDefaultDataSubId); 1221 boolean showRoamingNotification = config.getBoolean( 1222 CarrierConfigManager.KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL); 1223 1224 if (TextUtils.isEmpty(roamingNumeric)) { 1225 Log.d(LOG_TAG, "shouldShowRoamingNotification: roamingNumeric=" + roamingNumeric); 1226 return showRoamingNotification; 1227 } 1228 1229 String[] includedMccMncs = config.getStringArray(CarrierConfigManager 1230 .KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY); 1231 if (includedMccMncs != null) { 1232 for (String mccMnc : includedMccMncs) { 1233 if (roamingNumeric.equals(mccMnc)) { 1234 Log.d(LOG_TAG, "shouldShowRoamingNotification: show for MCC/MNC " + mccMnc); 1235 return showRoamingNotification; 1236 } 1237 } 1238 } 1239 1240 String[] excludedMccs = config.getStringArray(CarrierConfigManager 1241 .KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY); 1242 String roamingMcc = roamingNumeric.length() < 3 ? "" : roamingNumeric.substring(0, 3); 1243 if (excludedMccs != null && !TextUtils.isEmpty(roamingMcc)) { 1244 for (String mcc : excludedMccs) { 1245 if (roamingMcc.equals(mcc)) { 1246 Log.d(LOG_TAG, "shouldShowRoamingNotification: ignore for MCC " + mcc); 1247 return false; 1248 } 1249 } 1250 } 1251 1252 if (showRoamingNotification) { 1253 Log.d(LOG_TAG, "shouldShowRoamingNotification: show for numeric " + roamingNumeric); 1254 } 1255 return showRoamingNotification; 1256 } 1257 1258 private void updateLimitedSimFunctionForDualSim() { 1259 if (DBG) Log.d(LOG_TAG, "updateLimitedSimFunctionForDualSim"); 1260 // check conditions to display limited SIM function notification under dual SIM 1261 SubscriptionManager subMgr = (SubscriptionManager) getSystemService( 1262 Context.TELEPHONY_SUBSCRIPTION_SERVICE); 1263 List<SubscriptionInfo> subList = subMgr.getActiveSubscriptionInfoList(false); 1264 if (subList != null && subList.size() > 1) { 1265 CarrierConfigManager configMgr = (CarrierConfigManager) 1266 getSystemService(Context.CARRIER_CONFIG_SERVICE); 1267 for (SubscriptionInfo info : subList) { 1268 PersistableBundle b = configMgr.getConfigForSubId(info.getSubscriptionId()); 1269 if (b != null) { 1270 if (b.getBoolean(CarrierConfigManager 1271 .KEY_LIMITED_SIM_FUNCTION_NOTIFICATION_FOR_DSDS_BOOL)) { 1272 notificationMgr.showLimitedSimFunctionWarningNotification( 1273 info.getSubscriptionId(), 1274 info.getDisplayName().toString()); 1275 } else { 1276 notificationMgr.dismissLimitedSimFunctionWarningNotification( 1277 info.getSubscriptionId()); 1278 } 1279 } 1280 } 1281 } else { 1282 // cancel notifications for all subs 1283 notificationMgr.dismissLimitedSimFunctionWarningNotification( 1284 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1285 } 1286 notificationMgr.dismissLimitedSimFunctionWarningNotificationForInactiveSubs(); 1287 1288 } 1289 getPhoneInEcm()1290 public Phone getPhoneInEcm() { 1291 return phoneInEcm; 1292 } 1293 1294 /** 1295 * Triggers a refresh of the message waiting (voicemail) indicator. 1296 * 1297 * @param subId the subscription id we should refresh the notification for. 1298 */ refreshMwiIndicator(int subId)1299 public void refreshMwiIndicator(int subId) { 1300 notificationMgr.refreshMwi(subId); 1301 } 1302 1303 /** 1304 * Called when the network selection on the subscription {@code subId} is changed by the user. 1305 * 1306 * @param subId the subscription id. 1307 */ onNetworkSelectionChanged(int subId)1308 public void onNetworkSelectionChanged(int subId) { 1309 Phone phone = getPhone(subId); 1310 if (phone != null) { 1311 notificationMgr.updateNetworkSelection(phone.getServiceState().getState(), subId); 1312 } else { 1313 Log.w(LOG_TAG, "onNetworkSelectionChanged on null phone, subId: " + subId); 1314 } 1315 } 1316 1317 /** 1318 * @return whether the device supports RCS User Capability Exchange or not. 1319 */ getDeviceUceEnabled()1320 public boolean getDeviceUceEnabled() { 1321 return (mTelephonyRcsService == null) ? false : mTelephonyRcsService.isDeviceUceEnabled(); 1322 } 1323 1324 /** 1325 * Set the device supports RCS User Capability Exchange. 1326 * @param isEnabled true if the device supports UCE. 1327 */ setDeviceUceEnabled(boolean isEnabled)1328 public void setDeviceUceEnabled(boolean isEnabled) { 1329 if (mTelephonyRcsService != null) { 1330 mTelephonyRcsService.setDeviceUceEnabled(isEnabled); 1331 } 1332 } 1333 1334 /** 1335 * Dump the state of the object, add calls to other objects as desired. 1336 * 1337 * @param fd File descriptor 1338 * @param printWriter Print writer 1339 * @param args Arguments 1340 */ dump(FileDescriptor fd, PrintWriter printWriter, String[] args)1341 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 1342 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 1343 pw.println("------- PhoneGlobals -------"); 1344 pw.increaseIndent(); 1345 pw.println("FeatureFlags:"); 1346 pw.increaseIndent(); 1347 pw.decreaseIndent(); 1348 pw.println("mCurrentRoamingNotification=" + mCurrentRoamingNotification); 1349 pw.println("mDefaultDataSubId=" + mDefaultDataSubId); 1350 pw.println("isSmsCapable=" + TelephonyManager.from(this).isSmsCapable()); 1351 pw.println("mDataRoamingNotifLog:"); 1352 pw.increaseIndent(); 1353 mDataRoamingNotifLog.dump(fd, pw, args); 1354 pw.decreaseIndent(); 1355 pw.println("ImsResolver:"); 1356 pw.increaseIndent(); 1357 try { 1358 if (ImsResolver.getInstance() != null) ImsResolver.getInstance().dump(fd, pw, args); 1359 } catch (Exception e) { 1360 e.printStackTrace(); 1361 } 1362 pw.decreaseIndent(); 1363 pw.println("RcsService:"); 1364 try { 1365 if (mTelephonyRcsService != null) mTelephonyRcsService.dump(fd, pw, args); 1366 } catch (Exception e) { 1367 e.printStackTrace(); 1368 } 1369 pw.println("ImsStateCallbackController:"); 1370 try { 1371 if (mImsStateCallbackController != null) mImsStateCallbackController.dump(pw); 1372 } catch (Exception e) { 1373 e.printStackTrace(); 1374 } 1375 pw.println("DomainSelectionResolver:"); 1376 pw.increaseIndent(); 1377 try { 1378 if (DomainSelectionResolver.getInstance() != null) { 1379 DomainSelectionResolver.getInstance().dump(fd, pw, args); 1380 } 1381 } catch (Exception e) { 1382 e.printStackTrace(); 1383 } 1384 pw.decreaseIndent(); 1385 pw.decreaseIndent(); 1386 pw.println("mShownNotificationReasons=" + mShownNotificationReasons); 1387 pw.println("------- End PhoneGlobals -------"); 1388 } 1389 skipDataRoamingDisconnectedNotificationInSatelliteMode(int subId)1390 private boolean skipDataRoamingDisconnectedNotificationInSatelliteMode(int subId) { 1391 SatelliteController satelliteController = SatelliteController.getInstance(); 1392 if (satelliteController.isSatelliteEnabledOrBeingEnabled()) { 1393 Log.d(LOG_TAG, "skipDataRoamingDisconnected - skip notification as " 1394 + "satellite is enabled or being enabled"); 1395 return true; 1396 } 1397 1398 int phoneId = SubscriptionManager.getPhoneId(subId); 1399 Phone phone = PhoneFactory.getPhone(phoneId); 1400 ServiceState serviceState = phone.getServiceState(); 1401 if (serviceState != null && serviceState.isUsingNonTerrestrialNetwork()) { 1402 Log.d(LOG_TAG, "skipDataRoamingDisconnected - isUsingNtn"); 1403 List<Integer> capabilities = 1404 satelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(phone); 1405 if (!capabilities.contains(NetworkRegistrationInfo.SERVICE_TYPE_DATA)) { 1406 // Skip data roaming disconnected notification as device is connected to 1407 // non-terrestrial network that does not support data. 1408 Log.d(LOG_TAG, "skipDataRoamingDisconnected - skip notification as " 1409 + "NTN does not support data"); 1410 return true; 1411 } 1412 } 1413 1414 Log.d(LOG_TAG, "skipDataRoamingDisconnected - do not skip notification."); 1415 return false; 1416 } 1417 } 1418