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