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