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