diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index 75aeb0419cff7..c806d5c8ed3a0 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.app.Service; import android.content.Intent; @@ -29,12 +30,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; @@ -103,18 +106,47 @@ public class ImsService extends Service { /** * This ImsService supports the capability to place emergency calls over MMTEL. + *
+ * 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. + *
+ * 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 {}
@@ -125,6 +157,7 @@ public class ImsService extends Service {
*/
private static final Map
+ * 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
@@ -441,7 +502,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.
+ *
+ * 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 c956cbcc816cc..c6966b3cf53e8 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 0000000000000..fe233430ffad1
--- /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 0000000000000..17bd4b14925f1
--- /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 b259679ea1bf8..80c1d43480ccc 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;
@@ -48,6 +50,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.
*/
@@ -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);
}