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