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