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