| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.telephony.ims; |
| |
| import android.Manifest; |
| import android.annotation.CallbackExecutor; |
| import android.annotation.IntDef; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.RequiresPermission; |
| import android.annotation.SystemApi; |
| import android.annotation.TestApi; |
| import android.net.Uri; |
| import android.os.Binder; |
| import android.telephony.AccessNetworkConstants; |
| import android.telephony.ims.aidl.IImsRegistrationCallback; |
| import android.telephony.ims.feature.ImsFeature; |
| import android.telephony.ims.stub.ImsRegistrationImplBase; |
| import android.util.Log; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.concurrent.Executor; |
| import java.util.function.Consumer; |
| |
| /** |
| * Manages IMS Service registration state for associated {@link ImsFeature}s. |
| * @hide |
| */ |
| @SystemApi |
| @TestApi |
| public interface RegistrationManager { |
| |
| /** |
| * @hide |
| */ |
| // Defines the underlying radio technology type that we have registered for IMS over. |
| @IntDef(prefix = "REGISTRATION_STATE_", |
| value = { |
| REGISTRATION_STATE_NOT_REGISTERED, |
| REGISTRATION_STATE_REGISTERING, |
| REGISTRATION_STATE_REGISTERED |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface ImsRegistrationState {} |
| |
| /** |
| * The IMS service is currently not registered to the carrier network. |
| */ |
| int REGISTRATION_STATE_NOT_REGISTERED = 0; |
| |
| /** |
| * The IMS service is currently in the process of registering to the carrier network. |
| */ |
| int REGISTRATION_STATE_REGISTERING = 1; |
| |
| /** |
| * The IMS service is currently registered to the carrier network. |
| */ |
| int REGISTRATION_STATE_REGISTERED = 2; |
| |
| |
| /**@hide*/ |
| // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN |
| // and WWAN are more accurate constants. |
| Map<Integer, Integer> IMS_REG_TO_ACCESS_TYPE_MAP = |
| new HashMap<Integer, Integer>() {{ |
| // Map NONE to -1 to make sure that we handle the REGISTRATION_TECH_NONE |
| // case, since it is defined. |
| put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE, -1); |
| put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE, |
| AccessNetworkConstants.TRANSPORT_TYPE_WWAN); |
| put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, |
| AccessNetworkConstants.TRANSPORT_TYPE_WLAN); |
| }}; |
| |
| /** |
| * Callback class for receiving IMS network Registration callback events. |
| * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) |
| * @see #unregisterImsRegistrationCallback(RegistrationCallback) |
| */ |
| class RegistrationCallback { |
| |
| private static class RegistrationBinder extends IImsRegistrationCallback.Stub { |
| |
| private final RegistrationCallback mLocalCallback; |
| private Executor mExecutor; |
| |
| RegistrationBinder(RegistrationCallback localCallback) { |
| mLocalCallback = localCallback; |
| } |
| |
| @Override |
| public void onRegistered(int imsRadioTech) { |
| if (mLocalCallback == null) return; |
| |
| Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> |
| mLocalCallback.onRegistered(getAccessType(imsRadioTech)))); |
| } |
| |
| @Override |
| public void onRegistering(int imsRadioTech) { |
| if (mLocalCallback == null) return; |
| |
| Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> |
| mLocalCallback.onRegistering(getAccessType(imsRadioTech)))); |
| } |
| |
| @Override |
| public void onDeregistered(ImsReasonInfo info) { |
| if (mLocalCallback == null) return; |
| |
| Binder.withCleanCallingIdentity(() -> |
| mExecutor.execute(() -> mLocalCallback.onUnregistered(info))); |
| } |
| |
| @Override |
| public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) { |
| if (mLocalCallback == null) return; |
| |
| Binder.withCleanCallingIdentity(() -> |
| mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed( |
| getAccessType(imsRadioTech), info))); |
| } |
| |
| @Override |
| public void onSubscriberAssociatedUriChanged(Uri[] uris) { |
| if (mLocalCallback == null) return; |
| |
| Binder.withCleanCallingIdentity(() -> |
| mExecutor.execute(() -> |
| mLocalCallback.onSubscriberAssociatedUriChanged(uris))); |
| } |
| |
| private void setExecutor(Executor executor) { |
| mExecutor = executor; |
| } |
| |
| private static int getAccessType(int regType) { |
| if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regType)) { |
| Log.w("RegistrationManager", "RegistrationBinder - invalid regType returned: " |
| + regType); |
| return -1; |
| } |
| return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regType); |
| } |
| } |
| |
| private final RegistrationBinder mBinder = new RegistrationBinder(this); |
| |
| /** |
| * Notifies the framework when the IMS Provider is registered to the IMS network. |
| * |
| * @param imsTransportType the radio access technology. |
| */ |
| public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) { |
| } |
| |
| /** |
| * Notifies the framework when the IMS Provider is trying to register the IMS network. |
| * |
| * @param imsTransportType the radio access technology. |
| */ |
| public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) { |
| } |
| |
| /** |
| * Notifies the framework when the IMS Provider is deregistered from the IMS network. |
| * |
| * @param info the {@link ImsReasonInfo} associated with why registration was disconnected. |
| */ |
| public void onUnregistered(@Nullable ImsReasonInfo info) { |
| } |
| |
| /** |
| * A failure has occurred when trying to handover registration to another technology type. |
| * |
| * @param imsTransportType The transport type that has failed to handover registration to. |
| * @param info A {@link ImsReasonInfo} that identifies the reason for failure. |
| */ |
| public void onTechnologyChangeFailed( |
| @AccessNetworkConstants.TransportType int imsTransportType, |
| @Nullable ImsReasonInfo info) { |
| } |
| |
| /** |
| * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when |
| * it changes. Per RFC3455, an associated URI is a URI that the service provider has |
| * allocated to a user for their own usage. A user's phone number is typically one of the |
| * associated URIs. |
| * @param uris new array of subscriber {@link Uri}s that are associated with this IMS |
| * subscription. |
| * @hide |
| */ |
| public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) { |
| } |
| |
| /**@hide*/ |
| public final IImsRegistrationCallback getBinder() { |
| return mBinder; |
| } |
| |
| /**@hide*/ |
| //Only exposed as public for compatibility with deprecated ImsManager APIs. |
| public void setExecutor(Executor executor) { |
| mBinder.setExecutor(executor); |
| } |
| } |
| |
| /** |
| * Registers a {@link RegistrationCallback} with the system. Use |
| * {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed |
| * events and call {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up. |
| * |
| * When the callback is registered, it will initiate the callback c to be called with the |
| * current registration state. |
| * |
| * @param executor The executor the callback events should be run on. |
| * @param c The {@link RegistrationCallback} to be added. |
| * @see #unregisterImsRegistrationCallback(RegistrationCallback) |
| * @throws ImsException if the subscription associated with this callback is valid, but |
| * the {@link ImsService} associated with the subscription is not available. This can happen if |
| * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed |
| * reason. |
| */ |
| @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) |
| void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor, |
| @NonNull RegistrationCallback c) throws ImsException; |
| |
| /** |
| * Removes an existing {@link RegistrationCallback}. |
| * |
| * When the subscription associated with this callback is removed (SIM removed, ESIM swap, |
| * etc...), this callback will automatically be removed. If this method is called for an |
| * inactive subscription, it will result in a no-op. |
| * |
| * @param c The {@link RegistrationCallback} to be removed. |
| * @see SubscriptionManager.OnSubscriptionsChangedListener |
| * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) |
| */ |
| @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) |
| void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c); |
| |
| /** |
| * Gets the registration state of the IMS service. |
| * @param executor The {@link Executor} that will be used to call the IMS registration state |
| * callback. |
| * @param stateCallback A callback called on the supplied {@link Executor} that will contain the |
| * registration state of the IMS service, which will be one of the |
| * following: {@link #REGISTRATION_STATE_NOT_REGISTERED}, |
| * {@link #REGISTRATION_STATE_REGISTERING}, or |
| * {@link #REGISTRATION_STATE_REGISTERED}. |
| */ |
| @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) |
| void getRegistrationState(@NonNull @CallbackExecutor Executor executor, |
| @NonNull @ImsRegistrationState Consumer<Integer> stateCallback); |
| |
| /** |
| * Gets the Transport Type associated with the current IMS registration. |
| * @param executor The {@link Executor} that will be used to call the transportTypeCallback. |
| * @param transportTypeCallback The transport type associated with the current IMS registration, |
| * which will be one of following: |
| * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN}, |
| * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, or |
| * {@link AccessNetworkConstants#TRANSPORT_TYPE_INVALID}. |
| */ |
| @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) |
| void getRegistrationTransportType( |
| @NonNull @CallbackExecutor Executor executor, |
| @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback); |
| } |