• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 package android.telephony;
17 
18 import android.annotation.CallbackExecutor;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.RequiresPermission;
22 import android.compat.Compatibility;
23 import android.compat.annotation.ChangeId;
24 import android.compat.annotation.EnabledAfter;
25 import android.content.Context;
26 import android.os.Binder;
27 import android.os.Build;
28 import android.os.RemoteException;
29 import android.os.ServiceManager;
30 import android.service.carrier.CarrierService;
31 import android.telephony.Annotation.CallState;
32 import android.telephony.Annotation.DataActivityType;
33 import android.telephony.Annotation.DisconnectCauses;
34 import android.telephony.Annotation.NetworkType;
35 import android.telephony.Annotation.PreciseCallStates;
36 import android.telephony.Annotation.PreciseDisconnectCauses;
37 import android.telephony.Annotation.RadioPowerState;
38 import android.telephony.Annotation.SimActivationState;
39 import android.telephony.Annotation.SrvccState;
40 import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
41 import android.telephony.emergency.EmergencyNumber;
42 import android.telephony.ims.ImsReasonInfo;
43 import android.util.ArraySet;
44 import android.util.Log;
45 
46 import com.android.internal.annotations.GuardedBy;
47 import com.android.internal.listeners.ListenerExecutor;
48 import com.android.internal.telephony.ICarrierPrivilegesCallback;
49 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
50 import com.android.internal.telephony.ITelephonyRegistry;
51 
52 import java.lang.ref.WeakReference;
53 import java.util.Arrays;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.Set;
58 import java.util.WeakHashMap;
59 import java.util.concurrent.Executor;
60 import java.util.stream.Collectors;
61 
62 /**
63  * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update
64  * or {@link PhoneCapability} changed. This might trigger callback from applications side through
65  * {@link android.telephony.PhoneStateListener}
66  *
67  * TODO: limit API access to only carrier apps with certain permissions or apps running on
68  * privileged UID.
69  *
70  * @hide
71  */
72 public class TelephonyRegistryManager {
73 
74     private static final String TAG = "TelephonyRegistryManager";
75     private static ITelephonyRegistry sRegistry;
76     private final Context mContext;
77 
78     /**
79      * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and
80      * its callback IOnSubscriptionsChangedListener.
81      */
82     private final Map<SubscriptionManager.OnSubscriptionsChangedListener,
83                 IOnSubscriptionsChangedListener> mSubscriptionChangedListenerMap = new HashMap<>();
84     /**
85      * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and
86      * its callback IOnSubscriptionsChangedListener.
87      */
88     private final Map<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener,
89             IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap
90             = new HashMap<>();
91 
92 
93     /** @hide **/
TelephonyRegistryManager(@onNull Context context)94     public TelephonyRegistryManager(@NonNull Context context) {
95         mContext = context;
96         if (sRegistry == null) {
97             sRegistry = ITelephonyRegistry.Stub.asInterface(
98                 ServiceManager.getService("telephony.registry"));
99         }
100     }
101 
102     /**
103      * Register for changes to the list of active {@link SubscriptionInfo} records or to the
104      * individual records themselves. When a change occurs the onSubscriptionsChanged method of
105      * the listener will be invoked immediately if there has been a notification. The
106      * onSubscriptionChanged method will also be triggered once initially when calling this
107      * function.
108      *
109      * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener}
110      *                 with onSubscriptionsChanged overridden.
111      * @param executor the executor that will execute callbacks.
112      */
addOnSubscriptionsChangedListener( @onNull SubscriptionManager.OnSubscriptionsChangedListener listener, @NonNull Executor executor)113     public void addOnSubscriptionsChangedListener(
114             @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener,
115             @NonNull Executor executor) {
116         if (mSubscriptionChangedListenerMap.get(listener) != null) {
117             Log.d(TAG, "addOnSubscriptionsChangedListener listener already present");
118             return;
119         }
120         IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
121             @Override
122             public void onSubscriptionsChanged () {
123                 final long identity = Binder.clearCallingIdentity();
124                 try {
125                     executor.execute(() -> listener.onSubscriptionsChanged());
126                 } finally {
127                     Binder.restoreCallingIdentity(identity);
128                 }
129             }
130         };
131         mSubscriptionChangedListenerMap.put(listener, callback);
132         try {
133             sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(),
134                     mContext.getAttributionTag(), callback);
135         } catch (RemoteException ex) {
136             // system server crash
137             throw ex.rethrowFromSystemServer();
138         }
139     }
140 
141     /**
142      * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not
143      * strictly necessary as the listener will automatically be unregistered if an attempt to
144      * invoke the listener fails.
145      *
146      * @param listener that is to be unregistered.
147      */
removeOnSubscriptionsChangedListener( @onNull SubscriptionManager.OnSubscriptionsChangedListener listener)148     public void removeOnSubscriptionsChangedListener(
149             @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) {
150         if (mSubscriptionChangedListenerMap.get(listener) == null) {
151             return;
152         }
153         try {
154             sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
155                     mSubscriptionChangedListenerMap.get(listener));
156             mSubscriptionChangedListenerMap.remove(listener);
157         } catch (RemoteException ex) {
158             // system server crash
159             throw ex.rethrowFromSystemServer();
160         }
161     }
162 
163     /**
164      * Register for changes to the list of opportunistic subscription records or to the
165      * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
166      * method of the listener will be invoked immediately if there has been a notification.
167      *
168      * @param listener an instance of
169      * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with
170      *                 onOpportunisticSubscriptionsChanged overridden.
171      * @param executor an Executor that will execute callbacks.
172      */
addOnOpportunisticSubscriptionsChangedListener( @onNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, @NonNull Executor executor)173     public void addOnOpportunisticSubscriptionsChangedListener(
174             @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener,
175             @NonNull Executor executor) {
176         if (mOpportunisticSubscriptionChangedListenerMap.get(listener) != null) {
177             Log.d(TAG, "addOnOpportunisticSubscriptionsChangedListener listener already present");
178             return;
179         }
180         /**
181          * The callback methods need to be called on the executor thread where
182          * this object was created.  If the binder did that for us it'd be nice.
183          */
184         IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
185             @Override
186             public void onSubscriptionsChanged() {
187                 final long identity = Binder.clearCallingIdentity();
188                 try {
189                     Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received.");
190                     executor.execute(() -> listener.onOpportunisticSubscriptionsChanged());
191                 } finally {
192                     Binder.restoreCallingIdentity(identity);
193                 }
194             }
195         };
196         mOpportunisticSubscriptionChangedListenerMap.put(listener, callback);
197         try {
198             sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(),
199                     mContext.getAttributionTag(), callback);
200         } catch (RemoteException ex) {
201             // system server crash
202             throw ex.rethrowFromSystemServer();
203         }
204     }
205 
206     /**
207      * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener}
208      * that is currently listening opportunistic subscriptions change. This is not strictly
209      * necessary as the listener will automatically be unregistered if an attempt to invoke the
210      * listener fails.
211      *
212      * @param listener that is to be unregistered.
213      */
removeOnOpportunisticSubscriptionsChangedListener( @onNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener)214     public void removeOnOpportunisticSubscriptionsChangedListener(
215             @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) {
216         if (mOpportunisticSubscriptionChangedListenerMap.get(listener) == null) {
217             return;
218         }
219         try {
220             sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
221                     mOpportunisticSubscriptionChangedListenerMap.get(listener));
222             mOpportunisticSubscriptionChangedListenerMap.remove(listener);
223         } catch (RemoteException ex) {
224             // system server crash
225             throw ex.rethrowFromSystemServer();
226         }
227     }
228 
229     /**
230      * To check the SDK version for {@link #listenFromListener}.
231      */
232     @ChangeId
233     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
234     private static final long LISTEN_CODE_CHANGE = 147600208L;
235 
236     /**
237      * Listen for incoming subscriptions
238      * @param subId Subscription ID
239      * @param pkg Package name
240      * @param featureId Feature ID
241      * @param listener Listener providing callback
242      * @param events Events
243      * @param notifyNow Whether to notify instantly
244      */
listenFromListener(int subId, @NonNull boolean renounceFineLocationAccess, @NonNull boolean renounceCoarseLocationAccess, @NonNull String pkg, @NonNull String featureId, @NonNull PhoneStateListener listener, @NonNull int events, boolean notifyNow)245     public void listenFromListener(int subId, @NonNull boolean renounceFineLocationAccess,
246             @NonNull boolean renounceCoarseLocationAccess, @NonNull String pkg,
247             @NonNull String featureId, @NonNull PhoneStateListener listener,
248             @NonNull int events, boolean notifyNow) {
249         if (listener == null) {
250             throw new IllegalStateException("telephony service is null.");
251         }
252 
253         try {
254             int[] eventsList = getEventsFromBitmask(events).stream().mapToInt(i -> i).toArray();
255             // subId from PhoneStateListener is deprecated Q on forward, use the subId from
256             // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q.
257             if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) {
258                 // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is
259                 // the only place to set mSubId and its for "informational" only.
260                 listener.mSubId = (eventsList.length == 0)
261                         ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId;
262             } else if (listener.mSubId != null) {
263                 subId = listener.mSubId;
264             }
265             sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess,
266                     subId, pkg, featureId, listener.callback, eventsList, notifyNow);
267         } catch (RemoteException e) {
268             throw e.rethrowFromSystemServer();
269         }
270     }
271 
272     /**
273      * Listen for incoming subscriptions
274      * @param subId Subscription ID
275      * @param pkg Package name
276      * @param featureId Feature ID
277      * @param telephonyCallback Listener providing callback
278      * @param events List events
279      * @param notifyNow Whether to notify instantly
280      */
listenFromCallback(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, int subId, @NonNull String pkg, @NonNull String featureId, @NonNull TelephonyCallback telephonyCallback, @NonNull int[] events, boolean notifyNow)281     private void listenFromCallback(boolean renounceFineLocationAccess,
282             boolean renounceCoarseLocationAccess, int subId,
283             @NonNull String pkg, @NonNull String featureId,
284             @NonNull TelephonyCallback telephonyCallback, @NonNull int[] events,
285             boolean notifyNow) {
286         try {
287             sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess,
288                     subId, pkg, featureId, telephonyCallback.callback, events, notifyNow);
289         } catch (RemoteException e) {
290             throw e.rethrowFromSystemServer();
291         }
292     }
293 
294     /**
295      * Informs the system of an intentional upcoming carrier network change by a carrier app.
296      * This call only used to allow the system to provide alternative UI while telephony is
297      * performing an action that may result in intentional, temporary network lack of connectivity.
298      * <p>
299      * Based on the active parameter passed in, this method will either show or hide the alternative
300      * UI. There is no timeout associated with showing this UX, so a carrier app must be sure to
301      * call with active set to false sometime after calling with it set to {@code true}.
302      * <p>
303      * This will apply to all subscriptions the carrier app has carrier privileges on.
304      * <p>
305      * Requires Permission: calling app has carrier privileges.
306      *
307      * @param active Whether the carrier network change is or shortly will be
308      * active. Set this value to true to begin showing alternative UI and false to stop.
309      * @see TelephonyManager#hasCarrierPrivileges
310      */
notifyCarrierNetworkChange(boolean active)311     public void notifyCarrierNetworkChange(boolean active) {
312         try {
313             sRegistry.notifyCarrierNetworkChange(active);
314         } catch (RemoteException ex) {
315             // system server crash
316             throw ex.rethrowFromSystemServer();
317         }
318     }
319 
320     /**
321      * Informs the system of an intentional upcoming carrier network change by a carrier app on the
322      * given {@code subscriptionId}. This call only used to allow the system to provide alternative
323      * UI while telephony is performing an action that may result in intentional, temporary network
324      * lack of connectivity.
325      * <p>
326      * Based on the active parameter passed in, this method will either show or hide the
327      * alternative UI. There is no timeout associated with showing this UX, so a carrier app must be
328      * sure to call with active set to false sometime after calling with it set to {@code true}.
329      * <p>
330      * Requires Permission: calling app has carrier privileges.
331      *
332      * @param subscriptionId the subscription of the carrier network.
333      * @param active whether the carrier network change is or shortly will be active. Set this value
334      *              to true to begin showing alternative UI and false to stop.
335      * @see TelephonyManager#hasCarrierPrivileges
336      */
notifyCarrierNetworkChange(int subscriptionId, boolean active)337     public void notifyCarrierNetworkChange(int subscriptionId, boolean active) {
338         try {
339             sRegistry.notifyCarrierNetworkChangeWithSubId(subscriptionId, active);
340         } catch (RemoteException ex) {
341             // system server crash
342             throw ex.rethrowFromSystemServer();
343         }
344     }
345 
346     /**
347      * Notify call state changed on certain subscription.
348      *
349      * @param slotIndex for which call state changed. Can be derived from subId except when subId is
350      * invalid.
351      * @param subId for which call state changed.
352      * @param state latest call state. e.g, offhook, ringing
353      * @param incomingNumber incoming phone number.
354      */
notifyCallStateChanged(int slotIndex, int subId, @CallState int state, @Nullable String incomingNumber)355     public void notifyCallStateChanged(int slotIndex, int subId, @CallState int state,
356             @Nullable String incomingNumber) {
357         try {
358             sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber);
359         } catch (RemoteException ex) {
360             // system server crash
361             throw ex.rethrowFromSystemServer();
362         }
363     }
364 
365     /**
366      * Notify call state changed on all subscriptions.
367      *
368      * @param state latest call state. e.g, offhook, ringing
369      * @param incomingNumber incoming phone number.
370      * @hide
371      */
372     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
notifyCallStateChangedForAllSubscriptions(@allState int state, @Nullable String incomingNumber)373     public void notifyCallStateChangedForAllSubscriptions(@CallState int state,
374             @Nullable String incomingNumber) {
375         try {
376             sRegistry.notifyCallStateForAllSubs(state, incomingNumber);
377         } catch (RemoteException ex) {
378             // system server crash
379             throw ex.rethrowFromSystemServer();
380         }
381     }
382 
383     /**
384      * Notify {@link SubscriptionInfo} change.
385      * @hide
386      */
notifySubscriptionInfoChanged()387     public void notifySubscriptionInfoChanged() {
388         try {
389             sRegistry.notifySubscriptionInfoChanged();
390         } catch (RemoteException ex) {
391             // system server crash
392             throw ex.rethrowFromSystemServer();
393         }
394     }
395 
396     /**
397      * Notify opportunistic {@link SubscriptionInfo} change.
398      * @hide
399      */
notifyOpportunisticSubscriptionInfoChanged()400     public void notifyOpportunisticSubscriptionInfoChanged() {
401         try {
402             sRegistry.notifyOpportunisticSubscriptionInfoChanged();
403         } catch (RemoteException ex) {
404             // system server crash
405             throw ex.rethrowFromSystemServer();
406         }
407     }
408 
409     /**
410      * Notify {@link ServiceState} update on certain subscription.
411      *
412      * @param slotIndex for which the service state changed. Can be derived from subId except
413      * subId is invalid.
414      * @param subId for which the service state changed.
415      * @param state service state e.g, in service, out of service or roaming status.
416      */
notifyServiceStateChanged(int slotIndex, int subId, @NonNull ServiceState state)417     public void notifyServiceStateChanged(int slotIndex, int subId, @NonNull ServiceState state) {
418         try {
419             sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state);
420         } catch (RemoteException ex) {
421             // system server crash
422             throw ex.rethrowFromSystemServer();
423         }
424     }
425 
426     /**
427      * Notify {@link SignalStrength} update on certain subscription.
428      *
429      * @param slotIndex for which the signalstrength changed. Can be derived from subId except when
430      * subId is invalid.
431      * @param subId for which the signalstrength changed.
432      * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()}
433      */
notifySignalStrengthChanged(int slotIndex, int subId, @NonNull SignalStrength signalStrength)434     public void notifySignalStrengthChanged(int slotIndex, int subId,
435             @NonNull SignalStrength signalStrength) {
436         try {
437             sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength);
438         } catch (RemoteException ex) {
439             // system server crash
440             throw ex.rethrowFromSystemServer();
441         }
442     }
443 
444     /**
445      * Notify changes to the message-waiting indicator on certain subscription. e.g, The status bar
446      * uses message waiting indicator to determine when to display the voicemail icon.
447      *
448      * @param slotIndex for which message waiting indicator changed. Can be derived from subId
449      * except when subId is invalid.
450      * @param subId for which message waiting indicator changed.
451      * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false}
452      * otherwise.
453      */
notifyMessageWaitingChanged(int slotIndex, int subId, boolean msgWaitingInd)454     public void notifyMessageWaitingChanged(int slotIndex, int subId, boolean msgWaitingInd) {
455         try {
456             sRegistry.notifyMessageWaitingChangedForPhoneId(slotIndex, subId, msgWaitingInd);
457         } catch (RemoteException ex) {
458             // system process is dead
459             throw ex.rethrowFromSystemServer();
460         }
461     }
462 
463     /**
464      * Notify changes to the call-forwarding status on certain subscription.
465      *
466      * @param subId for which call forwarding status changed.
467      * @param callForwardInd {@code true} indicates there is call forwarding, {@code false}
468      * otherwise.
469      */
notifyCallForwardingChanged(int subId, boolean callForwardInd)470     public void notifyCallForwardingChanged(int subId, boolean callForwardInd) {
471         try {
472             sRegistry.notifyCallForwardingChangedForSubscriber(subId, callForwardInd);
473         } catch (RemoteException ex) {
474             // system process is dead
475             throw ex.rethrowFromSystemServer();
476         }
477     }
478 
479     /**
480      * Notify changes to activity state changes on certain subscription.
481      *
482      * @param subId for which data activity state changed.
483      * @param dataActivityType indicates the latest data activity type e.g, {@link
484      * TelephonyManager#DATA_ACTIVITY_IN}
485      */
notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType)486     public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) {
487         try {
488             sRegistry.notifyDataActivityForSubscriber(subId, dataActivityType);
489         } catch (RemoteException ex) {
490             // system process is dead
491             throw ex.rethrowFromSystemServer();
492         }
493     }
494 
495     /**
496      * Notify changes to default (Internet) data connection state on certain subscription.
497      *
498      * @param slotIndex for which data connections state changed. Can be derived from subId except
499      * when subId is invalid.
500      * @param subId for which data connection state changed.
501      * @param preciseState the PreciseDataConnectionState
502      *
503      * @see PreciseDataConnectionState
504      * @see TelephonyManager#DATA_DISCONNECTED
505      */
notifyDataConnectionForSubscriber(int slotIndex, int subId, @NonNull PreciseDataConnectionState preciseState)506     public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
507             @NonNull PreciseDataConnectionState preciseState) {
508         try {
509             sRegistry.notifyDataConnectionForSubscriber(
510                     slotIndex, subId, preciseState);
511         } catch (RemoteException ex) {
512             // system process is dead
513             throw ex.rethrowFromSystemServer();
514         }
515     }
516 
517     /**
518      * Notify {@link CallQuality} change on certain subscription.
519      *
520      * @param slotIndex for which call quality state changed. Can be derived from subId except when
521      * subId is invalid.
522      * @param subId for which call quality state changed.
523      * @param callQuality Information about call quality e.g, call quality level
524      * @param networkType associated with this data connection. e.g, LTE
525      */
notifyCallQualityChanged(int slotIndex, int subId, @NonNull CallQuality callQuality, @NetworkType int networkType)526     public void notifyCallQualityChanged(int slotIndex, int subId, @NonNull CallQuality callQuality,
527         @NetworkType int networkType) {
528         try {
529             sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType);
530         } catch (RemoteException ex) {
531             // system process is dead
532             throw ex.rethrowFromSystemServer();
533         }
534     }
535 
536     /**
537      * Notify emergency number list changed on certain subscription.
538      *
539      * @param slotIndex for which emergency number list changed. Can be derived from subId except
540      * when subId is invalid.
541      * @param subId for which emergency number list changed.
542      */
notifyEmergencyNumberList( int slotIndex, int subId)543     public void notifyEmergencyNumberList( int slotIndex, int subId) {
544         try {
545             sRegistry.notifyEmergencyNumberList(slotIndex, subId);
546         } catch (RemoteException ex) {
547             // system process is dead
548             throw ex.rethrowFromSystemServer();
549         }
550     }
551 
552     /**
553      * Notify outgoing emergency call.
554      * @param phoneId Sender phone ID.
555      * @param subId Sender subscription ID.
556      * @param emergencyNumber Emergency number.
557      */
notifyOutgoingEmergencyCall(int phoneId, int subId, @NonNull EmergencyNumber emergencyNumber)558     public void notifyOutgoingEmergencyCall(int phoneId, int subId,
559             @NonNull EmergencyNumber emergencyNumber) {
560         try {
561             sRegistry.notifyOutgoingEmergencyCall(phoneId, subId, emergencyNumber);
562         } catch (RemoteException ex) {
563             // system process is dead
564             throw ex.rethrowFromSystemServer();
565         }
566     }
567 
568     /**
569      * Notify outgoing emergency SMS.
570      * @param phoneId Sender phone ID.
571      * @param subId Sender subscription ID.
572      * @param emergencyNumber Emergency number.
573      */
notifyOutgoingEmergencySms(int phoneId, int subId, @NonNull EmergencyNumber emergencyNumber)574     public void notifyOutgoingEmergencySms(int phoneId, int subId,
575             @NonNull EmergencyNumber emergencyNumber) {
576         try {
577             sRegistry.notifyOutgoingEmergencySms(phoneId, subId, emergencyNumber);
578         } catch (RemoteException ex) {
579             // system process is dead
580             throw ex.rethrowFromSystemServer();
581         }
582     }
583 
584     /**
585      * Notify radio power state changed on certain subscription.
586      *
587      * @param slotIndex for which radio power state changed. Can be derived from subId except when
588      * subId is invalid.
589      * @param subId for which radio power state changed.
590      * @param radioPowerState the current modem radio state.
591      */
notifyRadioPowerStateChanged(int slotIndex, int subId, @RadioPowerState int radioPowerState)592     public void notifyRadioPowerStateChanged(int slotIndex, int subId,
593             @RadioPowerState int radioPowerState) {
594         try {
595             sRegistry.notifyRadioPowerStateChanged(slotIndex, subId, radioPowerState);
596         } catch (RemoteException ex) {
597             // system process is dead
598             throw ex.rethrowFromSystemServer();
599         }
600     }
601 
602     /**
603      * Notify {@link PhoneCapability} changed.
604      *
605      * @param phoneCapability the capability of the modem group.
606      */
notifyPhoneCapabilityChanged(@onNull PhoneCapability phoneCapability)607     public void notifyPhoneCapabilityChanged(@NonNull PhoneCapability phoneCapability) {
608         try {
609             sRegistry.notifyPhoneCapabilityChanged(phoneCapability);
610         } catch (RemoteException ex) {
611             // system process is dead
612             throw ex.rethrowFromSystemServer();
613         }
614     }
615 
616     /**
617      * Sim activation type: voice
618      * @see #notifyVoiceActivationStateChanged
619      * @hide
620      */
621     public static final int SIM_ACTIVATION_TYPE_VOICE = 0;
622     /**
623      * Sim activation type: data
624      * @see #notifyDataActivationStateChanged
625      * @hide
626      */
627     public static final int SIM_ACTIVATION_TYPE_DATA = 1;
628 
629     /**
630      * Notify data activation state changed on certain subscription.
631      * @see TelephonyManager#getDataActivationState()
632      *
633      * @param slotIndex for which data activation state changed. Can be derived from subId except
634      * when subId is invalid.
635      * @param subId for which data activation state changed.
636      * @param activationState sim activation state e.g, activated.
637      */
notifyDataActivationStateChanged(int slotIndex, int subId, @SimActivationState int activationState)638     public void notifyDataActivationStateChanged(int slotIndex, int subId,
639             @SimActivationState int activationState) {
640         try {
641             sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
642                     SIM_ACTIVATION_TYPE_DATA, activationState);
643         } catch (RemoteException ex) {
644             // system process is dead
645             throw ex.rethrowFromSystemServer();
646         }
647     }
648 
649     /**
650      * Notify voice activation state changed on certain subscription.
651      * @see TelephonyManager#getVoiceActivationState()
652      *
653      * @param slotIndex for which voice activation state changed. Can be derived from subId except
654      * subId is invalid.
655      * @param subId for which voice activation state changed.
656      * @param activationState sim activation state e.g, activated.
657      */
notifyVoiceActivationStateChanged(int slotIndex, int subId, @SimActivationState int activationState)658     public void notifyVoiceActivationStateChanged(int slotIndex, int subId,
659             @SimActivationState int activationState) {
660         try {
661             sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
662                     SIM_ACTIVATION_TYPE_VOICE, activationState);
663         } catch (RemoteException ex) {
664             // system process is dead
665             throw ex.rethrowFromSystemServer();
666         }
667     }
668 
669     /**
670      * Notify User mobile data state changed on certain subscription. e.g, mobile data is enabled
671      * or disabled.
672      *
673      * @param slotIndex for which mobile data state has changed. Can be derived from subId except
674      * when subId is invalid.
675      * @param subId for which mobile data state has changed.
676      * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise.
677      */
notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state)678     public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) {
679         try {
680             sRegistry.notifyUserMobileDataStateChangedForPhoneId(slotIndex, subId, state);
681         } catch (RemoteException ex) {
682             // system process is dead
683             throw ex.rethrowFromSystemServer();
684         }
685     }
686 
687     /**
688      * Notify display info changed.
689      *
690      * @param slotIndex The SIM slot index for which display info has changed. Can be
691      * derived from {@code subscriptionId} except when {@code subscriptionId} is invalid, such as
692      * when the device is in emergency-only mode.
693      * @param subscriptionId Subscription id for which display network info has changed.
694      * @param telephonyDisplayInfo The display info.
695      */
notifyDisplayInfoChanged(int slotIndex, int subscriptionId, @NonNull TelephonyDisplayInfo telephonyDisplayInfo)696     public void notifyDisplayInfoChanged(int slotIndex, int subscriptionId,
697             @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
698         try {
699             sRegistry.notifyDisplayInfoChanged(slotIndex, subscriptionId, telephonyDisplayInfo);
700         } catch (RemoteException ex) {
701             // system process is dead
702             throw ex.rethrowFromSystemServer();
703         }
704     }
705 
706     /**
707      * Notify IMS call disconnect causes which contains {@link android.telephony.ims.ImsReasonInfo}.
708      *
709      * @param subId for which ims call disconnect.
710      * @param imsReasonInfo the reason for ims call disconnect.
711      */
notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo)712     public void notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo) {
713         try {
714             sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo);
715         } catch (RemoteException ex) {
716             // system process is dead
717             throw ex.rethrowFromSystemServer();
718         }
719     }
720 
721     /**
722      * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call
723      * on certain subscription.
724      *
725      * @param subId for which srvcc state changed.
726      * @param state srvcc state
727      */
notifySrvccStateChanged(int subId, @SrvccState int state)728     public void notifySrvccStateChanged(int subId, @SrvccState int state) {
729         try {
730             sRegistry.notifySrvccStateChanged(subId, state);
731         } catch (RemoteException ex) {
732             // system process is dead
733             throw ex.rethrowFromSystemServer();
734         }
735     }
736 
737     /**
738      * Notify precise call state changed on certain subscription, including foreground, background
739      * and ringcall states.
740      *
741      * @param slotIndex for which precise call state changed. Can be derived from subId except when
742      * subId is invalid.
743      * @param subId for which precise call state changed.
744      * @param ringCallPreciseState ringCall state.
745      * @param foregroundCallPreciseState foreground call state.
746      * @param backgroundCallPreciseState background call state.
747      */
notifyPreciseCallState(int slotIndex, int subId, @PreciseCallStates int ringCallPreciseState, @PreciseCallStates int foregroundCallPreciseState, @PreciseCallStates int backgroundCallPreciseState)748     public void notifyPreciseCallState(int slotIndex, int subId,
749             @PreciseCallStates int ringCallPreciseState,
750             @PreciseCallStates int foregroundCallPreciseState,
751             @PreciseCallStates int backgroundCallPreciseState) {
752         try {
753             sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
754                 foregroundCallPreciseState, backgroundCallPreciseState);
755         } catch (RemoteException ex) {
756             // system process is dead
757             throw ex.rethrowFromSystemServer();
758         }
759     }
760 
761     /**
762      * Notify call disconnect causes which contains {@link DisconnectCause} and {@link
763      * android.telephony.PreciseDisconnectCause}.
764      *
765      * @param slotIndex for which call disconnected. Can be derived from subId except when subId is
766      * invalid.
767      * @param subId for which call disconnected.
768      * @param cause {@link DisconnectCause} for the disconnected call.
769      * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected
770      * call.
771      */
notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause, @PreciseDisconnectCauses int preciseCause)772     public void notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause,
773             @PreciseDisconnectCauses int preciseCause) {
774         try {
775             sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause);
776         } catch (RemoteException ex) {
777             // system process is dead
778             throw ex.rethrowFromSystemServer();
779         }
780     }
781 
782     /**
783      * Notify {@link android.telephony.CellLocation} changed.
784      *
785      * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is
786      * parcelable, and convert to CellLocation in client code.
787      */
notifyCellLocation(int subId, @NonNull CellIdentity cellLocation)788     public void notifyCellLocation(int subId, @NonNull CellIdentity cellLocation) {
789         try {
790             sRegistry.notifyCellLocationForSubscriber(subId, cellLocation);
791         } catch (RemoteException ex) {
792             // system process is dead
793             throw ex.rethrowFromSystemServer();
794         }
795     }
796 
797     /**
798      * Notify {@link CellInfo} changed on certain subscription. e.g, when an observed cell info has
799      * changed or new cells have been added or removed on the given subscription.
800      *
801      * @param subId for which cellinfo changed.
802      * @param cellInfo A list of cellInfo associated with the given subscription.
803      */
notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo)804     public void notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo) {
805         try {
806             sRegistry.notifyCellInfoForSubscriber(subId, cellInfo);
807         } catch (RemoteException ex) {
808             throw ex.rethrowFromSystemServer();
809         }
810     }
811 
812     /**
813      * Notify that the active data subscription ID has changed.
814      * @param activeDataSubId The new subscription ID for active data
815      */
notifyActiveDataSubIdChanged(int activeDataSubId)816     public void notifyActiveDataSubIdChanged(int activeDataSubId) {
817         try {
818             sRegistry.notifyActiveDataSubIdChanged(activeDataSubId);
819         } catch (RemoteException ex) {
820             throw ex.rethrowFromSystemServer();
821         }
822     }
823 
824     /**
825      * Report that Registration or a Location/Routing/Tracking Area update has failed.
826      *
827      * @param slotIndex for which call disconnected. Can be derived from subId except when subId is
828      * invalid.
829      * @param subId for which cellinfo changed.
830      * @param cellIdentity the CellIdentity, which must include the globally unique identifier
831      *        for the cell (for example, all components of the CGI or ECGI).
832      * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the
833      *         cell that was chosen for the failed registration attempt.
834      * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure.
835      * @param causeCode the primary failure cause code of the procedure.
836      *        For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95
837      *        For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147
838      *        For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9
839      *        For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2
840      *        Integer.MAX_VALUE if this value is unused.
841      * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate.
842      *        For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be
843      *        included as an additionalCauseCode. For LTE (ESM), cause codes are in
844      *        TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused.
845      */
notifyRegistrationFailed(int slotIndex, int subId, @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode)846     public void notifyRegistrationFailed(int slotIndex, int subId,
847             @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn,
848             int domain, int causeCode, int additionalCauseCode) {
849         try {
850             sRegistry.notifyRegistrationFailed(slotIndex, subId, cellIdentity,
851                     chosenPlmn, domain, causeCode, additionalCauseCode);
852         } catch (RemoteException ex) {
853             throw ex.rethrowFromSystemServer();
854         }
855     }
856 
857     /**
858      * Notify {@link BarringInfo} has changed for a specific subscription.
859      *
860      * @param slotIndex for the phone object that got updated barring info.
861      * @param subId for which the BarringInfo changed.
862      * @param barringInfo updated BarringInfo.
863      */
notifyBarringInfoChanged( int slotIndex, int subId, @NonNull BarringInfo barringInfo)864     public void notifyBarringInfoChanged(
865             int slotIndex, int subId, @NonNull BarringInfo barringInfo) {
866         try {
867             sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo);
868         } catch (RemoteException ex) {
869             // system server crash
870             throw ex.rethrowFromSystemServer();
871         }
872     }
873 
874     /**
875      * Notify {@link PhysicalChannelConfig} has changed for a specific subscription.
876      *
877      * @param slotIndex for which physical channel configs changed.
878      * @param subId the subId
879      * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel.
880      */
notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId, List<PhysicalChannelConfig> configs)881     public void notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId,
882             List<PhysicalChannelConfig> configs) {
883         try {
884             sRegistry.notifyPhysicalChannelConfigForSubscriber(slotIndex, subId, configs);
885         } catch (RemoteException ex) {
886             // system server crash
887             throw ex.rethrowFromSystemServer();
888         }
889     }
890 
891     /**
892      * Notify that the data enabled has changed.
893      *
894      * @param enabled True if data is enabled, otherwise disabled.
895      * @param reason Reason for data enabled/disabled. See {@code REASON_*} in
896      * {@link TelephonyManager}.
897      */
notifyDataEnabled(int slotIndex, int subId, boolean enabled, @TelephonyManager.DataEnabledReason int reason)898     public void notifyDataEnabled(int slotIndex, int subId, boolean enabled,
899             @TelephonyManager.DataEnabledReason int reason) {
900         try {
901             sRegistry.notifyDataEnabled(slotIndex, subId, enabled, reason);
902         } catch (RemoteException ex) {
903             // system server crash
904             throw ex.rethrowFromSystemServer();
905         }
906     }
907 
908     /**
909      * Notify the allowed network types has changed for a specific subscription and the specific
910      * reason.
911      * @param slotIndex for which allowed network types changed.
912      * @param subId for which allowed network types changed.
913      * @param reason an allowed network type reasons.
914      * @param allowedNetworkType an allowed network type bitmask value.
915      */
notifyAllowedNetworkTypesChanged(int slotIndex, int subId, int reason, long allowedNetworkType)916     public void notifyAllowedNetworkTypesChanged(int slotIndex, int subId,
917             int reason, long allowedNetworkType) {
918         try {
919             sRegistry.notifyAllowedNetworkTypesChanged(slotIndex, subId, reason,
920                     allowedNetworkType);
921         } catch (RemoteException ex) {
922             // system process is dead
923             throw ex.rethrowFromSystemServer();
924         }
925     }
926 
927     /**
928      * Notify that the link capacity estimate has changed.
929      * @param slotIndex for the phone object that gets the updated link capacity estimate
930      * @param subId for subscription that gets the updated link capacity estimate
931      * @param linkCapacityEstimateList a list of {@link  LinkCapacityEstimate}
932      */
notifyLinkCapacityEstimateChanged(int slotIndex, int subId, List<LinkCapacityEstimate> linkCapacityEstimateList)933     public void notifyLinkCapacityEstimateChanged(int slotIndex, int subId,
934             List<LinkCapacityEstimate> linkCapacityEstimateList) {
935         try {
936             sRegistry.notifyLinkCapacityEstimateChanged(slotIndex, subId, linkCapacityEstimateList);
937         } catch (RemoteException ex) {
938             // system server crash
939             throw ex.rethrowFromSystemServer();
940         }
941     }
942 
getEventsFromCallback( @onNull TelephonyCallback telephonyCallback)943     public @NonNull Set<Integer> getEventsFromCallback(
944             @NonNull TelephonyCallback telephonyCallback) {
945         Set<Integer> eventList = new ArraySet<>();
946 
947         if (telephonyCallback instanceof TelephonyCallback.ServiceStateListener) {
948             eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED);
949         }
950 
951         if (telephonyCallback instanceof TelephonyCallback.MessageWaitingIndicatorListener) {
952             eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
953         }
954 
955         if (telephonyCallback instanceof TelephonyCallback.CallForwardingIndicatorListener) {
956             eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
957         }
958 
959         if (telephonyCallback instanceof TelephonyCallback.CellLocationListener) {
960             eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
961         }
962 
963         // Note: Legacy PhoneStateListeners use EVENT_LEGACY_CALL_STATE_CHANGED
964         if (telephonyCallback instanceof TelephonyCallback.CallStateListener) {
965             eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED);
966         }
967 
968         if (telephonyCallback instanceof TelephonyCallback.DataConnectionStateListener) {
969             eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED);
970         }
971 
972         if (telephonyCallback instanceof TelephonyCallback.DataActivityListener) {
973             eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED);
974         }
975 
976         if (telephonyCallback instanceof TelephonyCallback.SignalStrengthsListener) {
977             eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED);
978         }
979 
980         if (telephonyCallback instanceof TelephonyCallback.CellInfoListener) {
981             eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED);
982         }
983 
984         if (telephonyCallback instanceof TelephonyCallback.PreciseCallStateListener) {
985             eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED);
986         }
987 
988         if (telephonyCallback instanceof TelephonyCallback.CallDisconnectCauseListener) {
989             eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
990         }
991 
992         if (telephonyCallback instanceof TelephonyCallback.ImsCallDisconnectCauseListener) {
993             eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
994         }
995 
996         if (telephonyCallback instanceof TelephonyCallback.PreciseDataConnectionStateListener) {
997             eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
998         }
999 
1000         if (telephonyCallback instanceof TelephonyCallback.SrvccStateListener) {
1001             eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED);
1002         }
1003 
1004         if (telephonyCallback instanceof TelephonyCallback.VoiceActivationStateListener) {
1005             eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
1006         }
1007 
1008         if (telephonyCallback instanceof TelephonyCallback.DataActivationStateListener) {
1009             eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED);
1010         }
1011 
1012         if (telephonyCallback instanceof TelephonyCallback.UserMobileDataStateListener) {
1013             eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
1014         }
1015 
1016         if (telephonyCallback instanceof TelephonyCallback.DisplayInfoListener) {
1017             eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED);
1018         }
1019 
1020         if (telephonyCallback instanceof TelephonyCallback.EmergencyNumberListListener) {
1021             eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
1022         }
1023 
1024         if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencyCallListener) {
1025             eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL);
1026         }
1027 
1028         if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencySmsListener) {
1029             eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS);
1030         }
1031 
1032         if (telephonyCallback instanceof TelephonyCallback.PhoneCapabilityListener) {
1033             eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED);
1034         }
1035 
1036         if (telephonyCallback instanceof TelephonyCallback.ActiveDataSubscriptionIdListener) {
1037             eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
1038         }
1039 
1040         if (telephonyCallback instanceof TelephonyCallback.RadioPowerStateListener) {
1041             eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED);
1042         }
1043 
1044         if (telephonyCallback instanceof TelephonyCallback.CarrierNetworkListener) {
1045             eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED);
1046         }
1047 
1048         if (telephonyCallback instanceof TelephonyCallback.RegistrationFailedListener) {
1049             eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE);
1050         }
1051 
1052         if (telephonyCallback instanceof TelephonyCallback.CallAttributesListener) {
1053             eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED);
1054         }
1055 
1056         if (telephonyCallback instanceof TelephonyCallback.BarringInfoListener) {
1057             eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
1058         }
1059 
1060         if (telephonyCallback instanceof TelephonyCallback.PhysicalChannelConfigListener) {
1061             eventList.add(TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
1062         }
1063 
1064         if (telephonyCallback instanceof TelephonyCallback.DataEnabledListener) {
1065             eventList.add(TelephonyCallback.EVENT_DATA_ENABLED_CHANGED);
1066         }
1067 
1068         if (telephonyCallback instanceof TelephonyCallback.AllowedNetworkTypesListener) {
1069             eventList.add(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED);
1070         }
1071 
1072         if (telephonyCallback instanceof TelephonyCallback.LinkCapacityEstimateChangedListener) {
1073             eventList.add(TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED);
1074         }
1075 
1076         return eventList;
1077     }
1078 
getEventsFromBitmask(int eventMask)1079     private @NonNull Set<Integer> getEventsFromBitmask(int eventMask) {
1080 
1081         Set<Integer> eventList = new ArraySet<>();
1082 
1083         if ((eventMask & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
1084             eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED);
1085         }
1086 
1087         if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
1088             eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED);
1089         }
1090 
1091         if ((eventMask & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
1092             eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED);
1093         }
1094 
1095         if ((eventMask & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
1096             eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED);
1097         }
1098 
1099         if ((eventMask & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) {
1100             eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED);
1101         }
1102 
1103         // Note: Legacy call state listeners can get the phone number which is not provided in the
1104         // new version in TelephonyCallback.
1105         if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
1106             eventList.add(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED);
1107         }
1108 
1109         if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
1110             eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED);
1111         }
1112 
1113         if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
1114             eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED);
1115         }
1116 
1117         if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
1118             eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED);
1119         }
1120 
1121         if ((eventMask & PhoneStateListener.LISTEN_CELL_INFO) != 0) {
1122             eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED);
1123         }
1124 
1125         if ((eventMask & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
1126             eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED);
1127         }
1128 
1129         if ((eventMask & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
1130             eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED);
1131         }
1132 
1133         if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
1134             eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED);
1135         }
1136 
1137         if ((eventMask & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) {
1138             eventList.add(TelephonyCallback.EVENT_OEM_HOOK_RAW);
1139         }
1140 
1141         if ((eventMask & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
1142             eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED);
1143         }
1144 
1145         if ((eventMask & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) {
1146             eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED);
1147         }
1148 
1149         if ((eventMask & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) {
1150             eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED);
1151         }
1152 
1153         if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) != 0) {
1154             eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED);
1155         }
1156 
1157         if ((eventMask & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) {
1158             eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED);
1159         }
1160 
1161         if ((eventMask & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) {
1162             eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED);
1163         }
1164 
1165         if ((eventMask & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) {
1166             eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED);
1167         }
1168 
1169         if ((eventMask & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
1170             eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED);
1171         }
1172 
1173         if ((eventMask & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
1174             eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED);
1175         }
1176 
1177         if ((eventMask & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) {
1178             eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED);
1179         }
1180 
1181         if ((eventMask & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
1182             eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED);
1183         }
1184 
1185         if ((eventMask & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) {
1186             eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED);
1187         }
1188 
1189         if ((eventMask & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) {
1190             eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED);
1191         }
1192 
1193         if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL) != 0) {
1194             eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL);
1195         }
1196 
1197         if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS) != 0) {
1198             eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS);
1199         }
1200 
1201         if ((eventMask & PhoneStateListener.LISTEN_REGISTRATION_FAILURE) != 0) {
1202             eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE);
1203         }
1204 
1205         if ((eventMask & PhoneStateListener.LISTEN_BARRING_INFO) != 0) {
1206             eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED);
1207         }
1208         return eventList;
1209 
1210     }
1211 
1212     /**
1213      * Registers a callback object to receive notification of changes in specified telephony states.
1214      * <p>
1215      * To register a callback, pass a {@link TelephonyCallback} which implements
1216      * interfaces of events. For example,
1217      * FakeServiceStateCallback extends {@link TelephonyCallback} implements
1218      * {@link TelephonyCallback.ServiceStateListener}.
1219      *
1220      * At registration, and when a specified telephony state changes, the telephony manager invokes
1221      * the appropriate callback method on the callback object and passes the current (updated)
1222      * values.
1223      * <p>
1224      *
1225      * If this TelephonyManager object has been created with
1226      * {@link TelephonyManager#createForSubscriptionId}, applies to the given subId.
1227      * Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}.
1228      * To register events for multiple subIds, pass a separate callback object to
1229      * each TelephonyManager object created with {@link TelephonyManager#createForSubscriptionId}.
1230      *
1231      * Note: if you call this method while in the middle of a binder transaction, you <b>must</b>
1232      * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
1233      * {@link SecurityException} will be thrown otherwise.
1234      *
1235      * This API should be used sparingly -- large numbers of callbacks will cause system
1236      * instability. If a process has registered too many callbacks without unregistering them, it
1237      * may encounter an {@link IllegalStateException} when trying to register more callbacks.
1238      *
1239      * @param callback The {@link TelephonyCallback} object to register.
1240      */
registerTelephonyCallback(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, @NonNull @CallbackExecutor Executor executor, int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback, boolean notifyNow)1241     public void registerTelephonyCallback(boolean renounceFineLocationAccess,
1242             boolean renounceCoarseLocationAccess,
1243             @NonNull @CallbackExecutor Executor executor,
1244             int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback,
1245             boolean notifyNow) {
1246         if (callback == null) {
1247             throw new IllegalStateException("telephony service is null.");
1248         }
1249         callback.init(executor);
1250         listenFromCallback(renounceFineLocationAccess, renounceCoarseLocationAccess, subId,
1251                 pkgName, attributionTag, callback,
1252                 getEventsFromCallback(callback).stream().mapToInt(i -> i).toArray(), notifyNow);
1253     }
1254 
1255     /**
1256      * Unregister an existing {@link TelephonyCallback}.
1257      *
1258      * @param callback The {@link TelephonyCallback} object to unregister.
1259      */
unregisterTelephonyCallback(int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback, boolean notifyNow)1260     public void unregisterTelephonyCallback(int subId, String pkgName, String attributionTag,
1261             @NonNull TelephonyCallback callback, boolean notifyNow) {
1262         listenFromCallback(false, false, subId,
1263                 pkgName, attributionTag, callback, new int[0], notifyNow);
1264     }
1265 
1266     private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub
1267             implements ListenerExecutor {
1268         @NonNull private final WeakReference<CarrierPrivilegesCallback> mCallback;
1269         @NonNull private final Executor mExecutor;
1270 
CarrierPrivilegesCallbackWrapper( @onNull CarrierPrivilegesCallback callback, @NonNull Executor executor)1271         CarrierPrivilegesCallbackWrapper(
1272                 @NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) {
1273             mCallback = new WeakReference<>(callback);
1274             mExecutor = executor;
1275         }
1276 
1277         @Override
onCarrierPrivilegesChanged( @onNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids)1278         public void onCarrierPrivilegesChanged(
1279                 @NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids) {
1280             // AIDL interface does not support Set, keep the List/Array and translate them here
1281             Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames);
1282             Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect(
1283                     Collectors.toSet());
1284             Binder.withCleanCallingIdentity(
1285                     () ->
1286                             executeSafely(
1287                                     mExecutor,
1288                                     mCallback::get,
1289                                     cpc ->
1290                                             cpc.onCarrierPrivilegesChanged(
1291                                                     privilegedPkgNamesSet, privilegedUidsSet)));
1292         }
1293 
1294         @Override
onCarrierServiceChanged(@ullable String packageName, int uid)1295         public void onCarrierServiceChanged(@Nullable String packageName, int uid) {
1296             Binder.withCleanCallingIdentity(
1297                     () ->
1298                             executeSafely(
1299                                     mExecutor,
1300                                     mCallback::get,
1301                                     cpc -> cpc.onCarrierServiceChanged(packageName, uid)));
1302         }
1303     }
1304 
1305     @NonNull
1306     @GuardedBy("sCarrierPrivilegeCallbacks")
1307     private static final WeakHashMap<CarrierPrivilegesCallback,
1308             WeakReference<CarrierPrivilegesCallbackWrapper>>
1309             sCarrierPrivilegeCallbacks = new WeakHashMap<>();
1310 
1311     /**
1312      * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to
1313      * receive callbacks when the set of packages with carrier privileges changes. The callback will
1314      * immediately be called with the latest state.
1315      *
1316      * @param logicalSlotIndex The SIM slot to listen on
1317      * @param executor The executor where {@code listener} will be invoked
1318      * @param callback The callback to register
1319      */
addCarrierPrivilegesCallback( int logicalSlotIndex, @NonNull @CallbackExecutor Executor executor, @NonNull CarrierPrivilegesCallback callback)1320     public void addCarrierPrivilegesCallback(
1321             int logicalSlotIndex,
1322             @NonNull @CallbackExecutor Executor executor,
1323             @NonNull CarrierPrivilegesCallback callback) {
1324         if (callback == null || executor == null) {
1325             throw new IllegalArgumentException("callback and executor must be non-null");
1326         }
1327         synchronized (sCarrierPrivilegeCallbacks) {
1328             WeakReference<CarrierPrivilegesCallbackWrapper> existing =
1329                     sCarrierPrivilegeCallbacks.get(callback);
1330             if (existing != null && existing.get() != null) {
1331                 Log.d(TAG, "addCarrierPrivilegesCallback: callback already registered");
1332                 return;
1333             }
1334             CarrierPrivilegesCallbackWrapper wrapper =
1335                     new CarrierPrivilegesCallbackWrapper(callback, executor);
1336             sCarrierPrivilegeCallbacks.put(callback, new WeakReference<>(wrapper));
1337             try {
1338                 sRegistry.addCarrierPrivilegesCallback(
1339                         logicalSlotIndex,
1340                         wrapper,
1341                         mContext.getOpPackageName(),
1342                         mContext.getAttributionTag());
1343             } catch (RemoteException e) {
1344                 throw e.rethrowFromSystemServer();
1345             }
1346         }
1347     }
1348 
1349     /**
1350      * Unregisters a {@link CarrierPrivilegesCallback}.
1351      *
1352      * @param callback The callback to unregister
1353      */
removeCarrierPrivilegesCallback(@onNull CarrierPrivilegesCallback callback)1354     public void removeCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) {
1355         if (callback == null) {
1356             throw new IllegalArgumentException("listener must be non-null");
1357         }
1358         synchronized (sCarrierPrivilegeCallbacks) {
1359             WeakReference<CarrierPrivilegesCallbackWrapper> ref =
1360                     sCarrierPrivilegeCallbacks.remove(callback);
1361             if (ref == null) return;
1362             CarrierPrivilegesCallbackWrapper wrapper = ref.get();
1363             if (wrapper == null) return;
1364             try {
1365                 sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName());
1366             } catch (RemoteException e) {
1367                 throw e.rethrowFromSystemServer();
1368             }
1369         }
1370     }
1371 
1372     /**
1373      * Notify listeners that the set of packages with carrier privileges has changed.
1374      *
1375      * @param logicalSlotIndex The SIM slot the change occurred on
1376      * @param privilegedPackageNames The updated set of packages names with carrier privileges
1377      * @param privilegedUids The updated set of UIDs with carrier privileges
1378      */
notifyCarrierPrivilegesChanged( int logicalSlotIndex, @NonNull Set<String> privilegedPackageNames, @NonNull Set<Integer> privilegedUids)1379     public void notifyCarrierPrivilegesChanged(
1380             int logicalSlotIndex,
1381             @NonNull Set<String> privilegedPackageNames,
1382             @NonNull Set<Integer> privilegedUids) {
1383         if (privilegedPackageNames == null || privilegedUids == null) {
1384             throw new IllegalArgumentException(
1385                     "privilegedPackageNames and privilegedUids must be non-null");
1386         }
1387         try {
1388             // AIDL doesn't support Set yet. Convert Set to List/Array
1389             List<String> pkgList = List.copyOf(privilegedPackageNames);
1390             int[] uids = privilegedUids.stream().mapToInt(Number::intValue).toArray();
1391             sRegistry.notifyCarrierPrivilegesChanged(logicalSlotIndex, pkgList, uids);
1392         } catch (RemoteException e) {
1393             throw e.rethrowFromSystemServer();
1394         }
1395     }
1396 
1397     /**
1398      * Notify listeners that the {@link CarrierService} for current user has changed.
1399      *
1400      * @param logicalSlotIndex the SIM slot the change occurred on
1401      * @param packageName the package name of the changed {@link CarrierService}
1402      * @param uid the UID of the changed {@link CarrierService}
1403      */
notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName, int uid)1404     public void notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName,
1405             int uid) {
1406         try {
1407             sRegistry.notifyCarrierServiceChanged(logicalSlotIndex, packageName, uid);
1408         } catch (RemoteException e) {
1409             throw e.rethrowFromSystemServer();
1410         }
1411     }
1412 }
1413