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