diff --git a/api/system-current.txt b/api/system-current.txt index 5c576e25aec24..9946f6dd3983e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -8812,9 +8812,11 @@ package android.telephony.ims { field @NonNull public static final android.os.Parcelable.Creator CREATOR; } - public class ImsMmTelManager { + public class ImsMmTelManager implements android.telephony.ims.RegistrationManager { method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.function.Consumer, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.function.Consumer, @NonNull java.util.concurrent.Executor); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.function.Consumer, @NonNull java.util.concurrent.Executor); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAdvancedCallingSettingEnabled(); @@ -8825,7 +8827,8 @@ package android.telephony.ims { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiRoamingSettingEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiSettingEnabled(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVtSettingEnabled(); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException; + method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException; method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException; method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean); @@ -8835,7 +8838,8 @@ package android.telephony.ims { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean); - method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback); + method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterMmTelCapabilityCallback(@NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback); field public static final int WIFI_MODE_CELLULAR_PREFERRED = 1; // 0x1 field public static final int WIFI_MODE_WIFI_ONLY = 0; // 0x0 @@ -8847,12 +8851,8 @@ package android.telephony.ims { method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities); } - public static class ImsMmTelManager.RegistrationCallback { - ctor public ImsMmTelManager.RegistrationCallback(); - method public void onRegistered(int); - method public void onRegistering(int); - method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo); - method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo); + @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback { + ctor @Deprecated public ImsMmTelManager.RegistrationCallback(); } public final class ImsReasonInfo implements android.os.Parcelable { @@ -9284,6 +9284,24 @@ package android.telephony.ims { method public void onProvisioningStringChanged(int, @NonNull String); } + public interface RegistrationManager { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.function.Consumer, @NonNull java.util.concurrent.Executor); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.function.Consumer, @NonNull java.util.concurrent.Executor); + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException; + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback); + field public static final int REGISTRATION_STATE_NOT_REGISTERED = 0; // 0x0 + field public static final int REGISTRATION_STATE_REGISTERED = 2; // 0x2 + field public static final int REGISTRATION_STATE_REGISTERING = 1; // 0x1 + } + + public static class RegistrationManager.RegistrationCallback { + ctor public RegistrationManager.RegistrationCallback(); + method public void onRegistered(int); + method public void onRegistering(int); + method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo); + method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo); + } + } package android.telephony.ims.feature { diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java index ed292be9cd052..7cafa1ea068cd 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -25,7 +25,6 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; -import android.net.Uri; import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; @@ -34,11 +33,9 @@ import android.telephony.AccessNetworkConstants; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.ims.aidl.IImsCapabilityCallback; -import android.telephony.ims.aidl.IImsRegistrationCallback; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; -import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IIntegerConsumer; @@ -46,8 +43,6 @@ import com.android.internal.telephony.ITelephony; 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; @@ -63,7 +58,7 @@ import java.util.function.Consumer; * @hide */ @SystemApi -public class ImsMmTelManager { +public class ImsMmTelManager implements RegistrationManager { /** * @hide @@ -96,94 +91,18 @@ public class ImsMmTelManager { * Callback class for receiving IMS network Registration callback events. * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) (RegistrationCallback) * @see #unregisterImsRegistrationCallback(RegistrationCallback) + * @deprecated Use {@link RegistrationManager.RegistrationCallback} instead. */ - public static class RegistrationCallback { - - private static class RegistrationBinder extends IImsRegistrationCallback.Stub { - - // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN - // and WWAN are more accurate constants. - private static final Map IMS_REG_TO_ACCESS_TYPE_MAP = - new HashMap() {{ - // 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); - }}; - - 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 (!IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regType)) { - Log.w("ImsMmTelManager", "RegistrationBinder - invalid regType returned: " - + regType); - return -1; - } - return IMS_REG_TO_ACCESS_TYPE_MAP.get(regType); - } - } - - private final RegistrationBinder mBinder = new RegistrationBinder(this); + // Do not add to this class, add to RegistrationManager.RegistrationCallback instead. + @Deprecated + public static class RegistrationCallback extends RegistrationManager.RegistrationCallback { /** * Notifies the framework when the IMS Provider is registered to the IMS network. * * @param imsTransportType the radio access technology. */ + @Override public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) { } @@ -192,6 +111,7 @@ public class ImsMmTelManager { * * @param imsTransportType the radio access technology. */ + @Override public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) { } @@ -200,6 +120,7 @@ public class ImsMmTelManager { * * @param info the {@link ImsReasonInfo} associated with why registration was disconnected. */ + @Override public void onUnregistered(@Nullable ImsReasonInfo info) { } @@ -209,33 +130,11 @@ public class ImsMmTelManager { * @param imsTransportType The transport type that has failed to handover registration to. * @param info A {@link ImsReasonInfo} that identifies the reason for failure. */ + @Override 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); - } } /** @@ -355,7 +254,10 @@ public class ImsMmTelManager { * 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. + * @deprecated Use {@link #registerImsRegistrationCallback( + * RegistrationManager.RegistrationCallback, Executor)} instead. */ + @Deprecated @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor, @NonNull RegistrationCallback c) throws ImsException { @@ -380,6 +282,28 @@ public class ImsMmTelManager { } } + /**{@inheritDoc}*/ + @Override + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void registerImsRegistrationCallback( + @NonNull RegistrationManager.RegistrationCallback c, + @NonNull @CallbackExecutor Executor executor) throws ImsException { + if (c == null) { + throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + c.setExecutor(executor); + try { + getITelephony().registerImsRegistrationCallback(mSubId, c.getBinder()); + } catch (ServiceSpecificException e) { + throw new ImsException(e.getMessage(), e.errorCode); + } catch (RemoteException | IllegalStateException e) { + throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE); + } + } + /** * Removes an existing {@link RegistrationCallback}. * @@ -390,7 +314,10 @@ public class ImsMmTelManager { * @param c The {@link RegistrationCallback} to be removed. * @see SubscriptionManager.OnSubscriptionsChangedListener * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) + * @deprecated Use {@link #unregisterImsRegistrationCallback( + * RegistrationManager.RegistrationCallback)}. */ + @Deprecated @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c) { if (c == null) { @@ -403,6 +330,69 @@ public class ImsMmTelManager { } } + /**{@inheritDoc}*/ + @Override + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void unregisterImsRegistrationCallback( + @NonNull RegistrationManager.RegistrationCallback c) { + if (c == null) { + throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); + } + try { + getITelephony().unregisterImsRegistrationCallback(mSubId, c.getBinder()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /**{@inheritDoc}*/ + @Override + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void getRegistrationState(@NonNull @ImsRegistrationState Consumer stateCallback, + @NonNull @CallbackExecutor Executor executor) { + if (stateCallback == null) { + throw new IllegalArgumentException("Must include a non-null callback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + try { + getITelephony().getImsMmTelRegistrationState(mSubId, new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> stateCallback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + + /**{@inheritDoc}*/ + @Override + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void getRegistrationTransportType( + @NonNull @AccessNetworkConstants.TransportType Consumer transportTypeCallback, + @NonNull @CallbackExecutor Executor executor) { + if (transportTypeCallback == null) { + throw new IllegalArgumentException("Must include a non-null callback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + try { + getITelephony().getImsMmTelRegistrationTransportType(mSubId, + new IIntegerConsumer.Stub() { + @Override + public void accept(int result) { + executor.execute(() -> transportTypeCallback.accept(result)); + } + }); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + /** * Registers a {@link CapabilityCallback} with the system, which will provide MmTel service * availability updates for the subscription specified in @@ -411,7 +401,7 @@ public class ImsMmTelManager { * * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to * subscription changed events and call - * {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up. + * {@link #unregisterMmTelCapabilityCallback(CapabilityCallback)} to clean up. * * When the callback is registered, it will initiate the callback c to be called with the * current capabilities. diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java index 3c343dd19a86d..25bd1caea431c 100644 --- a/telephony/java/android/telephony/ims/ImsRcsManager.java +++ b/telephony/java/android/telephony/ims/ImsRcsManager.java @@ -22,12 +22,14 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.content.Context; import android.os.Binder; +import android.telephony.AccessNetworkConstants; import android.telephony.SubscriptionManager; import android.telephony.ims.aidl.IImsCapabilityCallback; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.RcsFeature; import java.util.concurrent.Executor; +import java.util.function.Consumer; /** * Manager for interfacing with the framework RCS services, including the User Capability Exchange @@ -36,7 +38,7 @@ import java.util.concurrent.Executor; * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager. * @hide */ -public class ImsRcsManager { +public class ImsRcsManager implements RegistrationManager { /** * Receives RCS availability status updates from the ImsService. @@ -136,6 +138,64 @@ public class ImsRcsManager { mSubId = subId; } + /**{@inheritDoc}*/ + @Override + public void registerImsRegistrationCallback( + @NonNull RegistrationManager.RegistrationCallback c, + @NonNull @CallbackExecutor Executor executor) + throws ImsException { + if (c == null) { + throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + c.setExecutor(executor); + throw new UnsupportedOperationException("registerImsRegistrationCallback is not" + + "supported."); + } + + /**{@inheritDoc}*/ + @Override + public void unregisterImsRegistrationCallback( + @NonNull RegistrationManager.RegistrationCallback c) { + if (c == null) { + throw new IllegalArgumentException("Must include a non-null RegistrationCallback."); + } + throw new UnsupportedOperationException("unregisterImsRegistrationCallback is not" + + "supported."); + } + + /**{@inheritDoc}*/ + @Override + public void getRegistrationState(@NonNull @ImsRegistrationState Consumer stateCallback, + @NonNull @CallbackExecutor Executor executor) { + if (stateCallback == null) { + throw new IllegalArgumentException("Must include a non-null stateCallback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + throw new UnsupportedOperationException("getRegistrationState is not" + + "supported."); + } + + /**{@inheritDoc}*/ + @Override + public void getRegistrationTransportType( + @NonNull @AccessNetworkConstants.TransportType Consumer transportTypeCallback, + @NonNull @CallbackExecutor Executor executor) { + if (transportTypeCallback == null) { + throw new IllegalArgumentException("Must include a non-null transportTypeCallback."); + } + if (executor == null) { + throw new IllegalArgumentException("Must include a non-null Executor."); + } + throw new UnsupportedOperationException("getRegistrationTransportType is not" + + "supported."); + } + + /** * Registers an {@link AvailabilityCallback} with the system, which will provide RCS * availability updates for the subscription specified. diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java new file mode 100644 index 0000000000000..b4c11e3c32a1b --- /dev/null +++ b/telephony/java/android/telephony/ims/RegistrationManager.java @@ -0,0 +1,285 @@ +/* + * 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.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 +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 IMS_REG_TO_ACCESS_TYPE_MAP = + new HashMap() {{ + // 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(RegistrationCallback, Executor) + * @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 c The {@link RegistrationCallback} to be added. + * @param executor The executor the callback events should be run on. + * @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 RegistrationCallback c, + @NonNull @CallbackExecutor Executor executor) 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(RegistrationCallback, Executor) + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c); + + /** + * Gets the registration state of the IMS service. + * @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}. + * @param executor The {@link Executor} that will be used to call the IMS registration state + * callback. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + void getRegistrationState(@NonNull @ImsRegistrationState Consumer stateCallback, + @NonNull @CallbackExecutor Executor executor); + + /** + * Gets the Transport Type associated with the current IMS registration. + * @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}. + * @param executor The {@link Executor} that will be used to call the transportTypeCallback. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + void getRegistrationTransportType( + @NonNull @AccessNetworkConstants.TransportType Consumer transportTypeCallback, + @NonNull @CallbackExecutor Executor executor); +} diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index a08e0313bb5b1..b455c2eff8033 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -22,6 +22,7 @@ import android.net.Uri; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; @@ -72,9 +73,6 @@ public class ImsRegistrationImplBase { // with NOT_REGISTERED in the case where the ImsService has not updated the registration state // yet. private static final int REGISTRATION_STATE_UNKNOWN = -1; - private static final int REGISTRATION_STATE_NOT_REGISTERED = 0; - private static final int REGISTRATION_STATE_REGISTERING = 1; - private static final int REGISTRATION_STATE_REGISTERED = 2; private final IImsRegistration mBinder = new IImsRegistration.Stub() { @@ -128,7 +126,7 @@ public class ImsRegistrationImplBase { * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. */ public final void onRegistered(@ImsRegistrationTech int imsRadioTech) { - updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERED); + updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERED); mCallbacks.broadcast((c) -> { try { c.onRegistered(imsRadioTech); @@ -146,7 +144,7 @@ public class ImsRegistrationImplBase { * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. */ public final void onRegistering(@ImsRegistrationTech int imsRadioTech) { - updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERING); + updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERING); mCallbacks.broadcast((c) -> { try { c.onRegistering(imsRadioTech); @@ -230,7 +228,8 @@ public class ImsRegistrationImplBase { private void updateToDisconnectedState(ImsReasonInfo info) { synchronized (mLock) { - updateToState(REGISTRATION_TECH_NONE, REGISTRATION_STATE_NOT_REGISTERED); + updateToState(REGISTRATION_TECH_NONE, + RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); if (info != null) { mLastDisconnectCause = info; } else { @@ -264,15 +263,15 @@ public class ImsRegistrationImplBase { disconnectInfo = mLastDisconnectCause; } switch (state) { - case REGISTRATION_STATE_NOT_REGISTERED: { + case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED: { c.onDeregistered(disconnectInfo); break; } - case REGISTRATION_STATE_REGISTERING: { + case RegistrationManager.REGISTRATION_STATE_REGISTERING: { c.onRegistering(getConnectionType()); break; } - case REGISTRATION_STATE_REGISTERED: { + case RegistrationManager.REGISTRATION_STATE_REGISTERED: { c.onRegistered(getConnectionType()); break; } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index ab3861e2d5172..db0eac2874231 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1795,6 +1795,16 @@ interface ITelephony { */ void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c); + /** + * Get the IMS service registration state for the MmTelFeature associated with this sub id. + */ + void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer); + + /** + * Get the transport type for the IMS service registration state. + */ + void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer); + /** * Adds an IMS MmTel capabilities callback for the subscription specified. */