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