• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package android.telephony.ims;
18 
19 
20 import android.Manifest;
21 import android.annotation.CallbackExecutor;
22 import android.annotation.IntDef;
23 import android.annotation.NonNull;
24 import android.annotation.RequiresFeature;
25 import android.annotation.RequiresPermission;
26 import android.annotation.SuppressAutoDoc;
27 import android.annotation.SuppressLint;
28 import android.annotation.SystemApi;
29 import android.content.Context;
30 import android.content.pm.PackageManager;
31 import android.os.Binder;
32 import android.os.RemoteException;
33 import android.os.ServiceSpecificException;
34 import android.telephony.AccessNetworkConstants;
35 import android.telephony.BinderCacheManager;
36 import android.telephony.CarrierConfigManager;
37 import android.telephony.SubscriptionManager;
38 import android.telephony.TelephonyFrameworkInitializer;
39 import android.telephony.ims.aidl.IImsCapabilityCallback;
40 import android.telephony.ims.feature.ImsFeature;
41 import android.telephony.ims.feature.MmTelFeature;
42 import android.telephony.ims.stub.ImsRegistrationImplBase;
43 import android.util.Log;
44 
45 import com.android.internal.annotations.VisibleForTesting;
46 import com.android.internal.telephony.IIntegerConsumer;
47 import com.android.internal.telephony.ITelephony;
48 
49 import java.lang.annotation.Retention;
50 import java.lang.annotation.RetentionPolicy;
51 import java.util.Objects;
52 import java.util.concurrent.Executor;
53 import java.util.function.Consumer;
54 
55 /**
56  * A manager for the MmTel (Multimedia Telephony) feature of an IMS network, given an associated
57  * subscription.
58  *
59  * Allows a user to query the IMS MmTel feature information for a subscription, register for
60  * registration and MmTel capability status callbacks, as well as query/modify user settings for the
61  * associated subscription.
62  *
63  * Use {@link android.telephony.ims.ImsManager#getImsMmTelManager(int)} to get an instance of this
64  * manager.
65  */
66 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
67 public class ImsMmTelManager implements RegistrationManager {
68     private static final String TAG = "ImsMmTelManager";
69 
70     /**
71      * @hide
72      */
73     @Retention(RetentionPolicy.SOURCE)
74     @IntDef(prefix = "WIFI_MODE_", value = {
75             WIFI_MODE_WIFI_ONLY,
76             WIFI_MODE_CELLULAR_PREFERRED,
77             WIFI_MODE_WIFI_PREFERRED
78             })
79     public @interface WiFiCallingMode {}
80 
81     /**
82      * Register for IMS over IWLAN if WiFi signal quality is high enough. Do not hand over to LTE
83      * registration if signal quality degrades.
84      */
85     public static final int WIFI_MODE_WIFI_ONLY = 0;
86 
87     /**
88      * Prefer registering for IMS over LTE if LTE signal quality is high enough.
89      */
90     public static final int WIFI_MODE_CELLULAR_PREFERRED = 1;
91 
92     /**
93      * Prefer registering for IMS over IWLAN if possible if WiFi signal quality is high enough.
94      */
95     public static final int WIFI_MODE_WIFI_PREFERRED = 2;
96 
97     /**
98      * Callback class for receiving IMS network Registration callback events.
99      * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) (RegistrationCallback)
100      * @see #unregisterImsRegistrationCallback(RegistrationCallback)
101      * @deprecated Use {@link RegistrationManager.RegistrationCallback} instead.
102      * @hide
103      */
104     // Do not add to this class, add to RegistrationManager.RegistrationCallback instead.
105     @Deprecated
106     @SystemApi
107     public static class RegistrationCallback extends RegistrationManager.RegistrationCallback {
108 
109         /**
110          * Notifies the framework when the IMS Provider is registered to the IMS network.
111          *
112          * @param imsTransportType the radio access technology.
113          */
114         @Override
onRegistered(@ccessNetworkConstants.TransportType int imsTransportType)115         public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
116         }
117 
118         /**
119          * Notifies the framework when the IMS Provider is trying to register the IMS network.
120          *
121          * @param imsTransportType the radio access technology.
122          */
123         @Override
onRegistering(@ccessNetworkConstants.TransportType int imsTransportType)124         public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
125         }
126 
127         /**
128          * Notifies the framework when the IMS Provider is deregistered from the IMS network.
129          *
130          * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
131          */
132         @Override
onUnregistered(@onNull ImsReasonInfo info)133         public void onUnregistered(@NonNull ImsReasonInfo info) {
134         }
135 
136         /**
137          * A failure has occurred when trying to handover registration to another technology type.
138          *
139          * @param imsTransportType The transport type that has failed to handover registration to.
140          * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
141          */
142         @Override
onTechnologyChangeFailed( @ccessNetworkConstants.TransportType int imsTransportType, @NonNull ImsReasonInfo info)143         public void onTechnologyChangeFailed(
144                 @AccessNetworkConstants.TransportType int imsTransportType,
145                 @NonNull ImsReasonInfo info) {
146         }
147     }
148 
149     /**
150      * Receives IMS capability status updates from the ImsService.
151      *
152      * @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback) (CapabilityCallback)
153      * @see #unregisterMmTelCapabilityCallback(CapabilityCallback)
154      */
155     public static class CapabilityCallback {
156 
157         private static class CapabilityBinder extends IImsCapabilityCallback.Stub {
158 
159             private final CapabilityCallback mLocalCallback;
160             private Executor mExecutor;
161 
CapabilityBinder(CapabilityCallback c)162             CapabilityBinder(CapabilityCallback c) {
163                 mLocalCallback = c;
164             }
165 
166             @Override
onCapabilitiesStatusChanged(int config)167             public void onCapabilitiesStatusChanged(int config) {
168                 if (mLocalCallback == null) return;
169 
170                 final long callingIdentity = Binder.clearCallingIdentity();
171                 try {
172                     mExecutor.execute(() -> mLocalCallback.onCapabilitiesStatusChanged(
173                             new MmTelFeature.MmTelCapabilities(config)));
174                 } finally {
175                     restoreCallingIdentity(callingIdentity);
176                 }
177             }
178 
179             @Override
onQueryCapabilityConfiguration(int capability, int radioTech, boolean isEnabled)180             public void onQueryCapabilityConfiguration(int capability, int radioTech,
181                     boolean isEnabled) {
182                 // This is not used for public interfaces.
183             }
184 
185             @Override
onChangeCapabilityConfigurationError(int capability, int radioTech, @ImsFeature.ImsCapabilityError int reason)186             public void onChangeCapabilityConfigurationError(int capability, int radioTech,
187                     @ImsFeature.ImsCapabilityError int reason) {
188                 // This is not used for public interfaces
189             }
190 
setExecutor(Executor executor)191             private void setExecutor(Executor executor) {
192                 mExecutor = executor;
193             }
194         }
195 
196         private final CapabilityBinder mBinder = new CapabilityBinder(this);
197 
198         /**
199          * The status of the feature's capabilities has changed to either available or unavailable.
200          * If unavailable, the feature is not able to support the unavailable capability at this
201          * time.
202          *
203          * @param capabilities The new availability of the capabilities.
204          */
onCapabilitiesStatusChanged( @onNull MmTelFeature.MmTelCapabilities capabilities)205         public void onCapabilitiesStatusChanged(
206                 @NonNull MmTelFeature.MmTelCapabilities capabilities) {
207         }
208 
209         /**@hide*/
getBinder()210         public final IImsCapabilityCallback getBinder() {
211             return mBinder;
212         }
213 
214         /**@hide*/
215         // Only exposed as public method for compatibility with deprecated ImsManager APIs.
216         // TODO: clean up dependencies and change back to private visibility.
setExecutor(Executor executor)217         public final void setExecutor(Executor executor) {
218             mBinder.setExecutor(executor);
219         }
220     }
221 
222     private final Context mContext;
223     private final int mSubId;
224     private final BinderCacheManager<ITelephony> mBinderCache;
225 
226     // Cache Telephony Binder interfaces, one cache per process.
227     private static final BinderCacheManager<ITelephony> sTelephonyCache =
228             new BinderCacheManager<>(ImsMmTelManager::getITelephonyInterface);
229 
230     /**
231      * Create an instance of {@link ImsMmTelManager} for the subscription id specified.
232      *
233      * @param subId The ID of the subscription that this ImsMmTelManager will use.
234      * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
235      *
236      * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
237      * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
238      * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
239      *
240      * @throws IllegalArgumentException if the subscription is invalid.
241      * @deprecated Use {@link android.telephony.ims.ImsManager#getImsMmTelManager(int)} to get an
242      * instance of this class.
243      * @hide
244      */
245     @SystemApi
246     @Deprecated
247     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
248     @RequiresPermission(anyOf = {
249             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
250             android.Manifest.permission.READ_PRECISE_PHONE_STATE
251     })
252     @SuppressLint("ManagerLookup")
createForSubscriptionId(int subId)253     public static @NonNull ImsMmTelManager createForSubscriptionId(int subId) {
254         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
255             throw new IllegalArgumentException("Invalid subscription ID");
256         }
257 
258         return new ImsMmTelManager(subId, sTelephonyCache);
259     }
260 
261     /**
262      * Only visible for testing, use {@link ImsManager#getImsMmTelManager(int)} instead.
263      * @hide
264      */
265     @VisibleForTesting
ImsMmTelManager(int subId, BinderCacheManager<ITelephony> binderCache)266     public ImsMmTelManager(int subId, BinderCacheManager<ITelephony> binderCache) {
267         this(null, subId, binderCache);
268     }
269 
270     /**
271      * Only visible for testing, use {@link ImsManager#getImsMmTelManager(int)} instead.
272      * @hide
273      */
274     @VisibleForTesting
ImsMmTelManager(Context context, int subId, BinderCacheManager<ITelephony> binderCache)275     public ImsMmTelManager(Context context, int subId, BinderCacheManager<ITelephony> binderCache) {
276         mContext = context;
277         mSubId = subId;
278         mBinderCache = binderCache;
279     }
280 
281     /**
282      * Registers a {@link RegistrationCallback} with the system, which will provide registration
283      * updates for the subscription specified in {@link ImsManager#getImsMmTelManager(int)}. Use
284      * {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
285      * events and call {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up.
286      *
287      * When the callback is registered, it will initiate the callback c to be called with the
288      * current registration state.
289      *
290      * @param executor The executor the callback events should be run on.
291      * @param c The {@link RegistrationCallback} to be added.
292      * @see #unregisterImsRegistrationCallback(RegistrationCallback)
293      * @throws IllegalArgumentException if the subscription associated with this callback is not
294      * active (SIM is not inserted, ESIM inactive) or invalid, or a null {@link Executor} or
295      * {@link CapabilityCallback} callback.
296      * @throws ImsException if the subscription associated with this callback is valid, but
297      * the {@link ImsService} associated with the subscription is not available. This can happen if
298      * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
299      * reason.
300      * @deprecated Use {@link RegistrationManager#registerImsRegistrationCallback(Executor,
301      * RegistrationManager.RegistrationCallback)} instead.
302      * @hide
303      */
304     @Deprecated
305     @SystemApi
306     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
registerImsRegistrationCallback(@onNull @allbackExecutor Executor executor, @NonNull RegistrationCallback c)307     public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
308             @NonNull RegistrationCallback c) throws ImsException {
309         if (c == null) {
310             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
311         }
312         if (executor == null) {
313             throw new IllegalArgumentException("Must include a non-null Executor.");
314         }
315         c.setExecutor(executor);
316 
317         ITelephony iTelephony = getITelephony();
318         if (iTelephony == null) {
319             throw new ImsException("Could not find Telephony Service.",
320                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
321         }
322 
323         try {
324             iTelephony.registerImsRegistrationCallback(mSubId, c.getBinder());
325         } catch (ServiceSpecificException e) {
326             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
327                 // Rethrow as runtime error to keep API compatible.
328                 throw new IllegalArgumentException(e.getMessage());
329             } else {
330                 throw new ImsException(e.getMessage(), e.errorCode);
331             }
332         } catch (RemoteException | IllegalStateException e) {
333             throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
334         }
335     }
336 
337      /**
338      *
339      * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
340      * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
341      * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
342      *
343      * {@inheritDoc}
344      *
345      */
346     @Override
347     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
348     @RequiresPermission(anyOf = {
349             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
350             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
registerImsRegistrationCallback(@onNull @allbackExecutor Executor executor, @NonNull RegistrationManager.RegistrationCallback c)351     public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
352             @NonNull RegistrationManager.RegistrationCallback c) throws ImsException {
353         if (c == null) {
354             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
355         }
356         if (executor == null) {
357             throw new IllegalArgumentException("Must include a non-null Executor.");
358         }
359         c.setExecutor(executor);
360 
361         ITelephony iTelephony = getITelephony();
362         if (iTelephony == null) {
363             throw new ImsException("Could not find Telephony Service.",
364                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
365         }
366 
367         try {
368             iTelephony.registerImsRegistrationCallback(mSubId, c.getBinder());
369         } catch (ServiceSpecificException e) {
370             throw new ImsException(e.getMessage(), e.errorCode);
371         } catch (RemoteException | IllegalStateException e) {
372             throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
373         }
374     }
375 
376     /**
377      * Removes an existing {@link RegistrationCallback}.
378      *
379      * When the subscription associated with this callback is removed (SIM removed, ESIM swap,
380      * etc...), this callback will automatically be removed. If this method is called for an
381      * inactive subscription, it will result in a no-op.
382      *
383      * @param c The {@link RegistrationCallback} to be removed.
384      * @see SubscriptionManager.OnSubscriptionsChangedListener
385      * @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
386      * @deprecated Use {@link #unregisterImsRegistrationCallback(
387      * RegistrationManager.RegistrationCallback)}.
388      * @hide
389      */
390     @Deprecated
391     @SystemApi
392     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
unregisterImsRegistrationCallback(@onNull RegistrationCallback c)393     public void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c) {
394         if (c == null) {
395             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
396         }
397 
398         ITelephony iTelephony = getITelephony();
399         if (iTelephony == null) {
400             throw new RuntimeException("Could not find Telephony Service.");
401         }
402 
403         try {
404             iTelephony.unregisterImsRegistrationCallback(mSubId, c.getBinder());
405         } catch (RemoteException e) {
406             throw e.rethrowAsRuntimeException();
407         }
408     }
409 
410      /**
411      *
412      * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
413      * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
414      * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
415      * Access by profile owners is deprecated and will be removed in a future release.
416      *
417      *{@inheritDoc}
418      */
419     @Override
420     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
421     @RequiresPermission(anyOf = {
422             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
423             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
unregisterImsRegistrationCallback( @onNull RegistrationManager.RegistrationCallback c)424     public void unregisterImsRegistrationCallback(
425             @NonNull RegistrationManager.RegistrationCallback c) {
426         if (c == null) {
427             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
428         }
429 
430         ITelephony iTelephony = getITelephony();
431         if (iTelephony == null) {
432             throw new RuntimeException("Could not find Telephony Service.");
433         }
434 
435         try {
436             iTelephony.unregisterImsRegistrationCallback(mSubId, c.getBinder());
437         } catch (RemoteException e) {
438             throw e.rethrowAsRuntimeException();
439         }
440     }
441 
442     /**
443      * {@inheritDoc}
444      * @hide
445      */
446     @Override
447     @SystemApi
448     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getRegistrationState(@onNull @allbackExecutor Executor executor, @NonNull @ImsRegistrationState Consumer<Integer> stateCallback)449     public void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
450             @NonNull @ImsRegistrationState Consumer<Integer> stateCallback) {
451         if (stateCallback == null) {
452             throw new IllegalArgumentException("Must include a non-null callback.");
453         }
454         if (executor == null) {
455             throw new IllegalArgumentException("Must include a non-null Executor.");
456         }
457 
458         ITelephony iTelephony = getITelephony();
459         if (iTelephony == null) {
460             throw new RuntimeException("Could not find Telephony Service.");
461         }
462 
463         try {
464             iTelephony.getImsMmTelRegistrationState(mSubId, new IIntegerConsumer.Stub() {
465                 @Override
466                 public void accept(int result) {
467                     final long identity = Binder.clearCallingIdentity();
468                     try {
469                         executor.execute(() -> stateCallback.accept(result));
470                     } finally {
471                         Binder.restoreCallingIdentity(identity);
472                     }
473                 }
474             });
475         } catch (ServiceSpecificException | RemoteException e) {
476             Log.w("ImsMmTelManager", "Error getting registration state: " + e);
477             executor.execute(() -> stateCallback.accept(REGISTRATION_STATE_NOT_REGISTERED));
478         }
479     }
480 
481     /**
482      * <p>Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
483      * READ_PRECISE_PHONE_STATE} or that the calling app has carrier privileges
484      * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
485      * Access by profile owners is deprecated and will be removed in a future release.
486      *
487      *{@inheritDoc}
488      */
489     @Override
490     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
491     @RequiresPermission(anyOf = {
492             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
493             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
getRegistrationTransportType(@onNull @allbackExecutor Executor executor, @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback)494     public void getRegistrationTransportType(@NonNull @CallbackExecutor Executor executor,
495             @NonNull @AccessNetworkConstants.TransportType
496                     Consumer<Integer> transportTypeCallback) {
497         if (transportTypeCallback == null) {
498             throw new IllegalArgumentException("Must include a non-null callback.");
499         }
500         if (executor == null) {
501             throw new IllegalArgumentException("Must include a non-null Executor.");
502         }
503 
504         ITelephony iTelephony = getITelephony();
505         if (iTelephony == null) {
506             throw new RuntimeException("Could not find Telephony Service.");
507         }
508 
509         try {
510             iTelephony.getImsMmTelRegistrationTransportType(mSubId,
511                     new IIntegerConsumer.Stub() {
512                         @Override
513                         public void accept(int result) {
514                             final long identity = Binder.clearCallingIdentity();
515                             try {
516                                 executor.execute(() -> transportTypeCallback.accept(result));
517                             } finally {
518                                 Binder.restoreCallingIdentity(identity);
519                             }
520                         }
521                     });
522         } catch (ServiceSpecificException | RemoteException e) {
523             Log.w("ImsMmTelManager", "Error getting transport type: " + e);
524             executor.execute(() -> transportTypeCallback.accept(
525                     AccessNetworkConstants.TRANSPORT_TYPE_INVALID));
526         }
527     }
528 
529     /**
530      * Registers a {@link CapabilityCallback} with the system, which will provide MmTel service
531      * availability updates for the subscription specified in
532      * {@link ImsManager#getImsMmTelManager(int)}.
533      *
534      * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
535      * subscription changed events and call
536      * {@link #unregisterMmTelCapabilityCallback(CapabilityCallback)} to clean up.
537      * <p>This API requires one of the following:
538      * <ul>
539      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
540      *     <li>If the caller is the device or profile owner, the caller holds the
541      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
542      *     <li>The caller has carrier privileges (see
543      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
544      *     active subscription.</li>
545      *     <li>The caller is the default SMS app for the device.</li>
546      * </ul>
547      * <p>The profile owner is an app that owns a managed profile on the device; for more details
548      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
549      * Access by profile owners is deprecated and will be removed in a future release.
550      *
551      * When the callback is registered, it will initiate the callback c to be called with the
552      * current capabilities.
553      *
554      * @param executor The executor the callback events should be run on.
555      * @param c The MmTel {@link CapabilityCallback} to be registered.
556      * @see #unregisterMmTelCapabilityCallback(CapabilityCallback)
557      * @throws ImsException if the subscription associated with this callback is valid, but
558      * the {@link ImsService} associated with the subscription is not available. This can happen if
559      * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
560      * reason.
561      */
562     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
563     @RequiresPermission(anyOf = {
564             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
565             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
registerMmTelCapabilityCallback(@onNull @allbackExecutor Executor executor, @NonNull CapabilityCallback c)566     public void registerMmTelCapabilityCallback(@NonNull @CallbackExecutor Executor executor,
567             @NonNull CapabilityCallback c) throws ImsException {
568         if (c == null) {
569             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
570         }
571         if (executor == null) {
572             throw new IllegalArgumentException("Must include a non-null Executor.");
573         }
574         c.setExecutor(executor);
575 
576         ITelephony iTelephony = getITelephony();
577         if (iTelephony == null) {
578             throw new ImsException("Could not find Telephony Service.",
579                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
580         }
581 
582         try {
583             iTelephony.registerMmTelCapabilityCallback(mSubId, c.getBinder());
584         } catch (ServiceSpecificException e) {
585             throw new ImsException(e.getMessage(), e.errorCode);
586         } catch (RemoteException e) {
587             throw e.rethrowAsRuntimeException();
588         }  catch (IllegalStateException e) {
589             throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
590         }
591     }
592 
593     /**
594      * Removes an existing MmTel {@link CapabilityCallback}.
595      *
596      * When the subscription associated with this callback is removed (SIM removed, ESIM swap,
597      * etc...), this callback will automatically be removed. If this method is called for an
598      * inactive subscription, it will result in a no-op.
599      * <p>This API requires one of the following:
600      * <ul>
601      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
602      *     <li>If the caller is the device or profile owner, the caller holds the
603      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
604      *     <li>The caller has carrier privileges (see
605      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
606      *     active subscription.</li>
607      *     <li>The caller is the default SMS app for the device.</li>
608      * </ul>
609      * <p>The profile owner is an app that owns a managed profile on the device; for more details
610      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
611      * Access by profile owners is deprecated and will be removed in a future release.
612      *
613      * @param c The MmTel {@link CapabilityCallback} to be removed.
614      * @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback)
615      */
616     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
617     @RequiresPermission(anyOf = {
618             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
619             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
unregisterMmTelCapabilityCallback(@onNull CapabilityCallback c)620     public void unregisterMmTelCapabilityCallback(@NonNull CapabilityCallback c) {
621         if (c == null) {
622             throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
623         }
624 
625         ITelephony iTelephony = getITelephony();
626         if (iTelephony == null) {
627             Log.w("ImsMmTelManager", "Could not find Telephony Service.");
628             return;
629         }
630         try {
631             iTelephony.unregisterMmTelCapabilityCallback(mSubId, c.getBinder());
632         } catch (RemoteException e) {
633             throw e.rethrowAsRuntimeException();
634         }
635     }
636 
637     /**
638      * Query the user’s setting for “Advanced Calling” or "Enhanced 4G LTE", which is used to
639      * enable MmTel IMS features, depending on the carrier configuration for the current
640      * subscription. If this setting is enabled, IMS voice and video telephony over IWLAN/LTE will
641      * be enabled as long as the carrier has provisioned these services for the specified
642      * subscription. Other IMS services (SMS/UT) are not affected by this user setting and depend on
643      * carrier requirements.
644      * <p>
645      * Note: If the carrier configuration for advanced calling is not editable or hidden, this
646      * method will always return the default value.
647      * <p>This API requires one of the following:
648      * <ul>
649      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
650      *     <li>If the caller is the device or profile owner, the caller holds the
651      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
652      *     <li>The caller has carrier privileges (see
653      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
654      *     active subscription.</li>
655      *     <li>The caller is the default SMS app for the device.</li>
656      * </ul>
657      * <p>The profile owner is an app that owns a managed profile on the device; for more details
658      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
659      * Access by profile owners is deprecated and will be removed in a future release.
660      *
661      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
662      * @see android.telephony.CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL
663      * @see android.telephony.CarrierConfigManager#KEY_HIDE_ENHANCED_4G_LTE_BOOL
664      * @see android.telephony.CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL
665      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
666      * @throws IllegalArgumentException if the subscription associated with this operation is not
667      * active (SIM is not inserted, ESIM inactive) or invalid.
668      * @return true if the user's setting for advanced calling is enabled, false otherwise.
669      */
670     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
671     @RequiresPermission(anyOf = {
672             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
673             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
isAdvancedCallingSettingEnabled()674     public boolean isAdvancedCallingSettingEnabled() {
675         ITelephony iTelephony = getITelephony();
676         if (iTelephony == null) {
677             throw new RuntimeException("Could not find Telephony Service.");
678         }
679 
680         try {
681             return iTelephony.isAdvancedCallingSettingEnabled(mSubId);
682         } catch (ServiceSpecificException e) {
683             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
684                 // Rethrow as runtime error to keep API compatible.
685                 throw new IllegalArgumentException(e.getMessage());
686             } else {
687                 throw new RuntimeException(e.getMessage());
688             }
689         } catch (RemoteException e) {
690             throw e.rethrowAsRuntimeException();
691         }
692     }
693 
694     /**
695      * Modify the user’s setting for “Advanced Calling” or "Enhanced 4G LTE", which is used to
696      * enable MmTel IMS features, depending on the carrier configuration for the current
697      * subscription. If this setting is enabled, IMS voice and video telephony over IWLAN/LTE will
698      * be enabled as long as the carrier has provisioned these services for the specified
699      * subscription. Other IMS services (SMS/UT) are not affected by this user setting and depend on
700      * carrier requirements.
701      *
702      * Modifying this value may also trigger an IMS registration or deregistration, depending on
703      * whether or not the new value is enabled or disabled.
704      *
705      * Note: If the carrier configuration for advanced calling is not editable or hidden, this
706      * method will do nothing and will instead always use the default value.
707      *
708      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
709      * @see android.telephony.CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL
710      * @see android.telephony.CarrierConfigManager#KEY_HIDE_ENHANCED_4G_LTE_BOOL
711      * @see android.telephony.CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL
712      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
713      * @see #isAdvancedCallingSettingEnabled()
714      * @throws IllegalArgumentException if the subscription associated with this operation is not
715      * active (SIM is not inserted, ESIM inactive) or invalid.
716      * @hide
717      */
718     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
719     @SystemApi
setAdvancedCallingSettingEnabled(boolean isEnabled)720     public void setAdvancedCallingSettingEnabled(boolean isEnabled) {
721         ITelephony iTelephony = getITelephony();
722         if (iTelephony == null) {
723             throw new RuntimeException("Could not find Telephony Service.");
724         }
725 
726         try {
727             iTelephony.setAdvancedCallingSettingEnabled(mSubId, isEnabled);
728         } catch (ServiceSpecificException e) {
729             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
730                 // Rethrow as runtime error to keep API compatible.
731                 throw new IllegalArgumentException(e.getMessage());
732             } else {
733                 throw new RuntimeException(e.getMessage());
734             }
735         } catch (RemoteException e) {
736             throw e.rethrowAsRuntimeException();
737         }
738     }
739 
740     /**
741      * Query the IMS MmTel capability for a given registration technology. This does not
742      * necessarily mean that we are registered and the capability is available, but rather the
743      * subscription is capable of this service over IMS.
744      *
745      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
746      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VT_AVAILABLE_BOOL
747      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
748      * @see #isAvailable(int, int)
749      *
750      * @param imsRegTech The IMS registration technology.
751      * @param capability The IMS MmTel capability to query.
752      * @return {@code true} if the MmTel IMS capability is capable for this subscription, false
753      *         otherwise.
754      * @hide
755      */
756     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
757     @SystemApi
isCapable(@mTelFeature.MmTelCapabilities.MmTelCapability int capability, @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech)758     public boolean isCapable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
759             @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
760         ITelephony iTelephony = getITelephony();
761         if (iTelephony == null) {
762             throw new RuntimeException("Could not find Telephony Service.");
763         }
764 
765         try {
766             return iTelephony.isCapable(mSubId, capability, imsRegTech);
767         } catch (RemoteException e) {
768             throw e.rethrowAsRuntimeException();
769         }
770     }
771 
772     /**
773      * Query the availability of an IMS MmTel capability for a given registration technology. If
774      * a capability is available, IMS is registered and the service is currently available over IMS.
775      *
776      * @see #isCapable(int, int)
777      *
778      * @param imsRegTech The IMS registration technology.
779      * @param capability The IMS MmTel capability to query.
780      * @return {@code true} if the MmTel IMS capability is available for this subscription, false
781      *         otherwise.
782      * @hide
783      */
784     @SystemApi
785     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isAvailable(@mTelFeature.MmTelCapabilities.MmTelCapability int capability, @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech)786     public boolean isAvailable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
787             @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
788         ITelephony iTelephony = getITelephony();
789         if (iTelephony == null) {
790             throw new RuntimeException("Could not find Telephony Service.");
791         }
792 
793         try {
794             return iTelephony.isAvailable(mSubId, capability, imsRegTech);
795         } catch (RemoteException e) {
796             throw e.rethrowAsRuntimeException();
797         }
798     }
799 
800     /**
801      * Query whether or not the requested MmTel capability is supported by the carrier on the
802      * specified network transport.
803      * <p>
804      * This is a configuration option and does not change. The only time this may change is if a
805      * new IMS configuration is loaded when there is a
806      * {@link CarrierConfigManager#ACTION_CARRIER_CONFIG_CHANGED} broadcast for this subscription.
807      * @param capability The capability that is being queried for support on the carrier network.
808      * @param transportType The transport type of the capability to check support for.
809      * @param executor The executor that the callback will be called with.
810      * @param callback A consumer containing a Boolean result specifying whether or not the
811      *                 capability is supported on this carrier network for the transport specified.
812      * @throws ImsException if the subscription is no longer valid or the IMS service is not
813      * available.
814      * @hide
815      */
816     @SystemApi
817     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isSupported(@mTelFeature.MmTelCapabilities.MmTelCapability int capability, @AccessNetworkConstants.TransportType int transportType, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Boolean> callback)818     public void isSupported(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
819             @AccessNetworkConstants.TransportType int transportType,
820             @NonNull @CallbackExecutor Executor executor,
821             @NonNull Consumer<Boolean> callback) throws ImsException {
822         if (callback == null) {
823             throw new IllegalArgumentException("Must include a non-null Consumer.");
824         }
825         if (executor == null) {
826             throw new IllegalArgumentException("Must include a non-null Executor.");
827         }
828 
829         ITelephony iTelephony = getITelephony();
830         if (iTelephony == null) {
831             throw new ImsException("Could not find Telephony Service.",
832                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
833         }
834 
835         try {
836             iTelephony.isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() {
837                 @Override
838                 public void accept(int result) {
839                     final long identity = Binder.clearCallingIdentity();
840                     try {
841                         executor.execute(() -> callback.accept(result == 1));
842                     } finally {
843                         Binder.restoreCallingIdentity(identity);
844                     }
845                 }
846             }, capability, transportType);
847         } catch (ServiceSpecificException sse) {
848             throw new ImsException(sse.getMessage(), sse.errorCode);
849         } catch (RemoteException e) {
850             e.rethrowAsRuntimeException();
851         }
852     }
853 
854     /**
855      * The user's setting for whether or not they have enabled the "Video Calling" setting.
856      *
857      * <p>
858      * Note: If the carrier configuration for advanced calling is not editable or hidden, this
859      * method will always return the default value.
860      * <p>This API requires one of the following:
861      * <ul>
862      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
863      *     <li>If the caller is the device or profile owner, the caller holds the
864      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
865      *     <li>The caller has carrier privileges (see
866      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
867      *     active subscription.</li>
868      *     <li>The caller is the default SMS app for the device.</li>
869      * </ul>
870      * <p>The profile owner is an app that owns a managed profile on the device; for more details
871      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
872      * Access by profile owners is deprecated and will be removed in a future release.
873      *
874      * @throws IllegalArgumentException if the subscription associated with this operation is not
875      * active (SIM is not inserted, ESIM inactive) or invalid.
876      * @return true if the user’s “Video Calling” setting is currently enabled.
877      */
878     @RequiresPermission(anyOf = {
879             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
880             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
881     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
isVtSettingEnabled()882     public boolean isVtSettingEnabled() {
883         ITelephony iTelephony = getITelephony();
884         if (iTelephony == null) {
885             throw new RuntimeException("Could not find Telephony Service.");
886         }
887 
888         try {
889             return iTelephony.isVtSettingEnabled(mSubId);
890         } catch (ServiceSpecificException e) {
891             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
892                 // Rethrow as runtime error to keep API compatible.
893                 throw new IllegalArgumentException(e.getMessage());
894             } else {
895                 throw new RuntimeException(e.getMessage());
896             }
897         } catch (RemoteException e) {
898             throw e.rethrowAsRuntimeException();
899         }
900     }
901 
902     /**
903      * Change the user's setting for Video Telephony and enable the Video Telephony capability.
904      *
905      * @throws IllegalArgumentException if the subscription associated with this operation is not
906      * active (SIM is not inserted, ESIM inactive) or invalid.
907      * @see #isVtSettingEnabled()
908      * @hide
909      */
910     @SystemApi
911     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setVtSettingEnabled(boolean isEnabled)912     public void setVtSettingEnabled(boolean isEnabled) {
913         ITelephony iTelephony = getITelephony();
914         if (iTelephony == null) {
915             throw new RuntimeException("Could not find Telephony Service.");
916         }
917 
918         try {
919             iTelephony.setVtSettingEnabled(mSubId, isEnabled);
920         } catch (ServiceSpecificException e) {
921             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
922                 // Rethrow as runtime error to keep API compatible.
923                 throw new IllegalArgumentException(e.getMessage());
924             } else {
925                 throw new RuntimeException(e.getMessage());
926             }
927         } catch (RemoteException e) {
928             throw e.rethrowAsRuntimeException();
929         }
930     }
931 
932     /**
933      * @return true if the user's setting for Voice over WiFi is enabled and false if it is not.
934      *
935      * <p>This API requires one of the following:
936      * <ul>
937      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
938      *     <li>If the caller is the device or profile owner, the caller holds the
939      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
940      *     <li>The caller has carrier privileges (see
941      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
942      *     active subscription.</li>
943      *     <li>The caller is the default SMS app for the device.</li>
944      * </ul>
945      * <p>The profile owner is an app that owns a managed profile on the device; for more details
946      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
947      * Access by profile owners is deprecated and will be removed in a future release.
948      *
949      * @throws IllegalArgumentException if the subscription associated with this operation is not
950      * active (SIM is not inserted, ESIM inactive) or invalid.
951      */
952     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
953     @RequiresPermission(anyOf = {
954             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
955             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
isVoWiFiSettingEnabled()956     public boolean isVoWiFiSettingEnabled() {
957         ITelephony iTelephony = getITelephony();
958         if (iTelephony == null) {
959             throw new RuntimeException("Could not find Telephony Service.");
960         }
961 
962         try {
963             return iTelephony.isVoWiFiSettingEnabled(mSubId);
964         } catch (ServiceSpecificException e) {
965             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
966                 // Rethrow as runtime error to keep API compatible.
967                 throw new IllegalArgumentException(e.getMessage());
968             } else {
969                 throw new RuntimeException(e.getMessage());
970             }
971         } catch (RemoteException e) {
972             throw e.rethrowAsRuntimeException();
973         }
974     }
975 
976     /**
977      * Sets the user's setting for whether or not Voice over WiFi is enabled.
978      *
979      * @throws IllegalArgumentException if the subscription associated with this operation is not
980      * active (SIM is not inserted, ESIM inactive) or invalid.
981      * @param isEnabled true if the user's setting for Voice over WiFi is enabled, false otherwise=
982      * @see #isVoWiFiSettingEnabled()
983      * @hide
984      */
985     @SystemApi
986     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setVoWiFiSettingEnabled(boolean isEnabled)987     public void setVoWiFiSettingEnabled(boolean isEnabled) {
988         ITelephony iTelephony = getITelephony();
989         if (iTelephony == null) {
990             throw new RuntimeException("Could not find Telephony Service.");
991         }
992 
993         try {
994             iTelephony.setVoWiFiSettingEnabled(mSubId, isEnabled);
995         } catch (ServiceSpecificException e) {
996             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
997                 // Rethrow as runtime error to keep API compatible.
998                 throw new IllegalArgumentException(e.getMessage());
999             } else {
1000                 throw new RuntimeException(e.getMessage());
1001             }
1002         } catch (RemoteException e) {
1003             throw e.rethrowAsRuntimeException();
1004         }
1005     }
1006 
1007     /**
1008      * This configuration is meaningful only on dual sim device.
1009      * If enabled, this will result in the device setting up IMS of all other
1010      * active subscriptions over the INTERNET APN of the primary default data subscription
1011      * when any of those subscriptions are roaming or out of service and if wifi is not available
1012      * for VoWifi. This feature will be disabled if
1013      * {@link CarrierConfigManager#KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL} is set to false.
1014      * <p>Following are the conditions in which system will try to register IMS over
1015      * cross sim
1016      * <ul>
1017      *     <li>Wifi is not available, one SIM is roaming and the default data
1018      *     SIM is in home network. Then roaming SIM IMS will be registered over INTERNET APN of the
1019      *     default data subscription </li>
1020      *     <li>Wifi is not available, one SIM is out of service and the default data
1021      *     SIM is in home network. Then out of service SIM IMS will be registered over INTERNET
1022      *     APN of the default data subscription </li>
1023      * </ul>
1024      * <p>This API requires one of the following:
1025      * <ul>
1026      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
1027      *     <li>If the caller is the device or profile owner, the caller holds the
1028      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
1029      *     <li>The caller has carrier privileges (see
1030      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
1031      *     active subscription.</li>
1032      * </ul>
1033      * <p>The profile owner is an app that owns a managed profile on the device; for more details
1034      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
1035      * Access by profile owners is deprecated and will be removed in a future release.
1036      *
1037      * @throws ImsException if the IMS service associated with this subscription is not available or
1038      * the IMS service is not available.
1039      * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
1040      */
1041     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
1042     @RequiresPermission(anyOf = {
1043             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
1044             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
isCrossSimCallingEnabled()1045     public boolean isCrossSimCallingEnabled() throws ImsException {
1046         ITelephony iTelephony = getITelephony();
1047         if (iTelephony == null) {
1048             throw new ImsException("Could not find Telephony Service.",
1049                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
1050         }
1051 
1052         try {
1053             return iTelephony.isCrossSimCallingEnabledByUser(mSubId);
1054         } catch (ServiceSpecificException sse) {
1055             throw new ImsException(sse.getMessage(), sse.errorCode);
1056         } catch (RemoteException e) {
1057             e.rethrowAsRuntimeException();
1058         }
1059         // Not reachable. Adding return to make compiler happy.
1060         return false;
1061     }
1062 
1063     /**
1064      * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
1065      * If enabled, this will result in the device setting up IMS of all other
1066      * active subscriptions over the INTERNET APN of the primary default data subscription
1067      * when any of those subscriptions are roaming or out of service and if wifi is not available
1068      * for VoWifi. This feature will be disabled if
1069      * {@link CarrierConfigManager#KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL} is set to false.
1070      *
1071      * <p>Following are the conditions in which system will try to register IMS over
1072      * cross sim
1073      * <ul>
1074      *     <li>Wifi is not available, one SIM is roaming and the default data
1075      *     SIM is in home network. Then roaming SIM IMS will be registered over INTERNET APN of the
1076      *     default data subscription </li>
1077      *     <li>Wifi is not available, one SIM is out of service and the default data
1078      *     SIM is in home network. Then out of service SIM IMS will be registered over INTERNET
1079      *     APN of the default data subscription </li>
1080      * </ul>
1081      * @throws ImsException if the IMS service associated with this subscription is not available or
1082      * the IMS service is not available.
1083      * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
1084      *                 false otherwise
1085      * @see #isCrossSimCallingEnabled()
1086      * @hide
1087      */
1088     @SystemApi
1089     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setCrossSimCallingEnabled(boolean isEnabled)1090     public void setCrossSimCallingEnabled(boolean isEnabled) throws ImsException {
1091         ITelephony iTelephony = getITelephony();
1092         if (iTelephony == null) {
1093             throw new ImsException("Could not find Telephony Service.",
1094                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
1095         }
1096 
1097         try {
1098             iTelephony.setCrossSimCallingEnabled(mSubId, isEnabled);
1099         } catch (ServiceSpecificException sse) {
1100             throw new ImsException(sse.getMessage(), sse.errorCode);
1101         } catch (RemoteException e) {
1102             e.rethrowAsRuntimeException();
1103         }
1104     }
1105 
1106     /**
1107      * Returns the user's voice over WiFi roaming setting associated with the current subscription.
1108      *
1109      * <p>This API requires one of the following:
1110      * <ul>
1111      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
1112      *     <li>If the caller is the device or profile owner, the caller holds the
1113      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
1114      *     <li>The caller has carrier privileges (see
1115      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
1116      *     active subscription.</li>
1117      *     <li>The caller is the default SMS app for the device.</li>
1118      * </ul>
1119      * <p>The profile owner is an app that owns a managed profile on the device; for more details
1120      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
1121      * Access by profile owners is deprecated and will be removed in a future release.
1122      *
1123      * @throws IllegalArgumentException if the subscription associated with this operation is not
1124      * active (SIM is not inserted, ESIM inactive) or invalid.
1125      * @return true if the user's setting for Voice over WiFi while roaming is enabled, false
1126      * if disabled.
1127      */
1128     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
1129     @RequiresPermission(anyOf = {
1130             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
1131             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
isVoWiFiRoamingSettingEnabled()1132     public boolean isVoWiFiRoamingSettingEnabled() {
1133         ITelephony iTelephony = getITelephony();
1134         if (iTelephony == null) {
1135             throw new RuntimeException("Could not find Telephony Service.");
1136         }
1137 
1138         try {
1139             return iTelephony.isVoWiFiRoamingSettingEnabled(mSubId);
1140         } catch (ServiceSpecificException e) {
1141             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1142                 // Rethrow as runtime error to keep API compatible.
1143                 throw new IllegalArgumentException(e.getMessage());
1144             } else {
1145                 throw new RuntimeException(e.getMessage());
1146             }
1147         } catch (RemoteException e) {
1148             throw e.rethrowAsRuntimeException();
1149         }
1150     }
1151 
1152     /**
1153      * Change the user's setting for Voice over WiFi while roaming.
1154      *
1155      * @param isEnabled true if the user's setting for Voice over WiFi while roaming is enabled,
1156      *     false otherwise.
1157      * @throws IllegalArgumentException if the subscription associated with this operation is not
1158      * active (SIM is not inserted, ESIM inactive) or invalid.
1159      * @see #isVoWiFiRoamingSettingEnabled()
1160      * @hide
1161      */
1162     @SystemApi
1163     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setVoWiFiRoamingSettingEnabled(boolean isEnabled)1164     public void setVoWiFiRoamingSettingEnabled(boolean isEnabled) {
1165         ITelephony iTelephony = getITelephony();
1166         if (iTelephony == null) {
1167             throw new RuntimeException("Could not find Telephony Service.");
1168         }
1169 
1170         try {
1171             iTelephony.setVoWiFiRoamingSettingEnabled(mSubId, isEnabled);
1172         } catch (ServiceSpecificException e) {
1173             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1174                 // Rethrow as runtime error to keep API compatible.
1175                 throw new IllegalArgumentException(e.getMessage());
1176             } else {
1177                 throw new RuntimeException(e.getMessage());
1178             }
1179         } catch (RemoteException e) {
1180             throw e.rethrowAsRuntimeException();
1181         }
1182     }
1183 
1184     /**
1185      * Overrides the Voice over WiFi capability to true for IMS, but do not persist the setting.
1186      * Typically used during the Voice over WiFi registration process for some carriers.
1187      *
1188      * @param isCapable true if the IMS stack should try to register for IMS over IWLAN, false
1189      *     otherwise.
1190      * @param mode the Voice over WiFi mode preference to set, which can be one of the following:
1191      * - {@link #WIFI_MODE_WIFI_ONLY}
1192      * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
1193      * - {@link #WIFI_MODE_WIFI_PREFERRED}
1194      * @throws IllegalArgumentException if the subscription associated with this operation is not
1195      * active (SIM is not inserted, ESIM inactive) or invalid.
1196      * @see #setVoWiFiSettingEnabled(boolean)
1197      * @hide
1198      */
1199     @SystemApi
1200     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setVoWiFiNonPersistent(boolean isCapable, int mode)1201     public void setVoWiFiNonPersistent(boolean isCapable, int mode) {
1202         ITelephony iTelephony = getITelephony();
1203         if (iTelephony == null) {
1204             throw new RuntimeException("Could not find Telephony Service.");
1205         }
1206 
1207         try {
1208             iTelephony.setVoWiFiNonPersistent(mSubId, isCapable, mode);
1209         } catch (ServiceSpecificException e) {
1210             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1211                 // Rethrow as runtime error to keep API compatible.
1212                 throw new IllegalArgumentException(e.getMessage());
1213             } else {
1214                 throw new RuntimeException(e.getMessage());
1215             }
1216         } catch (RemoteException e) {
1217             throw e.rethrowAsRuntimeException();
1218         }
1219     }
1220 
1221     /**
1222      * Returns the user's voice over WiFi Roaming mode setting associated with the device.
1223      *
1224      * <p>This API requires one of the following:
1225      * <ul>
1226      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
1227      *     <li>If the caller is the device or profile owner, the caller holds the
1228      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
1229      *     <li>The caller has carrier privileges (see
1230      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
1231      *     active subscription.</li>
1232      *     <li>The caller is the default SMS app for the device.</li>
1233      * </ul>
1234      * <p>The profile owner is an app that owns a managed profile on the device; for more details
1235      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
1236      * Access by profile owners is deprecated and will be removed in a future release.
1237      *
1238      * @throws IllegalArgumentException if the subscription associated with this operation is not
1239      * active (SIM is not inserted, ESIM inactive) or invalid.
1240      * @return The Voice over WiFi Mode preference set by the user, which can be one of the
1241      * following:
1242      * - {@link #WIFI_MODE_WIFI_ONLY}
1243      * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
1244      * - {@link #WIFI_MODE_WIFI_PREFERRED}
1245      */
1246     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
1247     @RequiresPermission(anyOf = {
1248             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
1249             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
getVoWiFiModeSetting()1250     public @WiFiCallingMode int getVoWiFiModeSetting() {
1251         ITelephony iTelephony = getITelephony();
1252         if (iTelephony == null) {
1253             throw new RuntimeException("Could not find Telephony Service.");
1254         }
1255 
1256         try {
1257             return iTelephony.getVoWiFiModeSetting(mSubId);
1258         } catch (ServiceSpecificException e) {
1259             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1260                 // Rethrow as runtime error to keep API compatible.
1261                 throw new IllegalArgumentException(e.getMessage());
1262             } else {
1263                 throw new RuntimeException(e.getMessage());
1264             }
1265         } catch (RemoteException e) {
1266             throw e.rethrowAsRuntimeException();
1267         }
1268     }
1269 
1270     /**
1271      * Set the user's preference for Voice over WiFi calling mode.
1272      * @param mode The user's preference for the technology to register for IMS over, can be one of
1273      *    the following:
1274      * - {@link #WIFI_MODE_WIFI_ONLY}
1275      * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
1276      * - {@link #WIFI_MODE_WIFI_PREFERRED}
1277      * @throws IllegalArgumentException if the subscription associated with this operation is not
1278      * active (SIM is not inserted, ESIM inactive) or invalid.
1279      * @see #getVoWiFiModeSetting()
1280      * @hide
1281      */
1282     @SystemApi
1283     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setVoWiFiModeSetting(@iFiCallingMode int mode)1284     public void setVoWiFiModeSetting(@WiFiCallingMode int mode) {
1285         ITelephony iTelephony = getITelephony();
1286         if (iTelephony == null) {
1287             throw new RuntimeException("Could not find Telephony Service.");
1288         }
1289 
1290         try {
1291             iTelephony.setVoWiFiModeSetting(mSubId, mode);
1292         } catch (ServiceSpecificException e) {
1293             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1294                 // Rethrow as runtime error to keep API compatible.
1295                 throw new IllegalArgumentException(e.getMessage());
1296             } else {
1297                 throw new RuntimeException(e.getMessage());
1298             }
1299         } catch (RemoteException e) {
1300             throw e.rethrowAsRuntimeException();
1301         }
1302     }
1303 
1304     /**
1305      * Set the user's preference for Voice over WiFi calling mode while the device is roaming on
1306      * another network.
1307      *
1308      * @return The user's preference for the technology to register for IMS over when roaming on
1309      *     another network, can be one of the following:
1310      *     - {@link #WIFI_MODE_WIFI_ONLY}
1311      *     - {@link #WIFI_MODE_CELLULAR_PREFERRED}
1312      *     - {@link #WIFI_MODE_WIFI_PREFERRED}
1313      * @throws IllegalArgumentException if the subscription associated with this operation is not
1314      * active (SIM is not inserted, ESIM inactive) or invalid.
1315      * @see #setVoWiFiRoamingSettingEnabled(boolean)
1316      * @hide
1317      */
1318     @SystemApi
1319     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getVoWiFiRoamingModeSetting()1320     public @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
1321         ITelephony iTelephony = getITelephony();
1322         if (iTelephony == null) {
1323             throw new RuntimeException("Could not find Telephony Service.");
1324         }
1325 
1326         try {
1327             return iTelephony.getVoWiFiRoamingModeSetting(mSubId);
1328         } catch (ServiceSpecificException e) {
1329             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1330                 // Rethrow as runtime error to keep API compatible.
1331                 throw new IllegalArgumentException(e.getMessage());
1332             } else {
1333                 throw new RuntimeException(e.getMessage());
1334             }
1335         } catch (RemoteException e) {
1336             throw e.rethrowAsRuntimeException();
1337         }
1338     }
1339 
1340     /**
1341      * Set the user's preference for Voice over WiFi mode while the device is roaming on another
1342      * network.
1343      *
1344      * @param mode The user's preference for the technology to register for IMS over when roaming on
1345      *     another network, can be one of the following:
1346      *     - {@link #WIFI_MODE_WIFI_ONLY}
1347      *     - {@link #WIFI_MODE_CELLULAR_PREFERRED}
1348      *     - {@link #WIFI_MODE_WIFI_PREFERRED}
1349      * @throws IllegalArgumentException if the subscription associated with this operation is not
1350      * active (SIM is not inserted, ESIM inactive) or invalid.
1351      * @see #getVoWiFiRoamingModeSetting()
1352      * @hide
1353      */
1354     @SystemApi
1355     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setVoWiFiRoamingModeSetting(@iFiCallingMode int mode)1356     public void setVoWiFiRoamingModeSetting(@WiFiCallingMode int mode) {
1357         ITelephony iTelephony = getITelephony();
1358         if (iTelephony == null) {
1359             throw new RuntimeException("Could not find Telephony Service.");
1360         }
1361 
1362         try {
1363             iTelephony.setVoWiFiRoamingModeSetting(mSubId, mode);
1364         } catch (ServiceSpecificException e) {
1365             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1366                 // Rethrow as runtime error to keep API compatible.
1367                 throw new IllegalArgumentException(e.getMessage());
1368             } else {
1369                 throw new RuntimeException(e.getMessage());
1370             }
1371         } catch (RemoteException e) {
1372             throw e.rethrowAsRuntimeException();
1373         }
1374     }
1375 
1376     /**
1377      * Sets the capability of RTT for IMS calls placed on this subscription.
1378      *
1379      * Note: This does not affect the value of
1380      * {@link android.provider.Settings.Secure#RTT_CALLING_MODE}, which is the global user setting
1381      * for RTT. That value is enabled/disabled separately by the user through the Accessibility
1382      * settings.
1383      * @throws IllegalArgumentException if the subscription associated with this operation is not
1384      * active (SIM is not inserted, ESIM inactive) or invalid.
1385      * @param isEnabled if true RTT should be enabled during calls made on this subscription.
1386      * @hide
1387      */
1388     @SystemApi
1389     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setRttCapabilitySetting(boolean isEnabled)1390     public void setRttCapabilitySetting(boolean isEnabled) {
1391         ITelephony iTelephony = getITelephony();
1392         if (iTelephony == null) {
1393             throw new RuntimeException("Could not find Telephony Service.");
1394         }
1395 
1396         try {
1397             iTelephony.setRttCapabilitySetting(mSubId, isEnabled);
1398         } catch (ServiceSpecificException e) {
1399             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1400                 // Rethrow as runtime error to keep API compatible.
1401                 throw new IllegalArgumentException(e.getMessage());
1402             } else {
1403                 throw new RuntimeException(e.getMessage());
1404             }
1405         } catch (RemoteException e) {
1406             throw e.rethrowAsRuntimeException();
1407         }
1408     }
1409 
1410     /**
1411      * @return true if TTY over VoLTE is supported
1412      *
1413      * <p>This API requires one of the following:
1414      * <ul>
1415      *     <li>The caller holds the READ_PRECISE_PHONE_STATE permission.</li>
1416      *     <li>If the caller is the device or profile owner, the caller holds the
1417      *     {@link Manifest.permission#READ_PRECISE_PHONE_STATE} permission.</li>
1418      *     <li>The caller has carrier privileges (see
1419      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
1420      *     active subscription.</li>
1421      *     <li>The caller is the default SMS app for the device.</li>
1422      * </ul>
1423      * <p>The profile owner is an app that owns a managed profile on the device; for more details
1424      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
1425      * Access by profile owners is deprecated and will be removed in a future release.
1426      *
1427      * @throws IllegalArgumentException if the subscription associated with this operation is not
1428      * active (SIM is not inserted, ESIM inactive) or invalid.
1429      * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
1430      */
1431     @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
1432     @RequiresPermission(anyOf = {
1433             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
1434             android.Manifest.permission.READ_PRECISE_PHONE_STATE})
isTtyOverVolteEnabled()1435     public boolean isTtyOverVolteEnabled() {
1436         ITelephony iTelephony = getITelephony();
1437         if (iTelephony == null) {
1438             throw new RuntimeException("Could not find Telephony Service.");
1439         }
1440 
1441         try {
1442             return iTelephony.isTtyOverVolteEnabled(mSubId);
1443         } catch (ServiceSpecificException e) {
1444             if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
1445                 // Rethrow as runtime error to keep API compatible.
1446                 throw new IllegalArgumentException(e.getMessage());
1447             } else {
1448                 throw new RuntimeException(e.getMessage());
1449             }
1450         } catch (RemoteException e) {
1451             throw e.rethrowAsRuntimeException();
1452         }
1453     }
1454 
1455     /**
1456      * Get the status of the MmTel Feature registered on this subscription.
1457      * @param executor The executor that will be used to call the callback.
1458      * @param callback A callback containing an Integer describing the current state of the
1459      *                 MmTel feature, Which will be one of the following:
1460      *                 {@link ImsFeature#STATE_UNAVAILABLE},
1461      *                {@link ImsFeature#STATE_INITIALIZING},
1462      *                {@link ImsFeature#STATE_READY}. Will be called using the executor
1463      *                 specified when the service state has been retrieved from the IMS service.
1464      * @throws ImsException if the IMS service associated with this subscription is not available or
1465      * the IMS service is not available.
1466      * @hide
1467      */
1468     @SystemApi
1469     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
getFeatureState(@onNull @allbackExecutor Executor executor, @NonNull @ImsFeature.ImsState Consumer<Integer> callback)1470     public void getFeatureState(@NonNull @CallbackExecutor Executor executor,
1471             @NonNull @ImsFeature.ImsState Consumer<Integer> callback) throws ImsException {
1472         if (executor == null) {
1473             throw new IllegalArgumentException("Must include a non-null Executor.");
1474         }
1475         if (callback == null) {
1476             throw new IllegalArgumentException("Must include a non-null Consumer.");
1477         }
1478 
1479         ITelephony iTelephony = getITelephony();
1480         if (iTelephony == null) {
1481             throw new ImsException("Could not find Telephony Service.",
1482                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
1483         }
1484 
1485         try {
1486             iTelephony.getImsMmTelFeatureState(mSubId, new IIntegerConsumer.Stub() {
1487                 @Override
1488                 public void accept(int result) {
1489                     final long identity = Binder.clearCallingIdentity();
1490                     try {
1491                         executor.execute(() -> callback.accept(result));
1492                     } finally {
1493                         Binder.restoreCallingIdentity(identity);
1494                     }
1495                 }
1496             });
1497         } catch (ServiceSpecificException sse) {
1498             throw new ImsException(sse.getMessage(), sse.errorCode);
1499         } catch (RemoteException e) {
1500             e.rethrowAsRuntimeException();
1501         }
1502     }
1503 
1504     /**
1505      * Register a new callback, which is used to notify the registrant of changes to
1506      * the state of the underlying IMS service that is attached to telephony to
1507      * implement IMS functionality. If the manager is created for
1508      * the {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID},
1509      * this throws an {@link ImsException}.
1510      *
1511      * <p>Requires Permission:
1512      * {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE READ_PRECISE_PHONE_STATE}
1513      * or that the calling app has carrier privileges
1514      * (see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}).
1515      *
1516      * @param executor the Executor that will be used to call the {@link ImsStateCallback}.
1517      * @param callback The callback instance being registered.
1518      * @throws ImsException in the case that the callback can not be registered.
1519      * See {@link ImsException#getCode} for more information on when this is called.
1520      */
1521     @RequiresPermission(anyOf = {Manifest.permission.READ_PRECISE_PHONE_STATE,
1522             Manifest.permission.READ_PRIVILEGED_PHONE_STATE})
registerImsStateCallback(@onNull Executor executor, @NonNull ImsStateCallback callback)1523     public void registerImsStateCallback(@NonNull Executor executor,
1524             @NonNull ImsStateCallback callback) throws ImsException {
1525         Objects.requireNonNull(callback, "Must include a non-null ImsStateCallback.");
1526         Objects.requireNonNull(executor, "Must include a non-null Executor.");
1527 
1528         callback.init(executor);
1529         ITelephony telephony = mBinderCache.listenOnBinder(callback, callback::binderDied);
1530         if (telephony == null) {
1531             throw new ImsException("Telephony server is down",
1532                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
1533         }
1534 
1535         try {
1536             telephony.registerImsStateCallback(
1537                     mSubId, ImsFeature.FEATURE_MMTEL,
1538                     callback.getCallbackBinder(), getOpPackageName());
1539         } catch (ServiceSpecificException e) {
1540             throw new ImsException(e.getMessage(), e.errorCode);
1541         } catch (RemoteException | IllegalStateException e) {
1542             throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
1543         }
1544     }
1545 
1546     /**
1547      * Unregisters a previously registered callback.
1548      *
1549      * @param callback The callback instance to be unregistered.
1550      */
unregisterImsStateCallback(@onNull ImsStateCallback callback)1551     public void unregisterImsStateCallback(@NonNull ImsStateCallback callback) {
1552         Objects.requireNonNull(callback, "Must include a non-null ImsStateCallback.");
1553 
1554         ITelephony telephony = mBinderCache.removeRunnable(callback);
1555         try {
1556             if (telephony != null) {
1557                 telephony.unregisterImsStateCallback(callback.getCallbackBinder());
1558             }
1559         } catch (RemoteException ignore) {
1560             // ignore it
1561         }
1562     }
1563 
getOpPackageName()1564     private String getOpPackageName() {
1565         if (mContext != null) {
1566             return mContext.getOpPackageName();
1567         } else {
1568             return null;
1569         }
1570     }
1571 
getITelephony()1572     private ITelephony getITelephony() {
1573         return mBinderCache.getBinder();
1574     }
1575 
getITelephonyInterface()1576     private static ITelephony getITelephonyInterface() {
1577         ITelephony binder = ITelephony.Stub.asInterface(
1578                 TelephonyFrameworkInitializer
1579                         .getTelephonyServiceManager()
1580                         .getTelephonyServiceRegisterer()
1581                         .get());
1582         return binder;
1583     }
1584 }
1585