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