diff options
author | Brad Ebinger <breadley@google.com> | 2021-02-11 05:11:29 +0000 |
---|---|---|
committer | Brad Ebinger <breadley@google.com> | 2021-02-11 19:59:16 +0000 |
commit | 8420894edcd1cdd540a623880076ba7d94ebefa2 (patch) | |
tree | e3141dfe851b47b0418d0b9d3c8385cae3324405 /telephony/java | |
parent | c5bc3bcd8f95a75047c23d08dfbdfad846517946 (diff) |
Add the ability to send the feature tags associated with IMS registration
- In order to better support UCE, allow the IMS registration update to
the framework to include the feature tags associated with the registration
so that this information can be used in SIP PUBLISH.
- Encapsulate other IMS registration attributes into a singlular class.
Bug: 177375635
Test: atest CtsTelephonyTestCases:ImsServiceTest
Merged-In: Id730e5e0c9322c2a845523f3b3901f3d899c3f1c
Change-Id: Id730e5e0c9322c2a845523f3b3901f3d899c3f1c
Diffstat (limited to 'telephony/java')
5 files changed, 331 insertions, 62 deletions
diff --git a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl new file mode 100644 index 000000000000..0830ff2ff050 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 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; + +parcelable ImsRegistrationAttributes; diff --git a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java new file mode 100644 index 000000000000..a36f54953e63 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2021 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.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.AccessNetworkConstants; +import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.util.ArraySet; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +/** + * Contains the attributes associated with the current IMS registration. + */ +public final class ImsRegistrationAttributes implements Parcelable { + + /** + * Builder for creating {@link ImsRegistrationAttributes} instances. + * @hide + */ + @SystemApi + public static final class Builder { + private final int mRegistrationTech; + private Set<String> mFeatureTags = Collections.emptySet(); + + /** + * Build a new instance of {@link ImsRegistrationAttributes}. + * + * @param registrationTech The Radio Access Technology that IMS is registered on. + */ + public Builder(@ImsRegistrationImplBase.ImsRegistrationTech int registrationTech) { + mRegistrationTech = registrationTech; + } + + /** + * Optional IMS feature tags included in this IMS registration. + * @param tags A set of Strings containing the MMTEL and RCS feature tags associated with + * the IMS registration. This information is used for services such as the UCE + * service to ascertain the complete IMS registration state to ensure the SIP + * PUBLISH is accurate. The format of the set of feature tags must be one feature + * tag key and value per entry. Each feature tag will contain the feature tag name + * and string value (if applicable), even if they have the same feature tag name. + * For example, + * {@code +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg, + * urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", +g.gsma.callcomposer} must + * be split into three feature tag entries: + * {@code {+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg", + * +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", + * +g.gsma.callcomposer}}. + */ + public @NonNull Builder setFeatureTags(@NonNull Set<String> tags) { + if (tags == null) { + throw new IllegalArgumentException("feature tag set must not be null"); + } + mFeatureTags = new ArraySet<>(tags); + return this; + } + + /** + * @return A new instance created from this builder. + */ + public @NonNull ImsRegistrationAttributes build() { + return new ImsRegistrationAttributes(mRegistrationTech, + RegistrationManager.getAccessType(mRegistrationTech), + 0 /* No attributes in AOSP */, mFeatureTags); + } + + } + + private final int mRegistrationTech; + private final int mTransportType; + private final int mImsAttributeFlags; + private final ArrayList<String> mFeatureTags; + + /** + * Create a new {@link ImsRegistrationAttributes} instance. + * + * @param registrationTech The technology that IMS has been registered on. + * @param transportType The transport type that IMS has been registered on. + * @param imsAttributeFlags The attributes associated with the IMS registration. + * @param featureTags The feature tags included in the IMS registration. + * @see Builder + * @hide + */ + public ImsRegistrationAttributes( + @ImsRegistrationImplBase.ImsRegistrationTech int registrationTech, + @AccessNetworkConstants.TransportType int transportType, + int imsAttributeFlags, + @Nullable Set<String> featureTags) { + mRegistrationTech = registrationTech; + mTransportType = transportType; + mImsAttributeFlags = imsAttributeFlags; + mFeatureTags = new ArrayList<>(featureTags); + } + + /**@hide*/ + public ImsRegistrationAttributes(Parcel source) { + mRegistrationTech = source.readInt(); + mTransportType = source.readInt(); + mImsAttributeFlags = source.readInt(); + mFeatureTags = new ArrayList<>(); + source.readList(mFeatureTags, null /*classloader*/); + } + + /** + * @return The Radio Access Technology that the IMS registration has been registered over. + * @hide + */ + @SystemApi + public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTechnology() { + return mRegistrationTech; + } + + /** + * @return The access network transport type that IMS has been registered over. + */ + public @AccessNetworkConstants.TransportType int getTransportType() { + return mTransportType; + } + + /** + * @return A bit-mask containing attributes associated with the IMS registration. + */ + public int getAttributeFlags() { + return mImsAttributeFlags; + } + + /** + * Gets the Set of feature tags associated with the current IMS registration, if the IMS + * service supports supplying this information. + * <p> + * The format of the set of feature tags will be one feature tag key and value per entry and + * will potentially contain MMTEL and RCS feature tags, depending the configuration of the IMS + * service associated with the registration indications. Each feature tag will contain the + * feature tag name and string value (if applicable), even if they have the same feature tag + * name. For example, {@code +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg, + * urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", +g.gsma.callcomposer} will be split + * into three feature tag entries: + * {@code {+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg", + * +g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session", + * +g.gsma.callcomposer}}. + * @return The Set of feature tags associated with the current IMS registration. + */ + public @NonNull Set<String> getFeatureTags() { + if (mFeatureTags == null) { + return Collections.emptySet(); + } + return new ArraySet<>(mFeatureTags); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mRegistrationTech); + dest.writeInt(mTransportType); + dest.writeInt(mImsAttributeFlags); + dest.writeList(mFeatureTags); + } + + public static final @NonNull Creator<ImsRegistrationAttributes> CREATOR = + new Creator<ImsRegistrationAttributes>() { + @Override + public ImsRegistrationAttributes createFromParcel(Parcel source) { + return new ImsRegistrationAttributes(source); + } + + @Override + public ImsRegistrationAttributes[] newArray(int size) { + return new ImsRegistrationAttributes[size]; + } + }; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ImsRegistrationAttributes that = (ImsRegistrationAttributes) o; + return mRegistrationTech == that.mRegistrationTech + && mTransportType == that.mTransportType + && mImsAttributeFlags == that.mImsAttributeFlags + && Objects.equals(mFeatureTags, that.mFeatureTags); + } + + @Override + public int hashCode() { + return Objects.hash(mRegistrationTech, mTransportType, mImsAttributeFlags, mFeatureTags); + } + + @Override + public String toString() { + return "ImsRegistrationAttributes { transportType= " + mTransportType + ", attributeFlags=" + + mImsAttributeFlags + ", featureTags=[" + mFeatureTags + "]}"; + } +} diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java index 2c75368b86bf..c49121f4dc5d 100644 --- a/telephony/java/android/telephony/ims/RegistrationManager.java +++ b/telephony/java/android/telephony/ims/RegistrationManager.java @@ -71,7 +71,6 @@ public interface RegistrationManager { */ int REGISTRATION_STATE_REGISTERED = 2; - /**@hide*/ // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN // and WWAN are more accurate constants. @@ -79,7 +78,8 @@ public interface RegistrationManager { 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_NONE, + AccessNetworkConstants.TRANSPORT_TYPE_INVALID); put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, @@ -103,6 +103,20 @@ public interface RegistrationManager { } /** + * @param regtech The registration technology. + * @return The Access Network type from registration technology. + * @hide + */ + static int getAccessType(int regtech) { + if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regtech)) { + Log.w("RegistrationManager", "getAccessType - invalid regType returned: " + + regtech); + return AccessNetworkConstants.TRANSPORT_TYPE_INVALID; + } + return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regtech); + } + + /** * Callback class for receiving IMS network Registration callback events. * @see #registerImsRegistrationCallback(Executor, RegistrationCallback) * @see #unregisterImsRegistrationCallback(RegistrationCallback) @@ -119,26 +133,24 @@ public interface RegistrationManager { } @Override - public void onRegistered(int imsRadioTech) { + public void onRegistered(ImsRegistrationAttributes attr) { if (mLocalCallback == null) return; long callingIdentity = Binder.clearCallingIdentity(); try { - mExecutor.execute(() -> - mLocalCallback.onRegistered(getAccessType(imsRadioTech))); + mExecutor.execute(() -> mLocalCallback.onRegistered(attr)); } finally { restoreCallingIdentity(callingIdentity); } } @Override - public void onRegistering(int imsRadioTech) { + public void onRegistering(ImsRegistrationAttributes attr) { if (mLocalCallback == null) return; long callingIdentity = Binder.clearCallingIdentity(); try { - mExecutor.execute(() -> - mLocalCallback.onRegistering(getAccessType(imsRadioTech))); + mExecutor.execute(() -> mLocalCallback.onRegistering(attr)); } finally { restoreCallingIdentity(callingIdentity); } @@ -183,15 +195,6 @@ public interface RegistrationManager { 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); @@ -200,19 +203,42 @@ public interface RegistrationManager { * Notifies the framework when the IMS Provider is registered to the IMS network. * * @param imsTransportType the radio access technology. + * @deprecated Use {@link #onRegistered(ImsRegistrationAttributes)} instead. */ public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) { } /** + * Notifies the framework when the IMS Provider is registered to the IMS network + * with corresponding attributes. + * + * @param attributes The attributes associated with this IMS registration. + */ + public void onRegistered(@NonNull ImsRegistrationAttributes attributes) { + // Default impl to keep backwards compatibility with old implementations + onRegistered(attributes.getTransportType()); + } + + /** * Notifies the framework when the IMS Provider is trying to register the IMS network. * * @param imsTransportType the radio access technology. + * @deprecated Use {@link #onRegistering(ImsRegistrationAttributes)} instead. */ public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) { } /** + * Notifies the framework when the IMS Provider is trying to register the IMS network. + * + * @param attributes The attributes associated with this IMS registration. + */ + public void onRegistering(@NonNull ImsRegistrationAttributes attributes) { + // Default impl to keep backwards compatibility with old implementations + onRegistering(attributes.getTransportType()); + } + + /** * Notifies the framework when the IMS Provider is unregistered from the IMS network. * * @param info the {@link ImsReasonInfo} associated with why registration was disconnected. @@ -298,10 +324,10 @@ public interface RegistrationManager { * @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}. + * 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, diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl index 749b1916962e..179407c983e5 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl @@ -21,6 +21,7 @@ import android.net.Uri; import android.telephony.ims.stub.ImsFeatureConfiguration; import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsRegistrationAttributes; /** * See {@link ImsManager#RegistrationCallback} for more information. @@ -28,8 +29,8 @@ import android.telephony.ims.ImsReasonInfo; * {@hide} */ oneway interface IImsRegistrationCallback { - void onRegistered(int imsRadioTech); - void onRegistering(int imsRadioTech); + void onRegistered(in ImsRegistrationAttributes attr); + void onRegistering(in ImsRegistrationAttributes attr); void onDeregistered(in ImsReasonInfo info); void onTechnologyChangeFailed(int imsRadioTech, in ImsReasonInfo info); void onSubscriberAssociatedUriChanged(in Uri[] uris); diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java index 088a7e26a9d0..23032f0c4d38 100644 --- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java @@ -18,17 +18,18 @@ package android.telephony.ims.stub; import android.annotation.IntDef; import android.annotation.IntRange; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.net.Uri; import android.os.RemoteException; import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.ImsRegistrationAttributes; import android.telephony.ims.RegistrationManager; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsRegistrationCallback; import android.util.Log; -import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.util.RemoteCallbackListExt; import com.android.internal.util.ArrayUtils; @@ -83,7 +84,10 @@ public class ImsRegistrationImplBase { @Override public @ImsRegistrationTech int getRegistrationTechnology() throws RemoteException { - return getConnectionType(); + synchronized (mLock) { + return (mRegistrationAttributes == null) ? REGISTRATION_TECH_NONE + : mRegistrationAttributes.getRegistrationTechnology(); + } } @Override @@ -116,8 +120,7 @@ public class ImsRegistrationImplBase { new RemoteCallbackListExt<>(); private final Object mLock = new Object(); // Locked on mLock - private @ImsRegistrationTech - int mConnectionType = REGISTRATION_TECH_NONE; + private ImsRegistrationAttributes mRegistrationAttributes; // Locked on mLock private int mRegistrationState = REGISTRATION_STATE_UNKNOWN; // Locked on mLock, create unspecified disconnect cause. @@ -195,17 +198,24 @@ public class ImsRegistrationImplBase { /** * Notify the framework that the device is connected to the IMS network. * - * @param imsRadioTech the radio access technology. Valid values are defined as - * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. + * @param imsRadioTech the radio access technology. */ public final void onRegistered(@ImsRegistrationTech int imsRadioTech) { - updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERED); + onRegistered(new ImsRegistrationAttributes.Builder(imsRadioTech).build()); + } + + /** + * Notify the framework that the device is connected to the IMS network. + * + * @param attributes The attributes associated with the IMS registration. + */ + public final void onRegistered(@NonNull ImsRegistrationAttributes attributes) { + updateToState(attributes, RegistrationManager.REGISTRATION_STATE_REGISTERED); mCallbacks.broadcastAction((c) -> { try { - c.onRegistered(imsRadioTech); + c.onRegistered(attributes); } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "onRegistrationConnected() - Skipping " + - "callback."); + Log.w(LOG_TAG, e + "onRegistered(int, Set) - Skipping callback."); } }); } @@ -213,17 +223,24 @@ public class ImsRegistrationImplBase { /** * Notify the framework that the device is trying to connect the IMS network. * - * @param imsRadioTech the radio access technology. Valid values are defined as - * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}. + * @param imsRadioTech the radio access technology. */ public final void onRegistering(@ImsRegistrationTech int imsRadioTech) { - updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERING); + onRegistering(new ImsRegistrationAttributes.Builder(imsRadioTech).build()); + } + + /** + * Notify the framework that the device is trying to connect the IMS network. + * + * @param attributes The attributes associated with the IMS registration. + */ + public final void onRegistering(@NonNull ImsRegistrationAttributes attributes) { + updateToState(attributes, RegistrationManager.REGISTRATION_STATE_REGISTERING); mCallbacks.broadcastAction((c) -> { try { - c.onRegistering(imsRadioTech); + c.onRegistering(attributes); } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "onRegistrationProcessing() - Skipping " + - "callback."); + Log.w(LOG_TAG, e + "onRegistering(int, Set) - Skipping callback."); } }); } @@ -252,8 +269,7 @@ public class ImsRegistrationImplBase { try { c.onDeregistered(reasonInfo); } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "onRegistrationDisconnected() - Skipping " + - "callback."); + Log.w(LOG_TAG, e + "onDeregistered() - Skipping callback."); } }); } @@ -272,8 +288,7 @@ public class ImsRegistrationImplBase { try { c.onTechnologyChangeFailed(imsRadioTech, reasonInfo); } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "onRegistrationChangeFailed() - Skipping " + - "callback."); + Log.w(LOG_TAG, e + "onTechnologyChangeFailed() - Skipping callback."); } }); } @@ -297,14 +312,13 @@ public class ImsRegistrationImplBase { try { callback.onSubscriberAssociatedUriChanged(uris); } catch (RemoteException e) { - Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping " - + "callback."); + Log.w(LOG_TAG, e + "onSubscriberAssociatedUriChanged() - Skipping callback."); } } - private void updateToState(@ImsRegistrationTech int connType, int newState) { + private void updateToState(ImsRegistrationAttributes attributes, int newState) { synchronized (mLock) { - mConnectionType = connType; + mRegistrationAttributes = attributes; mRegistrationState = newState; mLastDisconnectCause = null; } @@ -316,7 +330,7 @@ public class ImsRegistrationImplBase { mUrisSet = false; mUris = null; - updateToState(REGISTRATION_TECH_NONE, + updateToState(new ImsRegistrationAttributes.Builder(REGISTRATION_TECH_NONE).build(), RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED); if (info != null) { mLastDisconnectCause = info; @@ -328,29 +342,19 @@ public class ImsRegistrationImplBase { } /** - * @return the current registration connection type. Valid values are - * {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN} - * @hide - */ - @VisibleForTesting - public final @ImsRegistrationTech int getConnectionType() { - synchronized (mLock) { - return mConnectionType; - } - } - - /** * @param c the newly registered callback that will be updated with the current registration * state. */ private void updateNewCallbackWithState(IImsRegistrationCallback c) throws RemoteException { int state; + ImsRegistrationAttributes attributes; ImsReasonInfo disconnectInfo; boolean urisSet; Uri[] uris; synchronized (mLock) { state = mRegistrationState; + attributes = mRegistrationAttributes; disconnectInfo = mLastDisconnectCause; urisSet = mUrisSet; uris = mUris; @@ -361,11 +365,11 @@ public class ImsRegistrationImplBase { break; } case RegistrationManager.REGISTRATION_STATE_REGISTERING: { - c.onRegistering(getConnectionType()); + c.onRegistering(attributes); break; } case RegistrationManager.REGISTRATION_STATE_REGISTERED: { - c.onRegistered(getConnectionType()); + c.onRegistered(attributes); break; } case REGISTRATION_STATE_UNKNOWN: { |