diff options
5 files changed, 192 insertions, 4 deletions
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index 8a05bdfc8401..90a6de7b66a3 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -17,6 +17,7 @@ package android.telephony.ims; import android.annotation.LongDef; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.Service; @@ -30,12 +31,14 @@ import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsServiceController; import android.telephony.ims.aidl.IImsServiceControllerListener; +import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.feature.ImsFeature; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.feature.RcsFeature; import android.telephony.ims.stub.ImsConfigImplBase; import android.telephony.ims.stub.ImsFeatureConfiguration; import android.telephony.ims.stub.ImsRegistrationImplBase; +import android.telephony.ims.stub.SipTransportImplBase; import android.util.Log; import android.util.SparseArray; @@ -105,18 +108,47 @@ public class ImsService extends Service { /** * This ImsService supports the capability to place emergency calls over MMTEL. + * <p> + * Note: This should never be set by {@link #getImsServiceCapabilities()}, as whether it is + * there or not depends on whether or not {@link ImsFeature#FEATURE_EMERGENCY_MMTEL} is defined + * for this ImsService. If it is set, it will be removed during sanitization before the final + * capabilities bitfield is sent back to the framework. * @hide This is encoded into the {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, but we will be * adding other capabilities in a central location, so track this capability here as well. */ public static final long CAPABILITY_EMERGENCY_OVER_MMTEL = 1 << 0; /** + * This ImsService supports the capability to create SIP delegates for other IMS applications + * to use to proxy SIP messaging traffic through it. + * <p> + * In order for the framework to report SipDelegate creation as being available for this + * ImsService implementation, this ImsService must report this capability flag in + * {@link #getImsServiceCapabilities()}, {@link #getSipTransport(int)} must not return null, and + * this ImsService MUST report the ability to create both {@link ImsFeature#FEATURE_MMTEL} and + * {@link ImsFeature#FEATURE_RCS} features. + * @hide + */ + public static final long CAPABILITY_SIP_DELEGATE_CREATION = 1 << 1; + + /** + * Used for internal correctness checks of capabilities set by the ImsService implementation and + * tracks the index of the largest defined flag in the capabilities long. + * @hide + */ + public static final long CAPABILITY_MAX_INDEX = + Long.numberOfTrailingZeros(CAPABILITY_SIP_DELEGATE_CREATION); + + /** * @hide */ @LongDef(flag = true, prefix = "CAPABILITY_", value = { - CAPABILITY_EMERGENCY_OVER_MMTEL + // CAPABILITY_EMERGENCY_OVER_MMTEL is not included here because it is managed by + // whether or not ImsFeature.FEATURE_EMERGENCY_MMTEL feature is set and should + // not be set by users of ImsService. + CAPABILITY_SIP_DELEGATE_CREATION }) @Retention(RetentionPolicy.SOURCE) public @interface ImsServiceCapability {} @@ -127,6 +159,7 @@ public class ImsService extends Service { */ private static final Map<Long, String> CAPABILITIES_LOG_MAP = new HashMap<Long, String>() {{ put(CAPABILITY_EMERGENCY_OVER_MMTEL, "EMERGENCY_OVER_MMTEL"); + put(CAPABILITY_SIP_DELEGATE_CREATION, "SIP_DELEGATE_CREATION"); }}; /** @@ -201,6 +234,17 @@ public class ImsService extends Service { } @Override + public long getImsServiceCapabilities() { + long caps = ImsService.this.getImsServiceCapabilities(); + long sanitizedCaps = sanitizeCapabilities(caps); + if (caps != sanitizedCaps) { + Log.w(LOG_TAG, "removing invalid bits from field: 0x" + + Long.toHexString(caps ^ sanitizedCaps)); + } + return sanitizedCaps; + } + + @Override public void notifyImsServiceReadyForFeatureCreation() { ImsService.this.readyForFeatureCreation(); } @@ -218,6 +262,12 @@ public class ImsService extends Service { } @Override + public ISipTransport getSipTransport(int slotId) { + SipTransportImplBase s = ImsService.this.getSipTransport(slotId); + return s != null ? s.getBinder() : null; + } + + @Override public void enableIms(int slotId) { ImsService.this.enableIms(slotId); } @@ -371,6 +421,17 @@ public class ImsService extends Service { } /** + * The optional capabilities that this ImsService supports. + * <p> + * This should be a static configuration and should not change at runtime. + * @return The optional static capabilities of this ImsService implementation. + * @hide + */ + public @ImsServiceCapability long getImsServiceCapabilities() { + return 0L; + } + + /** * The ImsService has been bound and is ready for ImsFeature creation based on the Features that * the ImsService has registered for with the framework, either in the manifest or via * {@link #querySupportedImsFeatures()}. @@ -443,7 +504,37 @@ public class ImsService extends Service { } /** - * @return A string representation of the ImsService capabilties for logging. + * Return the {@link SipTransportImplBase} implementation associated with the provided slot. + * <p> + * This is an optional interface used for devices that must support IMS single registration and + * proxy SIP traffic to remote IMS applications. If this is not supported for this IMS service, + * this method should return {@code null}. If this feature is supported, then this method must + * never be {@code null} and the optional ImsService capability flag + * {@link #CAPABILITY_SIP_DELEGATE_CREATION} must be set in + * {@link #getImsServiceCapabilities()}. Otherwise the framework will assume this feature is not + * supported for this ImsService. + * @param slotId The slot that is associated with the SipTransport implementation. + * @return the SipTransport implementation for the specified slot. + * @hide Keep this hidden until there is something to expose in SipTransport. + */ + public @Nullable SipTransportImplBase getSipTransport(int slotId) { + return null; + } + + private static long sanitizeCapabilities(@ImsServiceCapability long caps) { + long filter = 0xFFFFFFFFFFFFFFFFL; + // pad the "allowed" set with zeros + filter <<= CAPABILITY_MAX_INDEX + 1; + // remove values above the allowed set. + caps &= ~filter; + // CAPABILITY_EMERGENCY_OVER_MMTEL should also not be set here, will be set by telephony + // internally. + caps &= ~CAPABILITY_EMERGENCY_OVER_MMTEL; + return caps; + } + + /** + * @return A string representation of the ImsService capabilities for logging. * @hide */ public static String getCapabilitiesString(@ImsServiceCapability long caps) { diff --git a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl index c956cbcc816c..c6966b3cf53e 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl @@ -21,6 +21,7 @@ import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.aidl.IImsServiceControllerListener; +import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.stub.ImsFeatureConfiguration; import com.android.ims.internal.IImsFeatureStatusCallback; @@ -34,6 +35,7 @@ interface IImsServiceController { IImsMmTelFeature createMmTelFeature(int slotId); IImsRcsFeature createRcsFeature(int slotId); ImsFeatureConfiguration querySupportedImsFeatures(); + long getImsServiceCapabilities(); void addFeatureStatusCallback(int slotId, int featureType, in IImsFeatureStatusCallback c); void removeFeatureStatusCallback(int slotId, int featureType, in IImsFeatureStatusCallback c); // Synchronous call to ensure the ImsService is ready before continuing with feature creation. @@ -41,6 +43,7 @@ interface IImsServiceController { void removeImsFeature(int slotId, int featureType); IImsConfig getConfig(int slotId); IImsRegistration getRegistration(int slotId); + ISipTransport getSipTransport(int slotId); oneway void enableIms(int slotId); oneway void disableIms(int slotId); } diff --git a/telephony/java/android/telephony/ims/aidl/ISipTransport.aidl b/telephony/java/android/telephony/ims/aidl/ISipTransport.aidl new file mode 100644 index 000000000000..fe233430ffad --- /dev/null +++ b/telephony/java/android/telephony/ims/aidl/ISipTransport.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020 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.aidl; + +/** + * Interface for commands to the SIP Transport implementation. + * {@hide} + */ +interface ISipTransport { +} diff --git a/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java b/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java new file mode 100644 index 000000000000..17bd4b14925f --- /dev/null +++ b/telephony/java/android/telephony/ims/stub/SipTransportImplBase.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2020 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.stub; + +import android.annotation.NonNull; +import android.telephony.ims.aidl.ISipTransport; + +import java.util.concurrent.Executor; + +/** + * Manages the creation and destruction of SipDelegates in order to proxy SIP traffic to other + * IMS applications in order to support IMS single registration. + * + * @hide Until there is an implementation, keep this hidden + */ +public class SipTransportImplBase { + + private final Executor mBinderExecutor; + private final ISipTransport mSipTransportImpl = new ISipTransport.Stub() { + + }; + + /** + * Create an implementation of SipTransportImplBase. + * + * @param executor The executor that remote calls from the framework should be called on. + */ + public SipTransportImplBase(@NonNull Executor executor) { + if (executor == null) { + throw new IllegalArgumentException("executor must not be null"); + } + + mBinderExecutor = executor; + } + + /** + * @return The IInterface used by the framework. + * @hide + */ + public ISipTransport getBinder() { + return mSipTransportImpl; + } +} diff --git a/telephony/java/com/android/ims/ImsFeatureContainer.java b/telephony/java/com/android/ims/ImsFeatureContainer.java index b259679ea1bf..80c1d43480cc 100644 --- a/telephony/java/com/android/ims/ImsFeatureContainer.java +++ b/telephony/java/com/android/ims/ImsFeatureContainer.java @@ -17,12 +17,14 @@ package com.android.ims; import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.telephony.ims.ImsService; import android.telephony.ims.aidl.IImsConfig; import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.aidl.ISipTransport; import android.telephony.ims.feature.ImsFeature; import java.util.Objects; @@ -49,6 +51,11 @@ public final class ImsFeatureContainer implements Parcelable { public final IImsRegistration imsRegistration; /** + * An optional interface containing the SIP transport implementation from the ImsService. + */ + public final ISipTransport sipTransport; + + /** * State of the feature that is being tracked. */ private @ImsFeature.ImsState int mState = ImsFeature.STATE_UNAVAILABLE; @@ -66,10 +73,11 @@ public final class ImsFeatureContainer implements Parcelable { * @param initialCaps The initial capabilities that the ImsService supports. */ public ImsFeatureContainer(@NonNull IBinder iFace, @NonNull IImsConfig iConfig, - @NonNull IImsRegistration iReg, long initialCaps) { + @NonNull IImsRegistration iReg, @Nullable ISipTransport transport, long initialCaps) { imsFeature = iFace; imsConfig = iConfig; imsRegistration = iReg; + sipTransport = transport; mCapabilities = initialCaps; } @@ -80,6 +88,7 @@ public final class ImsFeatureContainer implements Parcelable { imsFeature = in.readStrongBinder(); imsConfig = IImsConfig.Stub.asInterface(in.readStrongBinder()); imsRegistration = IImsRegistration.Stub.asInterface(in.readStrongBinder()); + sipTransport = ISipTransport.Stub.asInterface(in.readStrongBinder()); mState = in.readInt(); mCapabilities = in.readLong(); } @@ -123,13 +132,15 @@ public final class ImsFeatureContainer implements Parcelable { return imsFeature.equals(that.imsFeature) && imsConfig.equals(that.imsConfig) && imsRegistration.equals(that.imsRegistration) && + sipTransport.equals(that.sipTransport) && mState == that.getState() && mCapabilities == that.getCapabilities(); } @Override public int hashCode() { - return Objects.hash(imsFeature, imsConfig, imsRegistration, mState, mCapabilities); + return Objects.hash(imsFeature, imsConfig, imsRegistration, sipTransport, mState, + mCapabilities); } @Override @@ -138,6 +149,7 @@ public final class ImsFeatureContainer implements Parcelable { "imsFeature=" + imsFeature + ", imsConfig=" + imsConfig + ", imsRegistration=" + imsRegistration + + ", sipTransport=" + sipTransport + ", state=" + ImsFeature.STATE_LOG_MAP.get(mState) + ", capabilities = " + ImsService.getCapabilitiesString(mCapabilities) + '}'; @@ -153,6 +165,7 @@ public final class ImsFeatureContainer implements Parcelable { dest.writeStrongBinder(imsFeature); dest.writeStrongInterface(imsConfig); dest.writeStrongInterface(imsRegistration); + dest.writeStrongInterface(sipTransport); dest.writeInt(mState); dest.writeLong(mCapabilities); } |