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