• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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.server;
18 
19 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
20 import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
21 import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_DATA;
22 import static android.telephony.TelephonyRegistryManager.SIM_ACTIVATION_TYPE_VOICE;
23 
24 import static java.util.Arrays.copyOf;
25 
26 import android.Manifest;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.app.ActivityManager;
30 import android.app.AppOpsManager;
31 import android.app.BroadcastOptions;
32 import android.app.compat.CompatChanges;
33 import android.compat.annotation.ChangeId;
34 import android.compat.annotation.EnabledSince;
35 import android.content.BroadcastReceiver;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.IntentFilter;
39 import android.content.pm.PackageManager;
40 import android.os.Binder;
41 import android.os.Build;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.IBinder;
45 import android.os.Message;
46 import android.os.Process;
47 import android.os.RemoteException;
48 import android.os.UserHandle;
49 import android.provider.DeviceConfig;
50 import android.telecom.TelecomManager;
51 import android.telephony.AccessNetworkConstants;
52 import android.telephony.Annotation;
53 import android.telephony.Annotation.RadioPowerState;
54 import android.telephony.Annotation.SrvccState;
55 import android.telephony.BarringInfo;
56 import android.telephony.CallQuality;
57 import android.telephony.CallState;
58 import android.telephony.CarrierConfigManager;
59 import android.telephony.CellIdentity;
60 import android.telephony.CellInfo;
61 import android.telephony.CellSignalStrength;
62 import android.telephony.CellSignalStrengthCdma;
63 import android.telephony.CellSignalStrengthGsm;
64 import android.telephony.CellSignalStrengthLte;
65 import android.telephony.CellSignalStrengthNr;
66 import android.telephony.CellSignalStrengthTdscdma;
67 import android.telephony.CellSignalStrengthWcdma;
68 import android.telephony.CellularIdentifierDisclosure;
69 import android.telephony.DisconnectCause;
70 import android.telephony.LinkCapacityEstimate;
71 import android.telephony.LocationAccessPolicy;
72 import android.telephony.NetworkRegistrationInfo;
73 import android.telephony.PhoneCapability;
74 import android.telephony.PhoneStateListener;
75 import android.telephony.PhysicalChannelConfig;
76 import android.telephony.PreciseCallState;
77 import android.telephony.PreciseDataConnectionState;
78 import android.telephony.PreciseDisconnectCause;
79 import android.telephony.Rlog;
80 import android.telephony.SecurityAlgorithmUpdate;
81 import android.telephony.ServiceState;
82 import android.telephony.SignalStrength;
83 import android.telephony.SubscriptionInfo;
84 import android.telephony.SubscriptionManager;
85 import android.telephony.TelephonyCallback;
86 import android.telephony.TelephonyDisplayInfo;
87 import android.telephony.TelephonyManager;
88 import android.telephony.data.ApnSetting;
89 import android.telephony.emergency.EmergencyNumber;
90 import android.telephony.ims.ImsCallSession;
91 import android.telephony.ims.ImsReasonInfo;
92 import android.telephony.ims.MediaQualityStatus;
93 import android.telephony.satellite.NtnSignalStrength;
94 import android.text.TextUtils;
95 import android.util.ArrayMap;
96 import android.util.ArraySet;
97 import android.util.IntArray;
98 import android.util.LocalLog;
99 import android.util.Pair;
100 import android.util.SparseArray;
101 
102 import com.android.internal.annotations.VisibleForTesting;
103 import com.android.internal.app.IBatteryStats;
104 import com.android.internal.telephony.ICarrierConfigChangeListener;
105 import com.android.internal.telephony.ICarrierPrivilegesCallback;
106 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
107 import com.android.internal.telephony.IPhoneStateListener;
108 import com.android.internal.telephony.ISatelliteStateChangeListener;
109 import com.android.internal.telephony.ITelephonyRegistry;
110 import com.android.internal.telephony.TelephonyPermissions;
111 import com.android.internal.telephony.flags.Flags;
112 import com.android.internal.telephony.util.TelephonyUtils;
113 import com.android.internal.util.ArrayUtils;
114 import com.android.internal.util.DumpUtils;
115 import com.android.internal.util.FrameworkStatsLog;
116 import com.android.internal.util.IndentingPrintWriter;
117 import com.android.server.am.BatteryStatsService;
118 
119 import dalvik.annotation.optimization.NeverCompile;
120 
121 import java.io.FileDescriptor;
122 import java.io.PrintWriter;
123 import java.util.ArrayList;
124 import java.util.Arrays;
125 import java.util.Collections;
126 import java.util.HashMap;
127 import java.util.HashSet;
128 import java.util.List;
129 import java.util.Map;
130 import java.util.NoSuchElementException;
131 import java.util.Objects;
132 import java.util.Set;
133 import java.util.concurrent.atomic.AtomicBoolean;
134 import java.util.stream.Collectors;
135 
136 /**
137  * Since phone process can be restarted, this class provides a centralized place
138  * that applications can register and be called back from.
139  *
140  * Change-Id: I450c968bda93767554b5188ee63e10c9f43c5aa4 fixes bugs 16148026
141  * and 15973975 by saving the phoneId of the registrant and then using the
142  * phoneId when deciding to to make a callback. This is necessary because
143  * a subId changes from to a placeholder value when a SIM is removed and thus won't
144  * compare properly. Because getPhoneIdFromSubId(int subId) handles
145  * the placeholder value conversion we properly do the callbacks.
146  *
147  * Eventually we may want to remove the notion of placeholder value but for now this
148  * looks like the best approach.
149  */
150 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
151 public class TelephonyRegistry extends ITelephonyRegistry.Stub {
152     private static final String TAG = "TelephonyRegistry";
153     private static final boolean DBG = false; // STOPSHIP if true
154     private static final boolean DBG_LOC = false; // STOPSHIP if true
155     private static final boolean VDBG = false; // STOPSHIP if true
156 
157     private static class Record {
158         Context context;
159 
160         String callingPackage;
161         String callingFeatureId;
162 
163         IBinder binder;
164 
165         TelephonyRegistryDeathRecipient deathRecipient;
166 
167         IPhoneStateListener callback;
168         IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
169         IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback;
170         ICarrierPrivilegesCallback carrierPrivilegesCallback;
171         ICarrierConfigChangeListener carrierConfigChangeListener;
172         ISatelliteStateChangeListener satelliteStateChangeListener;
173 
174         int callerUid;
175         int callerPid;
176         boolean renounceFineLocationAccess;
177         boolean renounceCoarseLocationAccess;
178 
179         Set<Integer> eventList;
180 
181         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
182 
183         int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
184 
matchTelephonyCallbackEvent(int event)185         boolean matchTelephonyCallbackEvent(int event) {
186             return (callback != null) && (this.eventList.contains(event));
187         }
188 
matchOnSubscriptionsChangedListener()189         boolean matchOnSubscriptionsChangedListener() {
190             return (onSubscriptionsChangedListenerCallback != null);
191         }
192 
matchOnOpportunisticSubscriptionsChangedListener()193         boolean matchOnOpportunisticSubscriptionsChangedListener() {
194             return (onOpportunisticSubscriptionsChangedListenerCallback != null);
195         }
196 
matchCarrierPrivilegesCallback()197         boolean matchCarrierPrivilegesCallback() {
198             return carrierPrivilegesCallback != null;
199         }
200 
matchCarrierConfigChangeListener()201         boolean matchCarrierConfigChangeListener() {
202             return carrierConfigChangeListener != null;
203         }
204 
matchSatelliteStateChangeListener()205         boolean matchSatelliteStateChangeListener() {
206             return satelliteStateChangeListener != null;
207         }
208 
canReadCallLog()209         boolean canReadCallLog() {
210             try {
211                 return TelephonyPermissions.checkReadCallLog(
212                         context, subId, callerPid, callerUid, callingPackage, callingFeatureId);
213             } catch (SecurityException e) {
214                 return false;
215             }
216         }
217 
218         @Override
toString()219         public String toString() {
220             return "{callingPackage=" + pii(callingPackage) + " callerUid=" + callerUid + " binder="
221                     + binder + " callback=" + callback
222                     + " onSubscriptionsChangedListenererCallback="
223                     + onSubscriptionsChangedListenerCallback
224                     + " onOpportunisticSubscriptionsChangedListenererCallback="
225                     + onOpportunisticSubscriptionsChangedListenerCallback
226                     + " carrierPrivilegesCallback=" + carrierPrivilegesCallback
227                     + " carrierConfigChangeListener=" + carrierConfigChangeListener
228                     + " satelliteStateChangeListener=" + satelliteStateChangeListener
229                     + " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}";
230         }
231     }
232 
233     /**
234      * Wrapper class to facilitate testing -- encapsulates bits of configuration that are
235      * normally fetched from static methods with many dependencies.
236      */
237     public static class ConfigurationProvider {
238         /**
239          * @return The per-pid registration limit for PhoneStateListeners, as set from DeviceConfig
240          * @noinspection ConstantConditions
241          */
getRegistrationLimit()242         public int getRegistrationLimit() {
243             return Binder.withCleanCallingIdentity(() ->
244                     DeviceConfig.getInt(DeviceConfig.NAMESPACE_TELEPHONY,
245                             TelephonyCallback.FLAG_PER_PID_REGISTRATION_LIMIT,
246                             TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT));
247         }
248 
249         /**
250          * @param uid uid to check
251          * @return Whether enforcement of the per-pid registation limit for PhoneStateListeners is
252          *         enabled in PlatformCompat for the given uid.
253          * @noinspection ConstantConditions
254          */
isRegistrationLimitEnabledInPlatformCompat(int uid)255         public boolean isRegistrationLimitEnabledInPlatformCompat(int uid) {
256             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
257                     TelephonyCallback.PHONE_STATE_LISTENER_LIMIT_CHANGE_ID, uid));
258         }
259 
260         /**
261          * See {@link TelecomManager#ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION} for more
262          * information.
263          * @noinspection ConstantConditions
264          */
isCallStateReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)265         public boolean isCallStateReadPhoneStateEnforcedInPlatformCompat(String packageName,
266                 UserHandle userHandle) {
267             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
268                     TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION, packageName,
269                     userHandle));
270         }
271 
272         /**
273          * To check the SDK version for
274          * {@link android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener} should add
275          * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12.
276          * @noinspection ConstantConditions
277          */
isActiveDataSubIdReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)278         public boolean isActiveDataSubIdReadPhoneStateEnforcedInPlatformCompat(String packageName,
279                 UserHandle userHandle) {
280             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
281                     REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_ACTIVE_DATA_SUB_ID, packageName,
282                     userHandle));
283         }
284 
285         /**
286          * To check the SDK version for
287          * {@link android.telephony.TelephonyCallback.CellInfoListener} should add
288          * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12.
289          * @noinspection ConstantConditions
290          */
isCellInfoReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)291         public boolean isCellInfoReadPhoneStateEnforcedInPlatformCompat(String packageName,
292                 UserHandle userHandle) {
293             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
294                     REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_CELL_INFO, packageName, userHandle));
295         }
296 
297         /**
298          * To check the SDK version for
299          * {@link android.telephony.TelephonyCallback.DisplayInfoListener} should remove
300          * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12.
301          * @noinspection ConstantConditions
302          */
isDisplayInfoReadPhoneStateEnforcedInPlatformCompat(String packageName, UserHandle userHandle)303         public boolean isDisplayInfoReadPhoneStateEnforcedInPlatformCompat(String packageName,
304                 UserHandle userHandle) {
305             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
306                     REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_DISPLAY_INFO, packageName, userHandle));
307         }
308 
309         /**
310          * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}.
311          *
312          * @noinspection ConstantConditions
313          */
isDisplayInfoNrAdvancedSupported(String packageName, UserHandle userHandle)314         public boolean isDisplayInfoNrAdvancedSupported(String packageName,
315                 UserHandle userHandle) {
316             return Binder.withCleanCallingIdentity(() -> CompatChanges.isChangeEnabled(
317                     DISPLAY_INFO_NR_ADVANCED_SUPPORTED, packageName, userHandle));
318         }
319     }
320 
321     private final Context mContext;
322 
323     private ConfigurationProvider mConfigurationProvider;
324 
325     // access should be inside synchronized (mRecords) for these two fields
326     private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>();
327     private final ArrayList<Record> mRecords = new ArrayList<Record>();
328 
329     private final IBatteryStats mBatteryStats;
330 
331     private final AppOpsManager mAppOps;
332 
333     private boolean mHasNotifySubscriptionInfoChangedOccurred = false;
334 
335     private boolean mHasNotifyOpportunisticSubscriptionInfoChangedOccurred = false;
336 
337     private int mNumPhones;
338 
339     private int[] mCallState;
340 
341     private String[] mCallIncomingNumber;
342 
343     private ServiceState[] mServiceState;
344 
345     private int[] mVoiceActivationState;
346 
347     private int[] mDataActivationState;
348 
349     private boolean[] mUserMobileDataState;
350 
351     private TelephonyDisplayInfo[] mTelephonyDisplayInfos;
352 
353     private SignalStrength[] mSignalStrength;
354 
355     private boolean[] mMessageWaiting;
356 
357     private boolean[] mCallForwarding;
358 
359     private int[] mDataActivity;
360 
361     // Connection state of default APN type data (i.e. internet) of phones
362     private int[] mDataConnectionState;
363 
364     private CellIdentity[] mCellIdentity;
365 
366     private int[] mDataConnectionNetworkType;
367 
368     private ArrayList<List<CellInfo>> mCellInfo;
369 
370     private Map<Integer, List<EmergencyNumber>> mEmergencyNumberList;
371 
372     private EmergencyNumber[] mOutgoingSmsEmergencyNumber;
373 
374     private EmergencyNumber[] mOutgoingCallEmergencyNumber;
375 
376     private CallQuality[] mCallQuality;
377 
378     private List<SparseArray<MediaQualityStatus>> mMediaQualityStatus;
379 
380     private ArrayList<List<CallState>> mCallStateLists;
381 
382     // network type of the call associated with the mCallStateLists and mCallQuality
383     private int[] mCallNetworkType;
384 
385     private int[] mSrvccState;
386 
387     private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
388 
389     private int mDefaultPhoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
390 
391     private int[] mRingingCallState;
392 
393     private int[] mForegroundCallState;
394 
395     private int[] mBackgroundCallState;
396 
397     private PreciseCallState[] mPreciseCallState;
398 
399     private int[] mCallDisconnectCause;
400 
401     private List<ImsReasonInfo> mImsReasonInfo = null;
402 
403     private int[] mCallPreciseDisconnectCause;
404 
405     private List<BarringInfo> mBarringInfo = null;
406 
407     private boolean[] mCarrierNetworkChangeState = null;
408 
409     private PhoneCapability mPhoneCapability = null;
410 
411     private int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
412 
413     @RadioPowerState
414     private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
415 
416     private final LocalLog mLocalLog = new LocalLog(200);
417 
418     private final LocalLog mListenLog = new LocalLog(200);
419 
420     private List<List<PhysicalChannelConfig>> mPhysicalChannelConfigs;
421 
422     private boolean[] mIsDataEnabled;
423 
424     private int[] mDataEnabledReason;
425 
426     private int[] mAllowedNetworkTypeReason;
427     private long[] mAllowedNetworkTypeValue;
428 
429     private static final List<LinkCapacityEstimate> INVALID_LCE_LIST =
430             new ArrayList<LinkCapacityEstimate>(Arrays.asList(new LinkCapacityEstimate(
431             LinkCapacityEstimate.LCE_TYPE_COMBINED,
432             LinkCapacityEstimate.INVALID, LinkCapacityEstimate.INVALID)));
433     private List<List<LinkCapacityEstimate>> mLinkCapacityEstimateLists;
434 
435     private int[] mSimultaneousCellularCallingSubIds = {};
436 
437     private int[] mECBMReason;
438     private long[] mECBMDuration;
439     private int[] mSCBMReason;
440     private long[] mSCBMDuration;
441 
442     private boolean[] mCarrierRoamingNtnMode = null;
443     private boolean[] mCarrierRoamingNtnEligible = null;
444 
445     private List<IntArray> mCarrierRoamingNtnAvailableServices;
446     private NtnSignalStrength[] mCarrierRoamingNtnSignalStrength;
447 
448     // Local cache to check if Satellite Modem is enabled
449     private AtomicBoolean mIsSatelliteEnabled;
450     private AtomicBoolean mWasSatelliteEnabledNotified;
451 
452     private final int mPid = Process.myPid();
453 
454     /**
455      * Per-phone map of precise data connection state. The key of the map is the pair of transport
456      * type and APN setting. This is the cache to prevent redundant callbacks to the listeners.
457      * A precise data connection with state {@link TelephonyManager#DATA_DISCONNECTED} removes
458      * its entry from the map.
459      */
460     private List<Map<Pair<Integer, ApnSetting>, PreciseDataConnectionState>>
461             mPreciseDataConnectionStates;
462 
463     /** Per-phoneId snapshot of privileged packages (names + UIDs). */
464     @NonNull private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates;
465     /** Per-phoneId of CarrierService (PackageName, UID) pair. */
466     @NonNull private List<Pair<String, Integer>> mCarrierServiceStates;
467 
468     /**
469      * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}.
470      */
471     @ChangeId
472     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
473     private static final long DISPLAY_INFO_NR_ADVANCED_SUPPORTED = 181658987L;
474 
475     /**
476      * To check the SDK version for
477      * {@link android.telephony.TelephonyCallback.DisplayInfoListener} should remove
478      * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12.
479      */
480     @ChangeId
481     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
482     private static final long REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_DISPLAY_INFO = 183164979L;
483 
484     /**
485      * To check the SDK version for
486      * {@link android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener} should add
487      * {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12.
488      */
489     @ChangeId
490     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
491     private static final long REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_ACTIVE_DATA_SUB_ID
492             = 182478738L;
493 
494     /**
495      * To check the SDK version for {@link android.telephony.TelephonyCallback.CellInfoListener}
496      * should add {@link android.Manifest.permission#READ_PHONE_STATE} since Android 12.
497      */
498     @ChangeId
499     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
500     private static final long REQUIRE_READ_PHONE_STATE_PERMISSION_FOR_CELL_INFO = 184323934L;
501 
502     private static final Set<Integer> REQUIRE_PRECISE_PHONE_STATE_PERMISSION;
503     static {
504         REQUIRE_PRECISE_PHONE_STATE_PERMISSION = new HashSet<Integer>();
505         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
506                 TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
507         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
508                 TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
509         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
510                 TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED);
511         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
512                 TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
513         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
514                 TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED);
515         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
516                 TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
517         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE);
518         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
519         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
520                 TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
521         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
522                 TelephonyCallback.EVENT_DATA_ENABLED_CHANGED);
523         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
524                 TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED);
525         REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(
526                 TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED);
527     }
528 
isLocationPermissionRequired(Set<Integer> events)529     private boolean isLocationPermissionRequired(Set<Integer> events) {
530         return events.contains(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)
531                 || events.contains(TelephonyCallback.EVENT_CELL_INFO_CHANGED);
532     }
533 
isPhoneStatePermissionRequired(Set<Integer> events, String callingPackage, UserHandle userHandle)534     private boolean isPhoneStatePermissionRequired(Set<Integer> events, String callingPackage,
535             UserHandle userHandle) {
536         if (events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
537                 || events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
538                 || events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) {
539             return true;
540         }
541 
542         // Only check READ_PHONE_STATE for CALL_STATE_CHANGED for Android 12 or above.
543         if ((events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
544                 || events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED))
545                 && mConfigurationProvider.isCallStateReadPhoneStateEnforcedInPlatformCompat(
546                         callingPackage, userHandle)) {
547             return true;
548         }
549 
550         // Only check READ_PHONE_STATE for ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED for Android 12
551         // or above.
552         if (events.contains(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)
553                 && mConfigurationProvider.isActiveDataSubIdReadPhoneStateEnforcedInPlatformCompat(
554                         callingPackage, userHandle)) {
555             return true;
556         }
557 
558         // Only check READ_PHONE_STATE for CELL_INFO_CHANGED for Android 12 or above.
559         if (events.contains(TelephonyCallback.EVENT_CELL_INFO_CHANGED)
560                 && mConfigurationProvider.isCellInfoReadPhoneStateEnforcedInPlatformCompat(
561                         callingPackage, userHandle)) {
562             return true;
563         }
564 
565         // Only check READ_PHONE_STATE for DISPLAY_INFO_CHANGED for Android 11 or older.
566         // READ_PHONE_STATE is not required anymore after Android 12.
567         if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)
568                 && !mConfigurationProvider.isDisplayInfoReadPhoneStateEnforcedInPlatformCompat(
569                         callingPackage, userHandle)) {
570             return true;
571         }
572 
573         return false;
574     }
575 
isPrecisePhoneStatePermissionRequired(Set<Integer> events)576     private boolean isPrecisePhoneStatePermissionRequired(Set<Integer> events) {
577         for (Integer requireEvent : REQUIRE_PRECISE_PHONE_STATE_PERMISSION) {
578             if (events.contains(requireEvent)) {
579                 return true;
580             }
581         }
582         return false;
583     }
584 
isActiveEmergencySessionPermissionRequired(Set<Integer> events)585     private boolean isActiveEmergencySessionPermissionRequired(Set<Integer> events) {
586         return events.contains(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL)
587                 || events.contains(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS);
588     }
589 
isPrivilegedPhoneStatePermissionRequired(Set<Integer> events)590     private boolean isPrivilegedPhoneStatePermissionRequired(Set<Integer> events) {
591         return events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)
592                 || events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
593                 || events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)
594                 || events.contains(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)
595                 || events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)
596                 || events.contains(TelephonyCallback
597                         .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED)
598                 || events.contains(TelephonyCallback.EVENT_CELLULAR_IDENTIFIER_DISCLOSED_CHANGED)
599                 || events.contains(TelephonyCallback.EVENT_SECURITY_ALGORITHMS_CHANGED);
600     }
601 
602     private static final int MSG_USER_SWITCHED = 1;
603     private static final int MSG_UPDATE_DEFAULT_SUB = 2;
604 
605     private final Handler mHandler = new Handler() {
606         @Override
607         public void handleMessage(Message msg) {
608             switch (msg.what) {
609                 case MSG_USER_SWITCHED: {
610                     if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1);
611                     int numPhones = getTelephonyManager().getActiveModemCount();
612                     for (int phoneId = 0; phoneId < numPhones; phoneId++) {
613                         int subId = SubscriptionManager.getSubscriptionId(phoneId);
614                         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
615                             subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
616                         }
617                         TelephonyRegistry.this.notifyCellLocationForSubscriber(
618                                 subId, mCellIdentity[phoneId], true /* hasUserSwitched */);
619                     }
620                     break;
621                 }
622                 case MSG_UPDATE_DEFAULT_SUB: {
623                     int newDefaultPhoneId = msg.arg1;
624                     int newDefaultSubId = msg.arg2;
625                     if (VDBG) {
626                         log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId
627                                 + " current mDefaultPhoneId=" + mDefaultPhoneId
628                                 + " newDefaultSubId=" + newDefaultSubId
629                                 + " newDefaultPhoneId=" + newDefaultPhoneId);
630                     }
631 
632                     //Due to possible race condition,(notify call back using the new
633                     //defaultSubId comes before new defaultSubId update) we need to recall all
634                     //possible missed notify callback
635                     synchronized (mRecords) {
636                         for (Record r : mRecords) {
637                             if(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
638                                 checkPossibleMissNotify(r, newDefaultPhoneId);
639                             }
640                         }
641                         handleRemoveListLocked();
642                     }
643                     mDefaultSubId = newDefaultSubId;
644                     mDefaultPhoneId = newDefaultPhoneId;
645                     mLocalLog.log("Default subscription updated: mDefaultPhoneId="
646                             + mDefaultPhoneId + ", mDefaultSubId=" + mDefaultSubId);
647                 }
648             }
649         }
650     };
651 
652     private class TelephonyRegistryDeathRecipient implements IBinder.DeathRecipient {
653 
654         private final IBinder binder;
655 
TelephonyRegistryDeathRecipient(IBinder binder)656         TelephonyRegistryDeathRecipient(IBinder binder) {
657             this.binder = binder;
658         }
659 
660         @Override
binderDied()661         public void binderDied() {
662             if (DBG) log("binderDied " + binder);
663             remove(binder);
664         }
665     }
666 
667     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
668         @Override
669         public void onReceive(Context context, Intent intent) {
670             String action = intent.getAction();
671             if (VDBG) log("mBroadcastReceiver: action=" + action);
672             if (Intent.ACTION_USER_SWITCHED.equals(action)) {
673                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
674                 if (DBG) log("onReceive: userHandle=" + userHandle);
675                 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0));
676             } else if (action.equals(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) {
677                 int newDefaultSubId = intent.getIntExtra(
678                         SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
679                         SubscriptionManager.getDefaultSubscriptionId());
680                 int newDefaultPhoneId = intent.getIntExtra(
681                         SubscriptionManager.EXTRA_SLOT_INDEX,
682                         getPhoneIdFromSubId(newDefaultSubId));
683                 if (DBG) {
684                     log("onReceive:current mDefaultSubId=" + mDefaultSubId
685                             + " current mDefaultPhoneId=" + mDefaultPhoneId
686                             + " newDefaultSubId=" + newDefaultSubId
687                             + " newDefaultPhoneId=" + newDefaultPhoneId);
688                 }
689 
690                 if (validatePhoneId(newDefaultPhoneId)
691                         && (newDefaultSubId != mDefaultSubId
692                                 || newDefaultPhoneId != mDefaultPhoneId)) {
693                     mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB,
694                             newDefaultPhoneId, newDefaultSubId));
695                 }
696             } else if (action.equals(ACTION_MULTI_SIM_CONFIG_CHANGED)) {
697                 onMultiSimConfigChanged();
698             }
699         }
700     };
701 
getTelephonyManager()702     private TelephonyManager getTelephonyManager() {
703         return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
704     }
705 
onMultiSimConfigChanged()706     private void onMultiSimConfigChanged() {
707         synchronized (mRecords) {
708             int oldNumPhones = mNumPhones;
709             mNumPhones = getTelephonyManager().getActiveModemCount();
710             if (oldNumPhones == mNumPhones) return;
711 
712             if (DBG) {
713                 log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones
714                         + " to " + mNumPhones);
715             }
716             mCallState = copyOf(mCallState, mNumPhones);
717             mDataActivity = copyOf(mCallState, mNumPhones);
718             mDataConnectionState = copyOf(mCallState, mNumPhones);
719             mDataConnectionNetworkType = copyOf(mCallState, mNumPhones);
720             mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones);
721             mServiceState = copyOf(mServiceState, mNumPhones);
722             mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones);
723             mDataActivationState = copyOf(mDataActivationState, mNumPhones);
724             mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones);
725             if (mSignalStrength != null) {
726                 mSignalStrength = copyOf(mSignalStrength, mNumPhones);
727             } else {
728                 mSignalStrength = new SignalStrength[mNumPhones];
729             }
730             mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
731             mCallForwarding = copyOf(mCallForwarding, mNumPhones);
732             mCellIdentity = copyOf(mCellIdentity, mNumPhones);
733             mSrvccState = copyOf(mSrvccState, mNumPhones);
734             mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
735             mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
736             mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones);
737             mRingingCallState = copyOf(mRingingCallState, mNumPhones);
738             mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones);
739             mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
740             mCallQuality = copyOf(mCallQuality, mNumPhones);
741             mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
742             mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
743             mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
744             mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
745             mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones);
746             mIsDataEnabled = copyOf(mIsDataEnabled, mNumPhones);
747             mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
748             mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
749             mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones);
750             mECBMReason = copyOf(mECBMReason, mNumPhones);
751             mECBMDuration = copyOf(mECBMDuration, mNumPhones);
752             mSCBMReason = copyOf(mSCBMReason, mNumPhones);
753             mSCBMDuration = copyOf(mSCBMDuration, mNumPhones);
754             mCarrierRoamingNtnMode = copyOf(mCarrierRoamingNtnMode, mNumPhones);
755             mCarrierRoamingNtnEligible = copyOf(mCarrierRoamingNtnEligible, mNumPhones);
756             if (mCarrierRoamingNtnSignalStrength != null) {
757                 mCarrierRoamingNtnSignalStrength = copyOf(
758                         mCarrierRoamingNtnSignalStrength, mNumPhones);
759             } else {
760                 mCarrierRoamingNtnSignalStrength = new NtnSignalStrength[mNumPhones];
761             }
762             // ds -> ss switch.
763             if (mNumPhones < oldNumPhones) {
764                 cutListToSize(mCellInfo, mNumPhones);
765                 cutListToSize(mImsReasonInfo, mNumPhones);
766                 cutListToSize(mPreciseDataConnectionStates, mNumPhones);
767                 cutListToSize(mBarringInfo, mNumPhones);
768                 cutListToSize(mPhysicalChannelConfigs, mNumPhones);
769                 cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
770                 cutListToSize(mCarrierPrivilegeStates, mNumPhones);
771                 cutListToSize(mCarrierServiceStates, mNumPhones);
772                 cutListToSize(mCallStateLists, mNumPhones);
773                 cutListToSize(mMediaQualityStatus, mNumPhones);
774                 cutListToSize(mCarrierRoamingNtnAvailableServices, mNumPhones);
775                 return;
776             }
777 
778             // mNumPhones > oldNumPhones: ss -> ds switch
779             for (int i = oldNumPhones; i < mNumPhones; i++) {
780                 mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
781                 mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
782                 mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
783                 mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
784                 mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
785                 mCallIncomingNumber[i] = "";
786                 mServiceState[i] = new ServiceState();
787                 mSignalStrength[i] = null;
788                 mUserMobileDataState[i] = false;
789                 mMessageWaiting[i] = false;
790                 mCallForwarding[i] = false;
791                 mCellIdentity[i] = null;
792                 mCellInfo.add(i, Collections.EMPTY_LIST);
793                 mImsReasonInfo.add(i, null);
794                 mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
795                 mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
796                 mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
797                 mCallQuality[i] = createCallQuality();
798                 mMediaQualityStatus.add(i, new SparseArray<>());
799                 mCallStateLists.add(i, new ArrayList<>());
800                 mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
801                 mPreciseCallState[i] = createPreciseCallState();
802                 mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
803                 mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
804                 mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
805                 mPreciseDataConnectionStates.add(new ArrayMap<>());
806                 mBarringInfo.add(i, new BarringInfo());
807                 mCarrierNetworkChangeState[i] = false;
808                 mTelephonyDisplayInfos[i] = null;
809                 mIsDataEnabled[i] = false;
810                 mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
811                 mPhysicalChannelConfigs.add(i, new ArrayList<>());
812                 mAllowedNetworkTypeReason[i] = -1;
813                 mAllowedNetworkTypeValue[i] = -1;
814                 mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
815                 mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
816                 mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID));
817                 mECBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN;
818                 mECBMDuration[i] = 0;
819                 mSCBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN;
820                 mSCBMDuration[i] = 0;
821                 mCarrierRoamingNtnMode[i] = false;
822                 mCarrierRoamingNtnEligible[i] = false;
823                 mCarrierRoamingNtnAvailableServices.add(i, new IntArray());
824                 mCarrierRoamingNtnSignalStrength[i] = new NtnSignalStrength(
825                         NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE);
826             }
827         }
828     }
829 
cutListToSize(List list, int size)830     private void cutListToSize(List list, int size) {
831         if (list == null) return;
832 
833         while (list.size() > size) {
834             list.remove(list.size() - 1);
835         }
836     }
837 
838     // we keep a copy of all of the state so we can send it out when folks
839     // register for it
840     //
841     // In these calls we call with the lock held. This is safe becasuse remote
842     // calls go through a oneway interface and local calls going through a
843     // handler before they get to app code.
844 
845     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
TelephonyRegistry(Context context, ConfigurationProvider configurationProvider)846     public TelephonyRegistry(Context context, ConfigurationProvider configurationProvider) {
847         mContext = context;
848         mConfigurationProvider = configurationProvider;
849         mBatteryStats = BatteryStatsService.getService();
850 
851         int numPhones = getTelephonyManager().getActiveModemCount();
852         if (DBG) log("TelephonyRegistry: ctor numPhones=" + numPhones);
853         mNumPhones = numPhones;
854         mCallState = new int[numPhones];
855         mDataActivity = new int[numPhones];
856         mDataConnectionState = new int[numPhones];
857         mDataConnectionNetworkType = new int[numPhones];
858         mCallIncomingNumber = new String[numPhones];
859         mServiceState = new ServiceState[numPhones];
860         mVoiceActivationState = new int[numPhones];
861         mDataActivationState = new int[numPhones];
862         mUserMobileDataState = new boolean[numPhones];
863         mSignalStrength = new SignalStrength[numPhones];
864         mMessageWaiting = new boolean[numPhones];
865         mCallForwarding = new boolean[numPhones];
866         mCellIdentity = new CellIdentity[numPhones];
867         mSrvccState = new int[numPhones];
868         mPreciseCallState = new PreciseCallState[numPhones];
869         mForegroundCallState = new int[numPhones];
870         mBackgroundCallState = new int[numPhones];
871         mRingingCallState = new int[numPhones];
872         mCallDisconnectCause = new int[numPhones];
873         mCallPreciseDisconnectCause = new int[numPhones];
874         mCallQuality = new CallQuality[numPhones];
875         mMediaQualityStatus = new ArrayList<>();
876         mCallNetworkType = new int[numPhones];
877         mCallStateLists = new ArrayList<>();
878         mPreciseDataConnectionStates = new ArrayList<>();
879         mCellInfo = new ArrayList<>(numPhones);
880         mImsReasonInfo = new ArrayList<>();
881         mEmergencyNumberList = new HashMap<>();
882         mOutgoingCallEmergencyNumber = new EmergencyNumber[numPhones];
883         mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones];
884         mBarringInfo = new ArrayList<>();
885         mCarrierNetworkChangeState = new boolean[numPhones];
886         mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones];
887         mPhysicalChannelConfigs = new ArrayList<>();
888         mAllowedNetworkTypeReason = new int[numPhones];
889         mAllowedNetworkTypeValue = new long[numPhones];
890         mIsDataEnabled = new boolean[numPhones];
891         mDataEnabledReason = new int[numPhones];
892         mLinkCapacityEstimateLists = new ArrayList<>();
893         mCarrierPrivilegeStates = new ArrayList<>();
894         mCarrierServiceStates = new ArrayList<>();
895         mECBMReason = new int[numPhones];
896         mECBMDuration = new long[numPhones];
897         mSCBMReason = new int[numPhones];
898         mSCBMDuration = new long[numPhones];
899         mCarrierRoamingNtnMode = new boolean[numPhones];
900         mCarrierRoamingNtnEligible = new boolean[numPhones];
901         mCarrierRoamingNtnAvailableServices = new ArrayList<>();
902         mCarrierRoamingNtnSignalStrength = new NtnSignalStrength[numPhones];
903         mIsSatelliteEnabled = new AtomicBoolean();
904         mWasSatelliteEnabledNotified = new AtomicBoolean();
905 
906         for (int i = 0; i < numPhones; i++) {
907             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
908             mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
909             mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
910             mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
911             mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
912             mCallIncomingNumber[i] =  "";
913             mServiceState[i] =  new ServiceState();
914             mSignalStrength[i] =  null;
915             mUserMobileDataState[i] = false;
916             mMessageWaiting[i] =  false;
917             mCallForwarding[i] =  false;
918             mCellIdentity[i] = null;
919             mCellInfo.add(i, Collections.EMPTY_LIST);
920             mImsReasonInfo.add(i, new ImsReasonInfo());
921             mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
922             mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
923             mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
924             mCallQuality[i] = createCallQuality();
925             mMediaQualityStatus.add(i, new SparseArray<>());
926             mCallStateLists.add(i, new ArrayList<>());
927             mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
928             mPreciseCallState[i] = createPreciseCallState();
929             mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
930             mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
931             mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
932             mPreciseDataConnectionStates.add(new ArrayMap<>());
933             mBarringInfo.add(i, new BarringInfo());
934             mCarrierNetworkChangeState[i] = false;
935             mTelephonyDisplayInfos[i] = null;
936             mIsDataEnabled[i] = false;
937             mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
938             mPhysicalChannelConfigs.add(i, new ArrayList<>());
939             mAllowedNetworkTypeReason[i] = -1;
940             mAllowedNetworkTypeValue[i] = -1;
941             mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
942             mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
943             mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID));
944             mECBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN;
945             mECBMDuration[i] = 0;
946             mSCBMReason[i] = TelephonyManager.STOP_REASON_UNKNOWN;
947             mSCBMDuration[i] = 0;
948             mCarrierRoamingNtnMode[i] = false;
949             mCarrierRoamingNtnEligible[i] = false;
950             mCarrierRoamingNtnAvailableServices.add(i, new IntArray());
951             mCarrierRoamingNtnSignalStrength[i] = new NtnSignalStrength(
952                     NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE);
953         }
954 
955         mAppOps = mContext.getSystemService(AppOpsManager.class);
956     }
957 
systemRunning()958     public void systemRunning() {
959         // Watch for interesting updates
960         final IntentFilter filter = new IntentFilter();
961         filter.addAction(Intent.ACTION_USER_SWITCHED);
962         filter.addAction(Intent.ACTION_USER_REMOVED);
963         filter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
964         filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED);
965         log("systemRunning register for intents");
966         mContext.registerReceiver(mBroadcastReceiver, filter);
967     }
968 
969     //helper function to determine if limit on num listeners applies to callingUid
doesLimitApplyForListeners(int callingUid, int exemptUid)970     private boolean doesLimitApplyForListeners(int callingUid, int exemptUid) {
971         return (!TelephonyPermissions.isSystemOrPhone(callingUid)
972                 && callingUid != exemptUid);
973     }
974 
975     @Override
addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId, IOnSubscriptionsChangedListener callback)976     public void addOnSubscriptionsChangedListener(String callingPackage, String callingFeatureId,
977             IOnSubscriptionsChangedListener callback) {
978         int callerUserId = UserHandle.getCallingUserId();
979         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
980         if (VDBG) {
981             log("listen oscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
982                     + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
983                     + " callback=" + callback + " callback.asBinder=" + callback.asBinder());
984         }
985 
986         synchronized (mRecords) {
987             // register
988             IBinder b = callback.asBinder();
989             boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
990                     Process.myUid());
991             Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); //
992 
993             if (r == null) {
994                 return;
995             }
996 
997             r.context = mContext;
998             r.onSubscriptionsChangedListenerCallback = callback;
999             r.callingPackage = callingPackage;
1000             r.callingFeatureId = callingFeatureId;
1001             r.callerUid = Binder.getCallingUid();
1002             r.callerPid = Binder.getCallingPid();
1003             r.eventList = new ArraySet<>();
1004             if (DBG) {
1005                 log("listen oscl:  Register r=" + r);
1006             }
1007             // Always notify when registration occurs if there has been a notification.
1008             if (mHasNotifySubscriptionInfoChangedOccurred) {
1009                 try {
1010                     if (VDBG) log("listen oscl: send to r=" + r);
1011                     r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
1012                     if (VDBG) log("listen oscl: sent to r=" + r);
1013                 } catch (RemoteException e) {
1014                     if (VDBG) log("listen oscl: remote exception sending to r=" + r + " e=" + e);
1015                     remove(r.binder);
1016                 }
1017             } else {
1018                 log("listen oscl: mHasNotifySubscriptionInfoChangedOccurred==false no callback");
1019             }
1020         }
1021     }
1022 
1023     @Override
removeOnSubscriptionsChangedListener(String pkgForDebug, IOnSubscriptionsChangedListener callback)1024     public void removeOnSubscriptionsChangedListener(String pkgForDebug,
1025             IOnSubscriptionsChangedListener callback) {
1026         if (DBG) log("listen oscl: Unregister");
1027         remove(callback.asBinder());
1028     }
1029 
1030 
1031     @Override
addOnOpportunisticSubscriptionsChangedListener(String callingPackage, String callingFeatureId, IOnSubscriptionsChangedListener callback)1032     public void addOnOpportunisticSubscriptionsChangedListener(String callingPackage,
1033             String callingFeatureId, IOnSubscriptionsChangedListener callback) {
1034         int callerUserId = UserHandle.getCallingUserId();
1035         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
1036         if (VDBG) {
1037             log("listen ooscl: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
1038                     + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
1039                     + " callback=" + callback + " callback.asBinder=" + callback.asBinder());
1040         }
1041 
1042         synchronized (mRecords) {
1043             // register
1044             IBinder b = callback.asBinder();
1045             boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
1046                     Process.myUid());
1047             Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); //
1048 
1049             if (r == null) {
1050                 return;
1051             }
1052 
1053             r.context = mContext;
1054             r.onOpportunisticSubscriptionsChangedListenerCallback = callback;
1055             r.callingPackage = callingPackage;
1056             r.callingFeatureId = callingFeatureId;
1057             r.callerUid = Binder.getCallingUid();
1058             r.callerPid = Binder.getCallingPid();
1059             r.eventList = new ArraySet<>();
1060             if (DBG) {
1061                 log("listen ooscl:  Register r=" + r);
1062             }
1063             // Always notify when registration occurs if there has been a notification.
1064             if (mHasNotifyOpportunisticSubscriptionInfoChangedOccurred) {
1065                 try {
1066                     if (VDBG) log("listen ooscl: send to r=" + r);
1067                     r.onOpportunisticSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
1068                     if (VDBG) log("listen ooscl: sent to r=" + r);
1069                 } catch (RemoteException e) {
1070                     if (VDBG) log("listen ooscl: remote exception sending to r=" + r + " e=" + e);
1071                     remove(r.binder);
1072                 }
1073             } else {
1074                 log("listen ooscl: hasNotifyOpptSubInfoChangedOccurred==false no callback");
1075             }
1076         }
1077     }
1078 
1079     @Override
notifySubscriptionInfoChanged()1080     public void notifySubscriptionInfoChanged() {
1081         if (VDBG) log("notifySubscriptionInfoChanged:");
1082         if (!checkNotifyPermission("notifySubscriptionInfoChanged()")) {
1083             return;
1084         }
1085 
1086         synchronized (mRecords) {
1087             if (!mHasNotifySubscriptionInfoChangedOccurred) {
1088                 log("notifySubscriptionInfoChanged: first invocation mRecords.size="
1089                         + mRecords.size());
1090             }
1091             mHasNotifySubscriptionInfoChangedOccurred = true;
1092             mRemoveList.clear();
1093             for (Record r : mRecords) {
1094                 if (r.matchOnSubscriptionsChangedListener()) {
1095                     try {
1096                         if (VDBG) log("notifySubscriptionInfoChanged: call osc to r=" + r);
1097                         r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged();
1098                         if (VDBG) log("notifySubscriptionInfoChanged: done osc to r=" + r);
1099                     } catch (RemoteException ex) {
1100                         if (VDBG) log("notifySubscriptionInfoChanged: RemoteException r=" + r);
1101                         mRemoveList.add(r.binder);
1102                     }
1103                 }
1104             }
1105             handleRemoveListLocked();
1106         }
1107     }
1108 
1109     @Override
notifyOpportunisticSubscriptionInfoChanged()1110     public void notifyOpportunisticSubscriptionInfoChanged() {
1111         if (VDBG) log("notifyOpptSubscriptionInfoChanged:");
1112         if (!checkNotifyPermission("notifyOpportunisticSubscriptionInfoChanged()")) {
1113             return;
1114         }
1115 
1116         synchronized (mRecords) {
1117             if (!mHasNotifyOpportunisticSubscriptionInfoChangedOccurred) {
1118                 log("notifyOpptSubscriptionInfoChanged: first invocation mRecords.size="
1119                         + mRecords.size());
1120             }
1121             mHasNotifyOpportunisticSubscriptionInfoChangedOccurred = true;
1122             mRemoveList.clear();
1123             for (Record r : mRecords) {
1124                 if (r.matchOnOpportunisticSubscriptionsChangedListener()) {
1125                     try {
1126                         if (VDBG) log("notifyOpptSubChanged: call oosc to r=" + r);
1127                         r.onOpportunisticSubscriptionsChangedListenerCallback
1128                                 .onSubscriptionsChanged();
1129                         if (VDBG) log("notifyOpptSubChanged: done oosc to r=" + r);
1130                     } catch (RemoteException ex) {
1131                         if (VDBG) log("notifyOpptSubChanged: RemoteException r=" + r);
1132                         mRemoveList.add(r.binder);
1133                     }
1134                 }
1135             }
1136             handleRemoveListLocked();
1137         }
1138     }
1139 
1140     @Override
listenWithEventList(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, int subId, String callingPackage, String callingFeatureId, IPhoneStateListener callback, int[] events, boolean notifyNow)1141     public void listenWithEventList(boolean renounceFineLocationAccess,
1142             boolean renounceCoarseLocationAccess, int subId, String callingPackage,
1143             String callingFeatureId, IPhoneStateListener callback,
1144             int[] events, boolean notifyNow) {
1145         Set<Integer> eventList = Arrays.stream(events).boxed().collect(Collectors.toSet());
1146         listen(renounceFineLocationAccess, renounceCoarseLocationAccess, callingPackage,
1147                 callingFeatureId, callback, eventList, notifyNow, subId);
1148     }
1149 
listen(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, String callingPackage, @Nullable String callingFeatureId, IPhoneStateListener callback, Set<Integer> events, boolean notifyNow, int subId)1150     private void listen(boolean renounceFineLocationAccess,
1151             boolean renounceCoarseLocationAccess, String callingPackage,
1152             @Nullable String callingFeatureId, IPhoneStateListener callback,
1153             Set<Integer> events, boolean notifyNow, int subId) {
1154         int callerUserId = UserHandle.getCallingUserId();
1155         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
1156         String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid()
1157                 + " events=" + events + " notifyNow=" + notifyNow
1158                 + " subId=" + subId + " myUserId=" + UserHandle.myUserId()
1159                 + " callerUserId=" + callerUserId;
1160         mListenLog.log(str);
1161         if (VDBG) {
1162             log(str);
1163         }
1164 
1165         if (events.isEmpty()) {
1166             if (DBG) {
1167                 log("listen: Unregister");
1168             }
1169             events.clear();
1170             remove(callback.asBinder());
1171             return;
1172         }
1173 
1174         // Checks permission and throws SecurityException for disallowed operations. For pre-M
1175         // apps whose runtime permission has been revoked, we return immediately to skip sending
1176         // events to the app without crashing it.
1177         if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId, "listen")) {
1178             return;
1179         }
1180 
1181         int subscriptionId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
1182         // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
1183         // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
1184         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1185             if (DBG) {
1186                 log("invalid subscription id, use default id");
1187             }
1188         } else { //APP specify subID
1189             subscriptionId = subId;
1190         }
1191         int phoneId = getPhoneIdFromSubId(subscriptionId);
1192 
1193         synchronized (mRecords) {
1194             // register
1195             IBinder b = callback.asBinder();
1196             boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
1197                     Process.myUid());
1198             Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);
1199 
1200             if (r == null) {
1201                 return;
1202             }
1203 
1204             r.context = mContext;
1205             r.callback = callback;
1206             r.callingPackage = callingPackage;
1207             r.callingFeatureId = callingFeatureId;
1208             r.renounceCoarseLocationAccess = renounceCoarseLocationAccess;
1209             r.renounceFineLocationAccess = renounceFineLocationAccess;
1210             r.callerUid = Binder.getCallingUid();
1211             r.callerPid = Binder.getCallingPid();
1212             r.subId = subscriptionId;
1213             r.phoneId = phoneId;
1214             r.eventList = events;
1215 
1216             if (DBG) {
1217                 log("listen:  Register r=" + r + " r.subId=" + r.subId + " r.phoneId=" + r.phoneId);
1218             }
1219             if (notifyNow && validatePhoneId(r.phoneId)) {
1220                 if (events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)){
1221                     try {
1222                         if (VDBG) log("listen: call onSSC state=" + mServiceState[r.phoneId]);
1223                         ServiceState rawSs = new ServiceState(mServiceState[r.phoneId]);
1224                         if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
1225                             r.callback.onServiceStateChanged(rawSs);
1226                         } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
1227                             r.callback.onServiceStateChanged(
1228                                     rawSs.createLocationInfoSanitizedCopy(false));
1229                         } else {
1230                             r.callback.onServiceStateChanged(
1231                                     rawSs.createLocationInfoSanitizedCopy(true));
1232                         }
1233                     } catch (RemoteException ex) {
1234                         remove(r.binder);
1235                     }
1236                 }
1237                 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) {
1238                     try {
1239                         if (mSignalStrength[r.phoneId] != null) {
1240                             int gsmSignalStrength = mSignalStrength[r.phoneId]
1241                                     .getGsmSignalStrength();
1242                             r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
1243                                     : gsmSignalStrength));
1244                         }
1245                     } catch (RemoteException ex) {
1246                         remove(r.binder);
1247                     }
1248                 }
1249                 if (events.contains(
1250                         TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
1251                     try {
1252                         r.callback.onMessageWaitingIndicatorChanged(
1253                                 mMessageWaiting[r.phoneId]);
1254                     } catch (RemoteException ex) {
1255                         remove(r.binder);
1256                     }
1257                 }
1258                 if (events.contains(
1259                         TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
1260                     try {
1261                         r.callback.onCallForwardingIndicatorChanged(
1262                                 mCallForwarding[r.phoneId]);
1263                     } catch (RemoteException ex) {
1264                         remove(r.binder);
1265                     }
1266                 }
1267                 if (validateEventAndUserLocked(
1268                         r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) {
1269                     try {
1270                         if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[r.phoneId]);
1271                         if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
1272                                 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
1273                             // null will be translated to empty CellLocation object in client.
1274                             r.callback.onCellLocationChanged(mCellIdentity[r.phoneId]);
1275                         }
1276                     } catch (RemoteException ex) {
1277                         remove(r.binder);
1278                     }
1279                 }
1280                 if (events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)) {
1281                     try {
1282                         r.callback.onLegacyCallStateChanged(mCallState[r.phoneId],
1283                                 getCallIncomingNumber(r, r.phoneId));
1284                     } catch (RemoteException ex) {
1285                         remove(r.binder);
1286                     }
1287                 }
1288                 if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
1289                     try {
1290                         r.callback.onCallStateChanged(mCallState[r.phoneId]);
1291                     } catch (RemoteException ex) {
1292                         remove(r.binder);
1293                     }
1294                 }
1295                 if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
1296                     try {
1297                         r.callback.onDataConnectionStateChanged(mDataConnectionState[r.phoneId],
1298                                 mDataConnectionNetworkType[r.phoneId]);
1299                     } catch (RemoteException ex) {
1300                         remove(r.binder);
1301                     }
1302                 }
1303                 if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)) {
1304                     try {
1305                         r.callback.onDataActivity(mDataActivity[r.phoneId]);
1306                     } catch (RemoteException ex) {
1307                         remove(r.binder);
1308                     }
1309                 }
1310                 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)) {
1311                     try {
1312                         if (mSignalStrength[r.phoneId] != null) {
1313                             r.callback.onSignalStrengthsChanged(mSignalStrength[r.phoneId]);
1314                         }
1315                     } catch (RemoteException ex) {
1316                         remove(r.binder);
1317                     }
1318                 }
1319                 if (validateEventAndUserLocked(
1320                         r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) {
1321                     try {
1322                         if (DBG_LOC) {
1323                             log("listen: mCellInfo[" + r.phoneId + "] = "
1324                                     + mCellInfo.get(r.phoneId));
1325                         }
1326                         if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
1327                                 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
1328                             r.callback.onCellInfoChanged(mCellInfo.get(r.phoneId));
1329                         }
1330                     } catch (RemoteException ex) {
1331                         remove(r.binder);
1332                     }
1333                 }
1334                 if (events.contains(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)) {
1335                     try {
1336                         r.callback.onPreciseCallStateChanged(mPreciseCallState[r.phoneId]);
1337                     } catch (RemoteException ex) {
1338                         remove(r.binder);
1339                     }
1340                 }
1341                 if (events.contains(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) {
1342                     try {
1343                         r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[r.phoneId],
1344                                 mCallPreciseDisconnectCause[r.phoneId]);
1345                     } catch (RemoteException ex) {
1346                         remove(r.binder);
1347                     }
1348                 }
1349                 if (events.contains(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) {
1350                     ImsReasonInfo imsReasonInfo = mImsReasonInfo.get(r.phoneId);
1351                     if (imsReasonInfo != null) {
1352                         try {
1353                             r.callback.onImsCallDisconnectCauseChanged(imsReasonInfo);
1354                         } catch (RemoteException ex) {
1355                             remove(r.binder);
1356                         }
1357                     }
1358                 }
1359                 if (events.contains(
1360                         TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) {
1361                     try {
1362                         for (PreciseDataConnectionState pdcs
1363                                 : mPreciseDataConnectionStates.get(r.phoneId).values()) {
1364                             r.callback.onPreciseDataConnectionStateChanged(pdcs);
1365                         }
1366                     } catch (RemoteException ex) {
1367                         remove(r.binder);
1368                     }
1369                 }
1370                 if (events.contains(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)) {
1371                     try {
1372                         r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState[r.phoneId]);
1373                     } catch (RemoteException ex) {
1374                         remove(r.binder);
1375                     }
1376                 }
1377                 if (events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) {
1378                     try {
1379                         r.callback.onVoiceActivationStateChanged(
1380                                 mVoiceActivationState[r.phoneId]);
1381                     } catch (RemoteException ex) {
1382                         remove(r.binder);
1383                     }
1384                 }
1385                 if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)) {
1386                     try {
1387                         r.callback.onDataActivationStateChanged(mDataActivationState[r.phoneId]);
1388                     } catch (RemoteException ex) {
1389                         remove(r.binder);
1390                     }
1391                 }
1392                 if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
1393                     try {
1394                         r.callback.onUserMobileDataStateChanged(mUserMobileDataState[r.phoneId]);
1395                     } catch (RemoteException ex) {
1396                         remove(r.binder);
1397                     }
1398                 }
1399                 if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) {
1400                     try {
1401                         if (mTelephonyDisplayInfos[r.phoneId] != null) {
1402                             r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[r.phoneId]);
1403                         }
1404                     } catch (RemoteException ex) {
1405                         remove(r.binder);
1406                     }
1407                 }
1408                 if (events.contains(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) {
1409                     try {
1410                         r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
1411                     } catch (RemoteException ex) {
1412                         remove(r.binder);
1413                     }
1414                 }
1415                 if (events.contains(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED)) {
1416                     try {
1417                         r.callback.onPhoneCapabilityChanged(mPhoneCapability);
1418                     } catch (RemoteException ex) {
1419                         remove(r.binder);
1420                     }
1421                 }
1422                 if (events.contains(
1423                         TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
1424                     try {
1425                         r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
1426                     } catch (RemoteException ex) {
1427                         remove(r.binder);
1428                     }
1429                 }
1430                 if (events.contains(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)) {
1431                     try {
1432                         r.callback.onRadioPowerStateChanged(mRadioPowerState);
1433                     } catch (RemoteException ex) {
1434                         remove(r.binder);
1435                     }
1436                 }
1437                 if (events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)) {
1438                     try {
1439                         r.callback.onSrvccStateChanged(mSrvccState[r.phoneId]);
1440                     } catch (RemoteException ex) {
1441                         remove(r.binder);
1442                     }
1443                 }
1444                 if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) {
1445                     try {
1446                         if (Flags.passCopiedCallStateList()) {
1447                             List<CallState> callList;
1448                             if (r.callerPid == mPid) {
1449                                 callList = List.copyOf(mCallStateLists.get(r.phoneId));
1450                             } else {
1451                                 callList = mCallStateLists.get(r.phoneId);
1452                             }
1453                             r.callback.onCallStatesChanged(callList);
1454                         } else {
1455                             r.callback.onCallStatesChanged(mCallStateLists.get(r.phoneId));
1456                         }
1457                     } catch (RemoteException ex) {
1458                         remove(r.binder);
1459                     }
1460                 }
1461                 if (events.contains(TelephonyCallback.EVENT_BARRING_INFO_CHANGED)) {
1462                     BarringInfo barringInfo = mBarringInfo.get(r.phoneId);
1463                     if (VDBG) {
1464                         log("listen: call onBarringInfoChanged=" + barringInfo);
1465                     }
1466                     if (barringInfo != null) {
1467                         BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy();
1468 
1469                         try {
1470                             r.callback.onBarringInfoChanged(
1471                                     checkFineLocationAccess(r, Build.VERSION_CODES.BASE)
1472                                             ? barringInfo : biNoLocation);
1473                         } catch (RemoteException ex) {
1474                             remove(r.binder);
1475                         }
1476                     }
1477                 }
1478                 if (events.contains(
1479                         TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) {
1480                     try {
1481                         r.callback.onPhysicalChannelConfigChanged(
1482                                 shouldSanitizeLocationForPhysicalChannelConfig(r)
1483                                         ? getLocationSanitizedConfigs(
1484                                                 mPhysicalChannelConfigs.get(r.phoneId))
1485                                         : mPhysicalChannelConfigs.get(r.phoneId));
1486                     } catch (RemoteException ex) {
1487                         remove(r.binder);
1488                     }
1489                 }
1490                 if (events.contains(
1491                         TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)) {
1492                     try {
1493                         r.callback.onDataEnabledChanged(
1494                                 mIsDataEnabled[r.phoneId], mDataEnabledReason[r.phoneId]);
1495                     } catch (RemoteException ex) {
1496                         remove(r.binder);
1497                     }
1498                 }
1499                 if (events.contains(TelephonyCallback
1500                         .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED)) {
1501                     try {
1502                         r.callback.onSimultaneousCallingStateChanged(
1503                                 mSimultaneousCellularCallingSubIds);
1504                     } catch (RemoteException ex) {
1505                         remove(r.binder);
1506                     }
1507                 }
1508                 if (events.contains(
1509                         TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)) {
1510                     try {
1511                         if (mLinkCapacityEstimateLists.get(r.phoneId) != null) {
1512                             r.callback.onLinkCapacityEstimateChanged(mLinkCapacityEstimateLists
1513                                     .get(r.phoneId));
1514                         }
1515                     } catch (RemoteException ex) {
1516                         remove(r.binder);
1517                     }
1518                 }
1519                 if (events.contains(TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED)) {
1520                     CallState callState = null;
1521                     for (CallState cs : mCallStateLists.get(r.phoneId)) {
1522                         if (cs.getCallState() == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
1523                             callState = cs;
1524                             break;
1525                         }
1526                     }
1527                     if (callState != null) {
1528                         String callId = callState.getImsCallSessionId();
1529                         try {
1530                             MediaQualityStatus status = mMediaQualityStatus.get(r.phoneId).get(
1531                                     MediaQualityStatus.MEDIA_SESSION_TYPE_AUDIO);
1532                             if (status != null && status.getCallSessionId().equals(callId)) {
1533                                 r.callback.onMediaQualityStatusChanged(status);
1534                             }
1535                             status = mMediaQualityStatus.get(r.phoneId).get(
1536                                     MediaQualityStatus.MEDIA_SESSION_TYPE_VIDEO);
1537                             if (status != null && status.getCallSessionId().equals(callId)) {
1538                                 r.callback.onMediaQualityStatusChanged(status);
1539                             }
1540                         } catch (RemoteException ex) {
1541                             remove(r.binder);
1542                         }
1543                     }
1544                 }
1545                 if (events.contains(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) {
1546                     try {
1547                         if (mECBMDuration[r.phoneId] != 0) {
1548                             r.callback.onCallbackModeStarted(
1549                                     TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL,
1550                                     mECBMDuration[r.phoneId], r.subId);
1551                         } else {
1552                             r.callback.onCallbackModeStopped(
1553                                     TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL,
1554                                     mECBMReason[r.phoneId], r.subId);
1555                         }
1556 
1557                         if (mSCBMReason[r.phoneId] != 0) {
1558                             r.callback.onCallbackModeStarted(
1559                                     TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS,
1560                                     mSCBMDuration[r.phoneId], r.subId);
1561                         } else {
1562                             r.callback.onCallbackModeStopped(
1563                                     TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS,
1564                                     mSCBMReason[r.phoneId], r.subId);
1565                         }
1566                     } catch (RemoteException ex) {
1567                         remove(r.binder);
1568                     }
1569                 }
1570                 if (events.contains(TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_MODE_CHANGED)) {
1571                     try {
1572                         r.callback.onCarrierRoamingNtnModeChanged(
1573                                 mCarrierRoamingNtnMode[r.phoneId]);
1574                     } catch (RemoteException ex) {
1575                         remove(r.binder);
1576                     }
1577                 }
1578                 if (events.contains(
1579                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_ELIGIBLE_STATE_CHANGED)) {
1580                     try {
1581                         r.callback.onCarrierRoamingNtnEligibleStateChanged(
1582                                 mCarrierRoamingNtnEligible[r.phoneId]);
1583                     } catch (RemoteException ex) {
1584                         remove(r.binder);
1585                     }
1586                 }
1587                 if (events.contains(
1588                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_AVAILABLE_SERVICES_CHANGED)) {
1589                     try {
1590                         r.callback.onCarrierRoamingNtnAvailableServicesChanged(
1591                                 mCarrierRoamingNtnAvailableServices.get(r.phoneId).toArray());
1592                     } catch (RemoteException ex) {
1593                         remove(r.binder);
1594                     }
1595                 }
1596                 if (events.contains(
1597                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_SIGNAL_STRENGTH_CHANGED)) {
1598                     try {
1599                         r.callback.onCarrierRoamingNtnSignalStrengthChanged(
1600                                 mCarrierRoamingNtnSignalStrength[r.phoneId]);
1601                     } catch (RemoteException ex) {
1602                         remove(r.binder);
1603                     }
1604                 }
1605             }
1606         }
1607     }
1608 
getCallIncomingNumber(Record record, int phoneId)1609     private String getCallIncomingNumber(Record record, int phoneId) {
1610         // Only reveal the incoming number if the record has read call log permission.
1611         return record.canReadCallLog() ? mCallIncomingNumber[phoneId] : "";
1612     }
1613 
add(IBinder binder, int callingUid, int callingPid, boolean doesLimitApply)1614     private Record add(IBinder binder, int callingUid, int callingPid, boolean doesLimitApply) {
1615         Record r;
1616 
1617         synchronized (mRecords) {
1618             final int N = mRecords.size();
1619             // While iterating through the records, keep track of how many we have from this pid.
1620             int numRecordsForPid = 0;
1621             for (int i = 0; i < N; i++) {
1622                 r = mRecords.get(i);
1623                 if (binder == r.binder) {
1624                     // Already existed.
1625                     return r;
1626                 }
1627                 if (r.callerPid == callingPid) {
1628                     numRecordsForPid++;
1629                 }
1630             }
1631             // If we've exceeded the limit for registrations, log an error and quit.
1632             int registrationLimit = mConfigurationProvider.getRegistrationLimit();
1633 
1634             if (doesLimitApply
1635                     && registrationLimit >= 1
1636                     && numRecordsForPid >= registrationLimit) {
1637                 String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible"
1638                         + " registered listeners. Ignoring request to add.";
1639                 loge(errorMsg);
1640                 if (mConfigurationProvider
1641                         .isRegistrationLimitEnabledInPlatformCompat(callingUid)) {
1642                     throw new IllegalStateException(errorMsg);
1643                 }
1644             } else if (numRecordsForPid
1645                     >= TelephonyCallback.DEFAULT_PER_PID_REGISTRATION_LIMIT / 2) {
1646                 // Log the warning independently of the dynamically set limit -- apps shouldn't be
1647                 // doing this regardless of whether we're throwing them an exception for it.
1648                 Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible"
1649                         + " registered listeners. Now at " + numRecordsForPid);
1650             }
1651 
1652             r = new Record();
1653             r.binder = binder;
1654             r.deathRecipient = new TelephonyRegistryDeathRecipient(binder);
1655 
1656             try {
1657                 binder.linkToDeath(r.deathRecipient, 0);
1658             } catch (RemoteException e) {
1659                 if (VDBG) log("LinkToDeath remote exception sending to r=" + r + " e=" + e);
1660                 // Binder already died. Return null.
1661                 return null;
1662             }
1663 
1664             mRecords.add(r);
1665             if (DBG) log("add new record");
1666         }
1667 
1668         return r;
1669     }
1670 
remove(IBinder binder)1671     private void remove(IBinder binder) {
1672         synchronized (mRecords) {
1673             final int recordCount = mRecords.size();
1674             for (int i = 0; i < recordCount; i++) {
1675                 Record r = mRecords.get(i);
1676                 if (r.binder == binder) {
1677                     if (DBG) {
1678                         log("remove: binder=" + binder + " r.callingPackage " + r.callingPackage
1679                                 + " r.callback " + r.callback);
1680                     }
1681 
1682                     if (r.deathRecipient != null) {
1683                         try {
1684                             binder.unlinkToDeath(r.deathRecipient, 0);
1685                         } catch (NoSuchElementException e) {
1686                             if (VDBG) log("UnlinkToDeath NoSuchElementException sending to r="
1687                                     + r + " e=" + e);
1688                         }
1689                     }
1690 
1691                     mRecords.remove(i);
1692                     return;
1693                 }
1694             }
1695         }
1696     }
1697 
notifyCallStateForAllSubs(int state, String phoneNumber)1698     public void notifyCallStateForAllSubs(int state, String phoneNumber) {
1699         if (!checkNotifyPermission("notifyCallState()")) {
1700             return;
1701         }
1702 
1703         if (VDBG) {
1704             log("notifyCallStateForAllSubs: state=" + state + " phoneNumber=" + phoneNumber);
1705         }
1706 
1707         synchronized (mRecords) {
1708             for (Record r : mRecords) {
1709                 if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
1710                         && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
1711                     try {
1712                         // Ensure the listener has read call log permission; if they do not return
1713                         // an empty phone number.
1714                         // This is ONLY for legacy onCallStateChanged in PhoneStateListener.
1715                         String phoneNumberOrEmpty = r.canReadCallLog() ? phoneNumber : "";
1716                         r.callback.onLegacyCallStateChanged(state, phoneNumberOrEmpty);
1717                     } catch (RemoteException ex) {
1718                         mRemoveList.add(r.binder);
1719                     }
1720                 }
1721 
1722                 if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
1723                         && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
1724                     try {
1725                         // The new callback does NOT provide the phone number.
1726                         r.callback.onCallStateChanged(state);
1727                     } catch (RemoteException ex) {
1728                         mRemoveList.add(r.binder);
1729                     }
1730                 }
1731             }
1732             handleRemoveListLocked();
1733         }
1734 
1735         // Called only by Telecomm to communicate call state across different phone accounts. So
1736         // there is no need to add a valid subId or slotId.
1737         broadcastCallStateChanged(state, phoneNumber,
1738                 SubscriptionManager.INVALID_SIM_SLOT_INDEX,
1739                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1740     }
1741 
notifyCallState(int phoneId, int subId, int state, String incomingNumber)1742     public void notifyCallState(int phoneId, int subId, int state, String incomingNumber) {
1743         if (!checkNotifyPermission("notifyCallState()")) {
1744             return;
1745         }
1746         if (VDBG) {
1747             log("notifyCallState: subId=" + subId
1748                 + " state=" + state + " incomingNumber=" + incomingNumber);
1749         }
1750         synchronized (mRecords) {
1751             if (validatePhoneId(phoneId)) {
1752                 mCallState[phoneId] = state;
1753                 mCallIncomingNumber[phoneId] = incomingNumber;
1754                 for (Record r : mRecords) {
1755                     if (r.matchTelephonyCallbackEvent(
1756                             TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)
1757                             && (r.subId == subId)
1758                             && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
1759                         try {
1760                             // Only the legacy PhoneStateListener receives the phone number.
1761                             String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);
1762                             r.callback.onLegacyCallStateChanged(state, incomingNumberOrEmpty);
1763                         } catch (RemoteException ex) {
1764                             mRemoveList.add(r.binder);
1765                         }
1766                     }
1767                     if (r.matchTelephonyCallbackEvent(TelephonyCallback.EVENT_CALL_STATE_CHANGED)
1768                             && (r.subId == subId)
1769                             && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
1770                         try {
1771                             // The phone number is not included in the new call state changed
1772                             // listener.
1773                             r.callback.onCallStateChanged(state);
1774                         } catch (RemoteException ex) {
1775                             mRemoveList.add(r.binder);
1776                         }
1777                     }
1778                 }
1779             }
1780             handleRemoveListLocked();
1781         }
1782         broadcastCallStateChanged(state, incomingNumber, phoneId, subId);
1783     }
1784 
notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state)1785     public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) {
1786         if (!checkNotifyPermission("notifyServiceState()")){
1787             return;
1788         }
1789 
1790         final long callingIdentity = Binder.clearCallingIdentity();
1791         try {
1792             synchronized (mRecords) {
1793                 String str = "notifyServiceStateForSubscriber: subId=" + subId + " phoneId="
1794                         + phoneId + " state=" + state;
1795                 if (VDBG) {
1796                     log(str);
1797                 }
1798                 mLocalLog.log(str);
1799                 // for service state updates, don't notify clients when subId is invalid. This
1800                 // prevents us from sending incorrect notifications like b/133140128
1801                 // In the future, we can remove this logic for every notification here and add a
1802                 // callback so listeners know when their PhoneStateListener's subId becomes invalid,
1803                 // but for now we use the simplest fix.
1804                 if (validatePhoneId(phoneId)) {
1805                     mServiceState[phoneId] = state;
1806 
1807                     if (SubscriptionManager.isValidSubscriptionId(subId)) {
1808 
1809                         for (Record r : mRecords) {
1810                             if (VDBG) {
1811                                 log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
1812                                         + " phoneId=" + phoneId + " state=" + state);
1813                             }
1814                             if (r.matchTelephonyCallbackEvent(
1815                                     TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)
1816                                     && idMatch(r, subId, phoneId)) {
1817 
1818                                 try {
1819                                     ServiceState stateToSend;
1820                                     if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
1821                                         stateToSend = new ServiceState(state);
1822                                     } else if(checkCoarseLocationAccess(
1823                                             r, Build.VERSION_CODES.Q)) {
1824                                         stateToSend = state.createLocationInfoSanitizedCopy(false);
1825                                     } else {
1826                                         stateToSend = state.createLocationInfoSanitizedCopy(true);
1827                                     }
1828                                     if (DBG) {
1829                                         log("notifyServiceStateForSubscriber: callback.onSSC r=" + r
1830                                                 + " subId=" + subId + " phoneId=" + phoneId
1831                                                 + " state=" + stateToSend);
1832                                     }
1833                                     r.callback.onServiceStateChanged(stateToSend);
1834                                 } catch (RemoteException ex) {
1835                                     mRemoveList.add(r.binder);
1836                                 }
1837                             }
1838                         }
1839                     }
1840                     else {
1841                         log("notifyServiceStateForSubscriber: INVALID subId=" +subId);
1842                     }
1843                 } else {
1844                     log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
1845                 }
1846                 handleRemoveListLocked();
1847             }
1848             broadcastServiceStateChanged(state, phoneId, subId);
1849         } finally {
1850             Binder.restoreCallingIdentity(callingIdentity);
1851         }
1852     }
1853 
notifySimActivationStateChangedForPhoneId(int phoneId, int subId, int activationType, int activationState)1854     public void notifySimActivationStateChangedForPhoneId(int phoneId, int subId,
1855             int activationType, int activationState) {
1856         if (!checkNotifyPermission("notifySimActivationState()")){
1857             return;
1858         }
1859         if (VDBG) {
1860             log("notifySimActivationStateForPhoneId: subId=" + subId + " phoneId=" + phoneId
1861                     + "type=" + activationType + " state=" + activationState);
1862         }
1863         synchronized (mRecords) {
1864             if (validatePhoneId(phoneId)) {
1865                 switch (activationType) {
1866                     case SIM_ACTIVATION_TYPE_VOICE:
1867                         mVoiceActivationState[phoneId] = activationState;
1868                         break;
1869                     case SIM_ACTIVATION_TYPE_DATA:
1870                         mDataActivationState[phoneId] = activationState;
1871                         break;
1872                     default:
1873                         return;
1874                 }
1875                 for (Record r : mRecords) {
1876                     if (VDBG) {
1877                         log("notifySimActivationStateForPhoneId: r=" + r + " subId=" + subId
1878                                 + " phoneId=" + phoneId + "type=" + activationType
1879                                 + " state=" + activationState);
1880                     }
1881                     try {
1882                         if ((activationType == SIM_ACTIVATION_TYPE_VOICE)
1883                                 && r.matchTelephonyCallbackEvent(
1884                                         TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
1885                                 && idMatch(r, subId, phoneId)) {
1886                             if (DBG) {
1887                                 log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r
1888                                         + " subId=" + subId + " phoneId=" + phoneId
1889                                         + " state=" + activationState);
1890                             }
1891                             r.callback.onVoiceActivationStateChanged(activationState);
1892                         }
1893                         if ((activationType == SIM_ACTIVATION_TYPE_DATA)
1894                                 && r.matchTelephonyCallbackEvent(
1895                                         TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)
1896                                 && idMatch(r, subId, phoneId)) {
1897                             if (DBG) {
1898                                 log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r
1899                                         + " subId=" + subId + " phoneId=" + phoneId
1900                                         + " state=" + activationState);
1901                             }
1902                             r.callback.onDataActivationStateChanged(activationState);
1903                         }
1904                     }  catch (RemoteException ex) {
1905                         mRemoveList.add(r.binder);
1906                     }
1907                 }
1908             } else {
1909                 log("notifySimActivationStateForPhoneId: INVALID phoneId=" + phoneId);
1910             }
1911             handleRemoveListLocked();
1912         }
1913     }
1914 
notifySignalStrengthForPhoneId(int phoneId, int subId, SignalStrength signalStrength)1915     public void notifySignalStrengthForPhoneId(int phoneId, int subId,
1916                 SignalStrength signalStrength) {
1917         if (!checkNotifyPermission("notifySignalStrength()")) {
1918             return;
1919         }
1920         if (VDBG) {
1921             log("notifySignalStrengthForPhoneId: subId=" + subId
1922                 +" phoneId=" + phoneId + " signalStrength=" + signalStrength);
1923         }
1924 
1925         synchronized (mRecords) {
1926             if (validatePhoneId(phoneId)) {
1927                 if (VDBG) log("notifySignalStrengthForPhoneId: valid phoneId=" + phoneId);
1928                 mSignalStrength[phoneId] = signalStrength;
1929                 for (Record r : mRecords) {
1930                     if (VDBG) {
1931                         log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId
1932                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
1933                     }
1934                     if (r.matchTelephonyCallbackEvent(
1935                             TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)
1936                             && idMatch(r, subId, phoneId)) {
1937                         try {
1938                             if (DBG) {
1939                                 log("notifySignalStrengthForPhoneId: callback.onSsS r=" + r
1940                                         + " subId=" + subId + " phoneId=" + phoneId
1941                                         + " ss=" + signalStrength);
1942                             }
1943                             r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
1944                         } catch (RemoteException ex) {
1945                             mRemoveList.add(r.binder);
1946                         }
1947                     }
1948                     if (r.matchTelephonyCallbackEvent(
1949                             TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)
1950                             && idMatch(r, subId, phoneId)) {
1951                         try {
1952                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
1953                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
1954                             if (DBG) {
1955                                 log("notifySignalStrengthForPhoneId: callback.onSS r=" + r
1956                                         + " subId=" + subId + " phoneId=" + phoneId
1957                                         + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
1958                             }
1959                             r.callback.onSignalStrengthChanged(ss);
1960                         } catch (RemoteException ex) {
1961                             mRemoveList.add(r.binder);
1962                         }
1963                     }
1964                 }
1965             } else {
1966                 log("notifySignalStrengthForPhoneId: invalid phoneId=" + phoneId);
1967             }
1968             handleRemoveListLocked();
1969         }
1970         broadcastSignalStrengthChanged(signalStrength, phoneId, subId);
1971     }
1972 
1973     @Override
notifyCarrierNetworkChange(boolean active)1974     public void notifyCarrierNetworkChange(boolean active) {
1975         // only CarrierService with carrier privilege rule should have the permission
1976         int[] subIds = Arrays.stream(SubscriptionManager.from(mContext)
1977                     .getCompleteActiveSubscriptionIdList())
1978                     .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext,
1979                             i)).toArray();
1980         if (ArrayUtils.isEmpty(subIds)) {
1981             loge("notifyCarrierNetworkChange without carrier privilege");
1982             // the active subId does not have carrier privilege.
1983             throw new SecurityException("notifyCarrierNetworkChange without carrier privilege");
1984         }
1985 
1986         for (int subId : subIds) {
1987             notifyCarrierNetworkChangeWithPermission(subId, active);
1988         }
1989     }
1990 
1991     @Override
notifyCarrierNetworkChangeWithSubId(int subId, boolean active)1992     public void notifyCarrierNetworkChangeWithSubId(int subId, boolean active) {
1993         if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) {
1994             throw new SecurityException(
1995                     "notifyCarrierNetworkChange without carrier privilege on subId " + subId);
1996         }
1997 
1998         notifyCarrierNetworkChangeWithPermission(subId, active);
1999     }
2000 
notifyCarrierNetworkChangeWithPermission(int subId, boolean active)2001     private void notifyCarrierNetworkChangeWithPermission(int subId, boolean active) {
2002         int phoneId = getPhoneIdFromSubId(subId);
2003         synchronized (mRecords) {
2004             mCarrierNetworkChangeState[phoneId] = active;
2005 
2006             if (VDBG) {
2007                 log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
2008             }
2009             for (Record r : mRecords) {
2010                 if (r.matchTelephonyCallbackEvent(
2011                         TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)
2012                         && idMatch(r, subId, phoneId)) {
2013                     try {
2014                         r.callback.onCarrierNetworkChange(active);
2015                     } catch (RemoteException ex) {
2016                         mRemoveList.add(r.binder);
2017                     }
2018                 }
2019             }
2020             handleRemoveListLocked();
2021         }
2022     }
2023 
notifyCellInfo(List<CellInfo> cellInfo)2024     public void notifyCellInfo(List<CellInfo> cellInfo) {
2025          notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellInfo);
2026     }
2027 
notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo)2028     public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) {
2029         if (!checkNotifyPermission("notifyCellInfoForSubscriber()")) {
2030             return;
2031         }
2032 
2033         if (VDBG) {
2034             log("notifyCellInfoForSubscriber: subId=" + subId
2035                 + " cellInfo=" + cellInfo);
2036         }
2037 
2038         if (cellInfo == null) {
2039             loge("notifyCellInfoForSubscriber() received a null list");
2040             cellInfo = Collections.EMPTY_LIST;
2041         }
2042 
2043         int phoneId = getPhoneIdFromSubId(subId);
2044         synchronized (mRecords) {
2045             if (validatePhoneId(phoneId)) {
2046                 mCellInfo.set(phoneId, cellInfo);
2047                 for (Record r : mRecords) {
2048                     if (validateEventAndUserLocked(
2049                             r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)
2050                             && idMatch(r, subId, phoneId)
2051                             && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
2052                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
2053                         try {
2054                             if (DBG_LOC) {
2055                                 log("notifyCellInfoForSubscriber: mCellInfo=" + cellInfo
2056                                     + " r=" + r);
2057                             }
2058                             r.callback.onCellInfoChanged(cellInfo);
2059                         } catch (RemoteException ex) {
2060                             mRemoveList.add(r.binder);
2061                         }
2062                     }
2063                 }
2064             }
2065             handleRemoveListLocked();
2066         }
2067     }
2068 
2069     @Override
notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi)2070     public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) {
2071         if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
2072             return;
2073         }
2074         if (VDBG) {
2075             log("notifyMessageWaitingChangedForSubscriberPhoneID: subId=" + phoneId
2076                 + " mwi=" + mwi);
2077         }
2078         synchronized (mRecords) {
2079             if (validatePhoneId(phoneId)) {
2080                 mMessageWaiting[phoneId] = mwi;
2081                 for (Record r : mRecords) {
2082                     if (r.matchTelephonyCallbackEvent(
2083                             TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
2084                             && idMatch(r, subId, phoneId)) {
2085                         try {
2086                             r.callback.onMessageWaitingIndicatorChanged(mwi);
2087                         } catch (RemoteException ex) {
2088                             mRemoveList.add(r.binder);
2089                         }
2090                     }
2091                 }
2092             }
2093             handleRemoveListLocked();
2094         }
2095     }
2096 
notifyUserMobileDataStateChangedForPhoneId(int phoneId, int subId, boolean state)2097     public void notifyUserMobileDataStateChangedForPhoneId(int phoneId, int subId, boolean state) {
2098         if (!checkNotifyPermission("notifyUserMobileDataStateChanged()")) {
2099             return;
2100         }
2101         if (VDBG) {
2102             log("notifyUserMobileDataStateChangedForSubscriberPhoneID: PhoneId=" + phoneId
2103                     + " subId=" + subId + " state=" + state);
2104         }
2105         synchronized (mRecords) {
2106             if (validatePhoneId(phoneId)) {
2107                 mUserMobileDataState[phoneId] = state;
2108                 for (Record r : mRecords) {
2109                     if (r.matchTelephonyCallbackEvent(
2110                             TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)
2111                             && idMatch(r, subId, phoneId)) {
2112                         try {
2113                             r.callback.onUserMobileDataStateChanged(state);
2114                         } catch (RemoteException ex) {
2115                             mRemoveList.add(r.binder);
2116                         }
2117                     }
2118                 }
2119             }
2120             handleRemoveListLocked();
2121         }
2122     }
2123 
2124     /**
2125      * Notify display network info changed.
2126      *
2127      * @param phoneId Phone id
2128      * @param subId Subscription id
2129      * @param telephonyDisplayInfo Display network info
2130      *
2131      * @see PhoneStateListener#onDisplayInfoChanged(TelephonyDisplayInfo)
2132      */
notifyDisplayInfoChanged(int phoneId, int subId, @NonNull TelephonyDisplayInfo telephonyDisplayInfo)2133     public void notifyDisplayInfoChanged(int phoneId, int subId,
2134                                          @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
2135         if (!checkNotifyPermission("notifyDisplayInfoChanged()")) {
2136             return;
2137         }
2138         String str = "notifyDisplayInfoChanged: PhoneId=" + phoneId + " subId=" + subId
2139                 + " telephonyDisplayInfo=" + telephonyDisplayInfo;
2140         if (VDBG) {
2141             log(str);
2142         }
2143         mLocalLog.log(str);
2144         synchronized (mRecords) {
2145             if (validatePhoneId(phoneId)) {
2146                 mTelephonyDisplayInfos[phoneId] = telephonyDisplayInfo;
2147                 for (Record r : mRecords) {
2148                     if (r.matchTelephonyCallbackEvent(
2149                             TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)
2150                             && idMatch(r, subId, phoneId)) {
2151                         try {
2152                             if (!mConfigurationProvider.isDisplayInfoNrAdvancedSupported(
2153                                     r.callingPackage, Binder.getCallingUserHandle())) {
2154                                 r.callback.onDisplayInfoChanged(
2155                                         getBackwardCompatibleTelephonyDisplayInfo(
2156                                                 telephonyDisplayInfo));
2157                             } else {
2158                                 r.callback.onDisplayInfoChanged(telephonyDisplayInfo);
2159                             }
2160                         } catch (RemoteException ex) {
2161                             mRemoveList.add(r.binder);
2162                         }
2163                     }
2164                 }
2165             }
2166             handleRemoveListLocked();
2167         }
2168     }
2169 
getBackwardCompatibleTelephonyDisplayInfo( @onNull TelephonyDisplayInfo telephonyDisplayInfo)2170     private TelephonyDisplayInfo getBackwardCompatibleTelephonyDisplayInfo(
2171             @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
2172         int networkType = telephonyDisplayInfo.getNetworkType();
2173         int overrideNetworkType = telephonyDisplayInfo.getOverrideNetworkType();
2174         if (networkType == TelephonyManager.NETWORK_TYPE_NR) {
2175             overrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE;
2176         } else if (networkType == TelephonyManager.NETWORK_TYPE_LTE
2177                 && overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) {
2178             overrideNetworkType = TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE;
2179         }
2180         boolean isRoaming = telephonyDisplayInfo.isRoaming();
2181         boolean isNtn = telephonyDisplayInfo.isNtn();
2182         boolean isSatelliteConstrainedData =
2183                 telephonyDisplayInfo.isSatelliteConstrainedData();
2184         return new TelephonyDisplayInfo(networkType, overrideNetworkType, isRoaming,
2185                 isNtn, isSatelliteConstrainedData);
2186     }
2187 
notifyCallForwardingChanged(boolean cfi)2188     public void notifyCallForwardingChanged(boolean cfi) {
2189         notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cfi);
2190     }
2191 
notifyCallForwardingChangedForSubscriber(int subId, boolean cfi)2192     public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) {
2193         if (!checkNotifyPermission("notifyCallForwardingChanged()")) {
2194             return;
2195         }
2196         if (VDBG) {
2197             log("notifyCallForwardingChangedForSubscriber: subId=" + subId
2198                 + " cfi=" + cfi);
2199         }
2200         int phoneId = getPhoneIdFromSubId(subId);
2201         synchronized (mRecords) {
2202             if (validatePhoneId(phoneId)) {
2203                 mCallForwarding[phoneId] = cfi;
2204                 for (Record r : mRecords) {
2205                     if (r.matchTelephonyCallbackEvent(
2206                             TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
2207                             && idMatch(r, subId, phoneId)) {
2208                         try {
2209                             r.callback.onCallForwardingIndicatorChanged(cfi);
2210                         } catch (RemoteException ex) {
2211                             mRemoveList.add(r.binder);
2212                         }
2213                     }
2214                 }
2215             }
2216             handleRemoveListLocked();
2217         }
2218     }
2219 
2220     /**
2221      * Send a notification to registrants about the data activity state.
2222      *
2223      * @param subId the subscriptionId for the data connection
2224      * @param state indicates the latest data activity type
2225      * e.g.,{@link TelephonyManager#DATA_ACTIVITY_IN}
2226      *
2227      */
2228 
notifyDataActivityForSubscriber(int subId, int state)2229     public void notifyDataActivityForSubscriber(int subId, int state) {
2230         if (!checkNotifyPermission("notifyDataActivity()")) {
2231             return;
2232         }
2233         int phoneId = getPhoneIdFromSubId(subId);
2234         synchronized (mRecords) {
2235             if (validatePhoneId(phoneId)) {
2236                 mDataActivity[phoneId] = state;
2237                 for (Record r : mRecords) {
2238                     // Notify by correct subId.
2239                     if (r.matchTelephonyCallbackEvent(
2240                             TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)
2241                             && idMatch(r, subId, phoneId)) {
2242                         try {
2243                             r.callback.onDataActivity(state);
2244                         } catch (RemoteException ex) {
2245                             mRemoveList.add(r.binder);
2246                         }
2247                     }
2248                 }
2249             }
2250             handleRemoveListLocked();
2251         }
2252     }
2253 
2254     /**
2255      * Send a notification to registrants about the data activity state.
2256      *
2257      * @param phoneId the phoneId carrying the data connection
2258      * @param subId the subscriptionId for the data connection
2259      * @param state indicates the latest data activity type
2260      * e.g.,{@link TelephonyManager#DATA_ACTIVITY_IN}
2261      *
2262      */
notifyDataActivityForSubscriberWithSlot(int phoneId, int subId, int state)2263     public void notifyDataActivityForSubscriberWithSlot(int phoneId, int subId, int state) {
2264         if (!checkNotifyPermission("notifyDataActivityWithSlot()")) {
2265             return;
2266         }
2267 
2268         synchronized (mRecords) {
2269             if (validatePhoneId(phoneId)) {
2270                 mDataActivity[phoneId] = state;
2271                 for (Record r : mRecords) {
2272                     if (r.matchTelephonyCallbackEvent(
2273                             TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)
2274                             && idMatch(r, subId, phoneId)) {
2275                         try {
2276                             r.callback.onDataActivity(state);
2277                         } catch (RemoteException ex) {
2278                             mRemoveList.add(r.binder);
2279                         }
2280                     }
2281                 }
2282             }
2283             handleRemoveListLocked();
2284         }
2285     }
2286 
2287     /**
2288      * Send a notification to registrants that the data connection state has changed.
2289      *
2290      * @param phoneId the phoneId carrying the data connection
2291      * @param subId the subscriptionId for the data connection
2292      * @param preciseState a PreciseDataConnectionState that has info about the data connection
2293      */
2294     @Override
notifyDataConnectionForSubscriber(int phoneId, int subId, @NonNull PreciseDataConnectionState preciseState)2295     public void notifyDataConnectionForSubscriber(int phoneId, int subId,
2296             @NonNull PreciseDataConnectionState preciseState) {
2297         if (!checkNotifyPermission("notifyDataConnection()" )) {
2298             return;
2299         }
2300 
2301         synchronized (mRecords) {
2302             if (validatePhoneId(phoneId) && preciseState.getApnSetting() != null) {
2303                 Pair<Integer, ApnSetting> key = Pair.create(preciseState.getTransportType(),
2304                         preciseState.getApnSetting());
2305                 PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId)
2306                         .remove(key);
2307                 if (!Objects.equals(oldState, preciseState)) {
2308                     for (Record r : mRecords) {
2309                         if (r.matchTelephonyCallbackEvent(
2310                                 TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
2311                                 && idMatchRelaxed(r, subId, phoneId)) {
2312                             try {
2313                                 r.callback.onPreciseDataConnectionStateChanged(preciseState);
2314                             } catch (RemoteException ex) {
2315                                 mRemoveList.add(r.binder);
2316                             }
2317                         }
2318                     }
2319                     handleRemoveListLocked();
2320 
2321                     broadcastDataConnectionStateChanged(phoneId, subId, preciseState);
2322 
2323                     String str = "notifyDataConnectionForSubscriber: phoneId=" + phoneId + " subId="
2324                             + subId + " " + preciseState;
2325                     log(str);
2326                     mLocalLog.log(str);
2327                 }
2328 
2329                 // If the state is disconnected, it would be the end of life cycle of a data
2330                 // connection, so remove it from the cache.
2331                 if (preciseState.getState() != TelephonyManager.DATA_DISCONNECTED) {
2332                     mPreciseDataConnectionStates.get(phoneId).put(key, preciseState);
2333                 }
2334 
2335                 // Note that below is just the workaround for reporting the correct data connection
2336                 // state. The actual fix should be put in the new data stack in T.
2337                 // TODO: Remove the code below in T.
2338 
2339                 // Collect all possible candidate data connection state for internet. Key is the
2340                 // data connection state, value is the precise data connection state.
2341                 Map<Integer, PreciseDataConnectionState> internetConnections = new ArrayMap<>();
2342                 if (preciseState.getState() == TelephonyManager.DATA_DISCONNECTED
2343                         && preciseState.getApnSetting().getApnTypes()
2344                         .contains(ApnSetting.TYPE_DEFAULT)) {
2345                     internetConnections.put(TelephonyManager.DATA_DISCONNECTED, preciseState);
2346                 }
2347                 for (Map.Entry<Pair<Integer, ApnSetting>, PreciseDataConnectionState> entry :
2348                         mPreciseDataConnectionStates.get(phoneId).entrySet()) {
2349                     if (entry.getKey().first == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
2350                             && entry.getKey().second.getApnTypes()
2351                             .contains(ApnSetting.TYPE_DEFAULT)) {
2352                         internetConnections.put(entry.getValue().getState(), entry.getValue());
2353                     }
2354                 }
2355 
2356                 // If any internet data is in connected state, then report connected, then check
2357                 // suspended, connecting, disconnecting, and disconnected. The order is very
2358                 // important.
2359                 int[] statesInPriority = new int[]{TelephonyManager.DATA_CONNECTED,
2360                         TelephonyManager.DATA_SUSPENDED, TelephonyManager.DATA_CONNECTING,
2361                         TelephonyManager.DATA_DISCONNECTING,
2362                         TelephonyManager.DATA_DISCONNECTED};
2363                 int state = TelephonyManager.DATA_DISCONNECTED;
2364                 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
2365                 for (int s : statesInPriority) {
2366                     if (internetConnections.containsKey(s)) {
2367                         state = s;
2368                         networkType = internetConnections.get(s).getNetworkType();
2369                         break;
2370                     }
2371                 }
2372 
2373                 if (mDataConnectionState[phoneId] != state
2374                         || mDataConnectionNetworkType[phoneId] != networkType) {
2375                     String str = "onDataConnectionStateChanged("
2376                             + TelephonyUtils.dataStateToString(state)
2377                             + ", " + TelephonyManager.getNetworkTypeName(networkType)
2378                             + ") subId=" + subId + ", phoneId=" + phoneId;
2379                     log(str);
2380                     mLocalLog.log(str);
2381                     for (Record r : mRecords) {
2382                         if (r.matchTelephonyCallbackEvent(
2383                                 TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)
2384                                 && idMatch(r, subId, phoneId)) {
2385                             try {
2386                                 if (DBG) {
2387                                     log("Notify data connection state changed on sub: " + subId);
2388                                 }
2389                                 r.callback.onDataConnectionStateChanged(state, networkType);
2390                             } catch (RemoteException ex) {
2391                                 mRemoveList.add(r.binder);
2392                             }
2393                         }
2394                     }
2395 
2396                     mDataConnectionState[phoneId] = state;
2397                     mDataConnectionNetworkType[phoneId] = networkType;
2398 
2399                     handleRemoveListLocked();
2400                 }
2401             }
2402         }
2403     }
2404 
2405     @Override
notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity)2406     public void notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity) {
2407         notifyCellLocationForSubscriber(subId, cellIdentity, false /* hasUserSwitched */);
2408     }
2409 
notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity, boolean hasUserSwitched)2410     private void notifyCellLocationForSubscriber(int subId, CellIdentity cellIdentity,
2411             boolean hasUserSwitched) {
2412         log("notifyCellLocationForSubscriber: subId=" + subId + " cellIdentity="
2413                 + Rlog.pii(DBG || VDBG || DBG_LOC, cellIdentity));
2414         if (!checkNotifyPermission("notifyCellLocation()")) {
2415             return;
2416         }
2417         int phoneId = getPhoneIdFromSubId(subId);
2418         synchronized (mRecords) {
2419             if (validatePhoneId(phoneId)
2420                     && (hasUserSwitched || !Objects.equals(cellIdentity, mCellIdentity[phoneId]))) {
2421                 mCellIdentity[phoneId] = cellIdentity;
2422                 for (Record r : mRecords) {
2423                     if (validateEventAndUserLocked(
2424                             r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)
2425                             && idMatch(r, subId, phoneId)
2426                             && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
2427                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
2428                         try {
2429                             if (DBG_LOC) {
2430                                 log("notifyCellLocation: cellIdentity=" + cellIdentity
2431                                         + " r=" + r);
2432                             }
2433                             r.callback.onCellLocationChanged(cellIdentity);
2434                         } catch (RemoteException ex) {
2435                             mRemoveList.add(r.binder);
2436                         }
2437                     }
2438                 }
2439             }
2440             handleRemoveListLocked();
2441         }
2442     }
2443 
2444     /**
2445      * Send a notification to registrants that the precise call state has changed.
2446      *
2447      * @param phoneId the phoneId carrying the data connection
2448      * @param subId the subscriptionId for the data connection
2449      * @param callStates Array of PreciseCallState of foreground, background & ringing calls.
2450      * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId()} for
2451      *                   ringing, foreground & background calls.
2452      * @param imsServiceTypes Array of IMS call service type for ringing, foreground &
2453      *                        background calls.
2454      * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls.
2455      */
notifyPreciseCallState(int phoneId, int subId, @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, @Annotation.ImsCallServiceType int[] imsServiceTypes, @Annotation.ImsCallType int[] imsCallTypes)2456     public void notifyPreciseCallState(int phoneId, int subId,
2457             @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds,
2458             @Annotation.ImsCallServiceType int[] imsServiceTypes,
2459             @Annotation.ImsCallType int[] imsCallTypes) {
2460         if (!checkNotifyPermission("notifyPreciseCallState()")) {
2461             return;
2462         }
2463 
2464         int ringingCallState = callStates[CallState.CALL_CLASSIFICATION_RINGING];
2465         int foregroundCallState = callStates[CallState.CALL_CLASSIFICATION_FOREGROUND];
2466         int backgroundCallState = callStates[CallState.CALL_CLASSIFICATION_BACKGROUND];
2467 
2468         synchronized (mRecords) {
2469             if (validatePhoneId(phoneId)) {
2470                 boolean preciseCallStateChanged = false;
2471                 mRingingCallState[phoneId] = ringingCallState;
2472                 mForegroundCallState[phoneId] = foregroundCallState;
2473                 mBackgroundCallState[phoneId] = backgroundCallState;
2474                 PreciseCallState preciseCallState = new PreciseCallState(
2475                         ringingCallState, foregroundCallState,
2476                         backgroundCallState,
2477                         DisconnectCause.NOT_VALID,
2478                         PreciseDisconnectCause.NOT_VALID);
2479                 if (!preciseCallState.equals(mPreciseCallState[phoneId])) {
2480                     preciseCallStateChanged = true;
2481                     mPreciseCallState[phoneId] = preciseCallState;
2482                 }
2483                 boolean notifyCallState = true;
2484                 if (mCallQuality == null) {
2485                     log("notifyPreciseCallState: mCallQuality is null, "
2486                             + "skipping call attributes");
2487                     notifyCallState = false;
2488                 } else {
2489                     // If the precise call state is no longer active, reset the call network type
2490                     // and call quality.
2491                     if (mPreciseCallState[phoneId].getForegroundCallState()
2492                             != PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
2493                         mCallNetworkType[phoneId] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
2494                         mCallQuality[phoneId] = createCallQuality();
2495                     }
2496                     List<CallState> prevCallStateList = new ArrayList<>();
2497                     prevCallStateList.addAll(mCallStateLists.get(phoneId));
2498                     mCallStateLists.get(phoneId).clear();
2499                     if (foregroundCallState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID
2500                             && foregroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) {
2501                         CallQuality callQuality = mCallQuality[phoneId];
2502                         CallState.Builder builder = new CallState.Builder(
2503                                 callStates[CallState.CALL_CLASSIFICATION_FOREGROUND])
2504                                 .setNetworkType(mCallNetworkType[phoneId])
2505                                 .setCallQuality(callQuality)
2506                                 .setCallClassification(
2507                                         CallState.CALL_CLASSIFICATION_FOREGROUND);
2508                         if (imsCallIds != null && imsServiceTypes != null && imsCallTypes != null) {
2509                             builder = builder
2510                                     .setImsCallSessionId(imsCallIds[
2511                                             CallState.CALL_CLASSIFICATION_FOREGROUND])
2512                                     .setImsCallServiceType(imsServiceTypes[
2513                                             CallState.CALL_CLASSIFICATION_FOREGROUND])
2514                                     .setImsCallType(imsCallTypes[
2515                                             CallState.CALL_CLASSIFICATION_FOREGROUND]);
2516                         }
2517                         mCallStateLists.get(phoneId).add(builder.build());
2518                     }
2519                     if (backgroundCallState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID
2520                             && backgroundCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) {
2521                         CallState.Builder builder = new CallState.Builder(
2522                                 callStates[CallState.CALL_CLASSIFICATION_BACKGROUND])
2523                                 .setNetworkType(mCallNetworkType[phoneId])
2524                                 .setCallQuality(createCallQuality())
2525                                 .setCallClassification(
2526                                         CallState.CALL_CLASSIFICATION_BACKGROUND);
2527                         if (imsCallIds != null && imsServiceTypes != null && imsCallTypes != null) {
2528                             builder = builder
2529                                     .setImsCallSessionId(imsCallIds[
2530                                             CallState.CALL_CLASSIFICATION_BACKGROUND])
2531                                     .setImsCallServiceType(imsServiceTypes[
2532                                             CallState.CALL_CLASSIFICATION_BACKGROUND])
2533                                     .setImsCallType(imsCallTypes[
2534                                             CallState.CALL_CLASSIFICATION_BACKGROUND]);
2535                         }
2536                         mCallStateLists.get(phoneId).add(builder.build());
2537                     }
2538                     if (ringingCallState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID
2539                             && ringingCallState != PreciseCallState.PRECISE_CALL_STATE_IDLE) {
2540                         CallState.Builder builder = new CallState.Builder(
2541                                 callStates[CallState.CALL_CLASSIFICATION_RINGING])
2542                                 .setNetworkType(mCallNetworkType[phoneId])
2543                                 .setCallQuality(createCallQuality())
2544                                 .setCallClassification(
2545                                         CallState.CALL_CLASSIFICATION_RINGING);
2546                         if (imsCallIds != null && imsServiceTypes != null && imsCallTypes != null) {
2547                             builder = builder
2548                                     .setImsCallSessionId(imsCallIds[
2549                                             CallState.CALL_CLASSIFICATION_RINGING])
2550                                     .setImsCallServiceType(imsServiceTypes[
2551                                             CallState.CALL_CLASSIFICATION_RINGING])
2552                                     .setImsCallType(imsCallTypes[
2553                                             CallState.CALL_CLASSIFICATION_RINGING]);
2554                         }
2555                         mCallStateLists.get(phoneId).add(builder.build());
2556                     }
2557                     if (prevCallStateList.equals(mCallStateLists.get(phoneId))) {
2558                         notifyCallState = false;
2559                     }
2560                     boolean hasOngoingCall = false;
2561                     for (CallState cs : mCallStateLists.get(phoneId)) {
2562                         if (cs.getCallState() != PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED) {
2563                             hasOngoingCall = true;
2564                             break;
2565                         }
2566                     }
2567                     if (!hasOngoingCall) {
2568                         //no ongoing call. clear media quality status cached.
2569                         mMediaQualityStatus.get(phoneId).clear();
2570                     }
2571                 }
2572 
2573                 if (preciseCallStateChanged) {
2574                     for (Record r : mRecords) {
2575                         if (r.matchTelephonyCallbackEvent(
2576                                 TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)
2577                                 && idMatch(r, subId, phoneId)) {
2578                             try {
2579                                 r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
2580                             } catch (RemoteException ex) {
2581                                 mRemoveList.add(r.binder);
2582                             }
2583                         }
2584                     }
2585                 }
2586 
2587                 if (notifyCallState) {
2588                     List<CallState> copyList = null;
2589                     for (Record r : mRecords) {
2590                         if (r.matchTelephonyCallbackEvent(
2591                                 TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
2592                                 && idMatch(r, subId, phoneId)) {
2593                             // If listener is in the same process, original instance can be passed
2594                             // to the listener via AIDL without serialization/de-serialization. We
2595                             // will pass the copied list. Since the element is newly created instead
2596                             // of modification for the change, we can use shallow copy for this.
2597                             try {
2598                                 if (Flags.passCopiedCallStateList()) {
2599                                     if (r.callerPid == mPid && copyList == null) {
2600                                         copyList = List.copyOf(mCallStateLists.get(phoneId));
2601                                     }
2602                                     r.callback.onCallStatesChanged(copyList == null
2603                                             ? mCallStateLists.get(phoneId) : copyList);
2604                                 } else {
2605                                     r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
2606                                 }
2607                             } catch (RemoteException ex) {
2608                                 mRemoveList.add(r.binder);
2609                             }
2610                         }
2611                     }
2612                 }
2613             }
2614             handleRemoveListLocked();
2615         }
2616     }
2617 
notifyDisconnectCause(int phoneId, int subId, int disconnectCause, int preciseDisconnectCause)2618     public void notifyDisconnectCause(int phoneId, int subId, int disconnectCause,
2619                                       int preciseDisconnectCause) {
2620         if (!checkNotifyPermission("notifyDisconnectCause()")) {
2621             return;
2622         }
2623         synchronized (mRecords) {
2624             if (validatePhoneId(phoneId)) {
2625                 mCallDisconnectCause[phoneId] = disconnectCause;
2626                 mCallPreciseDisconnectCause[phoneId] = preciseDisconnectCause;
2627                 for (Record r : mRecords) {
2628                     if (r.matchTelephonyCallbackEvent(
2629                             TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)
2630                             && idMatch(r, subId, phoneId)) {
2631                         try {
2632                             r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
2633                                     mCallPreciseDisconnectCause[phoneId]);
2634                         } catch (RemoteException ex) {
2635                             mRemoveList.add(r.binder);
2636                         }
2637                     }
2638                 }
2639             }
2640             handleRemoveListLocked();
2641         }
2642     }
2643 
notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo)2644     public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) {
2645         if (!checkNotifyPermission("notifyImsCallDisconnectCause()")) {
2646             return;
2647         }
2648         int phoneId = getPhoneIdFromSubId(subId);
2649         synchronized (mRecords) {
2650             if (validatePhoneId(phoneId)) {
2651                 if (imsReasonInfo == null) {
2652                     loge("ImsReasonInfo is null, subId=" + subId + ", phoneId=" + phoneId);
2653                     mImsReasonInfo.set(phoneId, new ImsReasonInfo());
2654                     return;
2655                 }
2656                 mImsReasonInfo.set(phoneId, imsReasonInfo);
2657                 for (Record r : mRecords) {
2658                     if (r.matchTelephonyCallbackEvent(
2659                             TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)
2660                             && idMatch(r, subId, phoneId)) {
2661                         try {
2662                             if (DBG_LOC) {
2663                                 log("notifyImsCallDisconnectCause: mImsReasonInfo="
2664                                         + imsReasonInfo + " r=" + r);
2665                             }
2666                             r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId));
2667                         } catch (RemoteException ex) {
2668                             mRemoveList.add(r.binder);
2669                         }
2670                     }
2671                 }
2672             }
2673             handleRemoveListLocked();
2674         }
2675     }
2676 
2677     @Override
notifySrvccStateChanged(int subId, @SrvccState int state)2678     public void notifySrvccStateChanged(int subId, @SrvccState int state) {
2679         if (!checkNotifyPermission("notifySrvccStateChanged()")) {
2680             return;
2681         }
2682         if (VDBG) {
2683             log("notifySrvccStateChanged: subId=" + subId + " srvccState=" + state);
2684         }
2685         int phoneId = getPhoneIdFromSubId(subId);
2686         synchronized (mRecords) {
2687             if (validatePhoneId(phoneId)) {
2688                 mSrvccState[phoneId] = state;
2689                 for (Record r : mRecords) {
2690                     if (r.matchTelephonyCallbackEvent(
2691                             TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)
2692                             && idMatch(r, subId, phoneId)) {
2693                         try {
2694                             if (DBG_LOC) {
2695                                 log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r);
2696                             }
2697                             r.callback.onSrvccStateChanged(state);
2698                         } catch (RemoteException ex) {
2699                             mRemoveList.add(r.binder);
2700                         }
2701                     }
2702                 }
2703             }
2704             handleRemoveListLocked();
2705         }
2706     }
2707 
notifyOemHookRawEventForSubscriber(int phoneId, int subId, byte[] rawData)2708     public void notifyOemHookRawEventForSubscriber(int phoneId, int subId, byte[] rawData) {
2709         if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) {
2710             return;
2711         }
2712 
2713         synchronized (mRecords) {
2714             if (validatePhoneId(phoneId)) {
2715                 for (Record r : mRecords) {
2716                     if (VDBG) {
2717                         log("notifyOemHookRawEventForSubscriber:  r=" + r + " subId=" + subId);
2718                     }
2719                     if ((r.matchTelephonyCallbackEvent(
2720                             TelephonyCallback.EVENT_OEM_HOOK_RAW))
2721                             && idMatch(r, subId, phoneId)) {
2722                         try {
2723                             r.callback.onOemHookRawEvent(rawData);
2724                         } catch (RemoteException ex) {
2725                             mRemoveList.add(r.binder);
2726                         }
2727                     }
2728                 }
2729             }
2730             handleRemoveListLocked();
2731         }
2732     }
2733 
notifyPhoneCapabilityChanged(PhoneCapability capability)2734     public void notifyPhoneCapabilityChanged(PhoneCapability capability) {
2735         if (!checkNotifyPermission("notifyPhoneCapabilityChanged()")) {
2736             return;
2737         }
2738 
2739         if (VDBG) {
2740             log("notifyPhoneCapabilityChanged: capability=" + capability);
2741         }
2742 
2743         synchronized (mRecords) {
2744             mPhoneCapability = capability;
2745 
2746             for (Record r : mRecords) {
2747                 if (r.matchTelephonyCallbackEvent(
2748                         TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED)) {
2749                     try {
2750                         r.callback.onPhoneCapabilityChanged(capability);
2751                     } catch (RemoteException ex) {
2752                         mRemoveList.add(r.binder);
2753                     }
2754                 }
2755             }
2756             handleRemoveListLocked();
2757         }
2758     }
2759 
notifyActiveDataSubIdChanged(int activeDataSubId)2760     public void notifyActiveDataSubIdChanged(int activeDataSubId) {
2761         if (!checkNotifyPermission("notifyActiveDataSubIdChanged()")) {
2762             return;
2763         }
2764 
2765         log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId);
2766         mLocalLog.log("notifyActiveDataSubIdChanged: activeDataSubId=" + activeDataSubId);
2767 
2768         mActiveDataSubId = activeDataSubId;
2769         synchronized (mRecords) {
2770             for (Record r : mRecords) {
2771                 if (r.matchTelephonyCallbackEvent(
2772                         TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) {
2773                     try {
2774                         r.callback.onActiveDataSubIdChanged(activeDataSubId);
2775                     } catch (RemoteException ex) {
2776                         mRemoveList.add(r.binder);
2777                     }
2778                 }
2779             }
2780             handleRemoveListLocked();
2781         }
2782     }
2783 
notifyRadioPowerStateChanged(int phoneId, int subId, @RadioPowerState int state)2784     public void notifyRadioPowerStateChanged(int phoneId, int subId, @RadioPowerState int state) {
2785         if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) {
2786             return;
2787         }
2788 
2789         if (VDBG) {
2790             log("notifyRadioPowerStateChanged: state= " + state + " subId=" + subId);
2791         }
2792 
2793         synchronized (mRecords) {
2794             if (validatePhoneId(phoneId)) {
2795                 mRadioPowerState = state;
2796 
2797                 for (Record r : mRecords) {
2798                     if (r.matchTelephonyCallbackEvent(
2799                             TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)
2800                             && idMatchRelaxed(r, subId, phoneId)) {
2801                         try {
2802                             r.callback.onRadioPowerStateChanged(state);
2803                         } catch (RemoteException ex) {
2804                             mRemoveList.add(r.binder);
2805                         }
2806                     }
2807                 }
2808 
2809             }
2810             handleRemoveListLocked();
2811         }
2812     }
2813 
2814     @Override
notifyEmergencyNumberList(int phoneId, int subId)2815     public void notifyEmergencyNumberList(int phoneId, int subId) {
2816         if (!checkNotifyPermission("notifyEmergencyNumberList()")) {
2817             return;
2818         }
2819         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
2820                 && !mContext.getPackageManager()
2821                         .hasSystemFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)) {
2822             // TelephonyManager.getEmergencyNumberList() throws an exception if
2823             // FEATURE_TELEPHONY_CALLING or FEATURE_TELEPHONY_MESSAGING is not defined.
2824             return;
2825         }
2826 
2827         synchronized (mRecords) {
2828             if (validatePhoneId(phoneId)) {
2829                 TelephonyManager tm = (TelephonyManager) mContext.getSystemService(
2830                         Context.TELEPHONY_SERVICE);
2831                 mEmergencyNumberList = tm.getEmergencyNumberList();
2832 
2833                 for (Record r : mRecords) {
2834                     if (r.matchTelephonyCallbackEvent(
2835                             TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
2836                             && idMatch(r, subId, phoneId)) {
2837                         try {
2838                             r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
2839                             if (VDBG) {
2840                                 log("notifyEmergencyNumberList: emergencyNumberList= "
2841                                         + mEmergencyNumberList);
2842                             }
2843                         } catch (RemoteException ex) {
2844                             mRemoveList.add(r.binder);
2845                         }
2846                     }
2847                 }
2848             }
2849 
2850             handleRemoveListLocked();
2851         }
2852     }
2853 
2854     @Override
notifyOutgoingEmergencyCall(int phoneId, int subId, EmergencyNumber emergencyNumber)2855     public void notifyOutgoingEmergencyCall(int phoneId, int subId,
2856             EmergencyNumber emergencyNumber) {
2857         if (!checkNotifyPermission("notifyOutgoingEmergencyCall()")) {
2858             return;
2859         }
2860         synchronized (mRecords) {
2861             if (validatePhoneId(phoneId)) {
2862                 mOutgoingCallEmergencyNumber[phoneId] = emergencyNumber;
2863             }
2864             for (Record r : mRecords) {
2865                 // Send to all listeners regardless of subscription
2866                 if (r.matchTelephonyCallbackEvent(
2867                         TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL)) {
2868                     try {
2869                         r.callback.onOutgoingEmergencyCall(emergencyNumber, subId);
2870                     } catch (RemoteException ex) {
2871                         mRemoveList.add(r.binder);
2872                     }
2873                 }
2874             }
2875         }
2876         handleRemoveListLocked();
2877     }
2878 
2879     @Override
notifyOutgoingEmergencySms(int phoneId, int subId, EmergencyNumber emergencyNumber)2880     public void notifyOutgoingEmergencySms(int phoneId, int subId,
2881             EmergencyNumber emergencyNumber) {
2882         if (!checkNotifyPermission("notifyOutgoingEmergencySms()")) {
2883             return;
2884         }
2885 
2886         synchronized (mRecords) {
2887             if (validatePhoneId(phoneId)) {
2888                 mOutgoingSmsEmergencyNumber[phoneId] = emergencyNumber;
2889                 for (Record r : mRecords) {
2890                     // Send to all listeners regardless of subscription
2891                     if (r.matchTelephonyCallbackEvent(
2892                             TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS)) {
2893                         try {
2894                             r.callback.onOutgoingEmergencySms(emergencyNumber, subId);
2895                         } catch (RemoteException ex) {
2896                             mRemoveList.add(r.binder);
2897                         }
2898                     }
2899                 }
2900             }
2901             handleRemoveListLocked();
2902         }
2903     }
2904 
2905     @Override
notifyCallQualityChanged(CallQuality callQuality, int phoneId, int subId, int callNetworkType)2906     public void notifyCallQualityChanged(CallQuality callQuality, int phoneId, int subId,
2907             int callNetworkType) {
2908         if (!checkNotifyPermission("notifyCallQualityChanged()")) {
2909             return;
2910         }
2911 
2912         synchronized (mRecords) {
2913             if (validatePhoneId(phoneId)) {
2914                 // merge CallQuality with PreciseCallState and network type
2915                 mCallQuality[phoneId] = callQuality;
2916                 mCallNetworkType[phoneId] = callNetworkType;
2917                 if (mCallStateLists.get(phoneId).size() > 0
2918                         && mCallStateLists.get(phoneId).get(0).getCallState()
2919                         == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
2920                     CallState prev = mCallStateLists.get(phoneId).remove(0);
2921                     mCallStateLists.get(phoneId).add(
2922                             0, new CallState.Builder(prev.getCallState())
2923                                     .setNetworkType(callNetworkType)
2924                                     .setCallQuality(callQuality)
2925                                     .setCallClassification(prev.getCallClassification())
2926                                     .setImsCallSessionId(prev.getImsCallSessionId())
2927                                     .setImsCallServiceType(prev.getImsCallServiceType())
2928                                     .setImsCallType(prev.getImsCallType()).build());
2929                 } else {
2930                     log("There is no active call to report CallQuality");
2931                     return;
2932                 }
2933                 List<CallState> copyList = null;
2934                 for (Record r : mRecords) {
2935                     if (r.matchTelephonyCallbackEvent(
2936                             TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
2937                             && idMatch(r, subId, phoneId)) {
2938                         try {
2939                             if (Flags.passCopiedCallStateList()) {
2940                                 if (r.callerPid == mPid && copyList == null) {
2941                                     copyList = List.copyOf(mCallStateLists.get(phoneId));
2942                                 }
2943                                 r.callback.onCallStatesChanged(copyList == null
2944                                         ? mCallStateLists.get(phoneId) : copyList);
2945                             } else {
2946                                 r.callback.onCallStatesChanged(mCallStateLists.get(phoneId));
2947                             }
2948                         } catch (RemoteException ex) {
2949                             mRemoveList.add(r.binder);
2950                         }
2951                     }
2952                 }
2953             }
2954             handleRemoveListLocked();
2955         }
2956     }
2957 
2958     @Override
notifyRegistrationFailed(int phoneId, int subId, @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode)2959     public void notifyRegistrationFailed(int phoneId, int subId, @NonNull CellIdentity cellIdentity,
2960             @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) {
2961         if (!checkNotifyPermission("notifyRegistrationFailed()")) {
2962             return;
2963         }
2964 
2965         // In case callers don't have fine location access, pre-construct a location-free version
2966         // of the CellIdentity. This will still have the PLMN ID, which should be sufficient for
2967         // most purposes.
2968         final CellIdentity noLocationCi = cellIdentity.sanitizeLocationInfo();
2969 
2970 
2971         // This shouldn't be necessary, but better to not take the chance
2972         final String primaryPlmn = (cellIdentity != null) ? cellIdentity.getPlmn() : "<UNKNOWN>";
2973 
2974         final String logStr = "Registration Failed for phoneId=" + phoneId
2975                 + " subId=" + subId + "primaryPlmn=" + primaryPlmn
2976                 + " chosenPlmn=" + chosenPlmn + " domain=" + domain
2977                 + " causeCode=" + causeCode + " additionalCauseCode=" + additionalCauseCode;
2978 
2979         mLocalLog.log(logStr);
2980         if (DBG) log(logStr);
2981 
2982         synchronized (mRecords) {
2983             if (validatePhoneId(phoneId)) {
2984                 for (Record r : mRecords) {
2985                     if (r.matchTelephonyCallbackEvent(
2986                             TelephonyCallback.EVENT_REGISTRATION_FAILURE)
2987                             && idMatch(r, subId, phoneId)) {
2988                         try {
2989                             r.callback.onRegistrationFailed(
2990                                     checkFineLocationAccess(r, Build.VERSION_CODES.BASE)
2991                                             ? cellIdentity : noLocationCi,
2992                                     chosenPlmn, domain, causeCode,
2993                                     additionalCauseCode);
2994                         } catch (RemoteException ex) {
2995                             mRemoveList.add(r.binder);
2996                         }
2997                     }
2998                 }
2999             }
3000             handleRemoveListLocked();
3001         }
3002     }
3003 
3004     /**
3005      * Send a notification of changes to barring status to PhoneStateListener registrants.
3006      *
3007      * @param phoneId the phoneId
3008      * @param subId the subId
3009      * @param barringInfo a structure containing the complete updated barring info.
3010      */
notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo)3011     public void notifyBarringInfoChanged(int phoneId, int subId, @NonNull BarringInfo barringInfo) {
3012         if (!checkNotifyPermission("notifyBarringInfo()")) {
3013             return;
3014         }
3015         if (!validatePhoneId(phoneId)) {
3016             loge("Received invalid phoneId for BarringInfo = " + phoneId);
3017             return;
3018         }
3019 
3020         synchronized (mRecords) {
3021             if (barringInfo == null) {
3022                 loge("Received null BarringInfo for subId=" + subId + ", phoneId=" + phoneId);
3023                 mBarringInfo.set(phoneId, new BarringInfo());
3024                 return;
3025             }
3026             if (barringInfo.equals(mBarringInfo.get(phoneId))) {
3027                 if (VDBG) log("Ignoring duplicate barring info.");
3028                 return;
3029             }
3030             mBarringInfo.set(phoneId, barringInfo);
3031             // Barring info is non-null
3032             BarringInfo biNoLocation = barringInfo.createLocationInfoSanitizedCopy();
3033             if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
3034             for (Record r : mRecords) {
3035                 if (r.matchTelephonyCallbackEvent(
3036                         TelephonyCallback.EVENT_BARRING_INFO_CHANGED)
3037                         && idMatch(r, subId, phoneId)) {
3038                     try {
3039                         if (DBG_LOC) {
3040                             log("notifyBarringInfo: mBarringInfo="
3041                                     + barringInfo + " r=" + r);
3042                         }
3043                         r.callback.onBarringInfoChanged(
3044                                 checkFineLocationAccess(r, Build.VERSION_CODES.BASE)
3045                                     ? barringInfo : biNoLocation);
3046                     } catch (RemoteException ex) {
3047                         mRemoveList.add(r.binder);
3048                     }
3049                 }
3050             }
3051             handleRemoveListLocked();
3052         }
3053     }
3054 
3055     /**
3056      * Send a notification to registrants that the configs of physical channel has changed for
3057      * a particular subscription.
3058      *
3059      * @param phoneId the phone id.
3060      * @param subId the subId
3061      * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
3062      */
notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId, List<PhysicalChannelConfig> configs)3063     public void notifyPhysicalChannelConfigForSubscriber(int phoneId, int subId,
3064             List<PhysicalChannelConfig> configs) {
3065         if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) {
3066             return;
3067         }
3068 
3069         List<PhysicalChannelConfig> sanitizedConfigs = getLocationSanitizedConfigs(configs);
3070         if (VDBG) {
3071             log("notifyPhysicalChannelConfig: subId=" + subId + " configs=" + configs
3072                     + " sanitizedConfigs=" + sanitizedConfigs);
3073         }
3074 
3075         synchronized (mRecords) {
3076             if (validatePhoneId(phoneId)) {
3077                 mPhysicalChannelConfigs.set(phoneId, configs);
3078                 for (Record r : mRecords) {
3079                     if (r.matchTelephonyCallbackEvent(
3080                             TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)
3081                             && idMatch(r, subId, phoneId)) {
3082                         try {
3083                             if (DBG_LOC) {
3084                                 log("notifyPhysicalChannelConfig: mPhysicalChannelConfigs="
3085                                         + (shouldSanitizeLocationForPhysicalChannelConfig(r)
3086                                                 ? sanitizedConfigs : configs)
3087                                         + " r=" + r);
3088                             }
3089                             r.callback.onPhysicalChannelConfigChanged(
3090                                     shouldSanitizeLocationForPhysicalChannelConfig(r)
3091                                             ? sanitizedConfigs : configs);
3092                         } catch (RemoteException ex) {
3093                             mRemoveList.add(r.binder);
3094                         }
3095                     }
3096                 }
3097             }
3098             handleRemoveListLocked();
3099         }
3100     }
3101 
shouldSanitizeLocationForPhysicalChannelConfig(Record record)3102     private static boolean shouldSanitizeLocationForPhysicalChannelConfig(Record record) {
3103         // Always redact location info from PhysicalChannelConfig if the registrant is from neither
3104         // PHONE nor SYSTEM process. There is no user case that the registrant needs the location
3105         // info (e.g. physicalCellId). This also remove the need for the location permissions check.
3106         return !TelephonyPermissions.isSystemOrPhone(record.callerUid);
3107     }
3108 
3109     /**
3110      * Return a copy of the PhysicalChannelConfig list but with location info removed.
3111      */
getLocationSanitizedConfigs( List<PhysicalChannelConfig> configs)3112     private static List<PhysicalChannelConfig> getLocationSanitizedConfigs(
3113             List<PhysicalChannelConfig> configs) {
3114         List<PhysicalChannelConfig> sanitizedConfigs = new ArrayList<>(configs.size());
3115         for (PhysicalChannelConfig config : configs) {
3116             sanitizedConfigs.add(config.createLocationInfoSanitizedCopy());
3117         }
3118         return sanitizedConfigs;
3119     }
3120 
3121     /**
3122      * Notify that the data enabled has changed.
3123      *
3124      * @param phoneId the phone id.
3125      * @param subId the subId.
3126      * @param enabled True if data is enabled, otherwise disabled.
3127      * @param reason  Reason for data enabled/disabled. See {@code DATA_*} in
3128      *                {@link TelephonyManager}.
3129      */
notifyDataEnabled(int phoneId, int subId, boolean enabled, @TelephonyManager.DataEnabledReason int reason)3130     public void notifyDataEnabled(int phoneId, int subId, boolean enabled,
3131             @TelephonyManager.DataEnabledReason int reason) {
3132         if (!checkNotifyPermission("notifyDataEnabled()")) {
3133             return;
3134         }
3135 
3136         if (VDBG) {
3137             log("notifyDataEnabled: PhoneId=" + phoneId + " subId=" + subId +
3138                     " enabled=" + enabled + " reason=" + reason);
3139         }
3140 
3141         synchronized (mRecords) {
3142             if (validatePhoneId(phoneId)) {
3143                 mIsDataEnabled[phoneId] = enabled;
3144                 mDataEnabledReason[phoneId] = reason;
3145                 for (Record r : mRecords) {
3146                     if (r.matchTelephonyCallbackEvent(
3147                             TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)
3148                             && idMatch(r, subId, phoneId)) {
3149                         try {
3150                             r.callback.onDataEnabledChanged(enabled, reason);
3151                         } catch (RemoteException ex) {
3152                             mRemoveList.add(r.binder);
3153                         }
3154                     }
3155                 }
3156             }
3157             handleRemoveListLocked();
3158         }
3159     }
3160 
3161     /**
3162      * Notify that the allowed network type has changed.
3163      *
3164      * @param phoneId the phone id.
3165      * @param subId the subId.
3166      * @param reason the allowed network type reason.
3167      * @param allowedNetworkType the allowed network type value.
3168      */
notifyAllowedNetworkTypesChanged(int phoneId, int subId, int reason, long allowedNetworkType)3169     public void notifyAllowedNetworkTypesChanged(int phoneId, int subId, int reason,
3170             long allowedNetworkType) {
3171         if (!checkNotifyPermission("notifyAllowedNetworkTypesChanged()")) {
3172             return;
3173         }
3174 
3175         synchronized (mRecords) {
3176             if (validatePhoneId(phoneId)) {
3177                 mAllowedNetworkTypeReason[phoneId] = reason;
3178                 mAllowedNetworkTypeValue[phoneId] = allowedNetworkType;
3179 
3180                 for (Record r : mRecords) {
3181                     if (r.matchTelephonyCallbackEvent(
3182                             TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)
3183                             && idMatch(r, subId, phoneId)) {
3184                         try {
3185                             if (VDBG) {
3186                                 log("notifyAllowedNetworkTypesChanged: reason= " + reason
3187                                         + ", allowed network type:"
3188                                         + TelephonyManager.convertNetworkTypeBitmaskToString(
3189                                         allowedNetworkType));
3190                             }
3191                             r.callback.onAllowedNetworkTypesChanged(reason, allowedNetworkType);
3192                         } catch (RemoteException ex) {
3193                             mRemoveList.add(r.binder);
3194                         }
3195                     }
3196                 }
3197             }
3198             handleRemoveListLocked();
3199         }
3200     }
3201 
3202     /**
3203      * Notify that the link capacity estimate has changed.
3204      * @param phoneId the phone id.
3205      * @param subId the subscription id.
3206      * @param linkCapacityEstimateList a list of {@link LinkCapacityEstimate}
3207      */
notifyLinkCapacityEstimateChanged(int phoneId, int subId, List<LinkCapacityEstimate> linkCapacityEstimateList)3208     public void notifyLinkCapacityEstimateChanged(int phoneId, int subId,
3209             List<LinkCapacityEstimate> linkCapacityEstimateList) {
3210         if (!checkNotifyPermission("notifyLinkCapacityEstimateChanged()")) {
3211             return;
3212         }
3213 
3214         if (VDBG) {
3215             log("notifyLinkCapacityEstimateChanged: linkCapacityEstimateList ="
3216                     + linkCapacityEstimateList);
3217         }
3218 
3219         synchronized (mRecords) {
3220             if (validatePhoneId(phoneId)) {
3221                 mLinkCapacityEstimateLists.set(phoneId, linkCapacityEstimateList);
3222                 for (Record r : mRecords) {
3223                     if (r.matchTelephonyCallbackEvent(
3224                             TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)
3225                             && idMatch(r, subId, phoneId)) {
3226                         try {
3227                             r.callback.onLinkCapacityEstimateChanged(linkCapacityEstimateList);
3228                         } catch (RemoteException ex) {
3229                             mRemoveList.add(r.binder);
3230                         }
3231                     }
3232                 }
3233             }
3234             handleRemoveListLocked();
3235         }
3236     }
3237 
3238     /**
3239      * Notify the listeners that simultaneous cellular calling subscriptions have changed
3240      * @param subIds The set of subIds that support simultaneous cellular calling
3241      */
notifySimultaneousCellularCallingSubscriptionsChanged(int[] subIds)3242     public void notifySimultaneousCellularCallingSubscriptionsChanged(int[] subIds) {
3243         if (!checkNotifyPermission("notifySimultaneousCellularCallingSubscriptionsChanged()")) {
3244             return;
3245         }
3246 
3247         if (VDBG) {
3248             StringBuilder b = new StringBuilder();
3249             b.append("notifySimultaneousCellularCallingSubscriptionsChanged: ");
3250             b.append("subIds = {");
3251             for (int i : subIds) {
3252                 b.append(" ");
3253                 b.append(i);
3254             }
3255             b.append("}");
3256             log(b.toString());
3257         }
3258 
3259         synchronized (mRecords) {
3260             mSimultaneousCellularCallingSubIds = subIds;
3261             for (Record r : mRecords) {
3262                 if (r.matchTelephonyCallbackEvent(TelephonyCallback
3263                         .EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED)) {
3264                     try {
3265                         r.callback.onSimultaneousCallingStateChanged(subIds);
3266                     } catch (RemoteException ex) {
3267                         mRemoveList.add(r.binder);
3268                     }
3269                 }
3270             }
3271             handleRemoveListLocked();
3272         }
3273     }
3274 
3275     @Override
addCarrierPrivilegesCallback( int phoneId, @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage, @NonNull String callingFeatureId)3276     public void addCarrierPrivilegesCallback(
3277             int phoneId,
3278             @NonNull ICarrierPrivilegesCallback callback,
3279             @NonNull String callingPackage,
3280             @NonNull String callingFeatureId) {
3281         int callerUserId = UserHandle.getCallingUserId();
3282         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3283         mContext.enforceCallingOrSelfPermission(
3284                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3285                 "addCarrierPrivilegesCallback");
3286         if (VDBG) {
3287             log(
3288                     "listen carrier privs: E pkg=" + pii(callingPackage) + " phoneId=" + phoneId
3289                             + " uid=" + Binder.getCallingUid()
3290                             + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId
3291                             + " callback=" + callback
3292                             + " callback.asBinder=" + callback.asBinder());
3293         }
3294 
3295         // In case this is triggered from the caller who has handled multiple SIM config change
3296         // firstly, we need to update the status (mNumPhone and mCarrierPrivilegeStates) firstly.
3297         // This is almost a no-op if there is no multiple SIM config change in advance.
3298         onMultiSimConfigChanged();
3299 
3300         synchronized (mRecords) {
3301             if (!validatePhoneId(phoneId)) {
3302                 throw new IllegalArgumentException("Invalid slot index: " + phoneId);
3303             }
3304             Record r = add(
3305                     callback.asBinder(), Binder.getCallingUid(), Binder.getCallingPid(), false);
3306 
3307             if (r == null) return;
3308 
3309             r.context = mContext;
3310             r.carrierPrivilegesCallback = callback;
3311             r.callingPackage = callingPackage;
3312             r.callingFeatureId = callingFeatureId;
3313             r.callerUid = Binder.getCallingUid();
3314             r.callerPid = Binder.getCallingPid();
3315             r.phoneId = phoneId;
3316             r.eventList = new ArraySet<>();
3317             if (DBG) {
3318                 log("listen carrier privs: Register r=" + r);
3319             }
3320 
3321             Pair<List<String>, int[]> state = mCarrierPrivilegeStates.get(phoneId);
3322             Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(phoneId);
3323             try {
3324                 if (r.matchCarrierPrivilegesCallback()) {
3325                     // Here, two callbacks are triggered in quick succession on the same binder.
3326                     // In typical case, we expect the callers to care about only one or the other.
3327                     r.carrierPrivilegesCallback.onCarrierPrivilegesChanged(
3328                             Collections.unmodifiableList(state.first),
3329                             Arrays.copyOf(state.second, state.second.length));
3330 
3331                     r.carrierPrivilegesCallback.onCarrierServiceChanged(carrierServiceState.first,
3332                             carrierServiceState.second);
3333                 }
3334             } catch (RemoteException ex) {
3335                 remove(r.binder);
3336             }
3337         }
3338     }
3339 
3340     @Override
removeCarrierPrivilegesCallback( @onNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage)3341     public void removeCarrierPrivilegesCallback(
3342             @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage) {
3343         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3344         mContext.enforceCallingOrSelfPermission(
3345                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3346                 "removeCarrierPrivilegesCallback");
3347         remove(callback.asBinder());
3348     }
3349 
3350     @Override
notifyCarrierPrivilegesChanged( int phoneId, List<String> privilegedPackageNames, int[] privilegedUids)3351     public void notifyCarrierPrivilegesChanged(
3352             int phoneId, List<String> privilegedPackageNames, int[] privilegedUids) {
3353         if (!checkNotifyPermission("notifyCarrierPrivilegesChanged")) {
3354             return;
3355         }
3356         if (VDBG) {
3357             log(
3358                     "notifyCarrierPrivilegesChanged: phoneId=" + phoneId
3359                             + ", <packages=" + pii(privilegedPackageNames)
3360                             + ", uids=" + Arrays.toString(privilegedUids) + ">");
3361         }
3362 
3363         // In case this is triggered from the caller who has handled multiple SIM config change
3364         // firstly, we need to update the status (mNumPhone and mCarrierPrivilegeStates) firstly.
3365         // This is almost a no-op if there is no multiple SIM config change in advance.
3366         onMultiSimConfigChanged();
3367 
3368         synchronized (mRecords) {
3369             if (!validatePhoneId(phoneId)) {
3370                 throw new IllegalArgumentException("Invalid slot index: " + phoneId);
3371             }
3372             mCarrierPrivilegeStates.set(
3373                     phoneId, new Pair<>(privilegedPackageNames, privilegedUids));
3374             for (Record r : mRecords) {
3375                 // Listeners are per-slot, not per-subscription. This is to provide a stable
3376                 // view across SIM profile switches.
3377                 if (!r.matchCarrierPrivilegesCallback()
3378                         || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) {
3379                     continue;
3380                 }
3381                 try {
3382                     // Make sure even in-process listeners can't modify the values.
3383                     r.carrierPrivilegesCallback.onCarrierPrivilegesChanged(
3384                             Collections.unmodifiableList(privilegedPackageNames),
3385                             Arrays.copyOf(privilegedUids, privilegedUids.length));
3386                 } catch (RemoteException ex) {
3387                     mRemoveList.add(r.binder);
3388                 }
3389             }
3390             handleRemoveListLocked();
3391         }
3392     }
3393 
3394     @Override
notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid)3395     public void notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid) {
3396         if (!checkNotifyPermission("notifyCarrierServiceChanged")) return;
3397         if (!validatePhoneId(phoneId)) return;
3398         if (VDBG) {
3399             log("notifyCarrierServiceChanged: phoneId=" + phoneId
3400                     + ", package=" + pii(packageName) + ", uid=" + uid);
3401         }
3402 
3403         // In case this is triggered from the caller who has handled multiple SIM config change
3404         // firstly, we need to update the status (mNumPhone and mCarrierServiceStates) firstly.
3405         // This is almost a no-op if there is no multiple SIM config change in advance.
3406         onMultiSimConfigChanged();
3407 
3408         synchronized (mRecords) {
3409             mCarrierServiceStates.set(
3410                     phoneId, new Pair<>(packageName, uid));
3411             for (Record r : mRecords) {
3412                 // Listeners are per-slot, not per-subscription.
3413                 if (!r.matchCarrierPrivilegesCallback()
3414                         || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) {
3415                     continue;
3416                 }
3417                 try {
3418                     r.carrierPrivilegesCallback.onCarrierServiceChanged(packageName, uid);
3419                 } catch (RemoteException ex) {
3420                     mRemoveList.add(r.binder);
3421                 }
3422             }
3423             handleRemoveListLocked();
3424         }
3425     }
3426 
3427     @Override
addCarrierConfigChangeListener(ICarrierConfigChangeListener listener, String pkg, String featureId)3428     public void addCarrierConfigChangeListener(ICarrierConfigChangeListener listener,
3429             String pkg, String featureId) {
3430         final int callerUserId = UserHandle.getCallingUserId();
3431         mAppOps.checkPackage(Binder.getCallingUid(), pkg);
3432         if (VDBG) {
3433             log("addCarrierConfigChangeListener pkg=" + pii(pkg) + " uid=" + Binder.getCallingUid()
3434                     + " myUserId=" + UserHandle.myUserId() + " callerUerId" + callerUserId
3435                     + " listener=" + listener + " listener.asBinder=" + listener.asBinder());
3436         }
3437 
3438         synchronized (mRecords) {
3439             IBinder b = listener.asBinder();
3440             boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
3441                     Process.myUid());
3442             Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);
3443 
3444             if (r == null) {
3445                 loge("Can not create Record instance!");
3446                 return;
3447             }
3448 
3449             r.context = mContext;
3450             r.carrierConfigChangeListener = listener;
3451             r.callingPackage = pkg;
3452             r.callingFeatureId = featureId;
3453             r.callerUid = Binder.getCallingUid();
3454             r.callerPid = Binder.getCallingPid();
3455             r.eventList = new ArraySet<>();
3456             if (DBG) {
3457                 log("addCarrierConfigChangeListener:  Register r=" + r);
3458             }
3459         }
3460     }
3461 
3462     @Override
removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener, String pkg)3463     public void removeCarrierConfigChangeListener(ICarrierConfigChangeListener listener,
3464             String pkg) {
3465         if (DBG) log("removeCarrierConfigChangeListener listener=" + listener + ", pkg=" + pkg);
3466         mAppOps.checkPackage(Binder.getCallingUid(), pkg);
3467         remove(listener.asBinder());
3468     }
3469 
3470     @Override
notifyCarrierConfigChanged(int phoneId, int subId, int carrierId, int specificCarrierId)3471     public void notifyCarrierConfigChanged(int phoneId, int subId, int carrierId,
3472             int specificCarrierId) {
3473         if (!validatePhoneId(phoneId)) {
3474             throw new IllegalArgumentException("Invalid phoneId: " + phoneId);
3475         }
3476         if (!checkNotifyPermission("notifyCarrierConfigChanged")) {
3477             loge("Caller has no notify permission!");
3478             return;
3479         }
3480         if (VDBG) {
3481             log("notifyCarrierConfigChanged: phoneId=" + phoneId + ", subId=" + subId
3482                     + ", carrierId=" + carrierId + ", specificCarrierId=" + specificCarrierId);
3483         }
3484 
3485         synchronized (mRecords) {
3486             mRemoveList.clear();
3487             for (Record r : mRecords) {
3488                 // Listeners are "global", neither per-slot nor per-sub, so no idMatch check here
3489                 if (!r.matchCarrierConfigChangeListener()) {
3490                     continue;
3491                 }
3492                 try {
3493                     r.carrierConfigChangeListener.onCarrierConfigChanged(phoneId, subId, carrierId,
3494                             specificCarrierId);
3495                 } catch (RemoteException re) {
3496                     mRemoveList.add(r.binder);
3497                 }
3498             }
3499             handleRemoveListLocked();
3500         }
3501     }
3502 
3503     @Override
addSatelliteStateChangeListener(@onNull ISatelliteStateChangeListener listener, @NonNull String pkg, @Nullable String featureId)3504     public void addSatelliteStateChangeListener(@NonNull ISatelliteStateChangeListener listener,
3505             @NonNull String pkg, @Nullable String featureId) {
3506         final int callerUserId = UserHandle.getCallingUserId();
3507         mAppOps.checkPackage(Binder.getCallingUid(), pkg);
3508         enforceCallingOrSelfAtLeastReadBasicPhoneStatePermission(pkg, featureId,
3509                 "addSatelliteStateChangeListener");
3510         if (VDBG) {
3511             log("addSatelliteStateChangeListener pkg=" + pii(pkg)
3512                     + " uid=" + Binder.getCallingUid()
3513                     + " myUserId=" + UserHandle.myUserId() + " callerUerId" + callerUserId
3514                     + " listener=" + listener + " listener.asBinder=" + listener.asBinder());
3515         }
3516 
3517         synchronized (mRecords) {
3518             final IBinder b = listener.asBinder();
3519             boolean doesLimitApply = doesLimitApplyForListeners(Binder.getCallingUid(),
3520                     Process.myUid());
3521             Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply);
3522 
3523             if (r == null) {
3524                 loge("addSatelliteStateChangeListener: can not create Record instance!");
3525                 return;
3526             }
3527 
3528             r.context = mContext;
3529             r.satelliteStateChangeListener = listener;
3530             r.callingPackage = pkg;
3531             r.callingFeatureId = featureId;
3532             r.callerUid = Binder.getCallingUid();
3533             r.callerPid = Binder.getCallingPid();
3534             r.eventList = new ArraySet<>();
3535             if (DBG) {
3536                 log("addSatelliteStateChangeListener:  Register r=" + r);
3537             }
3538 
3539             // Always notify registrants on registration if it has been notified before
3540             if (mWasSatelliteEnabledNotified.get() && r.matchSatelliteStateChangeListener()) {
3541                 try {
3542                     r.satelliteStateChangeListener.onSatelliteEnabledStateChanged(
3543                             mIsSatelliteEnabled.get());
3544                 } catch (RemoteException e) {
3545                     throw new RuntimeException(e);
3546                 }
3547             }
3548         }
3549     }
3550 
3551     @Override
removeSatelliteStateChangeListener(@onNull ISatelliteStateChangeListener listener, @NonNull String pkg)3552     public void removeSatelliteStateChangeListener(@NonNull ISatelliteStateChangeListener listener,
3553             @NonNull String pkg) {
3554         if (DBG) log("removeSatelliteStateChangeListener listener=" + listener + ", pkg=" + pkg);
3555         mAppOps.checkPackage(Binder.getCallingUid(), pkg);
3556         enforceCallingOrSelfAtLeastReadBasicPhoneStatePermission(pkg, null,
3557                 "removeSatelliteStateChangeListener");
3558         remove(listener.asBinder());
3559     }
3560 
3561     @Override
notifySatelliteStateChanged(boolean isEnabled)3562     public void notifySatelliteStateChanged(boolean isEnabled) {
3563         if (!checkNotifyPermission("notifySatelliteStateChanged")) {
3564             loge("notifySatelliteStateChanged: Caller has no notify permission!");
3565             return;
3566         }
3567         if (VDBG) {
3568             log("notifySatelliteStateChanged: isEnabled=" + isEnabled);
3569         }
3570 
3571         mWasSatelliteEnabledNotified.set(true);
3572         mIsSatelliteEnabled.set(isEnabled);
3573 
3574         synchronized (mRecords) {
3575             mRemoveList.clear();
3576             for (Record r : mRecords) {
3577                 // Listeners are "global", neither per-slot nor per-sub, so no idMatch check here
3578                 if (!r.matchSatelliteStateChangeListener()) {
3579                     continue;
3580                 }
3581                 try {
3582                     r.satelliteStateChangeListener.onSatelliteEnabledStateChanged(isEnabled);
3583                 } catch (RemoteException re) {
3584                     mRemoveList.add(r.binder);
3585                 }
3586             }
3587             handleRemoveListLocked();
3588         }
3589     }
3590 
3591     @Override
notifyMediaQualityStatusChanged(int phoneId, int subId, MediaQualityStatus status)3592     public void notifyMediaQualityStatusChanged(int phoneId, int subId, MediaQualityStatus status) {
3593         if (!checkNotifyPermission("notifyMediaQualityStatusChanged()")) {
3594             return;
3595         }
3596 
3597         synchronized (mRecords) {
3598             if (validatePhoneId(phoneId)) {
3599                 if (mCallStateLists.get(phoneId).size() > 0) {
3600                     CallState callState = null;
3601                     for (CallState cs : mCallStateLists.get(phoneId)) {
3602                         if (cs.getCallState() == PreciseCallState.PRECISE_CALL_STATE_ACTIVE) {
3603                             callState = cs;
3604                             break;
3605                         }
3606                     }
3607                     if (callState != null) {
3608                         String callSessionId = callState.getImsCallSessionId();
3609                         if (callSessionId != null
3610                                 && callSessionId.equals(status.getCallSessionId())) {
3611                             mMediaQualityStatus.get(phoneId)
3612                                     .put(status.getMediaSessionType(), status);
3613                         } else {
3614                             log("SessionId mismatch active call:" + callSessionId
3615                                     + " media quality:" + status.getCallSessionId());
3616                             return;
3617                         }
3618                     } else {
3619                         log("There is no active call to report CallQaulity");
3620                         return;
3621                     }
3622                 }
3623 
3624                 for (Record r : mRecords) {
3625                     if (r.matchTelephonyCallbackEvent(
3626                             TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED)
3627                             && idMatch(r, subId, phoneId)) {
3628                         try {
3629                             r.callback.onMediaQualityStatusChanged(status);
3630                         } catch (RemoteException ex) {
3631                             mRemoveList.add(r.binder);
3632                         }
3633                     }
3634                 }
3635             }
3636             handleRemoveListLocked();
3637         }
3638     }
3639 
3640     @Override
notifyCallbackModeStarted(int phoneId, int subId, int type, long durationMillis)3641     public void notifyCallbackModeStarted(int phoneId, int subId, int type, long durationMillis) {
3642         if (!checkNotifyPermission("notifyCallbackModeStarted()")) return;
3643 
3644         if (VDBG) {
3645             log("notifyCallbackModeStarted: phoneId=" + phoneId + ", subId=" + subId
3646                     + ", type=" + type);
3647         }
3648         synchronized (mRecords) {
3649             if (validatePhoneId(phoneId)) {
3650                 if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) {
3651                     mECBMDuration[phoneId] = durationMillis;
3652                 } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) {
3653                     mSCBMDuration[phoneId] = durationMillis;
3654                 }
3655             }
3656             for (Record r : mRecords) {
3657                 // Send to all listeners regardless of subscription
3658                 if (r.matchTelephonyCallbackEvent(
3659                         TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) {
3660                     try {
3661                         r.callback.onCallbackModeStarted(type, durationMillis, subId);
3662                     } catch (RemoteException ex) {
3663                         mRemoveList.add(r.binder);
3664                     }
3665                 }
3666             }
3667         }
3668         handleRemoveListLocked();
3669     }
3670 
3671     @Override
notifyCallbackModeRestarted(int phoneId, int subId, int type, long durationMillis)3672     public void notifyCallbackModeRestarted(int phoneId, int subId, int type,
3673             long durationMillis) {
3674         if (!checkNotifyPermission("notifyCallbackModeRestarted()")) return;
3675 
3676         if (VDBG) {
3677             log("notifyCallbackModeRestarted: phoneId=" + phoneId + ", subId=" + subId
3678                     + ", type=" + type);
3679         }
3680         synchronized (mRecords) {
3681             if (validatePhoneId(phoneId)) {
3682                 if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) {
3683                     mECBMDuration[phoneId] = durationMillis;
3684                 } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) {
3685                     mSCBMDuration[phoneId] = durationMillis;
3686                 }
3687             }
3688             for (Record r : mRecords) {
3689                 // Send to all listeners regardless of subscription
3690                 if (r.matchTelephonyCallbackEvent(
3691                         TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) {
3692                     try {
3693                         r.callback.onCallbackModeRestarted(type, durationMillis, subId);
3694                     } catch (RemoteException ex) {
3695                         mRemoveList.add(r.binder);
3696                     }
3697                 }
3698             }
3699         }
3700         handleRemoveListLocked();
3701     }
3702 
3703     @Override
notifyCallbackModeStopped(int phoneId, int subId, int type, int reason)3704     public void notifyCallbackModeStopped(int phoneId, int subId, int type, int reason) {
3705         if (!checkNotifyPermission("notifyCallbackModeStopped()")) return;
3706 
3707         if (VDBG) {
3708             log("notifyCallbackModeStopped: phoneId=" + phoneId + ", subId=" + subId
3709                     + ", type=" + type + ", reason=" + reason);
3710         }
3711         synchronized (mRecords) {
3712             if (validatePhoneId(phoneId)) {
3713                 if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL) {
3714                     mECBMReason[phoneId] = reason;
3715                     mECBMDuration[phoneId] = 0;
3716                 } else if (type == TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS) {
3717                     mSCBMReason[phoneId] = reason;
3718                     mSCBMDuration[phoneId] = 0;
3719                 }
3720             }
3721             for (Record r : mRecords) {
3722                 // Send to all listeners regardless of subscription
3723                 if (r.matchTelephonyCallbackEvent(
3724                         TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED)) {
3725                     try {
3726                         r.callback.onCallbackModeStopped(type, reason, subId);
3727                     } catch (RemoteException ex) {
3728                         mRemoveList.add(r.binder);
3729                     }
3730                 }
3731             }
3732         }
3733         handleRemoveListLocked();
3734     }
3735 
3736     /**
3737      * Notify external listeners that carrier roaming non-terrestrial network mode changed.
3738      * @param subId subscription ID.
3739      * @param active {@code true} If the device is connected to carrier roaming
3740      *                           non-terrestrial network or was connected within the
3741      *                           {CarrierConfigManager#KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT}
3742      *                           duration, {code false} otherwise.
3743      */
notifyCarrierRoamingNtnModeChanged(int subId, boolean active)3744     public void notifyCarrierRoamingNtnModeChanged(int subId, boolean active) {
3745         if (!checkNotifyPermission("notifyCarrierRoamingNtnModeChanged")) {
3746             return;
3747         }
3748 
3749         if (VDBG) {
3750             log("notifyCarrierRoamingNtnModeChanged: subId=" + subId + " active=" + active);
3751         }
3752 
3753         synchronized (mRecords) {
3754             int phoneId = getPhoneIdFromSubId(subId);
3755             if (!validatePhoneId(phoneId)) {
3756                 loge("Invalid phone ID " + phoneId + " for " + subId);
3757                 return;
3758             }
3759             mCarrierRoamingNtnMode[phoneId] = active;
3760             for (Record r : mRecords) {
3761                 if (r.matchTelephonyCallbackEvent(
3762                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_MODE_CHANGED)
3763                         && idMatch(r, subId, phoneId)) {
3764                     try {
3765                         r.callback.onCarrierRoamingNtnModeChanged(active);
3766                     } catch (RemoteException ex) {
3767                         mRemoveList.add(r.binder);
3768                     }
3769                 }
3770             }
3771             handleRemoveListLocked();
3772         }
3773     }
3774 
3775     /**
3776      * Notify external listeners that device eligibility to connect to carrier roaming
3777      * non-terrestrial network changed.
3778      *
3779      * @param subId subscription ID.
3780      * @param eligible {@code true} when the device is eligible for satellite
3781      * communication if all the following conditions are met:
3782      * <ul>
3783      * <li>Any subscription on the device supports P2P satellite messaging which is defined by
3784      * {@link CarrierConfigManager#KEY_SATELLITE_ATTACH_SUPPORTED_BOOL} </li>
3785      * <li>{@link CarrierConfigManager#KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT} set to
3786      * {@link CarrierConfigManager#CARRIER_ROAMING_NTN_CONNECT_MANUAL} </li>
3787      * <li>The device is in {@link ServiceState#STATE_OUT_OF_SERVICE}, not connected to Wi-Fi,
3788      * and the hysteresis timer defined by {@link CarrierConfigManager
3789      * #KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT} is expired. </li>
3790      * </ul>
3791      */
notifyCarrierRoamingNtnEligibleStateChanged(int subId, boolean eligible)3792     public void notifyCarrierRoamingNtnEligibleStateChanged(int subId, boolean eligible) {
3793         if (!checkNotifyPermission("notifyCarrierRoamingNtnEligibleStateChanged")) {
3794             log("notifyCarrierRoamingNtnEligibleStateChanged: caller does not have required "
3795                     + "permissions.");
3796             return;
3797         }
3798 
3799         if (VDBG) {
3800             log("notifyCarrierRoamingNtnEligibleStateChanged: "
3801                     + "subId=" + subId + " eligible" + eligible);
3802         }
3803 
3804         synchronized (mRecords) {
3805             int phoneId = getPhoneIdFromSubId(subId);
3806             if (!validatePhoneId(phoneId)) {
3807                 loge("Invalid phone ID " + phoneId + " for " + subId);
3808                 return;
3809             }
3810             mCarrierRoamingNtnEligible[phoneId] = eligible;
3811             for (Record r : mRecords) {
3812                 if (r.matchTelephonyCallbackEvent(
3813                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_ELIGIBLE_STATE_CHANGED)
3814                         && idMatch(r, subId, phoneId)) {
3815                     try {
3816                         r.callback.onCarrierRoamingNtnEligibleStateChanged(eligible);
3817                     } catch (RemoteException ex) {
3818                         mRemoveList.add(r.binder);
3819                     }
3820                 }
3821             }
3822             handleRemoveListLocked();
3823         }
3824     }
3825 
3826     /**
3827      * Notify external listeners that carrier roaming non-terrestrial available services changed.
3828      * @param availableServices The list of the supported services.
3829      */
notifyCarrierRoamingNtnAvailableServicesChanged( int subId, @NetworkRegistrationInfo.ServiceType int[] availableServices)3830     public void notifyCarrierRoamingNtnAvailableServicesChanged(
3831             int subId, @NetworkRegistrationInfo.ServiceType int[] availableServices) {
3832         if (!checkNotifyPermission("notifyCarrierRoamingNtnEligibleStateChanged")) {
3833             log("notifyCarrierRoamingNtnAvailableServicesChanged: caller does not have required "
3834                     + "permissions.");
3835             return;
3836         }
3837 
3838         if (VDBG) {
3839             log("notifyCarrierRoamingNtnAvailableServicesChanged: "
3840                     + "availableServices=" + Arrays.toString(availableServices));
3841         }
3842 
3843         synchronized (mRecords) {
3844             int phoneId = getPhoneIdFromSubId(subId);
3845             if (!validatePhoneId(phoneId)) {
3846                 loge("Invalid phone ID " + phoneId + " for " + subId);
3847                 return;
3848             }
3849             IntArray availableServicesIntArray = new IntArray(availableServices.length);
3850             availableServicesIntArray.addAll(availableServices);
3851             mCarrierRoamingNtnAvailableServices.set(phoneId, availableServicesIntArray);
3852             for (Record r : mRecords) {
3853                 if (r.matchTelephonyCallbackEvent(
3854                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_AVAILABLE_SERVICES_CHANGED)
3855                         && idMatch(r, subId, phoneId)) {
3856                     try {
3857                         r.callback.onCarrierRoamingNtnAvailableServicesChanged(availableServices);
3858                     } catch (RemoteException ex) {
3859                         mRemoveList.add(r.binder);
3860                     }
3861                 }
3862             }
3863             handleRemoveListLocked();
3864         }
3865     }
3866 
3867     /**
3868      * Notify external listeners that carrier roaming non-terrestrial network
3869      * signal strength changed.
3870      * @param subId subscription ID.
3871      * @param ntnSignalStrength non-terrestrial network signal strength.
3872      */
notifyCarrierRoamingNtnSignalStrengthChanged(int subId, @NonNull NtnSignalStrength ntnSignalStrength)3873     public void notifyCarrierRoamingNtnSignalStrengthChanged(int subId,
3874             @NonNull NtnSignalStrength ntnSignalStrength) {
3875         if (!checkNotifyPermission("notifyCarrierRoamingNtnSignalStrengthChanged")) {
3876             log("notifyCarrierRoamingNtnSignalStrengthChanged: caller does not have required "
3877                     + "permissions.");
3878             return;
3879         }
3880 
3881         if (VDBG) {
3882             log("notifyCarrierRoamingNtnSignalStrengthChanged: "
3883                     + "subId=" + subId + " ntnSignalStrength=" + ntnSignalStrength.getLevel());
3884         }
3885 
3886         synchronized (mRecords) {
3887             int phoneId = getPhoneIdFromSubId(subId);
3888             mCarrierRoamingNtnSignalStrength[phoneId] = ntnSignalStrength;
3889             for (Record r : mRecords) {
3890                 if (r.matchTelephonyCallbackEvent(
3891                         TelephonyCallback.EVENT_CARRIER_ROAMING_NTN_SIGNAL_STRENGTH_CHANGED)
3892                         && idMatch(r, subId, phoneId)) {
3893                     try {
3894                         r.callback.onCarrierRoamingNtnSignalStrengthChanged(ntnSignalStrength);
3895                     } catch (RemoteException ex) {
3896                         mRemoveList.add(r.binder);
3897                     }
3898                 }
3899             }
3900             handleRemoveListLocked();
3901         }
3902     }
3903 
3904     /**
3905      * Notify that the radio security algorithms have changed.
3906      *
3907      * @param phoneId the phone id.
3908      * @param subId the subId.
3909      * @param update the security algorithm update.
3910      */
notifySecurityAlgorithmsChanged(int phoneId, int subId, SecurityAlgorithmUpdate update)3911     public void notifySecurityAlgorithmsChanged(int phoneId, int subId,
3912             SecurityAlgorithmUpdate update) {
3913         if (!Flags.securityAlgorithmsUpdateIndications()) {
3914             log("Not available due to securityAlgorithmsUpdateIndications() flag");
3915             return;
3916         }
3917         if (!checkNotifyPermission("notifySecurityAlgorithmChanged()")) {
3918             return;
3919         }
3920 
3921         synchronized (mRecords) {
3922             if (validatePhoneId(phoneId)) {
3923                 if (update == null) {
3924                     loge("SecurityAlgorithmUpdate is null, subId=" + subId
3925                             + ", phoneId=" + phoneId);
3926                     // Listeners shouldn't be updated for null updates.
3927                     return;
3928                 }
3929 
3930                 for (Record r : mRecords) {
3931                     if (r.matchTelephonyCallbackEvent(
3932                             TelephonyCallback.EVENT_SECURITY_ALGORITHMS_CHANGED)
3933                             && idMatch(r, subId, phoneId)) {
3934                         try {
3935                             if (VDBG) {
3936                                 log("notifySecurityAlgorithmsChanged: securityAlgorithmUpdate= "
3937                                         + update);
3938                             }
3939                             r.callback.onSecurityAlgorithmsChanged(update);
3940                         } catch (RemoteException ex) {
3941                             mRemoveList.add(r.binder);
3942                         }
3943                     }
3944                 }
3945             }
3946             handleRemoveListLocked();
3947         }
3948     }
3949 
3950     /**
3951      * Notify of a cellular identifier disclosure.
3952      *
3953      * @param phoneId the phone id.
3954      * @param subId the subId.
3955      * @param disclosure the cellular identifier disclosure.
3956      */
notifyCellularIdentifierDisclosedChanged(int phoneId, int subId, @NonNull CellularIdentifierDisclosure disclosure)3957     public void notifyCellularIdentifierDisclosedChanged(int phoneId, int subId,
3958             @NonNull CellularIdentifierDisclosure disclosure) {
3959         if (!Flags.cellularIdentifierDisclosureIndications()) {
3960             log("Not available due to cellularIdentifierDisclosureIndications() flag");
3961             return;
3962         }
3963         if (!checkNotifyPermission("notifyCellularIdentifierDisclosedChanged()")) {
3964             return;
3965         }
3966 
3967         synchronized (mRecords) {
3968             if (validatePhoneId(phoneId)) {
3969                 if (disclosure == null) {
3970                     loge("CellularIdentifierDisclosure is null, subId=" + subId
3971                             + ", phoneId=" + phoneId);
3972                     // Listeners shouldn't be updated for null disclosures.
3973                     return;
3974                 }
3975 
3976                 for (Record r : mRecords) {
3977                     if (r.matchTelephonyCallbackEvent(
3978                             TelephonyCallback.EVENT_CELLULAR_IDENTIFIER_DISCLOSED_CHANGED)
3979                             && idMatch(r, subId, phoneId)) {
3980                         try {
3981                             if (VDBG) {
3982                                 log("notifyCellularIdentifierDisclosedChanged: disclosure= "
3983                                         + disclosure);
3984                             }
3985                             r.callback.onCellularIdentifierDisclosedChanged(disclosure);
3986                         } catch (RemoteException ex) {
3987                             mRemoveList.add(r.binder);
3988                         }
3989                     }
3990                 }
3991             }
3992             handleRemoveListLocked();
3993         }
3994     }
3995 
3996     @NeverCompile // Avoid size overhead of debugging code.
3997     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)3998     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
3999         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
4000 
4001         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
4002 
4003         synchronized (mRecords) {
4004             final int recordCount = mRecords.size();
4005             pw.println("last known state:");
4006             pw.increaseIndent();
4007             for (int i = 0; i < getTelephonyManager().getActiveModemCount(); i++) {
4008                 pw.println("Phone Id=" + i);
4009                 pw.increaseIndent();
4010                 pw.println("mCallState=" + mCallState[i]);
4011                 pw.println("mRingingCallState=" + mRingingCallState[i]);
4012                 pw.println("mForegroundCallState=" + mForegroundCallState[i]);
4013                 pw.println("mBackgroundCallState=" + mBackgroundCallState[i]);
4014                 pw.println("mPreciseCallState=" + mPreciseCallState[i]);
4015                 pw.println("mCallDisconnectCause=" + mCallDisconnectCause[i]);
4016                 pw.println("mCallIncomingNumber=" + mCallIncomingNumber[i]);
4017                 pw.println("mServiceState=" + mServiceState[i]);
4018                 pw.println("mVoiceActivationState= " + mVoiceActivationState[i]);
4019                 pw.println("mDataActivationState= " + mDataActivationState[i]);
4020                 pw.println("mUserMobileDataState= " + mUserMobileDataState[i]);
4021                 pw.println("mSignalStrength=" + mSignalStrength[i]);
4022                 pw.println("mMessageWaiting=" + mMessageWaiting[i]);
4023                 pw.println("mCallForwarding=" + mCallForwarding[i]);
4024                 pw.println("mDataActivity=" + mDataActivity[i]);
4025                 pw.println("mDataConnectionState=" + mDataConnectionState[i]);
4026                 pw.println("mCellIdentity=" + mCellIdentity[i]);
4027                 pw.println("mCellInfo=" + mCellInfo.get(i));
4028                 pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i));
4029                 pw.println("mSrvccState=" + mSrvccState[i]);
4030                 pw.println("mCallPreciseDisconnectCause=" + mCallPreciseDisconnectCause[i]);
4031                 pw.println("mCallQuality=" + mCallQuality[i]);
4032                 pw.println("mCallNetworkType=" + mCallNetworkType[i]);
4033                 pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i));
4034                 pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
4035                 pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
4036                 pw.println("mBarringInfo=" + mBarringInfo.get(i));
4037                 pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState[i]);
4038                 pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]);
4039                 pw.println("mIsDataEnabled=" + mIsDataEnabled[i]);
4040                 pw.println("mDataEnabledReason=" + mDataEnabledReason[i]);
4041                 pw.println("mAllowedNetworkTypeReason=" + mAllowedNetworkTypeReason[i]);
4042                 pw.println("mAllowedNetworkTypeValue=" + mAllowedNetworkTypeValue[i]);
4043                 pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs.get(i));
4044                 pw.println("mLinkCapacityEstimateList=" + mLinkCapacityEstimateLists.get(i));
4045                 pw.println("mECBMReason=" + mECBMReason[i]);
4046                 pw.println("mECBMDuration=" + mECBMDuration[i]);
4047                 pw.println("mSCBMReason=" + mSCBMReason[i]);
4048                 pw.println("mSCBMDuration=" + mSCBMDuration[i]);
4049                 pw.println("mCarrierRoamingNtnMode=" + mCarrierRoamingNtnMode[i]);
4050                 pw.println("mCarrierRoamingNtnEligible=" + mCarrierRoamingNtnEligible[i]);
4051                 pw.println("mCarrierRoamingNtnSignalStrength="
4052                         + mCarrierRoamingNtnSignalStrength[i]);
4053 
4054                 // We need to obfuscate package names, and primitive arrays' native toString is ugly
4055                 Pair<List<String>, int[]> carrierPrivilegeState = mCarrierPrivilegeStates.get(i);
4056                 pw.println(
4057                         "mCarrierPrivilegeState=<packages=" + pii(carrierPrivilegeState.first)
4058                                 + ", uids=" + Arrays.toString(carrierPrivilegeState.second) + ">");
4059                 Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(i);
4060                 pw.println("mCarrierServiceState=<package=" + pii(carrierServiceState.first)
4061                         + ", uid=" + carrierServiceState.second + ">");
4062                 pw.println("mCarrierRoamingNtnAvailableServices="
4063                         + mCarrierRoamingNtnAvailableServices.get(i));
4064                 pw.decreaseIndent();
4065             }
4066 
4067             pw.println("mPhoneCapability=" + mPhoneCapability);
4068             pw.println("mActiveDataSubId=" + mActiveDataSubId);
4069             pw.println("mRadioPowerState=" + mRadioPowerState);
4070             pw.println("mEmergencyNumberList=" + mEmergencyNumberList);
4071             pw.println("mDefaultPhoneId=" + mDefaultPhoneId);
4072             pw.println("mDefaultSubId=" + mDefaultSubId);
4073 
4074             pw.decreaseIndent();
4075 
4076             pw.println("local logs:");
4077             pw.increaseIndent();
4078             mLocalLog.dump(fd, pw, args);
4079             pw.decreaseIndent();
4080             pw.println("listen logs:");
4081             pw.increaseIndent();
4082             mListenLog.dump(fd, pw, args);
4083             pw.decreaseIndent();
4084             pw.println("registrations: count=" + recordCount);
4085             pw.increaseIndent();
4086             for (Record r : mRecords) {
4087                 pw.println(r);
4088             }
4089             pw.decreaseIndent();
4090         }
4091     }
4092 
4093     //
4094     // the legacy intent broadcasting
4095     //
4096 
4097     // Legacy intent action.
4098     /** Fired when a subscription's phone state changes. */
4099     private static final String ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED =
4100             "android.intent.action.SUBSCRIPTION_PHONE_STATE";
4101     /**
4102      * Broadcast Action: The data connection state has changed for any one of the
4103      * phone's mobile data connections (eg, default, MMS or GPS specific connection).
4104      */
4105     private static final String ACTION_ANY_DATA_CONNECTION_STATE_CHANGED =
4106             "android.intent.action.ANY_DATA_STATE";
4107 
4108     // Legacy intent extra keys, copied from PhoneConstants.
4109     // Used in legacy intents sent here, for backward compatibility.
4110     private static final String PHONE_CONSTANTS_DATA_APN_TYPE_KEY = "apnType";
4111     private static final String PHONE_CONSTANTS_DATA_APN_KEY = "apn";
4112     private static final String PHONE_CONSTANTS_SLOT_KEY = "slot";
4113     private static final String PHONE_CONSTANTS_STATE_KEY = "state";
4114     private static final String PHONE_CONSTANTS_SUBSCRIPTION_KEY = "subscription";
4115 
4116     /**
4117      * Broadcast Action: The phone's signal strength has changed. The intent will have the
4118      * following extra values:
4119      *   phoneName - A string version of the phone name.
4120      *   asu - A numeric value for the signal strength.
4121      *         An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
4122      *         The following special values are defined:
4123      *         0 means "-113 dBm or less".31 means "-51 dBm or greater".
4124      */
4125     public static final String ACTION_SIGNAL_STRENGTH_CHANGED = "android.intent.action.SIG_STR";
4126 
broadcastServiceStateChanged(ServiceState state, int phoneId, int subId)4127     private void broadcastServiceStateChanged(ServiceState state, int phoneId, int subId) {
4128         try {
4129             mBatteryStats.notePhoneState(state.getState());
4130         } catch (RemoteException re) {
4131             // Can't do much
4132         }
4133 
4134         // Send the broadcast exactly once to all possible disjoint sets of apps.
4135         // If the location master switch is on, broadcast the ServiceState 4 times:
4136         // - Full ServiceState sent to apps with ACCESS_FINE_LOCATION and READ_PHONE_STATE
4137         // - Full ServiceState sent to apps with ACCESS_FINE_LOCATION and
4138         //   READ_PRIVILEGED_PHONE_STATE but not READ_PHONE_STATE
4139         // - Sanitized ServiceState sent to apps with READ_PHONE_STATE but not ACCESS_FINE_LOCATION
4140         // - Sanitized ServiceState sent to apps with READ_PRIVILEGED_PHONE_STATE but neither
4141         //   READ_PHONE_STATE nor ACCESS_FINE_LOCATION
4142         // If the location master switch is off, broadcast the ServiceState multiple times:
4143         // - Full ServiceState sent to all apps permitted to bypass the location master switch if
4144         //   they have either READ_PHONE_STATE or READ_PRIVILEGED_PHONE_STATE
4145         // - Sanitized ServiceState sent to all other apps with READ_PHONE_STATE
4146         // - Sanitized ServiceState sent to all other apps with READ_PRIVILEGED_PHONE_STATE but not
4147         //   READ_PHONE_STATE
4148         //
4149         // Create a unique delivery group key for each variant for SERVICE_STATE broadcast so
4150         // that a new broadcast only replaces the pending broadcasts of the same variant.
4151         // In order to create a unique delivery group key, append tag of the form
4152         // "I:Included-permissions[,E:Excluded-permissions][,lbp]"
4153         // Note: Given that location-bypass-packages are static, we can just append "lbp" to the
4154         // tag to create a unique delivery group but if location-bypass-packages become dynamic
4155         // in the future, we would need to create a unique key for each group of
4156         // location-bypass-packages.
4157         if (LocationAccessPolicy.isLocationModeEnabled(mContext, mContext.getUserId())) {
4158             Intent fullIntent = createServiceStateIntent(state, subId, phoneId, false);
4159             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4160                     fullIntent,
4161                     new String[]{Manifest.permission.READ_PHONE_STATE,
4162                             Manifest.permission.ACCESS_FINE_LOCATION},
4163                     createServiceStateBroadcastOptions(subId, phoneId, "I:RA"));
4164             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4165                     fullIntent,
4166                     new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4167                             Manifest.permission.ACCESS_FINE_LOCATION},
4168                     new String[]{Manifest.permission.READ_PHONE_STATE},
4169                     null,
4170                     createServiceStateBroadcastOptions(subId, phoneId, "I:RPA,E:R"));
4171 
4172             Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true);
4173             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4174                     sanitizedIntent,
4175                     new String[]{Manifest.permission.READ_PHONE_STATE},
4176                     new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
4177                     null,
4178                     createServiceStateBroadcastOptions(subId, phoneId, "I:R,E:A"));
4179             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4180                     sanitizedIntent,
4181                     new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
4182                     new String[]{Manifest.permission.READ_PHONE_STATE,
4183                             Manifest.permission.ACCESS_FINE_LOCATION},
4184                     null,
4185                     createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:RA"));
4186         } else {
4187             String[] locationBypassPackages = Binder.withCleanCallingIdentity(() ->
4188                     LocationAccessPolicy.getLocationBypassPackages(mContext));
4189             for (String locationBypassPackage : locationBypassPackages) {
4190                 Intent fullIntent = createServiceStateIntent(state, subId, phoneId, false);
4191                 fullIntent.setPackage(locationBypassPackage);
4192                 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4193                         fullIntent,
4194                         new String[]{Manifest.permission.READ_PHONE_STATE},
4195                         createServiceStateBroadcastOptions(subId, phoneId, "I:R"));
4196                 mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4197                         fullIntent,
4198                         new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
4199                         new String[]{Manifest.permission.READ_PHONE_STATE},
4200                         null,
4201                         createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:R"));
4202             }
4203 
4204             Intent sanitizedIntent = createServiceStateIntent(state, subId, phoneId, true);
4205             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4206                     sanitizedIntent,
4207                     new String[]{Manifest.permission.READ_PHONE_STATE},
4208                     new String[]{/* no excluded permissions */},
4209                     locationBypassPackages,
4210                     createServiceStateBroadcastOptions(subId, phoneId, "I:R,lbp"));
4211             mContext.createContextAsUser(UserHandle.ALL, 0).sendBroadcastMultiplePermissions(
4212                     sanitizedIntent,
4213                     new String[]{Manifest.permission.READ_PRIVILEGED_PHONE_STATE},
4214                     new String[]{Manifest.permission.READ_PHONE_STATE},
4215                     locationBypassPackages,
4216                     createServiceStateBroadcastOptions(subId, phoneId, "I:RP,E:R,lbp"));
4217         }
4218     }
4219 
createServiceStateIntent(ServiceState state, int subId, int phoneId, boolean sanitizeLocation)4220     private Intent createServiceStateIntent(ServiceState state, int subId, int phoneId,
4221             boolean sanitizeLocation) {
4222         Intent intent = new Intent(Intent.ACTION_SERVICE_STATE);
4223         intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4224         Bundle data = new Bundle();
4225         if (sanitizeLocation) {
4226             state.createLocationInfoSanitizedCopy(true).fillInNotifierBundle(data);
4227         } else {
4228             state.fillInNotifierBundle(data);
4229         }
4230         intent.putExtras(data);
4231         intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
4232         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
4233         intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId);
4234         intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId);
4235         return intent;
4236     }
4237 
createServiceStateBroadcastOptions(int subId, int phoneId, String tag)4238     private BroadcastOptions createServiceStateBroadcastOptions(int subId, int phoneId,
4239             String tag) {
4240         return new BroadcastOptions()
4241                 .setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT)
4242                 // Use a combination of subId and phoneId as the key so that older broadcasts
4243                 // with same subId and phoneId will get discarded.
4244                 .setDeliveryGroupMatchingKey(Intent.ACTION_SERVICE_STATE,
4245                         subId + "-" + phoneId + "-" + tag)
4246                 .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
4247     }
4248 
broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId, int subId)4249     private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int phoneId,
4250             int subId) {
4251         final long ident = Binder.clearCallingIdentity();
4252         try {
4253             mBatteryStats.notePhoneSignalStrength(signalStrength);
4254         } catch (RemoteException e) {
4255             /* The remote entity disappeared, we can safely ignore the exception. */
4256         } finally {
4257             Binder.restoreCallingIdentity(ident);
4258         }
4259 
4260         Intent intent = new Intent(ACTION_SIGNAL_STRENGTH_CHANGED);
4261         Bundle data = new Bundle();
4262         fillInSignalStrengthNotifierBundle(signalStrength, data);
4263         intent.putExtras(data);
4264         intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
4265         intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId);
4266         mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
4267     }
4268 
fillInSignalStrengthNotifierBundle(SignalStrength signalStrength, Bundle bundle)4269     private void fillInSignalStrengthNotifierBundle(SignalStrength signalStrength, Bundle bundle) {
4270         List<CellSignalStrength> cellSignalStrengths = signalStrength.getCellSignalStrengths();
4271         for (CellSignalStrength cellSignalStrength : cellSignalStrengths) {
4272             if (cellSignalStrength instanceof CellSignalStrengthLte) {
4273                 bundle.putParcelable("Lte", (CellSignalStrengthLte) cellSignalStrength);
4274             } else if (cellSignalStrength instanceof CellSignalStrengthCdma) {
4275                 bundle.putParcelable("Cdma", (CellSignalStrengthCdma) cellSignalStrength);
4276             } else if (cellSignalStrength instanceof CellSignalStrengthGsm) {
4277                 bundle.putParcelable("Gsm", (CellSignalStrengthGsm) cellSignalStrength);
4278             } else if (cellSignalStrength instanceof CellSignalStrengthWcdma) {
4279                 bundle.putParcelable("Wcdma", (CellSignalStrengthWcdma) cellSignalStrength);
4280             } else if (cellSignalStrength instanceof CellSignalStrengthTdscdma) {
4281                 bundle.putParcelable("Tdscdma", (CellSignalStrengthTdscdma) cellSignalStrength);
4282             } else if (cellSignalStrength instanceof CellSignalStrengthNr) {
4283                 bundle.putParcelable("Nr", (CellSignalStrengthNr) cellSignalStrength);
4284             }
4285         }
4286     }
4287 
4288     /**
4289      * Broadcasts an intent notifying apps of a phone state change. {@code subId} can be
4290      * a valid subId, in which case this function fires a subId-specific intent, or it
4291      * can be {@code SubscriptionManager.INVALID_SUBSCRIPTION_ID}, in which case we send
4292      * a global state change broadcast ({@code TelephonyManager.ACTION_PHONE_STATE_CHANGED}).
4293      */
broadcastCallStateChanged(int state, String incomingNumber, int phoneId, int subId)4294     private void broadcastCallStateChanged(int state, String incomingNumber, int phoneId,
4295                 int subId) {
4296         final long ident = Binder.clearCallingIdentity();
4297         try {
4298             if (state == TelephonyManager.CALL_STATE_IDLE) {
4299                 mBatteryStats.notePhoneOff();
4300                 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_STATE_CHANGED,
4301                         FrameworkStatsLog.PHONE_STATE_CHANGED__STATE__OFF);
4302             } else {
4303                 mBatteryStats.notePhoneOn();
4304                 FrameworkStatsLog.write(FrameworkStatsLog.PHONE_STATE_CHANGED,
4305                         FrameworkStatsLog.PHONE_STATE_CHANGED__STATE__ON);
4306             }
4307         } catch (RemoteException e) {
4308             /* The remote entity disappeared, we can safely ignore the exception. */
4309         } finally {
4310             Binder.restoreCallingIdentity(ident);
4311         }
4312 
4313         Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
4314         intent.putExtra(TelephonyManager.EXTRA_STATE, callStateToString(state));
4315 
4316         // If a valid subId was specified, we should fire off a subId-specific state
4317         // change intent and include the subId.
4318         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4319             intent.setAction(ACTION_SUBSCRIPTION_PHONE_STATE_CHANGED);
4320             intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
4321             intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
4322         }
4323         // If the phoneId is invalid, the broadcast is for overall call state.
4324         if (phoneId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4325             intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, phoneId);
4326             intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId);
4327         }
4328 
4329         // Wakeup apps for the (SUBSCRIPTION_)PHONE_STATE broadcast.
4330         intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
4331 
4332         // Create a version of the intent with the number always populated.
4333         Intent intentWithPhoneNumber = new Intent(intent);
4334         intentWithPhoneNumber.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
4335 
4336         // Send broadcast twice, once for apps that have PRIVILEGED permission and once for those
4337         // that have the runtime one
4338         mContext.sendBroadcastAsUser(intentWithPhoneNumber, UserHandle.ALL,
4339                 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
4340         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
4341                 android.Manifest.permission.READ_PHONE_STATE,
4342                 AppOpsManager.OP_READ_PHONE_STATE);
4343         mContext.sendBroadcastAsUserMultiplePermissions(intentWithPhoneNumber, UserHandle.ALL,
4344                 new String[] { android.Manifest.permission.READ_PHONE_STATE,
4345                         android.Manifest.permission.READ_CALL_LOG});
4346     }
4347 
4348     /** Converts TelephonyManager#CALL_STATE_* to TelephonyManager#EXTRA_STATE_*. */
callStateToString(int callState)4349     private static String callStateToString(int callState) {
4350         switch (callState) {
4351             case TelephonyManager.CALL_STATE_RINGING:
4352                 return TelephonyManager.EXTRA_STATE_RINGING;
4353             case TelephonyManager.CALL_STATE_OFFHOOK:
4354                 return TelephonyManager.EXTRA_STATE_OFFHOOK;
4355             default:
4356                 return TelephonyManager.EXTRA_STATE_IDLE;
4357         }
4358     }
4359 
broadcastDataConnectionStateChanged(int slotIndex, int subId, @NonNull PreciseDataConnectionState pdcs)4360     private void broadcastDataConnectionStateChanged(int slotIndex, int subId,
4361             @NonNull PreciseDataConnectionState pdcs) {
4362         // Note: not reporting to the battery stats service here, because the
4363         // status bar takes care of that after taking into account all of the
4364         // required info.
4365         Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
4366         intent.putExtra(PHONE_CONSTANTS_STATE_KEY,
4367                 TelephonyUtils.dataStateToString(pdcs.getState()));
4368         intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName());
4369         intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY,
4370                 getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask()));
4371         intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex);
4372         intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId);
4373         // Send the broadcast twice -- once for all apps with READ_PHONE_STATE, then again
4374         // for all apps with READ_PRIV but not READ_PHONE_STATE. This ensures that any app holding
4375         // either READ_PRIV or READ_PHONE get this broadcast exactly once.
4376         mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE);
4377         mContext.createContextAsUser(UserHandle.ALL, 0)
4378                 .sendBroadcastMultiplePermissions(intent,
4379                         new String[] { Manifest.permission.READ_PRIVILEGED_PHONE_STATE },
4380                         new String[] { Manifest.permission.READ_PHONE_STATE });
4381     }
4382 
4383     /**
4384      * Reimplementation of {@link ApnSetting#getApnTypesStringFromBitmask}.
4385      */
4386     @VisibleForTesting
getApnTypesStringFromBitmask(int apnTypeBitmask)4387     public static String getApnTypesStringFromBitmask(int apnTypeBitmask) {
4388         List<String> types = new ArrayList<>();
4389         int remainingApnTypes = apnTypeBitmask;
4390         // special case for DEFAULT since it's not a pure bit
4391         if ((remainingApnTypes & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) {
4392             types.add(ApnSetting.TYPE_DEFAULT_STRING);
4393             remainingApnTypes &= ~ApnSetting.TYPE_DEFAULT;
4394         }
4395         while (remainingApnTypes != 0) {
4396             int highestApnTypeBit = Integer.highestOneBit(remainingApnTypes);
4397             String apnString = ApnSetting.getApnTypeString(highestApnTypeBit);
4398             if (!TextUtils.isEmpty(apnString)) types.add(apnString);
4399             remainingApnTypes &= ~highestApnTypeBit;
4400         }
4401         return TextUtils.join(",", types);
4402     }
4403 
enforceNotifyPermissionOrCarrierPrivilege(String method)4404     private void enforceNotifyPermissionOrCarrierPrivilege(String method) {
4405         if (checkNotifyPermission()) {
4406             return;
4407         }
4408 
4409         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext,
4410                 SubscriptionManager.getDefaultSubscriptionId(), method);
4411     }
4412 
checkNotifyPermission(String method)4413     private boolean checkNotifyPermission(String method) {
4414         if (checkNotifyPermission()) {
4415             return true;
4416         }
4417         String msg = "Modify Phone State Permission Denial: " + method + " from pid="
4418                 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
4419         if (DBG) log(msg);
4420         return false;
4421     }
4422 
checkNotifyPermission()4423     private boolean checkNotifyPermission() {
4424         return mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4425                 == PackageManager.PERMISSION_GRANTED;
4426     }
4427 
checkListenerPermission(Set<Integer> events, int subId, String callingPackage, @Nullable String callingFeatureId, String message)4428     private boolean checkListenerPermission(Set<Integer> events, int subId, String callingPackage,
4429             @Nullable String callingFeatureId, String message) {
4430         boolean isPermissionCheckSuccessful = true;
4431         if (isLocationPermissionRequired(events)) {
4432             LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder =
4433                     new LocationAccessPolicy.LocationPermissionQuery.Builder()
4434                             .setCallingPackage(callingPackage)
4435                             .setCallingFeatureId(callingFeatureId)
4436                             .setMethod(message + " events: " + events)
4437                             .setCallingPid(Binder.getCallingPid())
4438                             .setCallingUid(Binder.getCallingUid());
4439             // Everything that requires fine location started in Q. So far...
4440             locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q);
4441             // If we're enforcing fine starting in Q, we also want to enforce coarse even for
4442             // older SDK versions.
4443             locationQueryBuilder.setMinSdkVersionForCoarse(0);
4444             locationQueryBuilder.setMinSdkVersionForEnforcement(0);
4445             LocationAccessPolicy.LocationPermissionResult result =
4446                     LocationAccessPolicy.checkLocationPermission(
4447                             mContext, locationQueryBuilder.build());
4448             switch (result) {
4449                 case DENIED_HARD:
4450                     throw new SecurityException("Unable to listen for events " + events + " due to "
4451                             + "insufficient location permissions.");
4452                 case DENIED_SOFT:
4453                     isPermissionCheckSuccessful = false;
4454             }
4455         }
4456 
4457         if (isPhoneStatePermissionRequired(events, callingPackage, Binder.getCallingUserHandle())) {
4458             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4459                     mContext, subId, callingPackage, callingFeatureId, message)) {
4460                 isPermissionCheckSuccessful = false;
4461             }
4462         }
4463 
4464         if (isPrecisePhoneStatePermissionRequired(events)) {
4465             // check if calling app has either permission READ_PRECISE_PHONE_STATE
4466             // or with carrier privileges
4467             try {
4468                 mContext.enforceCallingOrSelfPermission(
4469                         android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
4470             } catch (SecurityException se) {
4471                 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, subId, message);
4472             }
4473         }
4474 
4475         if (isActiveEmergencySessionPermissionRequired(events)) {
4476             mContext.enforceCallingOrSelfPermission(
4477                     android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
4478         }
4479 
4480         if (isPrivilegedPhoneStatePermissionRequired(events)) {
4481             mContext.enforceCallingOrSelfPermission(
4482                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
4483         }
4484         return isPermissionCheckSuccessful;
4485     }
4486 
handleRemoveListLocked()4487     private void handleRemoveListLocked() {
4488         int size = mRemoveList.size();
4489         if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size);
4490         if (size > 0) {
4491             for (IBinder b : mRemoveList) {
4492                 remove(b);
4493             }
4494             mRemoveList.clear();
4495         }
4496     }
4497 
validateEventAndUserLocked(Record r, int event)4498     private boolean validateEventAndUserLocked(Record r, int event) {
4499         int foregroundUser;
4500         final long callingIdentity = Binder.clearCallingIdentity();
4501         boolean valid = false;
4502         try {
4503             foregroundUser = ActivityManager.getCurrentUser();
4504             valid = UserHandle.getUserId(r.callerUid) == foregroundUser
4505                     && r.matchTelephonyCallbackEvent(event);
4506             if (DBG | DBG_LOC) {
4507                 log("validateEventAndUserLocked: valid=" + valid
4508                         + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser
4509                         + " r.eventList=" + r.eventList + " event=" + event);
4510             }
4511         } finally {
4512             Binder.restoreCallingIdentity(callingIdentity);
4513         }
4514         return valid;
4515     }
4516 
validatePhoneId(int phoneId)4517     private boolean validatePhoneId(int phoneId) {
4518         // Call getActiveModemCount to get the latest value instead of depending on mNumPhone
4519         boolean valid = (phoneId >= 0) && (phoneId < getTelephonyManager().getActiveModemCount());
4520         if (VDBG) log("validatePhoneId: " + valid);
4521         return valid;
4522     }
4523 
log(String s)4524     private static void log(String s) {
4525         Rlog.d(TAG, s);
4526     }
4527 
loge(String s)4528     private static void loge(String s) {
4529         Rlog.e(TAG, s);
4530     }
4531 
4532     /**
4533      * Match the sub id or phone id of the event to the record
4534      *
4535      * We follow the rules below:
4536      * 1) If sub id of the event is invalid, phone id should be used.
4537      * 2) The event on default sub should be notified to the records
4538      * which register the default sub id.
4539      * 3) Sub id should be exactly matched for all other cases.
4540      */
idMatch(Record r, int subId, int phoneId)4541     boolean idMatch(Record r, int subId, int phoneId) {
4542 
4543         if (subId < 0) {
4544             // Invalid case, we need compare phoneId.
4545             return (r.phoneId == phoneId);
4546         }
4547         if (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
4548             return (subId == mDefaultSubId);
4549         } else {
4550             return (r.subId == subId);
4551         }
4552     }
4553 
4554     /**
4555      * Match the sub id or phone id of the event to the record with relaxed rules
4556      *
4557      * We follow the rules below:
4558      * 1) If sub id of the event is invalid, phone id should be used.
4559      * 2) If record's phoneId is also invalid then allow phone 0 notifications
4560      * 3) The event on default sub should be notified to the records
4561      * which register the default sub id.
4562      * 4) Sub id should be exactly matched for all other cases.
4563      * TODO: b/337878785 for longterm fix
4564      */
idMatchRelaxed(Record r, int subId, int phoneId)4565     boolean idMatchRelaxed(Record r, int subId, int phoneId) {
4566         if (!Flags.useRelaxedIdMatch()) {
4567             return idMatch(r, subId, phoneId);
4568         }
4569 
4570         if (subId < 0) {
4571             // Invalid case, we need compare phoneId.
4572             // If the record does not have a valid phone Id send phone 0 notifications.
4573             // A record's phoneId can get invalid if there is no SIM or modem was restarting
4574             // when caller registered.
4575             if (r.phoneId == INVALID_SIM_SLOT_INDEX) {
4576                 return (phoneId == 0);
4577             } else {
4578                 return (r.phoneId == phoneId);
4579             }
4580         }
4581 
4582         if (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
4583             // if the registered record does not have a valid phoneId then use the phone 0
4584             if (r.phoneId == INVALID_SIM_SLOT_INDEX) {
4585                 return (phoneId == 0);
4586             }
4587             return (subId == mDefaultSubId);
4588         } else {
4589             return (r.subId == subId);
4590         }
4591     }
4592 
checkFineLocationAccess(Record r)4593     private boolean checkFineLocationAccess(Record r) {
4594         return checkFineLocationAccess(r, Build.VERSION_CODES.BASE);
4595     }
4596 
checkCoarseLocationAccess(Record r)4597     private boolean checkCoarseLocationAccess(Record r) {
4598         return checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE);
4599     }
4600 
4601     /**
4602      * Note -- this method should only be used at the site of a permission check if you need to
4603      * explicitly allow apps below a certain SDK level access regardless of location permissions.
4604      * If you don't need app compat logic, use {@link #checkFineLocationAccess(Record)}.
4605      */
checkFineLocationAccess(Record r, int minSdk)4606     private boolean checkFineLocationAccess(Record r, int minSdk) {
4607         if (r.renounceFineLocationAccess) {
4608             return false;
4609         }
4610         LocationAccessPolicy.LocationPermissionQuery query =
4611                 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4612                         .setCallingPackage(r.callingPackage)
4613                         .setCallingFeatureId(r.callingFeatureId)
4614                         .setCallingPid(r.callerPid)
4615                         .setCallingUid(r.callerUid)
4616                         .setMethod("TelephonyRegistry push")
4617                         .setLogAsInfo(true) // we don't need to log an error every time we push
4618                         .setMinSdkVersionForFine(minSdk)
4619                         .setMinSdkVersionForCoarse(minSdk)
4620                         .setMinSdkVersionForEnforcement(minSdk)
4621                         .build();
4622 
4623         return Binder.withCleanCallingIdentity(() -> {
4624             LocationAccessPolicy.LocationPermissionResult locationResult =
4625                     LocationAccessPolicy.checkLocationPermission(mContext, query);
4626             return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
4627         });
4628     }
4629 
4630     /**
4631      * Note -- this method should only be used at the site of a permission check if you need to
4632      * explicitly allow apps below a certain SDK level access regardless of location permissions.
4633      * If you don't need app compat logic, use {@link #checkCoarseLocationAccess(Record)}.
4634      */
checkCoarseLocationAccess(Record r, int minSdk)4635     private boolean checkCoarseLocationAccess(Record r, int minSdk) {
4636         if (r.renounceCoarseLocationAccess) {
4637             return false;
4638         }
4639         LocationAccessPolicy.LocationPermissionQuery query =
4640                 new LocationAccessPolicy.LocationPermissionQuery.Builder()
4641                         .setCallingPackage(r.callingPackage)
4642                         .setCallingFeatureId(r.callingFeatureId)
4643                         .setCallingPid(r.callerPid)
4644                         .setCallingUid(r.callerUid)
4645                         .setMethod("TelephonyRegistry push")
4646                         .setLogAsInfo(true) // we don't need to log an error every time we push
4647                         .setMinSdkVersionForCoarse(minSdk)
4648                         .setMinSdkVersionForFine(Integer.MAX_VALUE)
4649                         .setMinSdkVersionForEnforcement(minSdk)
4650                         .build();
4651 
4652         return Binder.withCleanCallingIdentity(() -> {
4653             LocationAccessPolicy.LocationPermissionResult locationResult =
4654                     LocationAccessPolicy.checkLocationPermission(mContext, query);
4655             return locationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
4656         });
4657     }
4658 
4659     private void checkPossibleMissNotify(Record r, int phoneId) {
4660         Set<Integer> events = r.eventList;
4661 
4662         if (events == null || events.isEmpty()) {
4663             log("checkPossibleMissNotify: events = null.");
4664             return;
4665         }
4666 
4667         if ((events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED))) {
4668             try {
4669                 if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" +
4670                         mServiceState[phoneId]);
4671                 ServiceState ss = new ServiceState(mServiceState[phoneId]);
4672                 if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
4673                     r.callback.onServiceStateChanged(ss);
4674                 } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
4675                     r.callback.onServiceStateChanged(
4676                             ss.createLocationInfoSanitizedCopy(false));
4677                 } else {
4678                     r.callback.onServiceStateChanged(
4679                             ss.createLocationInfoSanitizedCopy(true));
4680                 }
4681             } catch (RemoteException ex) {
4682                 mRemoveList.add(r.binder);
4683             }
4684         }
4685 
4686         if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)) {
4687             try {
4688                 if (mSignalStrength[phoneId] != null) {
4689                     SignalStrength signalStrength = mSignalStrength[phoneId];
4690                     if (DBG) {
4691                         log("checkPossibleMissNotify: onSignalStrengthsChanged SS="
4692                                 + signalStrength);
4693                     }
4694                     r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
4695                 }
4696             } catch (RemoteException ex) {
4697                 mRemoveList.add(r.binder);
4698             }
4699         }
4700 
4701         if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) {
4702             try {
4703                 if (mSignalStrength[phoneId] != null) {
4704                     int gsmSignalStrength = mSignalStrength[phoneId]
4705                             .getGsmSignalStrength();
4706                     if (DBG) {
4707                         log("checkPossibleMissNotify: onSignalStrengthChanged SS="
4708                                 + gsmSignalStrength);
4709                     }
4710                     r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
4711                             : gsmSignalStrength));
4712                 }
4713             } catch (RemoteException ex) {
4714                 mRemoveList.add(r.binder);
4715             }
4716         }
4717 
4718         if (validateEventAndUserLocked(r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) {
4719             try {
4720                 if (DBG_LOC) {
4721                     log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = "
4722                             + mCellInfo.get(phoneId));
4723                 }
4724                 if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
4725                         && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
4726                     r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
4727                 }
4728             } catch (RemoteException ex) {
4729                 mRemoveList.add(r.binder);
4730             }
4731         }
4732 
4733         if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
4734             try {
4735                 if (VDBG) {
4736                     log("checkPossibleMissNotify: onUserMobileDataStateChanged phoneId="
4737                             + phoneId + " umds=" + mUserMobileDataState[phoneId]);
4738                 }
4739                 r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]);
4740             } catch (RemoteException ex) {
4741                 mRemoveList.add(r.binder);
4742             }
4743         }
4744 
4745         if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) {
4746             try {
4747                 if (VDBG) {
4748                     log("checkPossibleMissNotify: onDisplayInfoChanged phoneId="
4749                             + phoneId + " dpi=" + mTelephonyDisplayInfos[phoneId]);
4750                 }
4751                 if (mTelephonyDisplayInfos[phoneId] != null) {
4752                     r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]);
4753                 }
4754             } catch (RemoteException ex) {
4755                 mRemoveList.add(r.binder);
4756             }
4757         }
4758 
4759         if (events.contains(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
4760             try {
4761                 if (VDBG) {
4762                     log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId="
4763                             + phoneId + " mwi=" + mMessageWaiting[phoneId]);
4764                 }
4765                 r.callback.onMessageWaitingIndicatorChanged(
4766                         mMessageWaiting[phoneId]);
4767             } catch (RemoteException ex) {
4768                 mRemoveList.add(r.binder);
4769             }
4770         }
4771 
4772         if (events.contains(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
4773             try {
4774                 if (VDBG) {
4775                     log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId="
4776                         + phoneId + " cfi=" + mCallForwarding[phoneId]);
4777                 }
4778                 r.callback.onCallForwardingIndicatorChanged(
4779                         mCallForwarding[phoneId]);
4780             } catch (RemoteException ex) {
4781                 mRemoveList.add(r.binder);
4782             }
4783         }
4784 
4785         if (validateEventAndUserLocked(r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) {
4786             try {
4787                 if (DBG_LOC) {
4788                     log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
4789                             + mCellIdentity[phoneId]);
4790                 }
4791                 if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
4792                         && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
4793                     // null will be translated to empty CellLocation object in client.
4794                     r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
4795                 }
4796             } catch (RemoteException ex) {
4797                 mRemoveList.add(r.binder);
4798             }
4799         }
4800 
4801         if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
4802             try {
4803                 if (DBG) {
4804                     log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState"
4805                             + "=" + mDataConnectionState[phoneId]
4806                             + ", mDataConnectionNetworkType=" + mDataConnectionNetworkType[phoneId]
4807                             + ")");
4808                 }
4809                 r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
4810                         mDataConnectionNetworkType[phoneId]);
4811             } catch (RemoteException ex) {
4812                 mRemoveList.add(r.binder);
4813             }
4814         }
4815     }
4816 
4817     /**
4818      * Returns a string representation of the radio technology (network type)
4819      * currently in use on the device.
4820      * @param type for which network type is returned
4821      * @return the name of the radio technology
4822      *
4823      */
4824     private String getNetworkTypeName(@Annotation.NetworkType int type) {
4825         switch (type) {
4826             case TelephonyManager.NETWORK_TYPE_GPRS:
4827                 return "GPRS";
4828             case TelephonyManager.NETWORK_TYPE_EDGE:
4829                 return "EDGE";
4830             case TelephonyManager.NETWORK_TYPE_UMTS:
4831                 return "UMTS";
4832             case TelephonyManager.NETWORK_TYPE_HSDPA:
4833                 return "HSDPA";
4834             case TelephonyManager.NETWORK_TYPE_HSUPA:
4835                 return "HSUPA";
4836             case TelephonyManager.NETWORK_TYPE_HSPA:
4837                 return "HSPA";
4838             case TelephonyManager.NETWORK_TYPE_CDMA:
4839                 return "CDMA";
4840             case TelephonyManager.NETWORK_TYPE_EVDO_0:
4841                 return "CDMA - EvDo rev. 0";
4842             case TelephonyManager.NETWORK_TYPE_EVDO_A:
4843                 return "CDMA - EvDo rev. A";
4844             case TelephonyManager.NETWORK_TYPE_EVDO_B:
4845                 return "CDMA - EvDo rev. B";
4846             case TelephonyManager.NETWORK_TYPE_1xRTT:
4847                 return "CDMA - 1xRTT";
4848             case TelephonyManager.NETWORK_TYPE_LTE:
4849                 return "LTE";
4850             case TelephonyManager.NETWORK_TYPE_EHRPD:
4851                 return "CDMA - eHRPD";
4852             case TelephonyManager.NETWORK_TYPE_IDEN:
4853                 return "iDEN";
4854             case TelephonyManager.NETWORK_TYPE_HSPAP:
4855                 return "HSPA+";
4856             case TelephonyManager.NETWORK_TYPE_GSM:
4857                 return "GSM";
4858             case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
4859                 return "TD_SCDMA";
4860             case TelephonyManager.NETWORK_TYPE_IWLAN:
4861                 return "IWLAN";
4862 
4863             //TODO: This network type is marked as hidden because it is not a
4864             // true network type and we are looking to remove it completely from the available list
4865             // of network types.  Since this method is only used for logging, in the event that this
4866             // network type is selected, the log will read as "Unknown."
4867             //case TelephonyManager.NETWORK_TYPE_LTE_CA:
4868             //    return "LTE_CA";
4869 
4870             case TelephonyManager.NETWORK_TYPE_NR:
4871                 return "NR";
4872             default:
4873                 return "UNKNOWN";
4874         }
4875     }
4876 
4877     /** Returns a new PreciseCallState object with default values. */
4878     private static PreciseCallState createPreciseCallState() {
4879         return new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
4880             PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
4881             PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
4882             DisconnectCause.NOT_VALID,
4883             PreciseDisconnectCause.NOT_VALID);
4884     }
4885 
4886     /** Returns a new CallQuality object with default values. */
4887     private static CallQuality createCallQuality() {
4888         return new CallQuality(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4889     }
4890 
4891     private int getPhoneIdFromSubId(int subId) {
4892         SubscriptionManager subManager = (SubscriptionManager)
4893                 mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
4894         if (subManager == null) return INVALID_SIM_SLOT_INDEX;
4895 
4896         if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
4897             subId = SubscriptionManager.getDefaultSubscriptionId();
4898         }
4899 
4900         SubscriptionInfo info = subManager.getActiveSubscriptionInfo(subId);
4901         if (info == null) return INVALID_SIM_SLOT_INDEX;
4902         return info.getSimSlotIndex();
4903     }
4904 
4905     /**
4906      * On certain build types, we should redact information by default. UID information will be
4907      * preserved in the same log line, so no debugging capability is lost in full bug reports.
4908      * However, privacy-constrained bug report types (e.g. connectivity) cannot display raw
4909      * package names on user builds as it's considered an information leak.
4910      */
4911     private static String pii(String packageName) {
4912         return Build.IS_DEBUGGABLE ? packageName : "***";
4913     }
4914 
4915     /** Redacts an entire list of package names if necessary. */
4916     private static String pii(List<String> packageNames) {
4917         if (packageNames.isEmpty() || Build.IS_DEBUGGABLE) return packageNames.toString();
4918         return "[***, size=" + packageNames.size() + "]";
4919     }
4920 
4921     /**
4922      * The method enforces the calling package at least has READ_BASIC_PHONE_STATE permission.
4923      * That is, calling package either has READ_PRIVILEGED_PHONE_STATE, READ_PHONE_STATE or Carrier
4924      * Privileges on ANY active subscription, or has READ_BASIC_PHONE_STATE permission.
4925      */
4926     private void enforceCallingOrSelfAtLeastReadBasicPhoneStatePermission(String pkgName,
4927             String featureId, String message) {
4928         // Check if calling app has READ_PHONE_STATE on ANY active subscription
4929         boolean hasReadPhoneState = false;
4930         SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
4931         if (sm != null) {
4932             for (int subId : sm.getActiveSubscriptionIdList()) {
4933                 if (TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(mContext, subId,
4934                         pkgName, featureId, message)) {
4935                     hasReadPhoneState = true;
4936                     break;
4937                 }
4938             }
4939         }
4940 
4941         // If yes, pass. If not, then enforce READ_BASIC_PHONE_STATE permission
4942         if (!hasReadPhoneState) {
4943             mContext.enforceCallingOrSelfPermission(
4944                     Manifest.permission.READ_BASIC_PHONE_STATE,
4945                     message);
4946         }
4947     }
4948 }
4949