diff --git a/Android.mk b/Android.mk index a798a311e0411..e727ff4b2eeb4 100644 --- a/Android.mk +++ b/Android.mk @@ -435,6 +435,7 @@ LOCAL_SRC_FILES += \ telephony/java/com/android/ims/internal/IImsEcbm.aidl \ telephony/java/com/android/ims/internal/IImsEcbmListener.aidl \ telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl \ + telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl \ telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl \ telephony/java/com/android/ims/internal/IImsService.aidl \ telephony/java/com/android/ims/internal/IImsServiceController.aidl \ diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java new file mode 100644 index 0000000000000..0f865a8437579 --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2017 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.app.PendingIntent; +import android.content.Intent; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteException; +import android.telephony.CarrierConfigManager; +import android.telephony.ims.feature.ImsFeature; +import android.telephony.ims.feature.MMTelFeature; +import android.telephony.ims.feature.RcsFeature; +import android.util.Log; +import android.util.SparseArray; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; +import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsFeatureStatusCallback; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsServiceController; +import com.android.ims.internal.IImsServiceFeatureListener; +import com.android.ims.internal.IImsUt; +import com.android.internal.annotations.VisibleForTesting; + +/** + * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend + * ImsService must register the service in their AndroidManifest to be detected by the framework. + * First, the application must declare that they use the "android.permission.BIND_IMS_SERVICE" + * permission. Then, the ImsService definition in the manifest must follow the following format: + * + * ... + * + * + * + * + * + * + * + * ... + * + * The telephony framework will then bind to the ImsService you have defined in your manifest + * if you are either: + * 1) Defined as the default ImsService for the device in the device overlay using + * "config_ims_package". + * 2) Defined as a Carrier Provided ImsService in the Carrier Configuration using + * {@link CarrierConfigManager#KEY_CONFIG_IMS_PACKAGE_OVERRIDE_STRING}. + * + * The features that are currently supported in an ImsService are: + * - RCS_FEATURE: This ImsService implements the {@link RcsFeature} class. + * - MMTEL_FEATURE: This ImsService implements the {@link MMTelFeature} class. + * - EMERGENCY_MMTEL_FEATURE: This ImsService implements the {@link MMTelFeature} class and will be + * available to place emergency calls at all times. This MUST be implemented by the default + * ImsService provided in the device overlay. + * + * @hide + */ +public abstract class ImsService extends ImsServiceBase { + + private static final String LOG_TAG = "ImsService"; + + /** + * The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService. + */ + public static final String SERVICE_INTERFACE = "android.telephony.ims.ImsService"; + + // A map of slot Id -> Set of features corresponding to that slot. + private final SparseArray> mFeatures = new SparseArray<>(); + + // Implements all supported features as a flat interface. + protected final IBinder mImsServiceController = new IImsServiceController.Stub() { + + @Override + public void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c) + throws RemoteException { + synchronized (mFeatures) { + onCreateImsFeatureInternal(slotId, feature, c); + } + } + + @Override + public void removeImsFeature(int slotId, int feature) throws RemoteException { + synchronized (mFeatures) { + onRemoveImsFeatureInternal(slotId, feature); + } + } + + @Override + public int startSession(int slotId, int featureType, PendingIntent incomingCallIntent, + IImsRegistrationListener listener) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.startSession(incomingCallIntent, listener); + } + } + return 0; + } + + @Override + public void endSession(int slotId, int featureType, int sessionId) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + feature.endSession(sessionId); + } + } + } + + @Override + public boolean isConnected(int slotId, int featureType, int sessionId, int callSessionType, + int callType) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.isConnected(sessionId, callSessionType, callType); + } + } + return false; + } + + @Override + public boolean isOpened(int slotId, int featureType, int sessionId) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.isOpened(sessionId); + } + } + return false; + } + + @Override + public int getFeatureStatus(int slotId, int featureType) throws RemoteException { + int status = ImsFeature.STATE_NOT_AVAILABLE; + synchronized (mFeatures) { + SparseArray featureMap = mFeatures.get(slotId); + if (featureMap != null) { + ImsFeature feature = getImsFeatureFromType(featureMap, featureType); + if (feature != null) { + status = feature.getFeatureState(); + } + } + } + return status; + } + + @Override + public void addRegistrationListener(int slotId, int featureType, int sessionId, + IImsRegistrationListener listener) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + feature.addRegistrationListener(sessionId, listener); + } + } + } + + @Override + public void removeRegistrationListener(int slotId, int featureType, int sessionId, + IImsRegistrationListener listener) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + feature.removeRegistrationListener(sessionId, listener); + } + } + } + + @Override + public ImsCallProfile createCallProfile(int slotId, int featureType, int sessionId, + int callSessionType, int callType) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.createCallProfile(sessionId, callSessionType, callType); + } + } + return null; + } + + @Override + public IImsCallSession createCallSession(int slotId, int featureType, int sessionId, + ImsCallProfile profile, IImsCallSessionListener listener) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.createCallSession(sessionId, profile, listener); + } + } + return null; + } + + @Override + public IImsCallSession getPendingCallSession(int slotId, int featureType, int sessionId, + String callId) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.getPendingCallSession(sessionId, callId); + } + } + return null; + } + + @Override + public IImsUt getUtInterface(int slotId, int featureType, int sessionId) + throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.getUtInterface(sessionId); + } + } + return null; + } + + @Override + public IImsConfig getConfigInterface(int slotId, int featureType, int sessionId) + throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.getConfigInterface(sessionId); + } + } + return null; + } + + @Override + public void turnOnIms(int slotId, int featureType, int sessionId) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + feature.turnOnIms(sessionId); + } + } + } + + @Override + public void turnOffIms(int slotId, int featureType, int sessionId) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + feature.turnOffIms(sessionId); + } + } + } + + @Override + public IImsEcbm getEcbmInterface(int slotId, int featureType, int sessionId) + throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.getEcbmInterface(sessionId); + } + } + return null; + } + + @Override + public void setUiTTYMode(int slotId, int featureType, int sessionId, int uiTtyMode, + Message onComplete) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + feature.setUiTTYMode(sessionId, uiTtyMode, onComplete); + } + } + } + + @Override + public IImsMultiEndpoint getMultiEndpointInterface(int slotId, int featureType, + int sessionId) throws RemoteException { + synchronized (mFeatures) { + MMTelFeature feature = resolveMMTelFeature(slotId, featureType); + if (feature != null) { + return feature.getMultiEndpointInterface(sessionId); + } + } + return null; + } + + }; + + @Override + public IBinder onBind(Intent intent) { + if(SERVICE_INTERFACE.equals(intent.getAction())) { + return mImsServiceController; + } + return null; + } + + /** + * Called from the ImsResolver to create the requested ImsFeature, as defined by the slot and + * featureType + * @param slotId An integer representing which SIM slot the ImsFeature is assigned to. + * @param featureType An integer representing the type of ImsFeature being created. This is + * defined in {@link ImsFeature}. + */ + // Be sure to lock on mFeatures before accessing this method + private void onCreateImsFeatureInternal(int slotId, int featureType, + IImsFeatureStatusCallback c) { + SparseArray featureMap = mFeatures.get(slotId); + if (featureMap == null) { + featureMap = new SparseArray<>(); + mFeatures.put(slotId, featureMap); + } + ImsFeature f = makeImsFeature(slotId, featureType); + if (f != null) { + f.setImsFeatureStatusCallback(c); + featureMap.put(featureType, f); + } + + } + /** + * Called from the ImsResolver to remove an existing ImsFeature, as defined by the slot and + * featureType. + * @param slotId An integer representing which SIM slot the ImsFeature is assigned to. + * @param featureType An integer representing the type of ImsFeature being removed. This is + * defined in {@link ImsFeature}. + */ + // Be sure to lock on mFeatures before accessing this method + private void onRemoveImsFeatureInternal(int slotId, int featureType) { + SparseArray featureMap = mFeatures.get(slotId); + if (featureMap == null) { + return; + } + + ImsFeature featureToRemove = getImsFeatureFromType(featureMap, featureType); + if (featureToRemove != null) { + featureMap.remove(featureType); + featureToRemove.notifyFeatureRemoved(slotId); + // Remove reference to Binder + featureToRemove.setImsFeatureStatusCallback(null); + } + } + + // Be sure to lock on mFeatures before accessing this method + private MMTelFeature resolveMMTelFeature(int slotId, int featureType) { + SparseArray features = getImsFeatureMap(slotId); + MMTelFeature feature = null; + if (features != null) { + feature = resolveImsFeature(features, featureType, MMTelFeature.class); + } + return feature; + } + + // Be sure to lock on mFeatures before accessing this method + private T resolveImsFeature(SparseArray set, int featureType, + Class className) { + ImsFeature feature = getImsFeatureFromType(set, featureType); + if (feature == null) { + return null; + } + try { + return className.cast(feature); + } catch (ClassCastException e) + { + Log.e(LOG_TAG, "Can not cast ImsFeature! Exception: " + e.getMessage()); + } + return null; + } + + @VisibleForTesting + // Be sure to lock on mFeatures before accessing this method + public SparseArray getImsFeatureMap(int slotId) { + return mFeatures.get(slotId); + } + + @VisibleForTesting + // Be sure to lock on mFeatures before accessing this method + public ImsFeature getImsFeatureFromType(SparseArray set, int featureType) { + return set.get(featureType); + } + + private ImsFeature makeImsFeature(int slotId, int feature) { + switch (feature) { + case ImsFeature.EMERGENCY_MMTEL: { + return onCreateEmergencyMMTelImsFeature(slotId); + } + case ImsFeature.MMTEL: { + return onCreateMMTelImsFeature(slotId); + } + case ImsFeature.RCS: { + return onCreateRcsFeature(slotId); + } + } + // Tried to create feature that is not defined. + return null; + } + + /** + * @return An implementation of MMTelFeature that will be used by the system for MMTel + * functionality. Must be able to handle emergency calls at any time as well. + */ + public abstract MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId); + + /** + * @return An implementation of MMTelFeature that will be used by the system for MMTel + * functionality. + */ + public abstract MMTelFeature onCreateMMTelImsFeature(int slotId); + + /** + * @return An implementation of RcsFeature that will be used by the system for RCS. + */ + public abstract RcsFeature onCreateRcsFeature(int slotId); +} diff --git a/telephony/java/android/telephony/ims/ImsServiceBase.java b/telephony/java/android/telephony/ims/ImsServiceBase.java index 0b50ecaeb1ca9..0878db8453478 100644 --- a/telephony/java/android/telephony/ims/ImsServiceBase.java +++ b/telephony/java/android/telephony/ims/ImsServiceBase.java @@ -22,7 +22,9 @@ import android.os.IBinder; /** - * Base ImsService Implementation, which is used by the ImsResolver to bind. + * Base ImsService Implementation, which is used by the ImsResolver to bind. ImsServices that do not + * need to provide an ImsService implementation but still wish to be managed by the ImsResolver + * lifecycle may implement this class directly. * @hide */ @SystemApi diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java new file mode 100644 index 0000000000000..b2cdba213771e --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsServiceProxy.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2017 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.app.PendingIntent; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteException; +import android.telephony.ims.feature.IRcsFeature; +import android.telephony.ims.feature.ImsFeature; +import android.util.Log; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; +import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsServiceController; +import com.android.ims.internal.IImsServiceFeatureListener; +import com.android.ims.internal.IImsUt; + +/** + * A container of the IImsServiceController binder, which implements all of the ImsFeatures that + * the platform currently supports: MMTel and RCS. + * @hide + */ + +public class ImsServiceProxy extends ImsServiceProxyCompat implements IRcsFeature { + + protected String LOG_TAG = "ImsServiceProxy"; + private final int mSupportedFeature; + + // Start by assuming the proxy is available for usage. + private boolean mIsAvailable = true; + // ImsFeature Status from the ImsService. Cached. + private Integer mFeatureStatusCached = null; + private ImsServiceProxy.INotifyStatusChanged mStatusCallback; + private final Object mLock = new Object(); + + public interface INotifyStatusChanged { + void notifyStatusChanged(); + } + + private final IImsServiceFeatureListener mListenerBinder = + new IImsServiceFeatureListener.Stub() { + + @Override + public void imsFeatureCreated(int slotId, int feature) throws RemoteException { + // The feature has been re-enabled. This may happen when the service crashes. + synchronized (mLock) { + if (!mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) { + Log.i(LOG_TAG, "Feature enabled on slotId: " + slotId + " for feature: " + + feature); + mIsAvailable = true; + } + } + } + + @Override + public void imsFeatureRemoved(int slotId, int feature) throws RemoteException { + synchronized (mLock) { + if (mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) { + Log.i(LOG_TAG, "Feature disabled on slotId: " + slotId + " for feature: " + + feature); + mIsAvailable = false; + } + } + } + + @Override + public void imsStatusChanged(int slotId, int feature, int status) throws RemoteException { + synchronized (mLock) { + Log.i(LOG_TAG, "imsStatusChanged: slot: " + slotId + " feature: " + feature + + " status: " + status); + if (mSlotId == slotId && feature == mSupportedFeature) { + mFeatureStatusCached = status; + } + } + if (mStatusCallback != null) { + mStatusCallback.notifyStatusChanged(); + } + } + }; + + public ImsServiceProxy(int slotId, IBinder binder, int featureType) { + super(slotId, binder); + mSupportedFeature = featureType; + } + + public ImsServiceProxy(int slotId, int featureType) { + super(slotId, null /*IBinder*/); + mSupportedFeature = featureType; + } + + public IImsServiceFeatureListener getListener() { + return mListenerBinder; + } + + public void setBinder(IBinder binder) { + mBinder = binder; + } + + @Override + public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).startSession(mSlotId, mSupportedFeature, + incomingCallIntent, listener); + } + } + + @Override + public void endSession(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId); + } + } + + @Override + public boolean isConnected(int sessionId, int callServiceType, int callType) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).isConnected(mSlotId, mSupportedFeature, sessionId, + callServiceType, callType); + } + } + + @Override + public boolean isOpened(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).isOpened(mSlotId, mSupportedFeature, sessionId); + } + } + + @Override + public void addRegistrationListener(int sessionId, IImsRegistrationListener listener) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + getServiceInterface(mBinder).addRegistrationListener(mSlotId, mSupportedFeature, + sessionId, listener); + } + } + + @Override + public void removeRegistrationListener(int sessionId, IImsRegistrationListener listener) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + getServiceInterface(mBinder).removeRegistrationListener(mSlotId, mSupportedFeature, + sessionId, listener); + } + } + + @Override + public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).createCallProfile(mSlotId, mSupportedFeature, + sessionId, callServiceType, callType); + } + } + + @Override + public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, + IImsCallSessionListener listener) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).createCallSession(mSlotId, mSupportedFeature, + sessionId, profile, listener); + } + } + + @Override + public IImsCallSession getPendingCallSession(int sessionId, String callId) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).getPendingCallSession(mSlotId, mSupportedFeature, + sessionId, callId); + } + } + + @Override + public IImsUt getUtInterface(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).getUtInterface(mSlotId, mSupportedFeature, + sessionId); + } + } + + @Override + public IImsConfig getConfigInterface(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).getConfigInterface(mSlotId, mSupportedFeature, + sessionId); + } + } + + @Override + public void turnOnIms(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + getServiceInterface(mBinder).turnOnIms(mSlotId, mSupportedFeature, sessionId); + } + } + + @Override + public void turnOffIms(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + getServiceInterface(mBinder).turnOffIms(mSlotId, mSupportedFeature, sessionId); + } + } + + @Override + public IImsEcbm getEcbmInterface(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).getEcbmInterface(mSlotId, mSupportedFeature, + sessionId); + } + } + + @Override + public void setUiTTYMode(int sessionId, int uiTtyMode, Message onComplete) + throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + getServiceInterface(mBinder).setUiTTYMode(mSlotId, mSupportedFeature, sessionId, + uiTtyMode, onComplete); + } + } + + @Override + public IImsMultiEndpoint getMultiEndpointInterface(int sessionId) throws RemoteException { + synchronized (mLock) { + checkBinderConnection(); + return getServiceInterface(mBinder).getMultiEndpointInterface(mSlotId, + mSupportedFeature, sessionId); + } + } + + @Override + public int getFeatureStatus() { + synchronized (mLock) { + if (mFeatureStatusCached != null) { + return mFeatureStatusCached; + } + } + // Don't synchronize on Binder call. + Integer status = retrieveFeatureStatus(); + synchronized (mLock) { + if (status == null) { + return ImsFeature.STATE_NOT_AVAILABLE; + } + // Cache only non-null value for feature status. + mFeatureStatusCached = status; + } + return status; + } + + /** + * Internal method used to retrieve the feature status from the corresponding ImsService. + */ + private Integer retrieveFeatureStatus() { + if (mBinder != null) { + try { + return getServiceInterface(mBinder).getFeatureStatus(mSlotId, mSupportedFeature); + } catch (RemoteException e) { + // Status check failed, don't update cache + } + } + return null; + } + + /** + * @param c Callback that will fire when the feature status has changed. + */ + public void setStatusCallback(INotifyStatusChanged c) { + mStatusCallback = c; + } + + @Override + public boolean isBinderAlive() { + return mIsAvailable && getFeatureStatus() == ImsFeature.STATE_READY && mBinder != null && + mBinder.isBinderAlive(); + } + + private IImsServiceController getServiceInterface(IBinder b) { + return IImsServiceController.Stub.asInterface(b); + } +} diff --git a/telephony/java/android/telephony/ims/ImsServiceProxyCompat.java b/telephony/java/android/telephony/ims/ImsServiceProxyCompat.java new file mode 100644 index 0000000000000..ff538584de45f --- /dev/null +++ b/telephony/java/android/telephony/ims/ImsServiceProxyCompat.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2017 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.app.PendingIntent; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteException; +import android.telephony.ims.feature.IMMTelFeature; +import android.telephony.ims.feature.ImsFeature; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; +import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsService; +import com.android.ims.internal.IImsUt; + +/** + * Compatibility class that implements the new ImsService IMMTelFeature interface, but + * uses the old IImsService interface to support older devices that implement the deprecated + * opt/net/ims interface. + * @hide + */ + +public class ImsServiceProxyCompat implements IMMTelFeature { + + protected final int mSlotId; + protected IBinder mBinder; + + public ImsServiceProxyCompat(int slotId, IBinder binder) { + mSlotId = slotId; + mBinder = binder; + } + + @Override + public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) + throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).open(mSlotId, ImsFeature.MMTEL, incomingCallIntent, + listener); + } + + @Override + public void endSession(int sessionId) throws RemoteException { + checkBinderConnection(); + getServiceInterface(mBinder).close(sessionId); + } + + @Override + public boolean isConnected(int sessionId, int callServiceType, int callType) + throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).isConnected(sessionId, callServiceType, callType); + } + + @Override + public boolean isOpened(int sessionId) throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).isOpened(sessionId); + } + + @Override + public void addRegistrationListener(int sessionId, IImsRegistrationListener listener) + throws RemoteException { + checkBinderConnection(); + getServiceInterface(mBinder).addRegistrationListener(mSlotId, ImsFeature.MMTEL, listener); + } + + @Override + public void removeRegistrationListener(int sessionId, IImsRegistrationListener listener) + throws RemoteException { + checkBinderConnection(); + // Not Implemented in old ImsService. If the registration listener becomes invalid, the + // ImsService will remove. + } + + @Override + public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType) + throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).createCallProfile(sessionId, callServiceType, callType); + } + + @Override + public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, + IImsCallSessionListener listener) throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).createCallSession(sessionId, profile, listener); + } + + @Override + public IImsCallSession getPendingCallSession(int sessionId, String callId) + throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).getPendingCallSession(sessionId, callId); + } + + @Override + public IImsUt getUtInterface(int sessionId) throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).getUtInterface(sessionId); + } + + @Override + public IImsConfig getConfigInterface(int sessionId) throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).getConfigInterface(mSlotId); + } + + @Override + public void turnOnIms(int sessionId) throws RemoteException { + checkBinderConnection(); + getServiceInterface(mBinder).turnOnIms(mSlotId); + } + + @Override + public void turnOffIms(int sessionId) throws RemoteException { + checkBinderConnection(); + getServiceInterface(mBinder).turnOffIms(mSlotId); + } + + @Override + public IImsEcbm getEcbmInterface(int sessionId) throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).getEcbmInterface(sessionId); + } + + @Override + public void setUiTTYMode(int sessionId, int uiTtyMode, Message onComplete) + throws RemoteException { + checkBinderConnection(); + getServiceInterface(mBinder).setUiTTYMode(sessionId, uiTtyMode, onComplete); + } + + @Override + public IImsMultiEndpoint getMultiEndpointInterface(int sessionId) throws RemoteException { + checkBinderConnection(); + return getServiceInterface(mBinder).getMultiEndpointInterface(sessionId); + } + + /** + * Base implementation, always returns READY for compatibility with old ImsService. + */ + public int getFeatureStatus() { + return ImsFeature.STATE_READY; + } + + /** + * @return false if the binder connection is no longer alive. + */ + public boolean isBinderAlive() { + return mBinder != null && mBinder.isBinderAlive(); + } + + private IImsService getServiceInterface(IBinder b) { + return IImsService.Stub.asInterface(b); + } + + protected void checkBinderConnection() throws RemoteException { + if (!isBinderAlive()) { + throw new RemoteException("ImsServiceProxy is not available for that feature."); + } + } +} diff --git a/telephony/java/android/telephony/ims/feature/IMMTelFeature.java b/telephony/java/android/telephony/ims/feature/IMMTelFeature.java new file mode 100644 index 0000000000000..e180843c8fa1a --- /dev/null +++ b/telephony/java/android/telephony/ims/feature/IMMTelFeature.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2017 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.feature; + +import android.app.PendingIntent; +import android.os.Message; +import android.os.RemoteException; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; +import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsUt; + +/** + * MMTel interface for an ImsService. When updating this interface, ensure that base implementations + * of your changes are also present in MMTelFeature for compatibility with older versions of the + * MMTel feature. + * @hide + */ + +public interface IMMTelFeature { + + /** + * Notifies the MMTel feature that you would like to start a session. This should always be + * done before making/receiving IMS calls. The IMS service will register the device to the + * operator's network with the credentials (from ISIM) periodically in order to receive calls + * from the operator's network. When the IMS service receives a new call, it will send out an + * intent with the provided action string. The intent contains a call ID extra + * {@link IImsCallSession#getCallId} and it can be used to take a call. + * + * @param incomingCallIntent When an incoming call is received, the IMS service will call + * {@link PendingIntent#send} to send back the intent to the caller with + * {@link #INCOMING_CALL_RESULT_CODE} as the result code and the intent to fill in the call ID; + * It cannot be null. + * @param listener To listen to IMS registration events; It cannot be null + * @return an integer (greater than 0) representing the session id associated with the session + * that has been started. + */ + int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) + throws RemoteException; + + /** + * End a previously started session using the associated sessionId. + * @param sessionId an integer (greater than 0) representing the ongoing session. See + * {@link #startSession}. + */ + void endSession(int sessionId) throws RemoteException; + + /** + * Checks if the IMS service has successfully registered to the IMS network with the specified + * service & call type. + * + * @param sessionId a session id which is obtained from {@link #startSession} + * @param callServiceType a service type that is specified in {@link ImsCallProfile} + * {@link ImsCallProfile#SERVICE_TYPE_NORMAL} + * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY} + * @param callType a call type that is specified in {@link ImsCallProfile} + * {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO} + * {@link ImsCallProfile#CALL_TYPE_VOICE} + * {@link ImsCallProfile#CALL_TYPE_VT} + * {@link ImsCallProfile#CALL_TYPE_VS} + * @return true if the specified service id is connected to the IMS network; false otherwise + * @throws RemoteException + */ + boolean isConnected(int sessionId, int callServiceType, int callType) throws RemoteException; + + /** + * Checks if the specified IMS service is opened. + * + * @param sessionId a service id which is obtained from {@link #startSession} + * @return true if the specified service id is opened; false otherwise + */ + boolean isOpened(int sessionId) throws RemoteException; + + /** + * Add a new registration listener for the client associated with the session Id. + * @param sessionId a session id which is obtained from {@link #startSession} + * @param listener An implementation of IImsRegistrationListener. + */ + void addRegistrationListener(int sessionId, IImsRegistrationListener listener) + throws RemoteException; + + /** + * Remove a previously registered listener using {@link #addRegistrationListener} for the client + * associated with the session Id. + * @param sessionId a session id which is obtained from {@link #startSession} + * @param listener A previously registered IImsRegistrationListener + */ + void removeRegistrationListener(int sessionId, IImsRegistrationListener listener) + throws RemoteException; + + /** + * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state. + * + * @param sessionId a session id which is obtained from {@link #startSession} + * @param callServiceType a service type that is specified in {@link ImsCallProfile} + * {@link ImsCallProfile#SERVICE_TYPE_NONE} + * {@link ImsCallProfile#SERVICE_TYPE_NORMAL} + * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY} + * @param callType a call type that is specified in {@link ImsCallProfile} + * {@link ImsCallProfile#CALL_TYPE_VOICE} + * {@link ImsCallProfile#CALL_TYPE_VT} + * {@link ImsCallProfile#CALL_TYPE_VT_TX} + * {@link ImsCallProfile#CALL_TYPE_VT_RX} + * {@link ImsCallProfile#CALL_TYPE_VT_NODIR} + * {@link ImsCallProfile#CALL_TYPE_VS} + * {@link ImsCallProfile#CALL_TYPE_VS_TX} + * {@link ImsCallProfile#CALL_TYPE_VS_RX} + * @return a {@link ImsCallProfile} object + */ + ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType) + throws RemoteException; + + /** + * Creates a {@link ImsCallSession} with the specified call profile. + * Use other methods, if applicable, instead of interacting with + * {@link ImsCallSession} directly. + * + * @param sessionId a session id which is obtained from {@link #startSession} + * @param profile a call profile to make the call + * @param listener An implementation of IImsCallSessionListener. + */ + IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, + IImsCallSessionListener listener) throws RemoteException; + + /** + * Retrieves the call session associated with a pending call. + * + * @param sessionId a session id which is obtained from {@link #startSession} + * @param callId a call id to make the call + */ + IImsCallSession getPendingCallSession(int sessionId, String callId) throws RemoteException; + + /** + * @return The Ut interface for the supplementary service configuration. + */ + IImsUt getUtInterface(int sessionId) throws RemoteException; + + /** + * @return The config interface for IMS Configuration + */ + IImsConfig getConfigInterface(int sessionId) throws RemoteException; + + /** + * Signal the MMTelFeature to turn on IMS when it has been turned off using {@link #turnOffIms} + * @param sessionId a session id which is obtained from {@link #startSession} + */ + void turnOnIms(int sessionId) throws RemoteException; + + /** + * Signal the MMTelFeature to turn off IMS when it has been turned on using {@link #turnOnIms} + * @param sessionId a session id which is obtained from {@link #startSession} + */ + void turnOffIms(int sessionId) throws RemoteException; + + /** + * @return The Emergency call-back mode interface for emergency VoLTE calls that support it. + */ + IImsEcbm getEcbmInterface(int sessionId) throws RemoteException; + + /** + * Sets the current UI TTY mode for the MMTelFeature. + * @param sessionId a session id which is obtained from {@link #startSession} + * @param uiTtyMode An integer containing the new UI TTY Mode. + * @param onComplete A {@link Message} to be used when the mode has been set. + * @throws RemoteException + */ + void setUiTTYMode(int sessionId, int uiTtyMode, Message onComplete) throws RemoteException; + + /** + * @return MultiEndpoint interface for DEP notifications + */ + IImsMultiEndpoint getMultiEndpointInterface(int sessionId) throws RemoteException; +} diff --git a/telephony/java/android/telephony/ims/feature/IRcsFeature.java b/telephony/java/android/telephony/ims/feature/IRcsFeature.java new file mode 100644 index 0000000000000..e28e1b38dfcd3 --- /dev/null +++ b/telephony/java/android/telephony/ims/feature/IRcsFeature.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 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.feature; + +/** + * Feature interface that provides access to RCS APIs. Currently empty until RCS support is added + * in the framework. + * @hide + */ + +public interface IRcsFeature { +} diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index 0509d604e688b..8d7d260104e28 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -16,18 +16,112 @@ package android.telephony.ims.feature; +import android.annotation.IntDef; +import android.os.RemoteException; +import android.util.Log; + +import com.android.ims.internal.IImsFeatureStatusCallback; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; + /** * Base class for all IMS features that are supported by the framework. * @hide */ -public class ImsFeature { +public abstract class ImsFeature { + + private static final String LOG_TAG = "ImsFeature"; // Invalid feature value public static final int INVALID = -1; - // ImsFeatures that are defined in the Manifests + // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously + // defined values in ImsServiceClass for compatibility purposes. public static final int EMERGENCY_MMTEL = 0; public static final int MMTEL = 1; public static final int RCS = 2; // Total number of features defined public static final int MAX = 3; + + // Integer values defining the state of the ImsFeature at any time. + @IntDef(flag = true, + value = { + STATE_NOT_AVAILABLE, + STATE_INITIALIZING, + STATE_READY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImsState {} + public static final int STATE_NOT_AVAILABLE = 0; + public static final int STATE_INITIALIZING = 1; + public static final int STATE_READY = 2; + + private List mRemovedListeners = new ArrayList<>(); + private IImsFeatureStatusCallback mStatusCallback; + private @ImsState int mState = STATE_NOT_AVAILABLE; + + public interface INotifyFeatureRemoved { + void onFeatureRemoved(int slotId); + } + + public void addFeatureRemovedListener(INotifyFeatureRemoved listener) { + synchronized (mRemovedListeners) { + mRemovedListeners.add(listener); + } + } + + public void removeFeatureRemovedListener(INotifyFeatureRemoved listener) { + synchronized (mRemovedListeners) { + mRemovedListeners.remove(listener); + } + } + + // Not final for testing. + public void notifyFeatureRemoved(int slotId) { + synchronized (mRemovedListeners) { + mRemovedListeners.forEach(l -> l.onFeatureRemoved(slotId)); + onFeatureRemoved(); + } + } + + public int getFeatureState() { + return mState; + } + + protected final void setFeatureState(@ImsState int state) { + if (mState != state) { + mState = state; + notifyFeatureState(state); + } + } + + // Not final for testing. + public void setImsFeatureStatusCallback(IImsFeatureStatusCallback c) { + mStatusCallback = c; + // If we have just connected, send queued status. + notifyFeatureState(mState); + } + + /** + * Internal method called by ImsFeature when setFeatureState has changed. + * @param state + */ + private void notifyFeatureState(@ImsState int state) { + if (mStatusCallback != null) { + try { + Log.i(LOG_TAG, "notifying ImsFeatureState"); + mStatusCallback.notifyImsFeatureStatus(state); + } catch (RemoteException e) { + mStatusCallback = null; + Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage()); + } + } + } + + /** + * Called when the feature is being removed and must be cleaned up. + */ + public abstract void onFeatureRemoved(); } diff --git a/telephony/java/android/telephony/ims/feature/MMTelFeature.java b/telephony/java/android/telephony/ims/feature/MMTelFeature.java new file mode 100644 index 0000000000000..570cd65b0e0bf --- /dev/null +++ b/telephony/java/android/telephony/ims/feature/MMTelFeature.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2017 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.feature; + +import android.app.PendingIntent; +import android.os.Message; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; +import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsUt; + +import java.util.ArrayList; +import java.util.List; + +/** + * Base implementation, which implements all methods in IMMTelFeature. Any class wishing to use + * MMTelFeature should extend this class and implement all methods that the service supports. + * + * @hide + */ + +public class MMTelFeature extends ImsFeature implements IMMTelFeature { + + @Override + public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) { + return 0; + } + + @Override + public void endSession(int sessionId) { + } + + @Override + public boolean isConnected(int sessionId, int callSessionType, int callType) { + return false; + } + + @Override + public boolean isOpened(int sessionId) { + return false; + } + + @Override + public void addRegistrationListener(int sessionId, IImsRegistrationListener listener) { + } + + @Override + public void removeRegistrationListener(int sessionId, IImsRegistrationListener listener) { + } + + @Override + public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType) { + return null; + } + + @Override + public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, + IImsCallSessionListener listener) { + return null; + } + + @Override + public IImsCallSession getPendingCallSession(int sessionId, String callId) { + return null; + } + + @Override + public IImsUt getUtInterface(int sessionId) { + return null; + } + + @Override + public IImsConfig getConfigInterface(int sessionId) { + return null; + } + + @Override + public void turnOnIms(int sessionId) { + } + + @Override + public void turnOffIms(int sessionId) { + } + + @Override + public IImsEcbm getEcbmInterface(int sessionId) { + return null; + } + + @Override + public void setUiTTYMode(int sessionId, int uiTtyMode, Message onComplete) { + } + + @Override + public IImsMultiEndpoint getMultiEndpointInterface(int sessionId) { + return null; + } + + @Override + public void onFeatureRemoved() { + + } +} diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java new file mode 100644 index 0000000000000..9cddc1b934dbf --- /dev/null +++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2017 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.feature; + +/** + * Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend + * this class and provide implementations of the IRcsFeature methods that they support. + * @hide + */ + +public class RcsFeature extends ImsFeature implements IRcsFeature { + + public RcsFeature() { + super(); + } + + @Override + public void onFeatureRemoved() { + + } +} diff --git a/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl b/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl new file mode 100644 index 0000000000000..41b1042e9a867 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017 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 com.android.ims.internal; + +/** +* Interface from ImsFeature in the ImsService to ImsServiceController. + * {@hide} + */ +oneway interface IImsFeatureStatusCallback { + void notifyImsFeatureStatus(int featureStatus); +} \ No newline at end of file diff --git a/telephony/java/com/android/ims/internal/IImsServiceController.aidl b/telephony/java/com/android/ims/internal/IImsServiceController.aidl index fa86a43c79d3f..b700f497d0373 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceController.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceController.aidl @@ -16,10 +16,50 @@ package com.android.ims.internal; +import android.app.PendingIntent; + +import com.android.ims.ImsCallProfile; +import com.android.ims.internal.IImsCallSession; +import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; +import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsFeatureStatusCallback; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; +import com.android.ims.internal.IImsUt; + +import android.os.Message; + /** + * See ImsService and IMMTelFeature for more information. * {@hide} */ interface IImsServiceController { - void createImsFeature(int slotId, int feature); + // ImsService Control + void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c); void removeImsFeature(int slotId, int feature); + // MMTel Feature + int startSession(int slotId, int featureType, in PendingIntent incomingCallIntent, + in IImsRegistrationListener listener); + void endSession(int slotId, int featureType, int sessionId); + boolean isConnected(int slotId, int featureType, int sessionId, int callSessionType, int callType); + boolean isOpened(int slotId, int featureType, int sessionId); + int getFeatureStatus(int slotId, int featureType); + void addRegistrationListener(int slotId, int featureType, int sessionId, + in IImsRegistrationListener listener); + void removeRegistrationListener(int slotId, int featureType, int sessionId, + in IImsRegistrationListener listener); + ImsCallProfile createCallProfile(int slotId, int featureType, int sessionId, int callSessionType, int callType); + IImsCallSession createCallSession(int slotId, int featureType, int sessionId, + in ImsCallProfile profile, IImsCallSessionListener listener); + IImsCallSession getPendingCallSession(int slotId, int featureType, int sessionId, + String callId); + IImsUt getUtInterface(int slotId, int featureType, int sessionId); + IImsConfig getConfigInterface(int slotId, int featureType, int sessionId); + void turnOnIms(int slotId, int featureType, int sessionId); + void turnOffIms(int slotId, int featureType, int sessionId); + IImsEcbm getEcbmInterface(int slotId, int featureType, int sessionId); + void setUiTTYMode(int slotId, int featureType, int sessionId, int uiTtyMode, + in Message onComplete); + IImsMultiEndpoint getMultiEndpointInterface(int slotId, int featureType, int sessionId); } diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl index 0a36b6bec6a2f..82a13dcb537c8 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceFeatureListener.aidl @@ -17,9 +17,11 @@ package com.android.ims.internal; /** +* Interface from ImsResolver to ImsServiceProxy in ImsManager. * {@hide} */ oneway interface IImsServiceFeatureListener { void imsFeatureCreated(int slotId, int feature); void imsFeatureRemoved(int slotId, int feature); + void imsStatusChanged(int slotId, int feature, int status); } \ No newline at end of file