• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.phone;
18 
19 import android.annotation.IntDef;
20 import android.app.Activity;
21 import android.app.KeyguardManager;
22 import android.app.ProgressDialog;
23 import android.content.BroadcastReceiver;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.ContextWrapper;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.pm.PackageManager;
30 import android.content.res.XmlResourceParser;
31 import android.media.AudioManager;
32 import android.net.ConnectivityManager;
33 import android.net.Uri;
34 import android.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