• 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.NonNull;
19 import android.annotation.Nullable;
20 import android.annotation.RequiresPermission;
21 import android.annotation.TestApi;
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.telephony.Annotation.ApnType;
31 import android.telephony.Annotation.CallState;
32 import android.telephony.Annotation.DataActivityType;
33 import android.telephony.Annotation.DataFailureCause;
34 import android.telephony.Annotation.DisconnectCauses;
35 import android.telephony.Annotation.NetworkType;
36 import android.telephony.Annotation.PreciseCallStates;
37 import android.telephony.Annotation.PreciseDisconnectCauses;
38 import android.telephony.Annotation.RadioPowerState;
39 import android.telephony.Annotation.SimActivationState;
40 import android.telephony.Annotation.SrvccState;
41 import android.telephony.data.ApnSetting;
42 import android.telephony.emergency.EmergencyNumber;
43 import android.telephony.ims.ImsReasonInfo;
44 import android.util.Log;
45 
46 import com.android.internal.telephony.IOnSubscriptionsChangedListener;
47 import com.android.internal.telephony.ITelephonyRegistry;
48 
49 import java.util.HashMap;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.concurrent.Executor;
53 
54 /**
55  * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update
56  * or {@link PhoneCapability} changed. This might trigger callback from applications side through
57  * {@link android.telephony.PhoneStateListener}
58  *
59  * TODO: limit API access to only carrier apps with certain permissions or apps running on
60  * privileged UID.
61  *
62  * @hide
63  */
64 public class TelephonyRegistryManager {
65 
66     private static final String TAG = "TelephonyRegistryManager";
67     private static ITelephonyRegistry sRegistry;
68     private final Context mContext;
69 
70     /**
71      * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and
72      * its callback IOnSubscriptionsChangedListener.
73      */
74     private final Map<SubscriptionManager.OnSubscriptionsChangedListener,
75                 IOnSubscriptionsChangedListener> mSubscriptionChangedListenerMap = new HashMap<>();
76     /**
77      * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and
78      * its callback IOnSubscriptionsChangedListener.
79      */
80     private final Map<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener,
81             IOnSubscriptionsChangedListener> mOpportunisticSubscriptionChangedListenerMap
82             = new HashMap<>();
83 
84 
85     /** @hide **/
TelephonyRegistryManager(@onNull Context context)86     public TelephonyRegistryManager(@NonNull Context context) {
87         mContext = context;
88         if (sRegistry == null) {
89             sRegistry = ITelephonyRegistry.Stub.asInterface(
90                 ServiceManager.getService("telephony.registry"));
91         }
92     }
93 
94     /**
95      * Register for changes to the list of active {@link SubscriptionInfo} records or to the
96      * individual records themselves. When a change occurs the onSubscriptionsChanged method of
97      * the listener will be invoked immediately if there has been a notification. The
98      * onSubscriptionChanged method will also be triggered once initially when calling this
99      * function.
100      *
101      * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener}
102      *                 with onSubscriptionsChanged overridden.
103      * @param executor the executor that will execute callbacks.
104      */
addOnSubscriptionsChangedListener( @onNull SubscriptionManager.OnSubscriptionsChangedListener listener, @NonNull Executor executor)105     public void addOnSubscriptionsChangedListener(
106             @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener,
107             @NonNull Executor executor) {
108         IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
109             @Override
110             public void onSubscriptionsChanged () {
111                 Log.d(TAG, "onSubscriptionsChangedListener callback received.");
112                 executor.execute(() -> listener.onSubscriptionsChanged());
113             }
114         };
115         mSubscriptionChangedListenerMap.put(listener, callback);
116         try {
117             sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(),
118                     mContext.getAttributionTag(), callback);
119         } catch (RemoteException ex) {
120             // system server crash
121         }
122     }
123 
124     /**
125      * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not
126      * strictly necessary as the listener will automatically be unregistered if an attempt to
127      * invoke the listener fails.
128      *
129      * @param listener that is to be unregistered.
130      */
removeOnSubscriptionsChangedListener( @onNull SubscriptionManager.OnSubscriptionsChangedListener listener)131     public void removeOnSubscriptionsChangedListener(
132             @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) {
133         if (mSubscriptionChangedListenerMap.get(listener) == null) {
134             return;
135         }
136         try {
137             sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
138                     mSubscriptionChangedListenerMap.get(listener));
139             mSubscriptionChangedListenerMap.remove(listener);
140         } catch (RemoteException ex) {
141             // system server crash
142         }
143     }
144 
145     /**
146      * Register for changes to the list of opportunistic subscription records or to the
147      * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged
148      * method of the listener will be invoked immediately if there has been a notification.
149      *
150      * @param listener an instance of
151      * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with
152      *                 onOpportunisticSubscriptionsChanged overridden.
153      * @param executor an Executor that will execute callbacks.
154      */
addOnOpportunisticSubscriptionsChangedListener( @onNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, @NonNull Executor executor)155     public void addOnOpportunisticSubscriptionsChangedListener(
156             @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener,
157             @NonNull Executor executor) {
158         /**
159          * The callback methods need to be called on the executor thread where
160          * this object was created.  If the binder did that for us it'd be nice.
161          */
162         IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() {
163             @Override
164             public void onSubscriptionsChanged() {
165                 final long identity = Binder.clearCallingIdentity();
166                 try {
167                     Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received.");
168                     executor.execute(() -> listener.onOpportunisticSubscriptionsChanged());
169                 } finally {
170                     Binder.restoreCallingIdentity(identity);
171                 }
172             }
173         };
174         mOpportunisticSubscriptionChangedListenerMap.put(listener, callback);
175         try {
176             sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(),
177                     mContext.getAttributionTag(), callback);
178         } catch (RemoteException ex) {
179             // system server crash
180         }
181     }
182 
183     /**
184      * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener}
185      * that is currently listening opportunistic subscriptions change. This is not strictly
186      * necessary as the listener will automatically be unregistered if an attempt to invoke the
187      * listener fails.
188      *
189      * @param listener that is to be unregistered.
190      */
removeOnOpportunisticSubscriptionsChangedListener( @onNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener)191     public void removeOnOpportunisticSubscriptionsChangedListener(
192             @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) {
193         try {
194             sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(),
195                     mOpportunisticSubscriptionChangedListenerMap.get(listener));
196             mOpportunisticSubscriptionChangedListenerMap.remove(listener);
197         } catch (RemoteException ex) {
198             // system server crash
199         }
200     }
201 
202     /**
203      * To check the SDK version for {@link #listenForSubscriber}.
204      */
205     @ChangeId
206     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P)
207     private static final long LISTEN_CODE_CHANGE = 147600208L;
208 
209     /**
210      * Listen for incoming subscriptions
211      * @param subId Subscription ID
212      * @param pkg Package name
213      * @param featureId Feature ID
214      * @param listener Listener providing callback
215      * @param events Events
216      * @param notifyNow Whether to notify instantly
217      */
listenForSubscriber(int subId, @NonNull String pkg, @NonNull String featureId, @NonNull PhoneStateListener listener, int events, boolean notifyNow)218     public void listenForSubscriber(int subId, @NonNull String pkg, @NonNull String featureId,
219             @NonNull PhoneStateListener listener, int events, boolean notifyNow) {
220         try {
221             // subId from PhoneStateListener is deprecated Q on forward, use the subId from
222             // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q.
223             if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) {
224                 // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is
225                 // the only place to set mSubId and its for "informational" only.
226                 listener.mSubId = (events == PhoneStateListener.LISTEN_NONE)
227                         ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId;
228             } else if (listener.mSubId != null) {
229                 subId = listener.mSubId;
230             }
231             sRegistry.listenForSubscriber(
232                     subId, pkg, featureId, listener.callback, events, notifyNow);
233         } catch (RemoteException e) {
234             throw e.rethrowFromSystemServer();
235         }
236     }
237 
238     /**
239      * Informs the system of an intentional upcoming carrier network change by a carrier app.
240      * This call only used to allow the system to provide alternative UI while telephony is
241      * performing an action that may result in intentional, temporary network lack of connectivity.
242      * <p>
243      * Based on the active parameter passed in, this method will either show or hide the alternative
244      * UI. There is no timeout associated with showing this UX, so a carrier app must be sure to
245      * call with active set to false sometime after calling with it set to {@code true}.
246      * <p>
247      * Requires Permission: calling app has carrier privileges.
248      *
249      * @param active Whether the carrier network change is or shortly will be
250      * active. Set this value to true to begin showing alternative UI and false to stop.
251      * @see TelephonyManager#hasCarrierPrivileges
252      */
notifyCarrierNetworkChange(boolean active)253     public void notifyCarrierNetworkChange(boolean active) {
254         try {
255             sRegistry.notifyCarrierNetworkChange(active);
256         } catch (RemoteException ex) {
257             // system server crash
258         }
259     }
260 
261     /**
262      * Notify call state changed on certain subscription.
263      *
264      * @param subId for which call state changed.
265      * @param slotIndex for which call state changed. Can be derived from subId except when subId is
266      * invalid.
267      * @param state latest call state. e.g, offhook, ringing
268      * @param incomingNumber incoming phone number.
269      */
notifyCallStateChanged(int subId, int slotIndex, @CallState int state, @Nullable String incomingNumber)270     public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state,
271             @Nullable String incomingNumber) {
272         try {
273             sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber);
274         } catch (RemoteException ex) {
275             // system server crash
276         }
277     }
278 
279     /**
280      * Notify call state changed on all subscriptions.
281      *
282      * @param state latest call state. e.g, offhook, ringing
283      * @param incomingNumber incoming phone number.
284      * @hide
285      */
286     @TestApi
287     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
notifyCallStateChangedForAllSubscriptions(@allState int state, @Nullable String incomingNumber)288     public void notifyCallStateChangedForAllSubscriptions(@CallState int state,
289             @Nullable String incomingNumber) {
290         try {
291             sRegistry.notifyCallStateForAllSubs(state, incomingNumber);
292         } catch (RemoteException ex) {
293             // system server crash
294         }
295     }
296 
297     /**
298      * Notify {@link SubscriptionInfo} change.
299      * @hide
300      */
notifySubscriptionInfoChanged()301     public void notifySubscriptionInfoChanged() {
302         try {
303             sRegistry.notifySubscriptionInfoChanged();
304         } catch (RemoteException ex) {
305             // system server crash
306         }
307     }
308 
309     /**
310      * Notify opportunistic {@link SubscriptionInfo} change.
311      * @hide
312      */
notifyOpportunisticSubscriptionInfoChanged()313     public void notifyOpportunisticSubscriptionInfoChanged() {
314         try {
315             sRegistry.notifyOpportunisticSubscriptionInfoChanged();
316         } catch (RemoteException ex) {
317             // system server crash
318         }
319     }
320 
321     /**
322      * Notify {@link ServiceState} update on certain subscription.
323      *
324      * @param subId for which the service state changed.
325      * @param slotIndex for which the service state changed. Can be derived from subId except
326      * subId is invalid.
327      * @param state service state e.g, in service, out of service or roaming status.
328      */
notifyServiceStateChanged(int subId, int slotIndex, @NonNull ServiceState state)329     public void notifyServiceStateChanged(int subId, int slotIndex, @NonNull ServiceState state) {
330         try {
331             sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state);
332         } catch (RemoteException ex) {
333             // system server crash
334         }
335     }
336 
337     /**
338      * Notify {@link SignalStrength} update on certain subscription.
339      *
340      * @param subId for which the signalstrength changed.
341      * @param slotIndex for which the signalstrength changed. Can be derived from subId except when
342      * subId is invalid.
343      * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()}
344      */
notifySignalStrengthChanged(int subId, int slotIndex, @NonNull SignalStrength signalStrength)345     public void notifySignalStrengthChanged(int subId, int slotIndex,
346             @NonNull SignalStrength signalStrength) {
347         try {
348             sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength);
349         } catch (RemoteException ex) {
350             // system server crash
351         }
352     }
353 
354     /**
355      * Notify changes to the message-waiting indicator on certain subscription. e.g, The status bar
356      * uses message waiting indicator to determine when to display the voicemail icon.
357      *
358      * @param subId for which message waiting indicator changed.
359      * @param slotIndex for which message waiting indicator changed. Can be derived from subId
360      * except when subId is invalid.
361      * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false}
362      * otherwise.
363      */
notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd)364     public void notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd) {
365         try {
366             sRegistry.notifyMessageWaitingChangedForPhoneId(slotIndex, subId, msgWaitingInd);
367         } catch (RemoteException ex) {
368             // system process is dead
369         }
370     }
371 
372     /**
373      * Notify changes to the call-forwarding status on certain subscription.
374      *
375      * @param subId for which call forwarding status changed.
376      * @param callForwardInd {@code true} indicates there is call forwarding, {@code false}
377      * otherwise.
378      */
notifyCallForwardingChanged(int subId, boolean callForwardInd)379     public void notifyCallForwardingChanged(int subId, boolean callForwardInd) {
380         try {
381             sRegistry.notifyCallForwardingChangedForSubscriber(subId, callForwardInd);
382         } catch (RemoteException ex) {
383             // system process is dead
384         }
385     }
386 
387     /**
388      * Notify changes to activity state changes on certain subscription.
389      *
390      * @param subId for which data activity state changed.
391      * @param dataActivityType indicates the latest data activity type e.g, {@link
392      * TelephonyManager#DATA_ACTIVITY_IN}
393      */
notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType)394     public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) {
395         try {
396             sRegistry.notifyDataActivityForSubscriber(subId, dataActivityType);
397         } catch (RemoteException ex) {
398             // system process is dead
399         }
400     }
401 
402     /**
403      * Notify changes to default (Internet) data connection state on certain subscription.
404      *
405      * @param subId for which data connection state changed.
406      * @param slotIndex for which data connections state changed. Can be derived from subId except
407      * when subId is invalid.
408      * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags.
409      * @param preciseState the PreciseDataConnectionState
410      *
411      * @see android.telephony.PreciseDataConnection
412      * @see TelephonyManager#DATA_DISCONNECTED
413      */
notifyDataConnectionForSubscriber(int slotIndex, int subId, @ApnType int apnType, @Nullable PreciseDataConnectionState preciseState)414     public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
415             @ApnType int apnType, @Nullable PreciseDataConnectionState preciseState) {
416         try {
417             sRegistry.notifyDataConnectionForSubscriber(
418                     slotIndex, subId, apnType, preciseState);
419         } catch (RemoteException ex) {
420             // system process is dead
421         }
422     }
423 
424     /**
425      * Notify {@link CallQuality} change on certain subscription.
426      *
427      * @param subId for which call quality state changed.
428      * @param slotIndex for which call quality state changed. Can be derived from subId except when
429      * subId is invalid.
430      * @param callQuality Information about call quality e.g, call quality level
431      * @param networkType associated with this data connection. e.g, LTE
432      */
notifyCallQualityChanged(int subId, int slotIndex, @NonNull CallQuality callQuality, @NetworkType int networkType)433     public void notifyCallQualityChanged(int subId, int slotIndex, @NonNull CallQuality callQuality,
434         @NetworkType int networkType) {
435         try {
436             sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType);
437         } catch (RemoteException ex) {
438             // system process is dead
439         }
440     }
441 
442     /**
443      * Notify emergency number list changed on certain subscription.
444      *
445      * @param subId for which emergency number list changed.
446      * @param slotIndex for which emergency number list changed. Can be derived from subId except
447      * when subId is invalid.
448      */
notifyEmergencyNumberList(int subId, int slotIndex)449     public void notifyEmergencyNumberList(int subId, int slotIndex) {
450         try {
451             sRegistry.notifyEmergencyNumberList(slotIndex, subId);
452         } catch (RemoteException ex) {
453             // system process is dead
454         }
455     }
456 
457     /**
458      * Notify outgoing emergency call.
459      * @param phoneId Sender phone ID.
460      * @param subId Sender subscription ID.
461      * @param emergencyNumber Emergency number.
462      */
notifyOutgoingEmergencyCall(int phoneId, int subId, @NonNull EmergencyNumber emergencyNumber)463     public void notifyOutgoingEmergencyCall(int phoneId, int subId,
464             @NonNull EmergencyNumber emergencyNumber) {
465         try {
466             sRegistry.notifyOutgoingEmergencyCall(phoneId, subId, emergencyNumber);
467         } catch (RemoteException ex) {
468             // system process is dead
469         }
470     }
471 
472     /**
473      * Notify outgoing emergency SMS.
474      * @param phoneId Sender phone ID.
475      * @param subId Sender subscription ID.
476      * @param emergencyNumber Emergency number.
477      */
notifyOutgoingEmergencySms(int phoneId, int subId, @NonNull EmergencyNumber emergencyNumber)478     public void notifyOutgoingEmergencySms(int phoneId, int subId,
479             @NonNull EmergencyNumber emergencyNumber) {
480         try {
481             sRegistry.notifyOutgoingEmergencySms(phoneId, subId, emergencyNumber);
482         } catch (RemoteException ex) {
483             // system process is dead
484         }
485     }
486 
487     /**
488      * Notify radio power state changed on certain subscription.
489      *
490      * @param subId for which radio power state changed.
491      * @param slotIndex for which radio power state changed. Can be derived from subId except when
492      * subId is invalid.
493      * @param radioPowerState the current modem radio state.
494      */
notifyRadioPowerStateChanged(int subId, int slotIndex, @RadioPowerState int radioPowerState)495     public void notifyRadioPowerStateChanged(int subId, int slotIndex,
496         @RadioPowerState int radioPowerState) {
497         try {
498             sRegistry.notifyRadioPowerStateChanged(slotIndex, subId, radioPowerState);
499         } catch (RemoteException ex) {
500             // system process is dead
501         }
502     }
503 
504     /**
505      * Notify {@link PhoneCapability} changed.
506      *
507      * @param phoneCapability the capability of the modem group.
508      */
notifyPhoneCapabilityChanged(@onNull PhoneCapability phoneCapability)509     public void notifyPhoneCapabilityChanged(@NonNull PhoneCapability phoneCapability) {
510         try {
511             sRegistry.notifyPhoneCapabilityChanged(phoneCapability);
512         } catch (RemoteException ex) {
513             // system process is dead
514         }
515     }
516 
517     /**
518      * Sim activation type: voice
519      * @see #notifyVoiceActivationStateChanged
520      * @hide
521      */
522     public static final int SIM_ACTIVATION_TYPE_VOICE = 0;
523     /**
524      * Sim activation type: data
525      * @see #notifyDataActivationStateChanged
526      * @hide
527      */
528     public static final int SIM_ACTIVATION_TYPE_DATA = 1;
529 
530     /**
531      * Notify data activation state changed on certain subscription.
532      * @see TelephonyManager#getDataActivationState()
533      *
534      * @param subId for which data activation state changed.
535      * @param slotIndex for which data activation state changed. Can be derived from subId except
536      * when subId is invalid.
537      * @param activationState sim activation state e.g, activated.
538      */
notifyDataActivationStateChanged(int subId, int slotIndex, @SimActivationState int activationState)539     public void notifyDataActivationStateChanged(int subId, int slotIndex,
540         @SimActivationState int activationState) {
541         try {
542             sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
543                     SIM_ACTIVATION_TYPE_DATA, activationState);
544         } catch (RemoteException ex) {
545             // system process is dead
546         }
547     }
548 
549     /**
550      * Notify voice activation state changed on certain subscription.
551      * @see TelephonyManager#getVoiceActivationState()
552      *
553      * @param subId for which voice activation state changed.
554      * @param slotIndex for which voice activation state changed. Can be derived from subId except
555      * subId is invalid.
556      * @param activationState sim activation state e.g, activated.
557      */
notifyVoiceActivationStateChanged(int subId, int slotIndex, @SimActivationState int activationState)558     public void notifyVoiceActivationStateChanged(int subId, int slotIndex,
559         @SimActivationState int activationState) {
560         try {
561             sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
562                     SIM_ACTIVATION_TYPE_VOICE, activationState);
563         } catch (RemoteException ex) {
564             // system process is dead
565         }
566     }
567 
568     /**
569      * Notify User mobile data state changed on certain subscription. e.g, mobile data is enabled
570      * or disabled.
571      *
572      * @param subId for which mobile data state has changed.
573      * @param slotIndex for which mobile data state has changed. Can be derived from subId except
574      * when subId is invalid.
575      * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise.
576      */
notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state)577     public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) {
578         try {
579             sRegistry.notifyUserMobileDataStateChangedForPhoneId(slotIndex, subId, state);
580         } catch (RemoteException ex) {
581             // system process is dead
582         }
583     }
584 
585     /**
586      * Notify display info changed.
587      *
588      * @param slotIndex The SIM slot index for which display info has changed. Can be
589      * derived from {@code subscriptionId} except when {@code subscriptionId} is invalid, such as
590      * when the device is in emergency-only mode.
591      * @param subscriptionId Subscription id for which display network info has changed.
592      * @param telephonyDisplayInfo The display info.
593      */
notifyDisplayInfoChanged(int slotIndex, int subscriptionId, @NonNull TelephonyDisplayInfo telephonyDisplayInfo)594     public void notifyDisplayInfoChanged(int slotIndex, int subscriptionId,
595                                          @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
596         try {
597             sRegistry.notifyDisplayInfoChanged(slotIndex, subscriptionId, telephonyDisplayInfo);
598         } catch (RemoteException ex) {
599             // system process is dead
600         }
601     }
602 
603     /**
604      * Notify IMS call disconnect causes which contains {@link android.telephony.ims.ImsReasonInfo}.
605      *
606      * @param subId for which ims call disconnect.
607      * @param imsReasonInfo the reason for ims call disconnect.
608      */
notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo)609     public void notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo) {
610         try {
611             sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo);
612         } catch (RemoteException ex) {
613             // system process is dead
614         }
615     }
616 
617     /**
618      * Notify precise data connection failed cause on certain subscription.
619      *
620      * @param subId for which data connection failed.
621      * @param slotIndex for which data conenction failed. Can be derived from subId except when
622      * subId is invalid.
623      * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags.
624      * @param apn the APN {@link ApnSetting#getApnName()} of this data connection.
625      * @param failCause data fail cause.
626      */
notifyPreciseDataConnectionFailed(int subId, int slotIndex, @ApnType int apnType, @Nullable String apn, @DataFailureCause int failCause)627     public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, @ApnType int apnType,
628             @Nullable String apn, @DataFailureCause int failCause) {
629         try {
630             sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause);
631         } catch (RemoteException ex) {
632             // system process is dead
633         }
634     }
635 
636     /**
637      * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call
638      * on certain subscription.
639      *
640      * @param subId for which srvcc state changed.
641      * @param state srvcc state
642      */
notifySrvccStateChanged(int subId, @SrvccState int state)643     public void notifySrvccStateChanged(int subId, @SrvccState int state) {
644         try {
645             sRegistry.notifySrvccStateChanged(subId, state);
646         } catch (RemoteException ex) {
647             // system process is dead
648         }
649     }
650 
651     /**
652      * Notify precise call state changed on certain subscription, including foreground, background
653      * and ringcall states.
654      *
655      * @param subId for which precise call state changed.
656      * @param slotIndex for which precise call state changed. Can be derived from subId except when
657      * subId is invalid.
658      * @param ringCallPreciseState ringCall state.
659      * @param foregroundCallPreciseState foreground call state.
660      * @param backgroundCallPreciseState background call state.
661      */
notifyPreciseCallState(int subId, int slotIndex, @PreciseCallStates int ringCallPreciseState, @PreciseCallStates int foregroundCallPreciseState, @PreciseCallStates int backgroundCallPreciseState)662     public void notifyPreciseCallState(int subId, int slotIndex,
663             @PreciseCallStates int ringCallPreciseState,
664             @PreciseCallStates int foregroundCallPreciseState,
665             @PreciseCallStates int backgroundCallPreciseState) {
666         try {
667             sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState,
668                 foregroundCallPreciseState, backgroundCallPreciseState);
669         } catch (RemoteException ex) {
670             // system process is dead
671         }
672     }
673 
674     /**
675      * Notify call disconnect causes which contains {@link DisconnectCause} and {@link
676      * android.telephony.PreciseDisconnectCause}.
677      *
678      * @param slotIndex for which call disconnected. Can be derived from subId except when subId is
679      * invalid.
680      * @param subId for which call disconnected.
681      * @param cause {@link DisconnectCause} for the disconnected call.
682      * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected
683      * call.
684      */
notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause, @PreciseDisconnectCauses int preciseCause)685     public void notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause,
686             @PreciseDisconnectCauses int preciseCause) {
687         try {
688             sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause);
689         } catch (RemoteException ex) {
690             // system process is dead
691         }
692     }
693 
694     /**
695      * Notify {@link android.telephony.CellLocation} changed.
696      *
697      * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is
698      * parcelable, and convert to CellLocation in client code.
699      */
notifyCellLocation(int subId, @NonNull CellIdentity cellLocation)700     public void notifyCellLocation(int subId, @NonNull CellIdentity cellLocation) {
701         try {
702             sRegistry.notifyCellLocationForSubscriber(subId, cellLocation);
703         } catch (RemoteException ex) {
704             // system process is dead
705         }
706     }
707 
708     /**
709      * Notify {@link CellInfo} changed on certain subscription. e.g, when an observed cell info has
710      * changed or new cells have been added or removed on the given subscription.
711      *
712      * @param subId for which cellinfo changed.
713      * @param cellInfo A list of cellInfo associated with the given subscription.
714      */
notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo)715     public void notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo) {
716         try {
717             sRegistry.notifyCellInfoForSubscriber(subId, cellInfo);
718         } catch (RemoteException ex) {
719 
720         }
721     }
722 
723     /**
724      * Notify that the active data subscription ID has changed.
725      * @param activeDataSubId The new subscription ID for active data
726      */
notifyActiveDataSubIdChanged(int activeDataSubId)727     public void notifyActiveDataSubIdChanged(int activeDataSubId) {
728         try {
729             sRegistry.notifyActiveDataSubIdChanged(activeDataSubId);
730         } catch (RemoteException ex) {
731 
732         }
733     }
734 
735     /**
736      * Report that Registration or a Location/Routing/Tracking Area update has failed.
737      *
738      * @param slotIndex for which call disconnected. Can be derived from subId except when subId is
739      * invalid.
740      * @param subId for which cellinfo changed.
741      * @param cellIdentity the CellIdentity, which must include the globally unique identifier
742      *        for the cell (for example, all components of the CGI or ECGI).
743      * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the
744      *         cell that was chosen for the failed registration attempt.
745      * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure.
746      * @param causeCode the primary failure cause code of the procedure.
747      *        For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95
748      *        For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147
749      *        For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9
750      *        For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2
751      *        Integer.MAX_VALUE if this value is unused.
752      * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate.
753      *        For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be
754      *        included as an additionalCauseCode. For LTE (ESM), cause codes are in
755      *        TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused.
756      */
notifyRegistrationFailed(int slotIndex, int subId, @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode)757     public void notifyRegistrationFailed(int slotIndex, int subId,
758             @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn,
759             int domain, int causeCode, int additionalCauseCode) {
760         try {
761             sRegistry.notifyRegistrationFailed(slotIndex, subId, cellIdentity,
762                     chosenPlmn, domain, causeCode, additionalCauseCode);
763         } catch (RemoteException ex) {
764         }
765     }
766 
767     /**
768      * Notify {@link BarringInfo} has changed for a specific subscription.
769      *
770      * @param slotIndex for the phone object that got updated barring info.
771      * @param subId for which the BarringInfo changed.
772      * @param barringInfo updated BarringInfo.
773      */
notifyBarringInfoChanged( int slotIndex, int subId, @NonNull BarringInfo barringInfo)774     public void notifyBarringInfoChanged(
775             int slotIndex, int subId, @NonNull BarringInfo barringInfo) {
776         try {
777             sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo);
778         } catch (RemoteException ex) {
779             // system server crash
780         }
781     }
782 
783 }
784