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