Integrate new MMTel APIs into the framework
am: 5b1883b5f1
Change-Id: Id45f87f7399ddd8c2fd0046f5fa3f5364ec5f583
This commit is contained in:
23
Android.bp
23
Android.bp
@@ -463,15 +463,17 @@ java_library {
|
||||
"telephony/java/android/telephony/data/IDataService.aidl",
|
||||
"telephony/java/android/telephony/data/IDataServiceCallback.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsCallSessionListener.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsCapabilityCallback.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsConfig.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsConfigCallback.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsMmTelFeature.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsMmTelListener.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsRcsFeature.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsServiceController.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsServiceControllerListener.aidl",
|
||||
"telephony/java/android/telephony/ims/internal/aidl/IImsSmsListener.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsCapabilityCallback.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsConfig.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsConfigCallback.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsMmTelFeature.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsMmTelListener.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsRegistration.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsRcsFeature.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
|
||||
"telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
|
||||
"telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
|
||||
"telephony/java/android/telephony/mbms/IDownloadStateCallback.aidl",
|
||||
@@ -490,13 +492,10 @@ java_library {
|
||||
"telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsMMTelFeature.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsRegistration.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsRegistrationCallback.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsRcsFeature.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsService.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsServiceController.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsSmsListener.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsUt.aidl",
|
||||
"telephony/java/com/android/ims/internal/IImsUtListener.aidl",
|
||||
|
||||
@@ -47,12 +47,13 @@ import android.service.carrier.CarrierIdentifier;
|
||||
import android.telecom.PhoneAccount;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telephony.VisualVoicemailService.VisualVoicemailTask;
|
||||
import android.telephony.ims.aidl.IImsConfig;
|
||||
import android.telephony.ims.aidl.IImsMmTelFeature;
|
||||
import android.telephony.ims.aidl.IImsRcsFeature;
|
||||
import android.telephony.ims.aidl.IImsRegistration;
|
||||
import android.telephony.ims.feature.ImsFeature;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
import com.android.ims.internal.IImsServiceFeatureCallback;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.telecom.ITelecomService;
|
||||
@@ -4889,57 +4890,60 @@ public class TelephonyManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@IntDef({ImsFeature.EMERGENCY_MMTEL, ImsFeature.MMTEL, ImsFeature.RCS})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Feature {}
|
||||
|
||||
/**
|
||||
* Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id and MMTel
|
||||
* feature or {@link null} if the service is not available. If an MMTelFeature is available, the
|
||||
* {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
|
||||
* @param slotIndex The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
|
||||
* @param callback Listener that will send updates to ImsManager when there are updates to
|
||||
* ImsServiceController.
|
||||
* @return {@link IImsMMTelFeature} interface for the feature specified or {@code null} if
|
||||
* it is unavailable.
|
||||
* Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
|
||||
* status updates, if not already enabled.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable IImsMMTelFeature getImsMMTelFeatureAndListen(int slotIndex,
|
||||
IImsServiceFeatureCallback callback) {
|
||||
public void enableIms(int slotId) {
|
||||
try {
|
||||
ITelephony telephony = getITelephony();
|
||||
if (telephony != null) {
|
||||
return telephony.getMMTelFeatureAndListen(slotIndex, callback);
|
||||
telephony.enableIms(slotId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Rlog.e(TAG, "getImsMMTelFeatureAndListen, RemoteException: "
|
||||
Rlog.e(TAG, "enableIms, RemoteException: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link IImsMMTelFeature} that corresponds to the given slot Id and MMTel
|
||||
* feature for emergency calling or {@link null} if the service is not available. If an
|
||||
* MMTelFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
|
||||
* listener for feature updates.
|
||||
* @param slotIndex The SIM slot that we are requesting the {@link IImsMMTelFeature} for.
|
||||
* Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
|
||||
* status updates to disabled.
|
||||
* @hide
|
||||
*/
|
||||
public void disableIms(int slotId) {
|
||||
try {
|
||||
ITelephony telephony = getITelephony();
|
||||
if (telephony != null) {
|
||||
telephony.disableIms(slotId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Rlog.e(TAG, "disableIms, RemoteException: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id and MMTel
|
||||
* feature or {@link null} if the service is not available. If an MMTelFeature is available, the
|
||||
* {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
|
||||
* @param slotIndex The SIM slot that we are requesting the {@link IImsMmTelFeature} for.
|
||||
* @param callback Listener that will send updates to ImsManager when there are updates to
|
||||
* ImsServiceController.
|
||||
* @return {@link IImsMMTelFeature} interface for the feature specified or {@code null} if
|
||||
* @return {@link IImsMmTelFeature} interface for the feature specified or {@code null} if
|
||||
* it is unavailable.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable IImsMMTelFeature getImsEmergencyMMTelFeatureAndListen(int slotIndex,
|
||||
public @Nullable IImsMmTelFeature getImsMmTelFeatureAndListen(int slotIndex,
|
||||
IImsServiceFeatureCallback callback) {
|
||||
try {
|
||||
ITelephony telephony = getITelephony();
|
||||
if (telephony != null) {
|
||||
return telephony.getEmergencyMMTelFeatureAndListen(slotIndex, callback);
|
||||
return telephony.getMmTelFeatureAndListen(slotIndex, callback);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Rlog.e(TAG, "getImsEmergencyMMTelFeatureAndListen, RemoteException: "
|
||||
Rlog.e(TAG, "getImsMmTelFeatureAndListen, RemoteException: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
return null;
|
||||
@@ -4990,6 +4994,25 @@ public class TelephonyManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@IImsConfig} interface that corresponds with the slot index and feature.
|
||||
* @param slotIndex The SIM slot corresponding to the ImsService ImsConfig is active for.
|
||||
* @param feature An integer indicating the feature that we wish to get the ImsConfig for.
|
||||
* Corresponds to features defined in ImsFeature.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable IImsConfig getImsConfig(int slotIndex, int feature) {
|
||||
try {
|
||||
ITelephony telephony = getITelephony();
|
||||
if (telephony != null) {
|
||||
return telephony.getImsConfig(slotIndex, feature);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Rlog.e(TAG, "getImsRegistration, RemoteException: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set IMS registration state
|
||||
*
|
||||
|
||||
@@ -16,25 +16,28 @@
|
||||
|
||||
package android.telephony.ims;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ims.aidl.IImsConfig;
|
||||
import android.telephony.ims.aidl.IImsMmTelFeature;
|
||||
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.feature.ImsFeature;
|
||||
import android.telephony.ims.feature.MMTelFeature;
|
||||
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.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.ims.internal.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
import com.android.ims.internal.IImsServiceController;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import static android.Manifest.permission.MODIFY_PHONE_STATE;
|
||||
@@ -62,14 +65,11 @@ import static android.Manifest.permission.MODIFY_PHONE_STATE;
|
||||
* 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}.
|
||||
* {@link CarrierConfigManager#KEY_CTONFIG_IMS_PACKAGE_OVERRIDE_STRING}.
|
||||
*
|
||||
* The features that are currently supported in an ImsService are:
|
||||
* - RCS_FEATURE: This ImsService implements the RcsFeature class.
|
||||
* - MMTEL_FEATURE: This ImsService implements the MMTelFeature class.
|
||||
* - EMERGENCY_MMTEL_FEATURE: This ImsService implements the 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.
|
||||
* - MMTEL_FEATURE: This ImsService implements the MmTelFeature class.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@@ -89,20 +89,36 @@ public class ImsService extends Service {
|
||||
// call ImsFeature#onFeatureRemoved.
|
||||
private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>();
|
||||
|
||||
private IImsServiceControllerListener mListener;
|
||||
|
||||
|
||||
/**
|
||||
* Listener that notifies the framework of ImsService changes.
|
||||
* @hide
|
||||
*/
|
||||
public static class Listener extends IImsServiceControllerListener.Stub {
|
||||
/**
|
||||
* The IMS features that this ImsService supports has changed.
|
||||
* @param c a new {@link ImsFeatureConfiguration} containing {@link ImsFeature.FeatureType}s
|
||||
* that this ImsService supports. This may trigger the addition/removal of feature
|
||||
* in this service.
|
||||
*/
|
||||
public void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected final IBinder mImsServiceController = new IImsServiceController.Stub() {
|
||||
|
||||
@Override
|
||||
public IImsMMTelFeature createEmergencyMMTelFeature(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
return createEmergencyMMTelFeatureInternal(slotId, c);
|
||||
public void setListener(IImsServiceControllerListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsMMTelFeature createMMTelFeature(int slotId, IImsFeatureStatusCallback c) {
|
||||
return createMMTelFeatureInternal(slotId, c);
|
||||
public IImsMmTelFeature createMmTelFeature(int slotId, IImsFeatureStatusCallback c) {
|
||||
return createMmTelFeatureInternal(slotId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,11 +132,43 @@ public class ImsService extends Service {
|
||||
ImsService.this.removeImsFeature(slotId, featureType, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImsFeatureConfiguration querySupportedImsFeatures() {
|
||||
return ImsService.this.querySupportedImsFeatures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyImsServiceReadyForFeatureCreation() {
|
||||
ImsService.this.readyForFeatureCreation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyImsFeatureReady(int slotId, int featureType)
|
||||
throws RemoteException {
|
||||
ImsService.this.notifyImsFeatureReady(slotId, featureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsConfig getConfig(int slotId) throws RemoteException {
|
||||
ImsConfigImplBase c = ImsService.this.getConfig(slotId);
|
||||
return c != null ? c.getIImsConfig() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsRegistration getRegistration(int slotId) throws RemoteException {
|
||||
ImsRegistrationImplBase r = ImsService.this.getRegistration(slotId);
|
||||
return r != null ? r.getBinder() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableIms(int slotId) {
|
||||
ImsService.this.enableIms(slotId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableIms(int slotId) {
|
||||
ImsService.this.disableIms(slotId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -143,47 +191,35 @@ public class ImsService extends Service {
|
||||
return mFeaturesBySlot.get(slotId);
|
||||
}
|
||||
|
||||
private IImsMMTelFeature createEmergencyMMTelFeatureInternal(int slotId,
|
||||
private IImsMmTelFeature createMmTelFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
MMTelFeature f = onCreateEmergencyMMTelImsFeature(slotId);
|
||||
MmTelFeature f = createMmTelFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.EMERGENCY_MMTEL, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IImsMMTelFeature createMMTelFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
MMTelFeature f = onCreateMMTelImsFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.MMTEL, c);
|
||||
setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
Log.e(LOG_TAG, "createMmTelFeatureInternal: null feature returned.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IImsRcsFeature createRcsFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
RcsFeature f = onCreateRcsFeature(slotId);
|
||||
RcsFeature f = createRcsFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.RCS, c);
|
||||
setupFeature(f, slotId, ImsFeature.FEATURE_RCS, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
Log.e(LOG_TAG, "createRcsFeatureInternal: null feature returned.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupFeature(ImsFeature f, int slotId, int featureType,
|
||||
IImsFeatureStatusCallback c) {
|
||||
f.setContext(this);
|
||||
f.setSlotId(slotId);
|
||||
f.addImsFeatureStatusCallback(c);
|
||||
f.initialize(this, slotId);
|
||||
addImsFeature(slotId, featureType, f);
|
||||
// TODO: Remove once new onFeatureReady AIDL is merged in.
|
||||
f.onFeatureReady();
|
||||
}
|
||||
|
||||
private void addImsFeature(int slotId, int featureType, ImsFeature f) {
|
||||
@@ -221,30 +257,113 @@ public class ImsService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyImsFeatureReady(int slotId, int featureType) {
|
||||
synchronized (mFeaturesBySlot) {
|
||||
// get ImsFeature associated with the slot/feature
|
||||
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
|
||||
if (features == null) {
|
||||
Log.w(LOG_TAG, "Can not notify ImsFeature ready. No ImsFeatures exist on " +
|
||||
"slot " + slotId);
|
||||
return;
|
||||
}
|
||||
ImsFeature f = features.get(featureType);
|
||||
if (f == null) {
|
||||
Log.w(LOG_TAG, "Can not notify ImsFeature ready. No feature with type "
|
||||
+ featureType + " exists on slot " + slotId);
|
||||
return;
|
||||
}
|
||||
f.onFeatureReady();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* When called, provide the {@link ImsFeatureConfiguration} that this ImsService currently
|
||||
* supports. This will trigger the framework to set up the {@link ImsFeature}s that correspond
|
||||
* to the {@link ImsFeature.FeatureType}s configured here.
|
||||
* @return an {@link ImsFeatureConfiguration} containing Features this ImsService supports,
|
||||
* defined in {@link ImsFeature.FeatureType}.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) {
|
||||
public ImsFeatureConfiguration querySupportedImsFeatures() {
|
||||
// Return empty for base implementation
|
||||
return new ImsFeatureConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the framework with a new {@link ImsFeatureConfiguration} containing the updated
|
||||
* features, defined in {@link ImsFeature.FeatureType} that this ImsService supports. This may
|
||||
* trigger the framework to add/remove new ImsFeatures, depending on the configuration.
|
||||
* @hide
|
||||
*/
|
||||
public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c)
|
||||
throws RemoteException {
|
||||
if (mListener == null) {
|
||||
throw new IllegalStateException("Framework is not ready");
|
||||
}
|
||||
mListener.onUpdateSupportedImsFeatures(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* The ImsService should use this signal instead of onCreate/onBind or similar to perform
|
||||
* feature initialization because the framework may bind to this service multiple times to
|
||||
* query the ImsService's {@link ImsFeatureConfiguration} via
|
||||
* {@link #querySupportedImsFeatures()}before creating features.
|
||||
* @hide
|
||||
*/
|
||||
public void readyForFeatureCreation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The framework has enabled IMS for the slot specified, the ImsService should register for IMS
|
||||
* and perform all appropriate initialization to bring up all ImsFeatures.
|
||||
* @hide
|
||||
*/
|
||||
public void enableIms(int slotId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The framework has disabled IMS for the slot specified. The ImsService must deregister for IMS
|
||||
* and set capability status to false for all ImsFeatures.
|
||||
* @hide
|
||||
*/
|
||||
public void disableIms(int slotId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* When called, the framework is requesting that a new MmTelFeature is created for the specified
|
||||
* slot.
|
||||
*
|
||||
* @param slotId The slot ID that the MMTel Feature is being created for.
|
||||
* @return The newly created MmTelFeature associated with the slot or null if the feature is not
|
||||
* supported.
|
||||
* @hide
|
||||
*/
|
||||
public MmTelFeature createMmTelFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An implementation of MMTelFeature that will be used by the system for MMTel
|
||||
* functionality.
|
||||
* When called, the framework is requesting that a new RcsFeature is created for the specified
|
||||
* slot
|
||||
*
|
||||
* @param slotId The slot ID that the RCS Feature is being created for.
|
||||
* @return The newly created RcsFeature associated with the slot or null if the feature is not
|
||||
* supported.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable MMTelFeature onCreateMMTelImsFeature(int slotId) {
|
||||
public RcsFeature createRcsFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An implementation of RcsFeature that will be used by the system for RCS.
|
||||
* @param slotId The slot that the IMS configuration is associated with.
|
||||
* @return ImsConfig implementation that is associated with the specified slot.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable RcsFeature onCreateRcsFeature(int slotId) {
|
||||
return null;
|
||||
public ImsConfigImplBase getConfig(int slotId) {
|
||||
return new ImsConfigImplBase();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,4 +374,4 @@ public class ImsService extends Service {
|
||||
public ImsRegistrationImplBase getRegistration(int slotId) {
|
||||
return new ImsRegistrationImplBase();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
/**
|
||||
* See ImsFeature#CapabilityCallback for more information.
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.telephony.ims.internal.aidl.IImsConfigCallback;
|
||||
import android.telephony.ims.aidl.IImsConfigCallback;
|
||||
|
||||
import com.android.ims.ImsConfigListener;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
/**
|
||||
* Provides callback interface for ImsConfig when a value has changed.
|
||||
@@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.os.Message;
|
||||
import android.telephony.ims.internal.aidl.IImsMmTelListener;
|
||||
import android.telephony.ims.internal.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.internal.feature.CapabilityChangeRequest;
|
||||
import android.telephony.ims.aidl.IImsMmTelListener;
|
||||
import android.telephony.ims.aidl.IImsSmsListener;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.feature.CapabilityChangeRequest;
|
||||
|
||||
import com.android.ims.ImsCallProfile;
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
@@ -37,6 +38,7 @@ interface IImsMmTelFeature {
|
||||
int getFeatureState();
|
||||
ImsCallProfile createCallProfile(int callSessionType, int callType);
|
||||
IImsCallSession createCallSession(in ImsCallProfile profile);
|
||||
int shouldProcessCall(in String[] uris);
|
||||
IImsUt getUtInterface();
|
||||
IImsEcbm getEcbmInterface();
|
||||
void setUiTtyMode(int uiTtyMode, in Message onCompleteMessage);
|
||||
@@ -14,7 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
|
||||
@@ -23,6 +25,6 @@ import com.android.ims.internal.IImsCallSession;
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface IImsMmTelListener {
|
||||
void onIncomingCall(IImsCallSession c);
|
||||
void onIncomingCall(IImsCallSession c, in Bundle extras);
|
||||
void onVoiceMessageCountUpdate(int count);
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
/**
|
||||
* See RcsFeature for more information.
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.android.ims.internal;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import com.android.ims.internal.IImsRegistrationCallback;
|
||||
import android.telephony.ims.aidl.IImsRegistrationCallback;
|
||||
|
||||
/**
|
||||
* See ImsRegistration for more information.
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
|
||||
|
||||
package com.android.ims.internal;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
|
||||
import android.telephony.ims.stub.ImsFeatureConfiguration;
|
||||
|
||||
import com.android.ims.ImsReasonInfo;
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.telephony.ims.internal.aidl.IImsMmTelFeature;
|
||||
import android.telephony.ims.internal.aidl.IImsRcsFeature;
|
||||
import android.telephony.ims.internal.aidl.IImsConfig;
|
||||
import android.telephony.ims.internal.aidl.IImsServiceControllerListener;
|
||||
import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
|
||||
import android.telephony.ims.aidl.IImsMmTelFeature;
|
||||
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.stub.ImsFeatureConfiguration;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
|
||||
/**
|
||||
* See ImsService and MmTelFeature for more information.
|
||||
@@ -41,4 +41,6 @@ interface IImsServiceController {
|
||||
void removeImsFeature(int slotId, int featureType, in IImsFeatureStatusCallback c);
|
||||
IImsConfig getConfig(int slotId);
|
||||
IImsRegistration getRegistration(int slotId);
|
||||
oneway void enableIms(int slotId);
|
||||
oneway void disableIms(int slotId);
|
||||
}
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.aidl;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
|
||||
import android.telephony.ims.stub.ImsFeatureConfiguration;
|
||||
|
||||
/**
|
||||
* See ImsService#Listener for more information.
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.ims.internal;
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
/**
|
||||
* See SmsImplBase for more information.
|
||||
* {@hide}
|
||||
*/
|
||||
interface IImsSmsListener {
|
||||
oneway interface IImsSmsListener {
|
||||
void onSendSmsResult(int token, int messageRef, int status, int reason);
|
||||
void onSmsStatusReportReceived(int token, int messageRef, in String format,
|
||||
in byte[] pdu);
|
||||
237
telephony/java/android/telephony/ims/compat/ImsService.java
Normal file
237
telephony/java/android/telephony/ims/compat/ImsService.java
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.compat;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ims.compat.feature.ImsFeature;
|
||||
import android.telephony.ims.compat.feature.MMTelFeature;
|
||||
import android.telephony.ims.compat.feature.RcsFeature;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.ims.internal.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
import com.android.ims.internal.IImsServiceController;
|
||||
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:
|
||||
*
|
||||
* ...
|
||||
* <service android:name=".EgImsService"
|
||||
* android:permission="android.permission.BIND_IMS_SERVICE" >
|
||||
* <!-- Apps must declare which features they support as metadata. The different categories are
|
||||
* defined below. In this example, the RCS_FEATURE feature is supported. -->
|
||||
* <meta-data android:name="android.telephony.ims.RCS_FEATURE" android:value="true" />
|
||||
* <intent-filter>
|
||||
* <action android:name="android.telephony.ims.compat.ImsService" />
|
||||
* </intent-filter>
|
||||
* </service>
|
||||
* ...
|
||||
*
|
||||
* 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 RcsFeature class.
|
||||
* - MMTEL_FEATURE: This ImsService implements the MMTelFeature class.
|
||||
* - EMERGENCY_MMTEL_FEATURE: This ImsService implements the 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 class ImsService extends Service {
|
||||
|
||||
private static final String LOG_TAG = "ImsService(Compat)";
|
||||
|
||||
/**
|
||||
* The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService.
|
||||
* @hide
|
||||
*/
|
||||
public static final String SERVICE_INTERFACE = "android.telephony.ims.compat.ImsService";
|
||||
|
||||
// A map of slot Id -> map of features (indexed by ImsFeature feature id) corresponding to that
|
||||
// slot.
|
||||
// We keep track of this to facilitate cleanup of the IImsFeatureStatusCallback and
|
||||
// call ImsFeature#onFeatureRemoved.
|
||||
private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>();
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected final IBinder mImsServiceController = new IImsServiceController.Stub() {
|
||||
|
||||
@Override
|
||||
public IImsMMTelFeature createEmergencyMMTelFeature(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
return createEmergencyMMTelFeatureInternal(slotId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsMMTelFeature createMMTelFeature(int slotId, IImsFeatureStatusCallback c) {
|
||||
return createMMTelFeatureInternal(slotId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) {
|
||||
return createRcsFeatureInternal(slotId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
|
||||
throws RemoteException {
|
||||
ImsService.this.removeImsFeature(slotId, featureType, c);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if(SERVICE_INTERFACE.equals(intent.getAction())) {
|
||||
Log.i(LOG_TAG, "ImsService(Compat) Bound.");
|
||||
return mImsServiceController;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public SparseArray<ImsFeature> getFeatures(int slotId) {
|
||||
return mFeaturesBySlot.get(slotId);
|
||||
}
|
||||
|
||||
private IImsMMTelFeature createEmergencyMMTelFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
MMTelFeature f = onCreateEmergencyMMTelImsFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.EMERGENCY_MMTEL, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IImsMMTelFeature createMMTelFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
MMTelFeature f = onCreateMMTelImsFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.MMTEL, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IImsRcsFeature createRcsFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
RcsFeature f = onCreateRcsFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.RCS, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupFeature(ImsFeature f, int slotId, int featureType,
|
||||
IImsFeatureStatusCallback c) {
|
||||
f.setContext(this);
|
||||
f.setSlotId(slotId);
|
||||
f.addImsFeatureStatusCallback(c);
|
||||
addImsFeature(slotId, featureType, f);
|
||||
// TODO: Remove once new onFeatureReady AIDL is merged in.
|
||||
f.onFeatureReady();
|
||||
}
|
||||
|
||||
private void addImsFeature(int slotId, int featureType, ImsFeature f) {
|
||||
synchronized (mFeaturesBySlot) {
|
||||
// Get SparseArray for Features, by querying slot Id
|
||||
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
|
||||
if (features == null) {
|
||||
// Populate new SparseArray of features if it doesn't exist for this slot yet.
|
||||
features = new SparseArray<>();
|
||||
mFeaturesBySlot.put(slotId, features);
|
||||
}
|
||||
features.put(featureType, f);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeImsFeature(int slotId, int featureType,
|
||||
IImsFeatureStatusCallback c) {
|
||||
synchronized (mFeaturesBySlot) {
|
||||
// get ImsFeature associated with the slot/feature
|
||||
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
|
||||
if (features == null) {
|
||||
Log.w(LOG_TAG, "Can not remove ImsFeature. No ImsFeatures exist on slot "
|
||||
+ slotId);
|
||||
return;
|
||||
}
|
||||
ImsFeature f = features.get(featureType);
|
||||
if (f == null) {
|
||||
Log.w(LOG_TAG, "Can not remove ImsFeature. No feature with type "
|
||||
+ featureType + " exists on slot " + slotId);
|
||||
return;
|
||||
}
|
||||
f.removeImsFeatureStatusCallback(c);
|
||||
f.onFeatureRemoved();
|
||||
features.remove(featureType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable MMTelFeature onCreateEmergencyMMTelImsFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An implementation of MMTelFeature that will be used by the system for MMTel
|
||||
* functionality.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable MMTelFeature onCreateMMTelImsFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An implementation of RcsFeature that will be used by the system for RCS.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable RcsFeature onCreateRcsFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.compat.feature;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IInterface;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Base class for all IMS features that are supported by the framework.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class ImsFeature {
|
||||
|
||||
private static final String LOG_TAG = "ImsFeature";
|
||||
|
||||
/**
|
||||
* Action to broadcast when ImsService is up.
|
||||
* Internal use only.
|
||||
* Only defined here separately compatibility purposes with the old ImsService.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_UP =
|
||||
"com.android.ims.IMS_SERVICE_UP";
|
||||
|
||||
/**
|
||||
* Action to broadcast when ImsService is down.
|
||||
* Internal use only.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_DOWN =
|
||||
"com.android.ims.IMS_SERVICE_DOWN";
|
||||
|
||||
/**
|
||||
* Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
|
||||
* A long value; the phone ID corresponding to the IMS service coming up or down.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_PHONE_ID = "android:phone_id";
|
||||
|
||||
// Invalid feature value
|
||||
public static final int INVALID = -1;
|
||||
// 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 final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap(
|
||||
new WeakHashMap<IImsFeatureStatusCallback, Boolean>());
|
||||
private @ImsState int mState = STATE_NOT_AVAILABLE;
|
||||
private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
protected Context mContext;
|
||||
|
||||
public void setContext(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public void setSlotId(int slotId) {
|
||||
mSlotId = slotId;
|
||||
}
|
||||
|
||||
public int getFeatureState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
protected final void setFeatureState(@ImsState int state) {
|
||||
if (mState != state) {
|
||||
mState = state;
|
||||
notifyFeatureState(state);
|
||||
}
|
||||
}
|
||||
|
||||
public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// If we have just connected, send queued status.
|
||||
c.notifyImsFeatureStatus(mState);
|
||||
// Add the callback if the callback completes successfully without a RemoteException.
|
||||
synchronized (mStatusCallbacks) {
|
||||
mStatusCallbacks.add(c);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (mStatusCallbacks) {
|
||||
mStatusCallbacks.remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method called by ImsFeature when setFeatureState has changed.
|
||||
* @param state
|
||||
*/
|
||||
private void notifyFeatureState(@ImsState int state) {
|
||||
synchronized (mStatusCallbacks) {
|
||||
for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
|
||||
iter.hasNext(); ) {
|
||||
IImsFeatureStatusCallback callback = iter.next();
|
||||
try {
|
||||
Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
|
||||
callback.notifyImsFeatureStatus(state);
|
||||
} catch (RemoteException e) {
|
||||
// remove if the callback is no longer alive.
|
||||
iter.remove();
|
||||
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
sendImsServiceIntent(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide backwards compatibility using deprecated service UP/DOWN intents.
|
||||
*/
|
||||
private void sendImsServiceIntent(@ImsState int state) {
|
||||
if(mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
|
||||
return;
|
||||
}
|
||||
Intent intent;
|
||||
switch (state) {
|
||||
case ImsFeature.STATE_NOT_AVAILABLE:
|
||||
case ImsFeature.STATE_INITIALIZING:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_DOWN);
|
||||
break;
|
||||
case ImsFeature.STATE_READY:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_UP);
|
||||
break;
|
||||
default:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_DOWN);
|
||||
}
|
||||
intent.putExtra(EXTRA_PHONE_ID, mSlotId);
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the feature is ready to use.
|
||||
*/
|
||||
public abstract void onFeatureReady();
|
||||
|
||||
/**
|
||||
* Called when the feature is being removed and must be cleaned up.
|
||||
*/
|
||||
public abstract void onFeatureRemoved();
|
||||
|
||||
/**
|
||||
* @return Binder instance
|
||||
*/
|
||||
public abstract IInterface getBinder();
|
||||
}
|
||||
@@ -16,33 +16,342 @@
|
||||
|
||||
package android.telephony.ims.compat.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.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsMultiEndpoint;
|
||||
import com.android.ims.internal.IImsRegistrationListener;
|
||||
import com.android.ims.internal.IImsUt;
|
||||
import com.android.ims.internal.ImsCallSession;
|
||||
|
||||
/**
|
||||
* Compatability layer for older implementations of MMTelFeature.
|
||||
* Base implementation for MMTel.
|
||||
* Any class wishing to use MMTelFeature should extend this class and implement all methods that the
|
||||
* service supports.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public class MMTelFeature extends android.telephony.ims.feature.MMTelFeature {
|
||||
public class MMTelFeature extends ImsFeature {
|
||||
|
||||
// Lock for feature synchronization
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final IImsMMTelFeature mImsMMTelBinder = new IImsMMTelFeature.Stub() {
|
||||
|
||||
@Override
|
||||
public int startSession(PendingIntent incomingCallIntent,
|
||||
IImsRegistrationListener listener) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.startSession(incomingCallIntent, listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endSession(int sessionId) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.endSession(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected(int callSessionType, int callType)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.isConnected(callSessionType, callType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpened() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.isOpened();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFeatureStatus() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getFeatureState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegistrationListener(IImsRegistrationListener listener)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.addRegistrationListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegistrationListener(IImsRegistrationListener listener)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.removeRegistrationListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.createCallProfile(sessionId, callSessionType, callType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.createCallSession(sessionId, profile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsCallSession getPendingCallSession(int sessionId, String callId)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getPendingCallSession(sessionId, callId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsUt getUtInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getUtInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsConfig getConfigInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getConfigInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOnIms() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.turnOnIms();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOffIms() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.turnOffIms();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsEcbm getEcbmInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getEcbmInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUiTTYMode(int uiTtyMode, Message onComplete) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.setUiTTYMode(uiTtyMode, onComplete);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getMultiEndpointInterface();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public final IImsCallSession createCallSession(int sessionId, ImsCallProfile profile) {
|
||||
return createCallSession(sessionId, profile, null /*listener*/);
|
||||
public final IImsMMTelFeature getBinder() {
|
||||
return mImsMMTelBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* ImsManager#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.
|
||||
*/
|
||||
public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* End a previously started session using the associated sessionId.
|
||||
* @param sessionId an integer (greater than 0) representing the ongoing session. See
|
||||
* {@link #startSession}.
|
||||
*/
|
||||
public void endSession(int sessionId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the IMS service has successfully registered to the IMS network with the specified
|
||||
* service & call type.
|
||||
*
|
||||
* @param callSessionType 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
|
||||
*/
|
||||
public boolean isConnected(int callSessionType, int callType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified IMS service is opened.
|
||||
*
|
||||
* @return true if the specified service id is opened; false otherwise
|
||||
*/
|
||||
public boolean isOpened() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new registration listener for the client associated with the session Id.
|
||||
* @param listener An implementation of IImsRegistrationListener.
|
||||
*/
|
||||
public void addRegistrationListener(IImsRegistrationListener listener) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a previously registered listener using {@link #addRegistrationListener} for the client
|
||||
* associated with the session Id.
|
||||
* @param listener A previously registered IImsRegistrationListener
|
||||
*/
|
||||
public void removeRegistrationListener(IImsRegistrationListener listener) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
|
||||
*
|
||||
* @param sessionId a session id which is obtained from {@link #startSession}
|
||||
* @param callSessionType 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
|
||||
*/
|
||||
public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@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.
|
||||
*/
|
||||
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
|
||||
IImsCallSessionListener listener) {
|
||||
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public IImsCallSession getPendingCallSession(int sessionId, String callId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Ut interface for the supplementary service configuration.
|
||||
*/
|
||||
public IImsUt getUtInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The config interface for IMS Configuration
|
||||
*/
|
||||
public IImsConfig getConfigInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the MMTelFeature to turn on IMS when it has been turned off using {@link #turnOffIms}
|
||||
*/
|
||||
public void turnOnIms() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the MMTelFeature to turn off IMS when it has been turned on using {@link #turnOnIms}
|
||||
*/
|
||||
public void turnOffIms() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Emergency call-back mode interface for emergency VoLTE calls that support it.
|
||||
*/
|
||||
public IImsEcbm getEcbmInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current UI TTY mode for the MMTelFeature.
|
||||
* @param uiTtyMode An integer containing the new UI TTY Mode.
|
||||
* @param onComplete A {@link Message} to be used when the mode has been set.
|
||||
*/
|
||||
public void setUiTTYMode(int uiTtyMode, Message onComplete) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MultiEndpoint interface for DEP notifications
|
||||
*/
|
||||
public IImsMultiEndpoint getMultiEndpointInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFeatureReady() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void onFeatureRemoved() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -14,9 +14,10 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.feature;
|
||||
package android.telephony.ims.compat.feature;
|
||||
|
||||
import android.telephony.ims.internal.aidl.IImsRcsFeature;
|
||||
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
|
||||
/**
|
||||
* Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
|
||||
@@ -36,9 +37,8 @@ public class RcsFeature extends ImsFeature {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
CapabilityCallbackProxy c) {
|
||||
// Do nothing for base implementation.
|
||||
public void onFeatureReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,12 +46,6 @@ public class RcsFeature extends ImsFeature {
|
||||
|
||||
}
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
@Override
|
||||
public void onFeatureReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IImsRcsFeature getBinder() {
|
||||
return mImsRcsBinder;
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.compat.stub;
|
||||
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.android.ims.ImsConfig;
|
||||
import com.android.ims.ImsConfigListener;
|
||||
import com.android.ims.internal.IImsConfig;
|
||||
|
||||
/**
|
||||
* Base implementation of ImsConfig, which implements stub versions of the methods
|
||||
* in the IImsConfig AIDL. Override the methods that your implementation of ImsConfig supports.
|
||||
*
|
||||
* DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
|
||||
* will break other implementations of ImsConfig maintained by other ImsServices.
|
||||
*
|
||||
* Provides APIs to get/set the IMS service feature/capability/parameters.
|
||||
* The config items include:
|
||||
* 1) Items provisioned by the operator.
|
||||
* 2) Items configured by user. Mainly service feature class.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public class ImsConfigImplBase extends IImsConfig.Stub {
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage. Synchronous blocking call.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in Integer format.
|
||||
*/
|
||||
@Override
|
||||
public int getProvisionedValue(int item) throws RemoteException {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage. Synchronous blocking call.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in String format.
|
||||
*/
|
||||
@Override
|
||||
public String getProvisionedStringValue(int item) throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived. Synchronous blocking call.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in Integer format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
@Override
|
||||
public int setProvisionedValue(int item, int value) throws RemoteException {
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived. Synchronous blocking call.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in String format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
@Override
|
||||
public int setProvisionedStringValue(int item, String value) throws RemoteException {
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the specified IMS feature item for specified network type.
|
||||
* This operation gets the feature config value from the master storage (i.e. final
|
||||
* value). Asynchronous non-blocking call.
|
||||
*
|
||||
* @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
|
||||
* @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
|
||||
* @param listener feature value returned asynchronously through listener.
|
||||
*/
|
||||
@Override
|
||||
public void getFeatureValue(int feature, int network, ImsConfigListener listener)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS feature item for specified network type.
|
||||
* This operation stores the user setting in setting db from which master db
|
||||
* is derived.
|
||||
*
|
||||
* @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
|
||||
* @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
|
||||
* @param value as defined in com.android.ims.ImsConfig#FeatureValueConstants.
|
||||
* @param listener, provided if caller needs to be notified for set result.
|
||||
*/
|
||||
@Override
|
||||
public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for IMS VoLTE provisioned.
|
||||
* This should be the same as the operator provisioned value if applies.
|
||||
*/
|
||||
@Override
|
||||
public boolean getVolteProvisioned() throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for IMS feature item video quality.
|
||||
*
|
||||
* @param listener Video quality value returned asynchronously through listener.
|
||||
*/
|
||||
@Override
|
||||
public void getVideoQuality(ImsConfigListener listener) throws RemoteException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS feature item video quality.
|
||||
*
|
||||
* @param quality, defines the value of video quality.
|
||||
* @param listener, provided if caller needs to be notified for set result.
|
||||
*/
|
||||
@Override
|
||||
public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException {
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,6 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.feature;
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
parcelable CapabilityChangeRequest;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.feature;
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@@ -182,7 +182,8 @@ public class CapabilityChangeRequest implements Parcelable {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CapabilityChangeRequest)) return false;
|
||||
|
||||
CapabilityChangeRequest that = (CapabilityChangeRequest) o;
|
||||
CapabilityChangeRequest
|
||||
that = (CapabilityChangeRequest) o;
|
||||
|
||||
if (!mCapabilitiesToEnable.equals(that.mCapabilitiesToEnable)) return false;
|
||||
return mCapabilitiesToDisable.equals(that.mCapabilitiesToDisable);
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -17,26 +17,29 @@
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IInterface;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Base class for all IMS features that are supported by the framework.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class ImsFeature {
|
||||
@@ -46,7 +49,8 @@ public abstract class ImsFeature {
|
||||
/**
|
||||
* Action to broadcast when ImsService is up.
|
||||
* Internal use only.
|
||||
* Only defined here separately compatibility purposes with the old ImsService.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_UP =
|
||||
@@ -56,6 +60,7 @@ public abstract class ImsFeature {
|
||||
* Action to broadcast when ImsService is down.
|
||||
* Internal use only.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_DOWN =
|
||||
@@ -65,67 +70,259 @@ public abstract class ImsFeature {
|
||||
* Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
|
||||
* A long value; the phone ID corresponding to the IMS service coming up or down.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_PHONE_ID = "android:phone_id";
|
||||
|
||||
// Invalid feature value
|
||||
public static final int INVALID = -1;
|
||||
public static final int FEATURE_INVALID = -1;
|
||||
// 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;
|
||||
public static final int FEATURE_EMERGENCY_MMTEL = 0;
|
||||
public static final int FEATURE_MMTEL = 1;
|
||||
public static final int FEATURE_RCS = 2;
|
||||
// Total number of features defined
|
||||
public static final int MAX = 3;
|
||||
public static final int FEATURE_MAX = 3;
|
||||
|
||||
// Integer values defining IMS features that are supported in ImsFeature.
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
FEATURE_EMERGENCY_MMTEL,
|
||||
FEATURE_MMTEL,
|
||||
FEATURE_RCS
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface FeatureType {}
|
||||
|
||||
// Integer values defining the state of the ImsFeature at any time.
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
STATE_NOT_AVAILABLE,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_INITIALIZING,
|
||||
STATE_READY,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ImsState {}
|
||||
public static final int STATE_NOT_AVAILABLE = 0;
|
||||
|
||||
public static final int STATE_UNAVAILABLE = 0;
|
||||
public static final int STATE_INITIALIZING = 1;
|
||||
public static final int STATE_READY = 2;
|
||||
|
||||
private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap(
|
||||
new WeakHashMap<IImsFeatureStatusCallback, Boolean>());
|
||||
private @ImsState int mState = STATE_NOT_AVAILABLE;
|
||||
private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
protected Context mContext;
|
||||
// Integer values defining the result codes that should be returned from
|
||||
// {@link changeEnabledCapabilities} when the framework tries to set a feature's capability.
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
CAPABILITY_ERROR_GENERIC,
|
||||
CAPABILITY_SUCCESS
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ImsCapabilityError {}
|
||||
|
||||
public void setContext(Context context) {
|
||||
mContext = context;
|
||||
public static final int CAPABILITY_ERROR_GENERIC = -1;
|
||||
public static final int CAPABILITY_SUCCESS = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The framework implements this callback in order to register for Feature Capability status
|
||||
* updates, via {@link #onCapabilitiesStatusChanged(Capabilities)}, query Capability
|
||||
* configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error
|
||||
* callbacks when the ImsService can not change the capability as requested, via
|
||||
* {@link #onChangeCapabilityConfigurationError}.
|
||||
*/
|
||||
public static class CapabilityCallback extends IImsCapabilityCallback.Stub {
|
||||
|
||||
@Override
|
||||
public final void onCapabilitiesStatusChanged(int config) throws RemoteException {
|
||||
onCapabilitiesStatusChanged(new Capabilities(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of a query for the capability configuration of a requested capability.
|
||||
*
|
||||
* @param capability The capability that was requested.
|
||||
* @param radioTech The IMS radio technology associated with the capability.
|
||||
* @param isEnabled true if the capability is enabled, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public void onQueryCapabilityConfiguration(int capability, int radioTech,
|
||||
boolean isEnabled) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a change to the capability configuration has returned an error.
|
||||
*
|
||||
* @param capability The capability that was requested to be changed.
|
||||
* @param radioTech The IMS radio technology associated with the capability.
|
||||
* @param reason error associated with the failure to change configuration.
|
||||
*/
|
||||
@Override
|
||||
public void onChangeCapabilityConfigurationError(int capability, int radioTech,
|
||||
int reason) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The status of the feature's capabilities has changed to either available or unavailable.
|
||||
* If unavailable, the feature is not able to support the unavailable capability at this
|
||||
* time.
|
||||
*
|
||||
* @param config The new availability of the capabilities.
|
||||
*/
|
||||
public void onCapabilitiesStatusChanged(Capabilities config) {
|
||||
}
|
||||
}
|
||||
|
||||
public void setSlotId(int slotId) {
|
||||
/**
|
||||
* Used by the ImsFeature to call back to the CapabilityCallback that the framework has
|
||||
* provided.
|
||||
*/
|
||||
protected static class CapabilityCallbackProxy {
|
||||
private final IImsCapabilityCallback mCallback;
|
||||
|
||||
public CapabilityCallbackProxy(IImsCapabilityCallback c) {
|
||||
mCallback = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method notifies the provided framework callback that the request to change the
|
||||
* indicated capability has failed and has not changed.
|
||||
*
|
||||
* @param capability The Capability that will be notified to the framework.
|
||||
* @param radioTech The radio tech that this capability failed for.
|
||||
* @param reason The reason this capability was unable to be changed.
|
||||
*/
|
||||
public void onChangeCapabilityConfigurationError(int capability, int radioTech,
|
||||
@ImsCapabilityError int reason) {
|
||||
if (mCallback == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCallback.onChangeCapabilityConfigurationError(capability, radioTech, reason);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOG_TAG, "onChangeCapabilityConfigurationError called on dead binder.");
|
||||
}
|
||||
}
|
||||
|
||||
public void onQueryCapabilityConfiguration(int capability, int radioTech,
|
||||
boolean isEnabled) {
|
||||
if (mCallback == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mCallback.onQueryCapabilityConfiguration(capability, radioTech, isEnabled);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOG_TAG, "onQueryCapabilityConfiguration called on dead binder.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask.
|
||||
*/
|
||||
public static class Capabilities {
|
||||
protected int mCapabilities = 0;
|
||||
|
||||
public Capabilities() {
|
||||
}
|
||||
|
||||
protected Capabilities(int capabilities) {
|
||||
mCapabilities = capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param capabilities Capabilities to be added to the configuration in the form of a
|
||||
* bit mask.
|
||||
*/
|
||||
public void addCapabilities(int capabilities) {
|
||||
mCapabilities |= capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param capabilities Capabilities to be removed to the configuration in the form of a
|
||||
* bit mask.
|
||||
*/
|
||||
public void removeCapabilities(int capabilities) {
|
||||
mCapabilities &= ~capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all of the capabilities specified are capable.
|
||||
*/
|
||||
public boolean isCapable(int capabilities) {
|
||||
return (mCapabilities & capabilities) == capabilities;
|
||||
}
|
||||
|
||||
public Capabilities copy() {
|
||||
return new Capabilities(mCapabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a bitmask containing the capability flags directly.
|
||||
*/
|
||||
public int getMask() {
|
||||
return mCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Capabilities)) return false;
|
||||
|
||||
Capabilities that = (Capabilities) o;
|
||||
|
||||
return mCapabilities == that.mCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Capabilities: " + Integer.toBinaryString(mCapabilities);
|
||||
}
|
||||
}
|
||||
|
||||
private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap(
|
||||
new WeakHashMap<IImsFeatureStatusCallback, Boolean>());
|
||||
private @ImsState int mState = STATE_UNAVAILABLE;
|
||||
private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
protected Context mContext;
|
||||
private final Object mLock = new Object();
|
||||
private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks
|
||||
= new RemoteCallbackList<>();
|
||||
private Capabilities mCapabilityStatus = new Capabilities();
|
||||
|
||||
public final void initialize(Context context, int slotId) {
|
||||
mContext = context;
|
||||
mSlotId = slotId;
|
||||
}
|
||||
|
||||
public int getFeatureState() {
|
||||
return mState;
|
||||
public final int getFeatureState() {
|
||||
synchronized (mLock) {
|
||||
return mState;
|
||||
}
|
||||
}
|
||||
|
||||
protected final void setFeatureState(@ImsState int state) {
|
||||
if (mState != state) {
|
||||
mState = state;
|
||||
notifyFeatureState(state);
|
||||
synchronized (mLock) {
|
||||
if (mState != state) {
|
||||
mState = state;
|
||||
notifyFeatureState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
// Not final for testing, but shouldn't be extended!
|
||||
@VisibleForTesting
|
||||
public void addImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
|
||||
try {
|
||||
// If we have just connected, send queued status.
|
||||
c.notifyImsFeatureStatus(mState);
|
||||
c.notifyImsFeatureStatus(getFeatureState());
|
||||
// Add the callback if the callback completes successfully without a RemoteException.
|
||||
synchronized (mStatusCallbacks) {
|
||||
synchronized (mLock) {
|
||||
mStatusCallbacks.add(c);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
@@ -133,23 +330,21 @@ public abstract class ImsFeature {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeImsFeatureStatusCallback(IImsFeatureStatusCallback c) {
|
||||
if (c == null) {
|
||||
return;
|
||||
}
|
||||
synchronized (mStatusCallbacks) {
|
||||
@VisibleForTesting
|
||||
// Not final for testing, but should not be extended!
|
||||
public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
|
||||
synchronized (mLock) {
|
||||
mStatusCallbacks.remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method called by ImsFeature when setFeatureState has changed.
|
||||
* @param state
|
||||
*/
|
||||
private void notifyFeatureState(@ImsState int state) {
|
||||
synchronized (mStatusCallbacks) {
|
||||
synchronized (mLock) {
|
||||
for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
|
||||
iter.hasNext(); ) {
|
||||
iter.hasNext(); ) {
|
||||
IImsFeatureStatusCallback callback = iter.next();
|
||||
try {
|
||||
Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
|
||||
@@ -168,12 +363,12 @@ public abstract class ImsFeature {
|
||||
* Provide backwards compatibility using deprecated service UP/DOWN intents.
|
||||
*/
|
||||
private void sendImsServiceIntent(@ImsState int state) {
|
||||
if(mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
|
||||
if (mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
|
||||
return;
|
||||
}
|
||||
Intent intent;
|
||||
switch (state) {
|
||||
case ImsFeature.STATE_NOT_AVAILABLE:
|
||||
case ImsFeature.STATE_UNAVAILABLE:
|
||||
case ImsFeature.STATE_INITIALIZING:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_DOWN);
|
||||
break;
|
||||
@@ -187,18 +382,92 @@ public abstract class ImsFeature {
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the feature is ready to use.
|
||||
*/
|
||||
public abstract void onFeatureReady();
|
||||
public final void addCapabilityCallback(IImsCapabilityCallback c) {
|
||||
mCapabilityCallbacks.register(c);
|
||||
}
|
||||
|
||||
public final void removeCapabilityCallback(IImsCapabilityCallback c) {
|
||||
mCapabilityCallbacks.unregister(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the feature is being removed and must be cleaned up.
|
||||
* @return the cached capabilities status for this feature.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Capabilities queryCapabilityStatus() {
|
||||
synchronized (mLock) {
|
||||
return mCapabilityStatus.copy();
|
||||
}
|
||||
}
|
||||
|
||||
// Called internally to request the change of enabled capabilities.
|
||||
@VisibleForTesting
|
||||
public final void requestChangeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
IImsCapabilityCallback c) throws RemoteException {
|
||||
if (request == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"ImsFeature#requestChangeEnabledCapabilities called with invalid params.");
|
||||
}
|
||||
changeEnabledCapabilities(request, new CapabilityCallbackProxy(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the ImsFeature when the capabilities status has changed.
|
||||
*
|
||||
* @param c A {@link Capabilities} containing the new Capabilities status.
|
||||
*/
|
||||
protected final void notifyCapabilitiesStatusChanged(Capabilities c) {
|
||||
synchronized (mLock) {
|
||||
mCapabilityStatus = c.copy();
|
||||
}
|
||||
int count = mCapabilityCallbacks.beginBroadcast();
|
||||
try {
|
||||
for (int i = 0; i < count; i++) {
|
||||
try {
|
||||
mCapabilityCallbacks.getBroadcastItem(i).onCapabilitiesStatusChanged(
|
||||
c.mCapabilities);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, e + " " + "notifyCapabilitiesStatusChanged() - Skipping " +
|
||||
"callback.");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mCapabilityCallbacks.finishBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Features should override this method to receive Capability preference change requests from
|
||||
* the framework using the provided {@link CapabilityChangeRequest}. If any of the capabilities
|
||||
* in the {@link CapabilityChangeRequest} are not able to be completed due to an error,
|
||||
* {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError} should be called for
|
||||
* each failed capability.
|
||||
*
|
||||
* @param request A {@link CapabilityChangeRequest} containing requested capabilities to
|
||||
* enable/disable.
|
||||
* @param c A {@link CapabilityCallbackProxy}, which will be used to call back to the framework
|
||||
* setting a subset of these capabilities fail, using
|
||||
* {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError}.
|
||||
*/
|
||||
public abstract void changeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
CapabilityCallbackProxy c);
|
||||
|
||||
/**
|
||||
* Called when the framework is removing this feature and it needs to be cleaned up.
|
||||
*/
|
||||
public abstract void onFeatureRemoved();
|
||||
|
||||
/**
|
||||
* @return Binder instance
|
||||
* Called when the feature has been initialized and communication with the framework is set up.
|
||||
* Any attempt by this feature to access the framework before this method is called will return
|
||||
* with an {@link IllegalStateException}.
|
||||
* The IMS provider should use this method to trigger registration for this feature on the IMS
|
||||
* network, if needed.
|
||||
*/
|
||||
public abstract IInterface getBinder();
|
||||
public abstract void onFeatureReady();
|
||||
|
||||
/**
|
||||
* @return Binder instance that the framework will use to communicate with this feature.
|
||||
*/
|
||||
protected abstract IInterface getBinder();
|
||||
}
|
||||
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* 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 android.telephony.ims.internal.stub.SmsImplBase;
|
||||
|
||||
import com.android.ims.ImsCallProfile;
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import com.android.ims.internal.IImsConfig;
|
||||
import com.android.ims.internal.IImsEcbm;
|
||||
import com.android.ims.internal.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsMultiEndpoint;
|
||||
import com.android.ims.internal.IImsRegistrationListener;
|
||||
import com.android.ims.internal.IImsSmsListener;
|
||||
import com.android.ims.internal.IImsUt;
|
||||
import com.android.ims.internal.ImsCallSession;
|
||||
|
||||
/**
|
||||
* Base implementation for MMTel.
|
||||
* Any class wishing to use MMTelFeature should extend this class and implement all methods that the
|
||||
* service supports.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public class MMTelFeature extends ImsFeature {
|
||||
|
||||
// Lock for feature synchronization
|
||||
private final Object mLock = new Object();
|
||||
|
||||
private final IImsMMTelFeature mImsMMTelBinder = new IImsMMTelFeature.Stub() {
|
||||
|
||||
@Override
|
||||
public int startSession(PendingIntent incomingCallIntent,
|
||||
IImsRegistrationListener listener) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.startSession(incomingCallIntent, listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endSession(int sessionId) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.endSession(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected(int callSessionType, int callType)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.isConnected(callSessionType, callType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpened() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.isOpened();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFeatureStatus() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getFeatureState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegistrationListener(IImsRegistrationListener listener)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.addRegistrationListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegistrationListener(IImsRegistrationListener listener)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.removeRegistrationListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.createCallProfile(sessionId, callSessionType, callType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.createCallSession(sessionId, profile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsCallSession getPendingCallSession(int sessionId, String callId)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getPendingCallSession(sessionId, callId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsUt getUtInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getUtInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsConfig getConfigInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getConfigInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOnIms() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.turnOnIms();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void turnOffIms() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.turnOffIms();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsEcbm getEcbmInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getEcbmInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUiTTYMode(int uiTtyMode, Message onComplete) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.setUiTTYMode(uiTtyMode, onComplete);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getMultiEndpointInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSmsListener(IImsSmsListener l) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.setSmsListener(l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSms(int token, int messageRef, String format, String smsc, boolean retry,
|
||||
byte[] pdu) {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.sendSms(token, messageRef, format, smsc, retry, pdu);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledgeSms(int token, int messageRef, int result) {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.acknowledgeSms(token, messageRef, result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledgeSmsReport(int token, int messageRef, int result) {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.acknowledgeSmsReport(token, messageRef, result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSmsFormat() {
|
||||
synchronized (mLock) {
|
||||
return MMTelFeature.this.getSmsFormat();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmsReady() {
|
||||
synchronized (mLock) {
|
||||
MMTelFeature.this.onSmsReady();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public final IImsMMTelFeature getBinder() {
|
||||
return mImsMMTelBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* ImsManager#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.
|
||||
*/
|
||||
public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* End a previously started session using the associated sessionId.
|
||||
* @param sessionId an integer (greater than 0) representing the ongoing session. See
|
||||
* {@link #startSession}.
|
||||
*/
|
||||
public void endSession(int sessionId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the IMS service has successfully registered to the IMS network with the specified
|
||||
* service & call type.
|
||||
*
|
||||
* @param callSessionType 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
|
||||
*/
|
||||
public boolean isConnected(int callSessionType, int callType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified IMS service is opened.
|
||||
*
|
||||
* @return true if the specified service id is opened; false otherwise
|
||||
*/
|
||||
public boolean isOpened() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new registration listener for the client associated with the session Id.
|
||||
* @param listener An implementation of IImsRegistrationListener.
|
||||
*/
|
||||
public void addRegistrationListener(IImsRegistrationListener listener) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a previously registered listener using {@link #addRegistrationListener} for the client
|
||||
* associated with the session Id.
|
||||
* @param listener A previously registered IImsRegistrationListener
|
||||
*/
|
||||
public void removeRegistrationListener(IImsRegistrationListener listener) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
|
||||
*
|
||||
* @param sessionId a session id which is obtained from {@link #startSession}
|
||||
* @param callSessionType 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
|
||||
*/
|
||||
public ImsCallProfile createCallProfile(int sessionId, int callSessionType, int callType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@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
|
||||
*/
|
||||
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public IImsCallSession getPendingCallSession(int sessionId, String callId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Ut interface for the supplementary service configuration.
|
||||
*/
|
||||
public IImsUt getUtInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The config interface for IMS Configuration
|
||||
*/
|
||||
public IImsConfig getConfigInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the MMTelFeature to turn on IMS when it has been turned off using {@link #turnOffIms}
|
||||
*/
|
||||
public void turnOnIms() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal the MMTelFeature to turn off IMS when it has been turned on using {@link #turnOnIms}
|
||||
*/
|
||||
public void turnOffIms() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Emergency call-back mode interface for emergency VoLTE calls that support it.
|
||||
*/
|
||||
public IImsEcbm getEcbmInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current UI TTY mode for the MMTelFeature.
|
||||
* @param uiTtyMode An integer containing the new UI TTY Mode.
|
||||
* @param onComplete A {@link Message} to be used when the mode has been set.
|
||||
*/
|
||||
public void setUiTTYMode(int uiTtyMode, Message onComplete) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MultiEndpoint interface for DEP notifications
|
||||
*/
|
||||
public IImsMultiEndpoint getMultiEndpointInterface() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setSmsListener(IImsSmsListener listener) {
|
||||
getSmsImplementation().registerSmsListener(listener);
|
||||
}
|
||||
|
||||
private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
|
||||
byte[] pdu) {
|
||||
getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu);
|
||||
}
|
||||
|
||||
private void acknowledgeSms(int token, int messageRef,
|
||||
@SmsImplBase.DeliverStatusResult int result) {
|
||||
getSmsImplementation().acknowledgeSms(token, messageRef, result);
|
||||
}
|
||||
|
||||
private void acknowledgeSmsReport(int token, int messageRef,
|
||||
@SmsImplBase.StatusReportResult int result) {
|
||||
getSmsImplementation().acknowledgeSmsReport(token, messageRef, result);
|
||||
}
|
||||
|
||||
private void onSmsReady() {
|
||||
getSmsImplementation().onReady();
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default
|
||||
* non-functional implementation is returned.
|
||||
*
|
||||
* @return an instance of {@link SmsImplBase} which should be implemented by the IMS Provider.
|
||||
*/
|
||||
protected SmsImplBase getSmsImplementation() {
|
||||
return new SmsImplBase();
|
||||
}
|
||||
|
||||
public String getSmsFormat() {
|
||||
return getSmsImplementation().getSmsFormat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFeatureReady() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void onFeatureRemoved() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -14,17 +14,20 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.feature;
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.ims.internal.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.internal.aidl.IImsMmTelFeature;
|
||||
import android.telephony.ims.internal.aidl.IImsMmTelListener;
|
||||
import android.telephony.ims.internal.stub.SmsImplBase;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.aidl.IImsMmTelFeature;
|
||||
import android.telephony.ims.aidl.IImsMmTelListener;
|
||||
import android.telephony.ims.aidl.IImsSmsListener;
|
||||
import android.telephony.ims.stub.ImsRegistrationImplBase;
|
||||
import android.telephony.ims.stub.ImsSmsImplBase;
|
||||
import android.telephony.ims.stub.ImsEcbmImplBase;
|
||||
import android.telephony.ims.stub.ImsMultiEndpointImplBase;
|
||||
import android.telephony.ims.stub.ImsUtImplBase;
|
||||
@@ -34,7 +37,6 @@ import com.android.ims.ImsCallProfile;
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import com.android.ims.internal.IImsEcbm;
|
||||
import com.android.ims.internal.IImsMultiEndpoint;
|
||||
import com.android.ims.internal.IImsSmsListener;
|
||||
import com.android.ims.internal.IImsUt;
|
||||
import com.android.ims.internal.ImsCallSession;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -87,6 +89,13 @@ public class MmTelFeature extends ImsFeature {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int shouldProcessCall(String[] numbers) {
|
||||
synchronized (mLock) {
|
||||
return MmTelFeature.this.shouldProcessCall(numbers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsUt getUtInterface() throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
@@ -199,6 +208,10 @@ public class MmTelFeature extends ImsFeature {
|
||||
mCapabilities = c.mCapabilities;
|
||||
}
|
||||
|
||||
public MmTelCapabilities(int capabilities) {
|
||||
mCapabilities = capabilities;
|
||||
}
|
||||
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
CAPABILITY_TYPE_VOICE,
|
||||
@@ -243,6 +256,21 @@ public class MmTelFeature extends ImsFeature {
|
||||
public final boolean isCapable(@MmTelCapability int capabilities) {
|
||||
return super.isCapable(capabilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder("MmTel Capabilities - [");
|
||||
builder.append("Voice: ");
|
||||
builder.append(isCapable(CAPABILITY_TYPE_VOICE));
|
||||
builder.append(" Video: ");
|
||||
builder.append(isCapable(CAPABILITY_TYPE_VIDEO));
|
||||
builder.append(" UT: ");
|
||||
builder.append(isCapable(CAPABILITY_TYPE_UT));
|
||||
builder.append(" SMS: ");
|
||||
builder.append(isCapable(CAPABILITY_TYPE_SMS));
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,9 +278,13 @@ public class MmTelFeature extends ImsFeature {
|
||||
*/
|
||||
public static class Listener extends IImsMmTelListener.Stub {
|
||||
|
||||
/**
|
||||
* Called when the IMS provider receives an incoming call.
|
||||
* @param c The {@link ImsCallSession} associated with the new call.
|
||||
*/
|
||||
@Override
|
||||
public final void onIncomingCall(IImsCallSession c) {
|
||||
onIncomingCall(new ImsCallSession(c));
|
||||
public void onIncomingCall(IImsCallSession c, Bundle extras) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,15 +295,34 @@ public class MmTelFeature extends ImsFeature {
|
||||
public void onVoiceMessageCountUpdate(int count) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS provider receives an incoming call.
|
||||
* @param c The {@link ImsCallSession} associated with the new call.
|
||||
*/
|
||||
public void onIncomingCall(ImsCallSession c) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To be returned by {@link #shouldProcessCall(Uri[])} when the ImsService should process the
|
||||
* outgoing call as IMS.
|
||||
*/
|
||||
public static final int PROCESS_CALL_IMS = 0;
|
||||
/**
|
||||
* To be returned by {@link #shouldProcessCall(Uri[])} when the telephony framework should not
|
||||
* process the outgoing NON_EMERGENCY call as IMS and should instead use circuit switch.
|
||||
*/
|
||||
public static final int PROCESS_CALL_CSFB = 1;
|
||||
/**
|
||||
* To be returned by {@link #shouldProcessCall(Uri[])} when the telephony framework should not
|
||||
* process the outgoing EMERGENCY call as IMS and should instead use circuit switch.
|
||||
*/
|
||||
public static final int PROCESS_CALL_EMERGENCY_CSFB = 2;
|
||||
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
PROCESS_CALL_IMS,
|
||||
PROCESS_CALL_CSFB,
|
||||
PROCESS_CALL_EMERGENCY_CSFB
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ProcessCallResult {}
|
||||
|
||||
|
||||
// Lock for feature synchronization
|
||||
private final Object mLock = new Object();
|
||||
private IImsMmTelListener mListener;
|
||||
@@ -284,6 +335,9 @@ public class MmTelFeature extends ImsFeature {
|
||||
synchronized (mLock) {
|
||||
mListener = listener;
|
||||
}
|
||||
if (mListener != null) {
|
||||
onFeatureReady();
|
||||
}
|
||||
}
|
||||
|
||||
private void queryCapabilityConfigurationInternal(int capability, int radioTech,
|
||||
@@ -332,12 +386,13 @@ public class MmTelFeature extends ImsFeature {
|
||||
* @throws RemoteException if the connection to the framework is not available. If this happens,
|
||||
* the call should be no longer considered active and should be cleaned up.
|
||||
* */
|
||||
protected final void notifyIncomingCall(ImsCallSession c) throws RemoteException {
|
||||
protected final void notifyIncomingCall(ImsCallSession c, Bundle extras)
|
||||
throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
if (mListener == null) {
|
||||
throw new IllegalStateException("Session is not available.");
|
||||
}
|
||||
mListener.onIncomingCall(c.getSession());
|
||||
mListener.onIncomingCall(c.getSession(), extras);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +463,19 @@ public class MmTelFeature extends ImsFeature {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the framework to determine if the outgoing call, designated by the outgoing
|
||||
* {@link Uri}s, should be processed as an IMS call or CSFB call.
|
||||
* @param numbers An array of {@link String}s that will be used for placing the call. There can
|
||||
* be multiple {@link Strings}s listed in the case when we want to place an outgoing
|
||||
* call as a conference.
|
||||
* @return a {@link ProcessCallResult} to the framework, which will be used to determine if the
|
||||
* call wil lbe placed over IMS or via CSFB.
|
||||
*/
|
||||
public @ProcessCallResult int shouldProcessCall(String[] numbers) {
|
||||
return PROCESS_CALL_IMS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Ut interface for the supplementary service configuration.
|
||||
*/
|
||||
@@ -445,22 +513,22 @@ public class MmTelFeature extends ImsFeature {
|
||||
// Base Implementation - Should be overridden
|
||||
}
|
||||
|
||||
public void setSmsListener(IImsSmsListener listener) {
|
||||
private void setSmsListener(IImsSmsListener listener) {
|
||||
getSmsImplementation().registerSmsListener(listener);
|
||||
}
|
||||
|
||||
public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
|
||||
private void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
|
||||
byte[] pdu) {
|
||||
getSmsImplementation().sendSms(token, messageRef, format, smsc, isRetry, pdu);
|
||||
}
|
||||
|
||||
public void acknowledgeSms(int token, int messageRef,
|
||||
@SmsImplBase.DeliverStatusResult int result) {
|
||||
private void acknowledgeSms(int token, int messageRef,
|
||||
@ImsSmsImplBase.DeliverStatusResult int result) {
|
||||
getSmsImplementation().acknowledgeSms(token, messageRef, result);
|
||||
}
|
||||
|
||||
public void acknowledgeSmsReport(int token, int messageRef,
|
||||
@SmsImplBase.StatusReportResult int result) {
|
||||
private void acknowledgeSmsReport(int token, int messageRef,
|
||||
@ImsSmsImplBase.StatusReportResult int result) {
|
||||
getSmsImplementation().acknowledgeSmsReport(token, messageRef, result);
|
||||
}
|
||||
|
||||
@@ -468,11 +536,11 @@ public class MmTelFeature extends ImsFeature {
|
||||
* Must be overridden by IMS Provider to be able to support SMS over IMS. Otherwise a default
|
||||
* non-functional implementation is returned.
|
||||
*
|
||||
* @return an instance of {@link SmsImplBase} which should be implemented by the IMS
|
||||
* @return an instance of {@link ImsSmsImplBase} which should be implemented by the IMS
|
||||
* Provider.
|
||||
*/
|
||||
public SmsImplBase getSmsImplementation() {
|
||||
return new SmsImplBase();
|
||||
protected ImsSmsImplBase getSmsImplementation() {
|
||||
return new ImsSmsImplBase();
|
||||
}
|
||||
|
||||
private String getSmsFormat() {
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
import android.telephony.ims.aidl.IImsRcsFeature;
|
||||
|
||||
/**
|
||||
* Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
|
||||
@@ -36,8 +36,9 @@ public class RcsFeature extends ImsFeature {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFeatureReady() {
|
||||
|
||||
public void changeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
CapabilityCallbackProxy c) {
|
||||
// Do nothing for base implementation.
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,6 +46,12 @@ public class RcsFeature extends ImsFeature {
|
||||
|
||||
}
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
@Override
|
||||
public void onFeatureReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IImsRcsFeature getBinder() {
|
||||
return mImsRcsBinder;
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
/*
|
||||
* 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.internal;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.ims.internal.aidl.IImsConfig;
|
||||
import android.telephony.ims.internal.aidl.IImsMmTelFeature;
|
||||
import android.telephony.ims.internal.aidl.IImsRcsFeature;
|
||||
import android.telephony.ims.internal.aidl.IImsServiceController;
|
||||
import android.telephony.ims.internal.aidl.IImsServiceControllerListener;
|
||||
import android.telephony.ims.internal.feature.ImsFeature;
|
||||
import android.telephony.ims.internal.feature.MmTelFeature;
|
||||
import android.telephony.ims.internal.feature.RcsFeature;
|
||||
import android.telephony.ims.internal.stub.ImsConfigImplBase;
|
||||
import android.telephony.ims.internal.stub.ImsFeatureConfiguration;
|
||||
import android.telephony.ims.stub.ImsRegistrationImplBase;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
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:
|
||||
*
|
||||
* ...
|
||||
* <service android:name=".EgImsService"
|
||||
* android:permission="android.permission.BIND_IMS_SERVICE" >
|
||||
* <!-- Apps must declare which features they support as metadata. The different categories are
|
||||
* defined below. In this example, the RCS_FEATURE feature is supported. -->
|
||||
* <meta-data android:name="android.telephony.ims.RCS_FEATURE" android:value="true" />
|
||||
* <intent-filter>
|
||||
* <action android:name="android.telephony.ims.ImsService" />
|
||||
* </intent-filter>
|
||||
* </service>
|
||||
* ...
|
||||
*
|
||||
* 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 RcsFeature class.
|
||||
* - MMTEL_FEATURE: This ImsService implements the MmTelFeature class.
|
||||
* @hide
|
||||
*/
|
||||
public class ImsService extends Service {
|
||||
|
||||
private static final String LOG_TAG = "ImsService";
|
||||
|
||||
/**
|
||||
* The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService.
|
||||
* @hide
|
||||
*/
|
||||
public static final String SERVICE_INTERFACE = "android.telephony.ims.ImsService";
|
||||
|
||||
// A map of slot Id -> map of features (indexed by ImsFeature feature id) corresponding to that
|
||||
// slot.
|
||||
// We keep track of this to facilitate cleanup of the IImsFeatureStatusCallback and
|
||||
// call ImsFeature#onFeatureRemoved.
|
||||
private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>();
|
||||
|
||||
private IImsServiceControllerListener mListener;
|
||||
|
||||
|
||||
/**
|
||||
* Listener that notifies the framework of ImsService changes.
|
||||
*/
|
||||
public static class Listener extends IImsServiceControllerListener.Stub {
|
||||
/**
|
||||
* The IMS features that this ImsService supports has changed.
|
||||
* @param c a new {@link ImsFeatureConfiguration} containing {@link ImsFeature.FeatureType}s
|
||||
* that this ImsService supports. This may trigger the addition/removal of feature
|
||||
* in this service.
|
||||
*/
|
||||
public void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected final IBinder mImsServiceController = new IImsServiceController.Stub() {
|
||||
@Override
|
||||
public void setListener(IImsServiceControllerListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsMmTelFeature createMmTelFeature(int slotId, IImsFeatureStatusCallback c) {
|
||||
return createMmTelFeatureInternal(slotId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsRcsFeature createRcsFeature(int slotId, IImsFeatureStatusCallback c) {
|
||||
return createRcsFeatureInternal(slotId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImsFeature(int slotId, int featureType, IImsFeatureStatusCallback c)
|
||||
throws RemoteException {
|
||||
ImsService.this.removeImsFeature(slotId, featureType, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImsFeatureConfiguration querySupportedImsFeatures() {
|
||||
return ImsService.this.querySupportedImsFeatures();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyImsServiceReadyForFeatureCreation() {
|
||||
ImsService.this.readyForFeatureCreation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyImsFeatureReady(int slotId, int featureType)
|
||||
throws RemoteException {
|
||||
ImsService.this.notifyImsFeatureReady(slotId, featureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsConfig getConfig(int slotId) throws RemoteException {
|
||||
ImsConfigImplBase c = ImsService.this.getConfig(slotId);
|
||||
return c != null ? c.getBinder() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IImsRegistration getRegistration(int slotId) throws RemoteException {
|
||||
ImsRegistrationImplBase r = ImsService.this.getRegistration(slotId);
|
||||
return r != null ? r.getBinder() : null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
if(SERVICE_INTERFACE.equals(intent.getAction())) {
|
||||
Log.i(LOG_TAG, "ImsService Bound.");
|
||||
return mImsServiceController;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public SparseArray<ImsFeature> getFeatures(int slotId) {
|
||||
return mFeaturesBySlot.get(slotId);
|
||||
}
|
||||
|
||||
private IImsMmTelFeature createMmTelFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
MmTelFeature f = createMmTelFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
Log.e(LOG_TAG, "createMmTelFeatureInternal: null feature returned.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IImsRcsFeature createRcsFeatureInternal(int slotId,
|
||||
IImsFeatureStatusCallback c) {
|
||||
RcsFeature f = createRcsFeature(slotId);
|
||||
if (f != null) {
|
||||
setupFeature(f, slotId, ImsFeature.FEATURE_RCS, c);
|
||||
return f.getBinder();
|
||||
} else {
|
||||
Log.e(LOG_TAG, "createRcsFeatureInternal: null feature returned.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setupFeature(ImsFeature f, int slotId, int featureType,
|
||||
IImsFeatureStatusCallback c) {
|
||||
f.addImsFeatureStatusCallback(c);
|
||||
f.initialize(this, slotId);
|
||||
addImsFeature(slotId, featureType, f);
|
||||
}
|
||||
|
||||
private void addImsFeature(int slotId, int featureType, ImsFeature f) {
|
||||
synchronized (mFeaturesBySlot) {
|
||||
// Get SparseArray for Features, by querying slot Id
|
||||
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
|
||||
if (features == null) {
|
||||
// Populate new SparseArray of features if it doesn't exist for this slot yet.
|
||||
features = new SparseArray<>();
|
||||
mFeaturesBySlot.put(slotId, features);
|
||||
}
|
||||
features.put(featureType, f);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeImsFeature(int slotId, int featureType,
|
||||
IImsFeatureStatusCallback c) {
|
||||
synchronized (mFeaturesBySlot) {
|
||||
// get ImsFeature associated with the slot/feature
|
||||
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
|
||||
if (features == null) {
|
||||
Log.w(LOG_TAG, "Can not remove ImsFeature. No ImsFeatures exist on slot "
|
||||
+ slotId);
|
||||
return;
|
||||
}
|
||||
ImsFeature f = features.get(featureType);
|
||||
if (f == null) {
|
||||
Log.w(LOG_TAG, "Can not remove ImsFeature. No feature with type "
|
||||
+ featureType + " exists on slot " + slotId);
|
||||
return;
|
||||
}
|
||||
f.removeImsFeatureStatusCallback(c);
|
||||
f.onFeatureRemoved();
|
||||
features.remove(featureType);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyImsFeatureReady(int slotId, int featureType) {
|
||||
synchronized (mFeaturesBySlot) {
|
||||
// get ImsFeature associated with the slot/feature
|
||||
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
|
||||
if (features == null) {
|
||||
Log.w(LOG_TAG, "Can not notify ImsFeature ready. No ImsFeatures exist on " +
|
||||
"slot " + slotId);
|
||||
return;
|
||||
}
|
||||
ImsFeature f = features.get(featureType);
|
||||
if (f == null) {
|
||||
Log.w(LOG_TAG, "Can not notify ImsFeature ready. No feature with type "
|
||||
+ featureType + " exists on slot " + slotId);
|
||||
return;
|
||||
}
|
||||
f.onFeatureReady();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When called, provide the {@link ImsFeatureConfiguration} that this ImsService currently
|
||||
* supports. This will trigger the framework to set up the {@link ImsFeature}s that correspond
|
||||
* to the {@link ImsFeature.FeatureType}s configured here.
|
||||
* @return an {@link ImsFeatureConfiguration} containing Features this ImsService supports,
|
||||
* defined in {@link ImsFeature.FeatureType}.
|
||||
*/
|
||||
public ImsFeatureConfiguration querySupportedImsFeatures() {
|
||||
// Return empty for base implementation
|
||||
return new ImsFeatureConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the framework with a new {@link ImsFeatureConfiguration} containing the updated
|
||||
* features, defined in {@link ImsFeature.FeatureType} that this ImsService supports. This may
|
||||
* trigger the framework to add/remove new ImsFeatures, depending on the configuration.
|
||||
*/
|
||||
public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c)
|
||||
throws RemoteException {
|
||||
if (mListener == null) {
|
||||
throw new IllegalStateException("Framework is not ready");
|
||||
}
|
||||
mListener.onUpdateSupportedImsFeatures(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* The ImsService should use this signal instead of onCreate/onBind or similar to perform
|
||||
* feature initialization because the framework may bind to this service multiple times to
|
||||
* query the ImsService's {@link ImsFeatureConfiguration} via
|
||||
* {@link #querySupportedImsFeatures()}before creating features.
|
||||
*/
|
||||
public void readyForFeatureCreation() {
|
||||
}
|
||||
|
||||
/**
|
||||
* When called, the framework is requesting that a new MmTelFeature is created for the specified
|
||||
* slot.
|
||||
*
|
||||
* @param slotId The slot ID that the MMTel Feature is being created for.
|
||||
* @return The newly created MmTelFeature associated with the slot or null if the feature is not
|
||||
* supported.
|
||||
*/
|
||||
public MmTelFeature createMmTelFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* When called, the framework is requesting that a new RcsFeature is created for the specified
|
||||
* slot
|
||||
*
|
||||
* @param slotId The slot ID that the RCS Feature is being created for.
|
||||
* @return The newly created RcsFeature associated with the slot or null if the feature is not
|
||||
* supported.
|
||||
*/
|
||||
public RcsFeature createRcsFeature(int slotId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param slotId The slot that the IMS configuration is associated with.
|
||||
* @return ImsConfig implementation that is associated with the specified slot.
|
||||
*/
|
||||
public ImsConfigImplBase getConfig(int slotId) {
|
||||
return new ImsConfigImplBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param slotId The slot that is associated with the IMS Registration.
|
||||
* @return the ImsRegistration implementation associated with the slot.
|
||||
*/
|
||||
public ImsRegistrationImplBase getRegistration(int slotId) {
|
||||
return new ImsRegistrationImplBase();
|
||||
}
|
||||
}
|
||||
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
* 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.internal.feature;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IInterface;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.ims.internal.aidl.IImsCapabilityCallback;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Base class for all IMS features that are supported by the framework.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class ImsFeature {
|
||||
|
||||
private static final String LOG_TAG = "ImsFeature";
|
||||
|
||||
/**
|
||||
* Action to broadcast when ImsService is up.
|
||||
* Internal use only.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_UP =
|
||||
"com.android.ims.IMS_SERVICE_UP";
|
||||
|
||||
/**
|
||||
* Action to broadcast when ImsService is down.
|
||||
* Internal use only.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_DOWN =
|
||||
"com.android.ims.IMS_SERVICE_DOWN";
|
||||
|
||||
/**
|
||||
* Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
|
||||
* A long value; the phone ID corresponding to the IMS service coming up or down.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_PHONE_ID = "android:phone_id";
|
||||
|
||||
// Invalid feature value
|
||||
public static final int FEATURE_INVALID = -1;
|
||||
// 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 FEATURE_EMERGENCY_MMTEL = 0;
|
||||
public static final int FEATURE_MMTEL = 1;
|
||||
public static final int FEATURE_RCS = 2;
|
||||
// Total number of features defined
|
||||
public static final int FEATURE_MAX = 3;
|
||||
|
||||
// Integer values defining IMS features that are supported in ImsFeature.
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
FEATURE_EMERGENCY_MMTEL,
|
||||
FEATURE_MMTEL,
|
||||
FEATURE_RCS
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface FeatureType {}
|
||||
|
||||
// Integer values defining the state of the ImsFeature at any time.
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_INITIALIZING,
|
||||
STATE_READY,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ImsState {}
|
||||
|
||||
public static final int STATE_UNAVAILABLE = 0;
|
||||
public static final int STATE_INITIALIZING = 1;
|
||||
public static final int STATE_READY = 2;
|
||||
|
||||
// Integer values defining the result codes that should be returned from
|
||||
// {@link changeEnabledCapabilities} when the framework tries to set a feature's capability.
|
||||
@IntDef(flag = true,
|
||||
value = {
|
||||
CAPABILITY_ERROR_GENERIC,
|
||||
CAPABILITY_SUCCESS
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ImsCapabilityError {}
|
||||
|
||||
public static final int CAPABILITY_ERROR_GENERIC = -1;
|
||||
public static final int CAPABILITY_SUCCESS = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The framework implements this callback in order to register for Feature Capability status
|
||||
* updates, via {@link #onCapabilitiesStatusChanged(Capabilities)}, query Capability
|
||||
* configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error
|
||||
* callbacks when the ImsService can not change the capability as requested, via
|
||||
* {@link #onChangeCapabilityConfigurationError}.
|
||||
*/
|
||||
public static class CapabilityCallback extends IImsCapabilityCallback.Stub {
|
||||
|
||||
@Override
|
||||
public final void onCapabilitiesStatusChanged(int config) throws RemoteException {
|
||||
onCapabilitiesStatusChanged(new Capabilities(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the result of a query for the capability configuration of a requested capability.
|
||||
*
|
||||
* @param capability The capability that was requested.
|
||||
* @param radioTech The IMS radio technology associated with the capability.
|
||||
* @param isEnabled true if the capability is enabled, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public void onQueryCapabilityConfiguration(int capability, int radioTech,
|
||||
boolean isEnabled) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a change to the capability configuration has returned an error.
|
||||
*
|
||||
* @param capability The capability that was requested to be changed.
|
||||
* @param radioTech The IMS radio technology associated with the capability.
|
||||
* @param reason error associated with the failure to change configuration.
|
||||
*/
|
||||
@Override
|
||||
public void onChangeCapabilityConfigurationError(int capability, int radioTech,
|
||||
int reason) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The status of the feature's capabilities has changed to either available or unavailable.
|
||||
* If unavailable, the feature is not able to support the unavailable capability at this
|
||||
* time.
|
||||
*
|
||||
* @param config The new availability of the capabilities.
|
||||
*/
|
||||
public void onCapabilitiesStatusChanged(Capabilities config) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the ImsFeature to call back to the CapabilityCallback that the framework has
|
||||
* provided.
|
||||
*/
|
||||
protected static class CapabilityCallbackProxy {
|
||||
private final IImsCapabilityCallback mCallback;
|
||||
|
||||
public CapabilityCallbackProxy(IImsCapabilityCallback c) {
|
||||
mCallback = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method notifies the provided framework callback that the request to change the
|
||||
* indicated capability has failed and has not changed.
|
||||
*
|
||||
* @param capability The Capability that will be notified to the framework.
|
||||
* @param radioTech The radio tech that this capability failed for.
|
||||
* @param reason The reason this capability was unable to be changed.
|
||||
*/
|
||||
public void onChangeCapabilityConfigurationError(int capability, int radioTech,
|
||||
@ImsCapabilityError int reason) {
|
||||
try {
|
||||
mCallback.onChangeCapabilityConfigurationError(capability, radioTech, reason);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOG_TAG, "onChangeCapabilityConfigurationError called on dead binder.");
|
||||
}
|
||||
}
|
||||
|
||||
public void onQueryCapabilityConfiguration(int capability, int radioTech,
|
||||
boolean isEnabled) {
|
||||
try {
|
||||
mCallback.onQueryCapabilityConfiguration(capability, radioTech, isEnabled);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOG_TAG, "onQueryCapabilityConfiguration called on dead binder.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the capabilities defined and supported by an ImsFeature in the form of a bit mask.
|
||||
*/
|
||||
public static class Capabilities {
|
||||
protected int mCapabilities = 0;
|
||||
|
||||
public Capabilities() {
|
||||
}
|
||||
|
||||
protected Capabilities(int capabilities) {
|
||||
mCapabilities = capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param capabilities Capabilities to be added to the configuration in the form of a
|
||||
* bit mask.
|
||||
*/
|
||||
public void addCapabilities(int capabilities) {
|
||||
mCapabilities |= capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param capabilities Capabilities to be removed to the configuration in the form of a
|
||||
* bit mask.
|
||||
*/
|
||||
public void removeCapabilities(int capabilities) {
|
||||
mCapabilities &= ~capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if all of the capabilities specified are capable.
|
||||
*/
|
||||
public boolean isCapable(int capabilities) {
|
||||
return (mCapabilities & capabilities) == capabilities;
|
||||
}
|
||||
|
||||
public Capabilities copy() {
|
||||
return new Capabilities(mCapabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a bitmask containing the capability flags directly.
|
||||
*/
|
||||
public int getMask() {
|
||||
return mCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Capabilities)) return false;
|
||||
|
||||
Capabilities that = (Capabilities) o;
|
||||
|
||||
return mCapabilities == that.mCapabilities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mCapabilities;
|
||||
}
|
||||
}
|
||||
|
||||
private final Set<IImsFeatureStatusCallback> mStatusCallbacks = Collections.newSetFromMap(
|
||||
new WeakHashMap<IImsFeatureStatusCallback, Boolean>());
|
||||
private @ImsState int mState = STATE_UNAVAILABLE;
|
||||
private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
private Context mContext;
|
||||
private final Object mLock = new Object();
|
||||
private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks
|
||||
= new RemoteCallbackList<>();
|
||||
private Capabilities mCapabilityStatus = new Capabilities();
|
||||
|
||||
public final void initialize(Context context, int slotId) {
|
||||
mContext = context;
|
||||
mSlotId = slotId;
|
||||
}
|
||||
|
||||
public final int getFeatureState() {
|
||||
synchronized (mLock) {
|
||||
return mState;
|
||||
}
|
||||
}
|
||||
|
||||
protected final void setFeatureState(@ImsState int state) {
|
||||
synchronized (mLock) {
|
||||
if (mState != state) {
|
||||
mState = state;
|
||||
notifyFeatureState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not final for testing, but shouldn't be extended!
|
||||
@VisibleForTesting
|
||||
public void addImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
|
||||
try {
|
||||
// If we have just connected, send queued status.
|
||||
c.notifyImsFeatureStatus(getFeatureState());
|
||||
// Add the callback if the callback completes successfully without a RemoteException.
|
||||
synchronized (mLock) {
|
||||
mStatusCallbacks.add(c);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
// Not final for testing, but should not be extended!
|
||||
public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
|
||||
synchronized (mLock) {
|
||||
mStatusCallbacks.remove(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method called by ImsFeature when setFeatureState has changed.
|
||||
*/
|
||||
private void notifyFeatureState(@ImsState int state) {
|
||||
synchronized (mLock) {
|
||||
for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
|
||||
iter.hasNext(); ) {
|
||||
IImsFeatureStatusCallback callback = iter.next();
|
||||
try {
|
||||
Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
|
||||
callback.notifyImsFeatureStatus(state);
|
||||
} catch (RemoteException e) {
|
||||
// remove if the callback is no longer alive.
|
||||
iter.remove();
|
||||
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
sendImsServiceIntent(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide backwards compatibility using deprecated service UP/DOWN intents.
|
||||
*/
|
||||
private void sendImsServiceIntent(@ImsState int state) {
|
||||
if (mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
|
||||
return;
|
||||
}
|
||||
Intent intent;
|
||||
switch (state) {
|
||||
case ImsFeature.STATE_UNAVAILABLE:
|
||||
case ImsFeature.STATE_INITIALIZING:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_DOWN);
|
||||
break;
|
||||
case ImsFeature.STATE_READY:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_UP);
|
||||
break;
|
||||
default:
|
||||
intent = new Intent(ACTION_IMS_SERVICE_DOWN);
|
||||
}
|
||||
intent.putExtra(EXTRA_PHONE_ID, mSlotId);
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
public final void addCapabilityCallback(IImsCapabilityCallback c) {
|
||||
mCapabilityCallbacks.register(c);
|
||||
}
|
||||
|
||||
public final void removeCapabilityCallback(IImsCapabilityCallback c) {
|
||||
mCapabilityCallbacks.unregister(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cached capabilities status for this feature.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Capabilities queryCapabilityStatus() {
|
||||
synchronized (mLock) {
|
||||
return mCapabilityStatus.copy();
|
||||
}
|
||||
}
|
||||
|
||||
// Called internally to request the change of enabled capabilities.
|
||||
@VisibleForTesting
|
||||
public final void requestChangeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
IImsCapabilityCallback c) throws RemoteException {
|
||||
if (request == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"ImsFeature#requestChangeEnabledCapabilities called with invalid params.");
|
||||
}
|
||||
changeEnabledCapabilities(request, new CapabilityCallbackProxy(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the ImsFeature when the capabilities status has changed.
|
||||
*
|
||||
* @param c A {@link Capabilities} containing the new Capabilities status.
|
||||
*/
|
||||
protected final void notifyCapabilitiesStatusChanged(Capabilities c) {
|
||||
synchronized (mLock) {
|
||||
mCapabilityStatus = c.copy();
|
||||
}
|
||||
int count = mCapabilityCallbacks.beginBroadcast();
|
||||
try {
|
||||
for (int i = 0; i < count; i++) {
|
||||
try {
|
||||
mCapabilityCallbacks.getBroadcastItem(i).onCapabilitiesStatusChanged(
|
||||
c.mCapabilities);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, e + " " + "notifyCapabilitiesStatusChanged() - Skipping " +
|
||||
"callback.");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mCapabilityCallbacks.finishBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Features should override this method to receive Capability preference change requests from
|
||||
* the framework using the provided {@link CapabilityChangeRequest}. If any of the capabilities
|
||||
* in the {@link CapabilityChangeRequest} are not able to be completed due to an error,
|
||||
* {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError} should be called for
|
||||
* each failed capability.
|
||||
*
|
||||
* @param request A {@link CapabilityChangeRequest} containing requested capabilities to
|
||||
* enable/disable.
|
||||
* @param c A {@link CapabilityCallbackProxy}, which will be used to call back to the framework
|
||||
* setting a subset of these capabilities fail, using
|
||||
* {@link CapabilityCallbackProxy#onChangeCapabilityConfigurationError}.
|
||||
*/
|
||||
public abstract void changeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
CapabilityCallbackProxy c);
|
||||
|
||||
/**
|
||||
* Called when the framework is removing this feature and it needs to be cleaned up.
|
||||
*/
|
||||
public abstract void onFeatureRemoved();
|
||||
|
||||
/**
|
||||
* Called when the feature has been initialized and communication with the framework is set up.
|
||||
* Any attempt by this feature to access the framework before this method is called will return
|
||||
* with an {@link IllegalStateException}.
|
||||
* The IMS provider should use this method to trigger registration for this feature on the IMS
|
||||
* network, if needed.
|
||||
*/
|
||||
public abstract void onFeatureReady();
|
||||
|
||||
/**
|
||||
* @return Binder instance that the framework will use to communicate with this feature.
|
||||
*/
|
||||
protected abstract IInterface getBinder();
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* 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.internal.stub;
|
||||
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.internal.aidl.IImsConfig;
|
||||
import android.telephony.ims.internal.aidl.IImsConfigCallback;
|
||||
|
||||
import com.android.ims.ImsConfig;
|
||||
|
||||
/**
|
||||
* Controls the modification of IMS specific configurations. For more information on the supported
|
||||
* IMS configuration constants, see {@link ImsConfig}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public class ImsConfigImplBase {
|
||||
|
||||
//TODO: Implement the Binder logic to call base APIs. Need to finish other ImsService Config
|
||||
// work first.
|
||||
private final IImsConfig mBinder = new IImsConfig.Stub() {
|
||||
|
||||
@Override
|
||||
public void addImsConfigCallback(IImsConfigCallback c) throws RemoteException {
|
||||
ImsConfigImplBase.this.addImsConfigCallback(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImsConfigCallback(IImsConfigCallback c) throws RemoteException {
|
||||
ImsConfigImplBase.this.removeImsConfigCallback(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConfigInt(int item) throws RemoteException {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigString(int item) throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setConfigInt(int item, int value) throws RemoteException {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setConfigString(int item, String value) throws RemoteException {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
};
|
||||
|
||||
public class Callback extends IImsConfigCallback.Stub {
|
||||
|
||||
@Override
|
||||
public final void onIntConfigChanged(int item, int value) throws RemoteException {
|
||||
onConfigChanged(item, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onStringConfigChanged(int item, String value) throws RemoteException {
|
||||
onConfigChanged(item, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS configuration has changed.
|
||||
* @param item the IMS configuration key constant, as defined in ImsConfig.
|
||||
* @param value the new integer value of the IMS configuration constant.
|
||||
*/
|
||||
public void onConfigChanged(int item, int value) {
|
||||
// Base Implementation
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS configuration has changed.
|
||||
* @param item the IMS configuration key constant, as defined in ImsConfig.
|
||||
* @param value the new String value of the IMS configuration constant.
|
||||
*/
|
||||
public void onConfigChanged(int item, String value) {
|
||||
// Base Implementation
|
||||
}
|
||||
}
|
||||
|
||||
private final RemoteCallbackList<IImsConfigCallback> mCallbacks = new RemoteCallbackList<>();
|
||||
|
||||
/**
|
||||
* Adds a {@link Callback} to the list of callbacks notified when a value in the configuration
|
||||
* changes.
|
||||
* @param c callback to add.
|
||||
*/
|
||||
private void addImsConfigCallback(IImsConfigCallback c) {
|
||||
mCallbacks.register(c);
|
||||
}
|
||||
/**
|
||||
* Removes a {@link Callback} to the list of callbacks notified when a value in the
|
||||
* configuration changes.
|
||||
*
|
||||
* @param c callback to remove.
|
||||
*/
|
||||
private void removeImsConfigCallback(IImsConfigCallback c) {
|
||||
mCallbacks.unregister(c);
|
||||
}
|
||||
|
||||
public final IImsConfig getBinder() {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in Integer format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
public int setConfig(int item, int value) {
|
||||
// Base Implementation - To be overridden.
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in String format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
public int setConfig(int item, String value) {
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in Integer format.
|
||||
*/
|
||||
public int getConfigInt(int item) {
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in String format.
|
||||
*/
|
||||
public String getConfigString(int item) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -16,135 +16,370 @@
|
||||
|
||||
package android.telephony.ims.stub;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.aidl.IImsConfig;
|
||||
import android.telephony.ims.aidl.IImsConfigCallback;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.ImsConfig;
|
||||
import com.android.ims.ImsConfigListener;
|
||||
import com.android.ims.internal.IImsConfig;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Base implementation of ImsConfig, which implements stub versions of the methods
|
||||
* in the IImsConfig AIDL. Override the methods that your implementation of ImsConfig supports.
|
||||
*
|
||||
* DO NOT remove or change the existing APIs, only add new ones to this Base implementation or you
|
||||
* will break other implementations of ImsConfig maintained by other ImsServices.
|
||||
*
|
||||
* Provides APIs to get/set the IMS service feature/capability/parameters.
|
||||
* The config items include:
|
||||
* 1) Items provisioned by the operator.
|
||||
* 2) Items configured by user. Mainly service feature class.
|
||||
* Controls the modification of IMS specific configurations. For more information on the supported
|
||||
* IMS configuration constants, see {@link ImsConfig}.
|
||||
*
|
||||
* The inner class {@link ImsConfigStub} implements methods of IImsConfig AIDL interface.
|
||||
* The IImsConfig AIDL interface is called by ImsConfig, which may exist in many other processes.
|
||||
* ImsConfigImpl access to the configuration parameters may be arbitrarily slow, especially in
|
||||
* during initialization, or times when a lot of configuration parameters are being set/get
|
||||
* (such as during boot up or SIM card change). By providing a cache in ImsConfigStub, we can speed
|
||||
* up access to these configuration parameters, so a query to the ImsConfigImpl does not have to be
|
||||
* performed every time.
|
||||
* @hide
|
||||
*/
|
||||
|
||||
public class ImsConfigImplBase extends IImsConfig.Stub {
|
||||
public class ImsConfigImplBase {
|
||||
|
||||
static final private String TAG = "ImsConfigImplBase";
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage. Synchronous blocking call.
|
||||
* Implements the IImsConfig AIDL interface, which is called by potentially many processes
|
||||
* in order to get/set configuration parameters.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in Integer format.
|
||||
* It holds an object of ImsConfigImplBase class which is usually extended by ImsConfigImpl
|
||||
* with actual implementations from vendors. This class caches provisioned values from
|
||||
* ImsConfigImpl layer because queries through ImsConfigImpl can be slow. When query goes in,
|
||||
* it first checks cache layer. If missed, it will call the vendor implementation of
|
||||
* ImsConfigImplBase API.
|
||||
* and cache the return value if the set succeeds.
|
||||
*
|
||||
* Provides APIs to get/set the IMS service feature/capability/parameters.
|
||||
* The config items include:
|
||||
* 1) Items provisioned by the operator.
|
||||
* 2) Items configured by user. Mainly service feature class.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public int getProvisionedValue(int item) throws RemoteException {
|
||||
return -1;
|
||||
@VisibleForTesting
|
||||
static public class ImsConfigStub extends IImsConfig.Stub {
|
||||
WeakReference<ImsConfigImplBase> mImsConfigImplBaseWeakReference;
|
||||
private HashMap<Integer, Integer> mProvisionedIntValue = new HashMap<>();
|
||||
private HashMap<Integer, String> mProvisionedStringValue = new HashMap<>();
|
||||
|
||||
@VisibleForTesting
|
||||
public ImsConfigStub(ImsConfigImplBase imsConfigImplBase) {
|
||||
mImsConfigImplBaseWeakReference =
|
||||
new WeakReference<ImsConfigImplBase>(imsConfigImplBase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addImsConfigCallback(IImsConfigCallback c) throws RemoteException {
|
||||
getImsConfigImpl().addImsConfigCallback(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeImsConfigCallback(IImsConfigCallback c) throws RemoteException {
|
||||
getImsConfigImpl().removeImsConfigCallback(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters. It first checks its local cache,
|
||||
* if missed, it will call ImsConfigImplBase.getProvisionedValue.
|
||||
* Synchronous blocking call.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in Integer format.
|
||||
*/
|
||||
@Override
|
||||
public synchronized int getConfigInt(int item) throws RemoteException {
|
||||
if (mProvisionedIntValue.containsKey(item)) {
|
||||
return mProvisionedIntValue.get(item);
|
||||
} else {
|
||||
int retVal = getImsConfigImpl().getConfigInt(item);
|
||||
if (retVal != ImsConfig.OperationStatusConstants.UNKNOWN) {
|
||||
updateCachedValue(item, retVal, false);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters. It first checks its local cache,
|
||||
* if missed, it will call #ImsConfigImplBase.getProvisionedValue.
|
||||
* Synchronous blocking call.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in String format.
|
||||
*/
|
||||
@Override
|
||||
public synchronized String getConfigString(int item) throws RemoteException {
|
||||
if (mProvisionedIntValue.containsKey(item)) {
|
||||
return mProvisionedStringValue.get(item);
|
||||
} else {
|
||||
String retVal = getImsConfigImpl().getConfigString(item);
|
||||
if (retVal != null) {
|
||||
updateCachedValue(item, retVal, false);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived, and write it into local cache.
|
||||
* Synchronous blocking call.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in Integer format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
@Override
|
||||
public synchronized int setConfigInt(int item, int value) throws RemoteException {
|
||||
mProvisionedIntValue.remove(item);
|
||||
int retVal = getImsConfigImpl().setConfig(item, value);
|
||||
if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) {
|
||||
updateCachedValue(item, retVal, true);
|
||||
} else {
|
||||
Log.d(TAG, "Set provision value of " + item +
|
||||
" to " + value + " failed with error code " + retVal);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived, and write it into local cache.
|
||||
* Synchronous blocking call.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in String format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
@Override
|
||||
public synchronized int setConfigString(int item, String value)
|
||||
throws RemoteException {
|
||||
mProvisionedStringValue.remove(item);
|
||||
int retVal = getImsConfigImpl().setConfig(item, value);
|
||||
if (retVal == ImsConfig.OperationStatusConstants.SUCCESS) {
|
||||
updateCachedValue(item, retVal, true);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private ImsConfigImplBase getImsConfigImpl() throws RemoteException {
|
||||
ImsConfigImplBase ref = mImsConfigImplBaseWeakReference.get();
|
||||
if (ref == null) {
|
||||
throw new RemoteException("Fail to get ImsConfigImpl");
|
||||
} else {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyImsConfigChanged(int item, int value) throws RemoteException {
|
||||
getImsConfigImpl().notifyConfigChanged(item, value);
|
||||
}
|
||||
|
||||
private void notifyImsConfigChanged(int item, String value) throws RemoteException {
|
||||
getImsConfigImpl().notifyConfigChanged(item, value);
|
||||
}
|
||||
|
||||
protected synchronized void updateCachedValue(int item, int value, boolean notifyChange)
|
||||
throws RemoteException {
|
||||
mProvisionedIntValue.put(item, value);
|
||||
if (notifyChange) {
|
||||
notifyImsConfigChanged(item, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized void updateCachedValue(int item, String value,
|
||||
boolean notifyChange) throws RemoteException {
|
||||
mProvisionedStringValue.put(item, value);
|
||||
if (notifyChange) {
|
||||
notifyImsConfigChanged(item, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage. Synchronous blocking call.
|
||||
* Callback that the framework uses for receiving Configuration change updates.
|
||||
* {@hide}
|
||||
*/
|
||||
public static class Callback extends IImsConfigCallback.Stub {
|
||||
|
||||
@Override
|
||||
public final void onIntConfigChanged(int item, int value) throws RemoteException {
|
||||
onConfigChanged(item, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onStringConfigChanged(int item, String value) throws RemoteException {
|
||||
onConfigChanged(item, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS configuration has changed.
|
||||
* @param item the IMS configuration key constant, as defined in ImsConfig.
|
||||
* @param value the new integer value of the IMS configuration constant.
|
||||
*/
|
||||
public void onConfigChanged(int item, int value) {
|
||||
// Base Implementation
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IMS configuration has changed.
|
||||
* @param item the IMS configuration key constant, as defined in ImsConfig.
|
||||
* @param value the new String value of the IMS configuration constant.
|
||||
*/
|
||||
public void onConfigChanged(int item, String value) {
|
||||
// Base Implementation
|
||||
}
|
||||
}
|
||||
|
||||
private final RemoteCallbackList<IImsConfigCallback> mCallbacks = new RemoteCallbackList<>();
|
||||
ImsConfigStub mImsConfigStub;
|
||||
|
||||
public ImsConfigImplBase(Context context) {
|
||||
mImsConfigStub = new ImsConfigStub(this);
|
||||
}
|
||||
public ImsConfigImplBase() {
|
||||
mImsConfigStub = new ImsConfigStub(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link Callback} to the list of callbacks notified when a value in the configuration
|
||||
* changes.
|
||||
* @param c callback to add.
|
||||
*/
|
||||
private void addImsConfigCallback(IImsConfigCallback c) {
|
||||
mCallbacks.register(c);
|
||||
}
|
||||
/**
|
||||
* Removes a {@link Callback} to the list of callbacks notified when a value in the
|
||||
* configuration changes.
|
||||
*
|
||||
* @param c callback to remove.
|
||||
*/
|
||||
private void removeImsConfigCallback(IImsConfigCallback c) {
|
||||
mCallbacks.unregister(c);
|
||||
}
|
||||
|
||||
void notifyConfigChanged(int item, int value) {
|
||||
// can be null in testing
|
||||
if (mCallbacks == null) {
|
||||
return;
|
||||
}
|
||||
mCallbacks.broadcast(c -> {
|
||||
try {
|
||||
c.onIntConfigChanged(item, value);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "notifyConfigChanged(int): dead binder in notify, skipping.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void notifyConfigChanged(int item, String value) {
|
||||
// can be null in testing
|
||||
if (mCallbacks == null) {
|
||||
return;
|
||||
}
|
||||
mCallbacks.broadcast(c -> {
|
||||
try {
|
||||
c.onStringConfigChanged(item, value);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "notifyConfigChanged(string): dead binder in notify, skipping.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public IImsConfig getIImsConfig() { return mImsConfigStub; }
|
||||
|
||||
/**
|
||||
* Updates provisioning value and notifies the framework of the change.
|
||||
* Doesn't call #setProvisionedValue and assumes the result succeeded.
|
||||
* This should only be used by modem when they implicitly changed provisioned values.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in String format.
|
||||
* @param value in Integer format.
|
||||
*/
|
||||
@Override
|
||||
public String getProvisionedStringValue(int item) throws RemoteException {
|
||||
return null;
|
||||
public final void notifyProvisionedValueChanged(int item, int value) {
|
||||
try {
|
||||
mImsConfigStub.updateCachedValue(item, value, true);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "notifyProvisionedValueChanged(int): Framework connection is dead.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates provisioning value and notifies the framework of the change.
|
||||
* Doesn't call #setProvisionedValue and assumes the result succeeded.
|
||||
* This should only be used by modem when they implicitly changed provisioned values.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in String format.
|
||||
*/
|
||||
public final void notifyProvisionedValueChanged(int item, String value) {
|
||||
try {
|
||||
mImsConfigStub.updateCachedValue(item, value, true);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "notifyProvisionedValueChanged(string): Framework connection is dead.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived. Synchronous blocking call.
|
||||
* from which the master value is derived.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in Integer format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
@Override
|
||||
public int setProvisionedValue(int item, int value) throws RemoteException {
|
||||
public int setConfig(int item, int value) {
|
||||
// Base Implementation - To be overridden.
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by the operator device
|
||||
* management entity. It sets the config item value in the provisioned storage
|
||||
* from which the master value is derived. Synchronous blocking call.
|
||||
* from which the master value is derived.
|
||||
*
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in String format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants.
|
||||
*/
|
||||
@Override
|
||||
public int setProvisionedStringValue(int item, String value) throws RemoteException {
|
||||
public int setConfig(int item, String value) {
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the specified IMS feature item for specified network type.
|
||||
* This operation gets the feature config value from the master storage (i.e. final
|
||||
* value). Asynchronous non-blocking call.
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage.
|
||||
*
|
||||
* @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
|
||||
* @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
|
||||
* @param listener feature value returned asynchronously through listener.
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in Integer format.
|
||||
*/
|
||||
@Override
|
||||
public void getFeatureValue(int feature, int network, ImsConfigListener listener)
|
||||
throws RemoteException {
|
||||
public int getConfigInt(int item) {
|
||||
return ImsConfig.OperationStatusConstants.FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS feature item for specified network type.
|
||||
* This operation stores the user setting in setting db from which master db
|
||||
* is derived.
|
||||
* Gets the value for ims service/capabilities parameters from the provisioned
|
||||
* value storage.
|
||||
*
|
||||
* @param feature as defined in com.android.ims.ImsConfig#FeatureConstants.
|
||||
* @param network as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
|
||||
* @param value as defined in com.android.ims.ImsConfig#FeatureValueConstants.
|
||||
* @param listener, provided if caller needs to be notified for set result.
|
||||
* @param item as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in String format.
|
||||
*/
|
||||
@Override
|
||||
public void setFeatureValue(int feature, int network, int value, ImsConfigListener listener)
|
||||
throws RemoteException {
|
||||
public String getConfigString(int item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for IMS VoLTE provisioned.
|
||||
* This should be the same as the operator provisioned value if applies.
|
||||
*/
|
||||
@Override
|
||||
public boolean getVolteProvisioned() throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for IMS feature item video quality.
|
||||
*
|
||||
* @param listener Video quality value returned asynchronously through listener.
|
||||
*/
|
||||
@Override
|
||||
public void getVideoQuality(ImsConfigListener listener) throws RemoteException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS feature item video quality.
|
||||
*
|
||||
* @param quality, defines the value of video quality.
|
||||
* @param listener, provided if caller needs to be notified for set result.
|
||||
*/
|
||||
@Override
|
||||
public void setVideoQuality(int quality, ImsConfigListener listener) throws RemoteException {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,6 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.stub;
|
||||
package android.telephony.ims.stub;
|
||||
|
||||
parcelable ImsFeatureConfiguration;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* Copyright (C) 2018 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.
|
||||
@@ -14,14 +14,13 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.stub;
|
||||
package android.telephony.ims.stub;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.telephony.ims.internal.feature.ImsFeature;
|
||||
import android.telephony.ims.feature.ImsFeature;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -135,7 +134,8 @@ public class ImsFeatureConfiguration implements Parcelable {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ImsFeatureConfiguration)) return false;
|
||||
|
||||
ImsFeatureConfiguration that = (ImsFeatureConfiguration) o;
|
||||
ImsFeatureConfiguration
|
||||
that = (ImsFeatureConfiguration) o;
|
||||
|
||||
return mFeatures.equals(that.mFeatures);
|
||||
}
|
||||
@@ -18,14 +18,13 @@ package android.telephony.ims.stub;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.aidl.IImsRegistration;
|
||||
import android.telephony.ims.aidl.IImsRegistrationCallback;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.ImsReasonInfo;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
import com.android.ims.internal.IImsRegistrationCallback;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -14,17 +14,16 @@
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.telephony.ims.internal.stub;
|
||||
package android.telephony.ims.stub;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.SmsMessage;
|
||||
import android.telephony.ims.aidl.IImsSmsListener;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsSmsListener;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@@ -37,7 +36,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public class SmsImplBase {
|
||||
public class ImsSmsImplBase {
|
||||
private static final String LOG_TAG = "SmsImplBase";
|
||||
|
||||
/** @hide */
|
||||
@@ -19,8 +19,8 @@ package com.android.ims;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.Rlog;
|
||||
|
||||
import com.android.ims.internal.IImsConfig;
|
||||
import android.telephony.ims.aidl.IImsConfig;
|
||||
import android.telephony.ims.stub.ImsConfigImplBase;
|
||||
|
||||
/**
|
||||
* Provides APIs to get/set the IMS service feature/capability/parameters.
|
||||
@@ -46,7 +46,7 @@ public class ImsConfig {
|
||||
|
||||
/**
|
||||
* Broadcast action: the configuration was changed
|
||||
*
|
||||
* @deprecated Use {@link ImsConfig#addConfigCallback(ImsConfigImplBase.Callback)} instead.
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_CONFIG_CHANGED =
|
||||
@@ -70,6 +70,8 @@ public class ImsConfig {
|
||||
|
||||
/**
|
||||
* Defines IMS service/capability feature constants.
|
||||
* @deprecated Use
|
||||
* {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability} instead.
|
||||
*/
|
||||
public static class FeatureConstants {
|
||||
public static final int FEATURE_TYPE_UNKNOWN = -1;
|
||||
@@ -539,162 +541,164 @@ public class ImsConfig {
|
||||
}
|
||||
|
||||
public ImsConfig(IImsConfig iconfig, Context context) {
|
||||
if (DBG) Rlog.d(TAG, "ImsConfig creates");
|
||||
if (DBG) Rlog.d(TAG, "ImsConfig created");
|
||||
miConfig = iconfig;
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the provisioned value for IMS service/capabilities parameters used by IMS stack.
|
||||
* This function should not be called from the mainthread as it could block the
|
||||
* mainthread.
|
||||
* @deprecated see {@link #getInt(int)} instead.
|
||||
*/
|
||||
public int getProvisionedValue(int item) throws ImsException {
|
||||
return getConfigInt(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration value for IMS service/capabilities parameters used by IMS stack.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return the value in Integer format.
|
||||
*
|
||||
* @throws ImsException if calling the IMS service results in an error.
|
||||
* @throws ImsException if the ImsService is unavailable.
|
||||
*/
|
||||
public int getProvisionedValue(int item) throws ImsException {
|
||||
public int getConfigInt(int item) throws ImsException {
|
||||
int ret = 0;
|
||||
try {
|
||||
ret = miConfig.getProvisionedValue(item);
|
||||
ret = miConfig.getConfigInt(item);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("getValue()", e,
|
||||
throw new ImsException("getInt()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
if (DBG) Rlog.d(TAG, "getProvisionedValue(): item = " + item + ", ret =" + ret);
|
||||
if (DBG) Rlog.d(TAG, "getInt(): item = " + item + ", ret =" + ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the provisioned value for IMS service/capabilities parameters used by IMS stack.
|
||||
* This function should not be called from the mainthread as it could block the
|
||||
* mainthread.
|
||||
* @deprecated see {@link #getConfigString(int)} instead
|
||||
*/
|
||||
public String getProvisionedStringValue(int item) throws ImsException {
|
||||
return getConfigString(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration value for IMS service/capabilities parameters used by IMS stack.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @return value in String format.
|
||||
*
|
||||
* @throws ImsException if calling the IMS service results in an error.
|
||||
* @throws ImsException if the ImsService is unavailable.
|
||||
*/
|
||||
public String getProvisionedStringValue(int item) throws ImsException {
|
||||
public String getConfigString(int item) throws ImsException {
|
||||
String ret = "Unknown";
|
||||
try {
|
||||
ret = miConfig.getProvisionedStringValue(item);
|
||||
ret = miConfig.getConfigString(item);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("getProvisionedStringValue()", e,
|
||||
throw new ImsException("getConfigString()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
if (DBG) Rlog.d(TAG, "getProvisionedStringValue(): item = " + item + ", ret =" + ret);
|
||||
if (DBG) Rlog.d(TAG, "getConfigString(): item = " + item + ", ret =" + ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by
|
||||
* the operator device management entity.
|
||||
* This function should not be called from main thread as it could block
|
||||
* mainthread.
|
||||
* @deprecated see {@link #setConfig(int, int)} instead.
|
||||
*/
|
||||
public int setProvisionedValue(int item, int value) throws ImsException {
|
||||
return setConfig(item, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated see {@link #setConfig(int, String)} instead.
|
||||
*/
|
||||
public int setProvisionedStringValue(int item, String value) throws ImsException {
|
||||
return setConfig(item, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for ImsService configuration item.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in Integer format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants
|
||||
*
|
||||
* @throws ImsException if calling the IMS service results in an error.
|
||||
* @throws ImsException if the ImsService is unavailable.
|
||||
*/
|
||||
public int setProvisionedValue(int item, int value)
|
||||
throws ImsException {
|
||||
public int setConfig(int item, int value) throws ImsException {
|
||||
int ret = OperationStatusConstants.UNKNOWN;
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "setProvisionedValue(): item = " + item +
|
||||
Rlog.d(TAG, "setConfig(): item = " + item +
|
||||
"value = " + value);
|
||||
}
|
||||
try {
|
||||
ret = miConfig.setProvisionedValue(item, value);
|
||||
ret = miConfig.setConfigInt(item, value);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("setProvisionedValue()", e,
|
||||
throw new ImsException("setConfig()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "setProvisionedValue(): item = " + item +
|
||||
Rlog.d(TAG, "setConfig(): item = " + item +
|
||||
" value = " + value + " ret = " + ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for ImsService configuration item.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in Integer format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants
|
||||
*
|
||||
* @throws ImsException if the ImsService is unavailable.
|
||||
*/
|
||||
public int setConfig(int item, String value) throws ImsException {
|
||||
int ret = OperationStatusConstants.UNKNOWN;
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "setConfig(): item = " + item +
|
||||
"value = " + value);
|
||||
}
|
||||
try {
|
||||
ret = miConfig.setConfigString(item, value);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("setConfig()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "setConfig(): item = " + item +
|
||||
" value = " + value + " ret = " + ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS service/capabilities parameters by
|
||||
* the operator device management entity.
|
||||
* This function should not be called from main thread as it could block
|
||||
* mainthread.
|
||||
* Adds a {@link ImsConfigImplBase.Callback} to the ImsService to notify when a Configuration
|
||||
* item has changed.
|
||||
*
|
||||
* @param item, as defined in com.android.ims.ImsConfig#ConfigConstants.
|
||||
* @param value in String format.
|
||||
* @return as defined in com.android.ims.ImsConfig#OperationStatusConstants
|
||||
*
|
||||
* @throws ImsException if calling the IMS service results in an error.
|
||||
* Make sure to call {@link #removeConfigCallback(ImsConfigImplBase.Callback)} when finished
|
||||
* using this callback.
|
||||
*/
|
||||
public int setProvisionedStringValue(int item, String value)
|
||||
throws ImsException {
|
||||
int ret = OperationStatusConstants.UNKNOWN;
|
||||
public void addConfigCallback(ImsConfigImplBase.Callback callback) throws ImsException {
|
||||
if (DBG) Rlog.d(TAG, "addConfigCallback: " + callback);
|
||||
try {
|
||||
ret = miConfig.setProvisionedStringValue(item, value);
|
||||
miConfig.addImsConfigCallback(callback);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("setProvisionedStringValue()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "setProvisionedStringValue(): item = " + item +
|
||||
", value =" + value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for IMS feature item for specified network type.
|
||||
*
|
||||
* @param feature, defined as in FeatureConstants.
|
||||
* @param network, defined as in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
|
||||
* @param listener, provided to be notified for the feature on/off status.
|
||||
* @return void
|
||||
*
|
||||
* @throws ImsException if calling the IMS service results in an error.
|
||||
*/
|
||||
public void getFeatureValue(int feature, int network,
|
||||
ImsConfigListener listener) throws ImsException {
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "getFeatureValue: feature = " + feature + ", network =" + network +
|
||||
", listener =" + listener);
|
||||
}
|
||||
try {
|
||||
miConfig.getFeatureValue(feature, network, listener);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("getFeatureValue()", e,
|
||||
throw new ImsException("addConfigCallback()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for IMS feature item for specified network type.
|
||||
*
|
||||
* @param feature, as defined in FeatureConstants.
|
||||
* @param network, as defined in android.telephony.TelephonyManager#NETWORK_TYPE_XXX.
|
||||
* @param value, as defined in FeatureValueConstants.
|
||||
* @param listener, provided if caller needs to be notified for set result.
|
||||
* @return void
|
||||
*
|
||||
* @throws ImsException if calling the IMS service results in an error.
|
||||
* Removes a {@link ImsConfigImplBase.Callback} from the ImsService that was previously added
|
||||
* by {@link #addConfigCallback(ImsConfigImplBase.Callback)}.
|
||||
*/
|
||||
public void setFeatureValue(int feature, int network, int value,
|
||||
ImsConfigListener listener) throws ImsException {
|
||||
if (DBG) {
|
||||
Rlog.d(TAG, "setFeatureValue: feature = " + feature + ", network =" + network +
|
||||
", value =" + value + ", listener =" + listener);
|
||||
}
|
||||
public void removeConfigCallback(ImsConfigImplBase.Callback callback) throws ImsException {
|
||||
if (DBG) Rlog.d(TAG, "removeConfigCallback: " + callback);
|
||||
try {
|
||||
miConfig.setFeatureValue(feature, network, value, listener);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("setFeatureValue()", e,
|
||||
miConfig.removeImsConfigCallback(callback);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException("removeConfigCallback()", e,
|
||||
ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -24,7 +24,6 @@ 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.IImsSmsListener;
|
||||
import com.android.ims.internal.IImsUt;
|
||||
|
||||
import android.os.Message;
|
||||
@@ -52,12 +51,4 @@ interface IImsMMTelFeature {
|
||||
IImsEcbm getEcbmInterface();
|
||||
void setUiTTYMode(int uiTtyMode, in Message onComplete);
|
||||
IImsMultiEndpoint getMultiEndpointInterface();
|
||||
// SMS APIs
|
||||
void setSmsListener(IImsSmsListener l);
|
||||
oneway void sendSms(in int token, int messageRef, String format, String smsc, boolean retry,
|
||||
in byte[] pdu);
|
||||
oneway void acknowledgeSms(int token, int messageRef, int result);
|
||||
oneway void acknowledgeSmsReport(int token, int messageRef, int result);
|
||||
String getSmsFormat();
|
||||
oneway void onSmsReady();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.ims.internal;
|
||||
|
||||
import com.android.ims.internal.IImsFeatureStatusCallback;
|
||||
import com.android.ims.internal.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
|
||||
/**
|
||||
@@ -30,5 +29,4 @@ interface IImsServiceController {
|
||||
IImsMMTelFeature createMMTelFeature(int slotId, in IImsFeatureStatusCallback c);
|
||||
IImsRcsFeature createRcsFeature(int slotId, in IImsFeatureStatusCallback c);
|
||||
void removeImsFeature(int slotId, int featureType, in IImsFeatureStatusCallback c);
|
||||
IImsRegistration getRegistration(int slotId);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.annotation.NonNull;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/** The implementation of exponential backoff with jitter applied. */
|
||||
public class ExponentialBackoff {
|
||||
private int mRetryCounter;
|
||||
@@ -27,8 +29,31 @@ public class ExponentialBackoff {
|
||||
private long mMaximumDelayMs;
|
||||
private long mCurrentDelayMs;
|
||||
private int mMultiplier;
|
||||
private Runnable mRunnable;
|
||||
private Handler mHandler;
|
||||
private final Runnable mRunnable;
|
||||
private final Handler mHandler;
|
||||
|
||||
/**
|
||||
* Implementation of Handler methods, Adapter for testing (can't spy on final methods).
|
||||
*/
|
||||
private HandlerAdapter mHandlerAdapter = new HandlerAdapter() {
|
||||
@Override
|
||||
public boolean postDelayed(Runnable runnable, long delayMillis) {
|
||||
return mHandler.postDelayed(runnable, delayMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCallbacks(Runnable runnable) {
|
||||
mHandler.removeCallbacks(runnable);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Need to spy final methods for testing.
|
||||
*/
|
||||
public interface HandlerAdapter {
|
||||
boolean postDelayed(Runnable runnable, long delayMillis);
|
||||
void removeCallbacks(Runnable runnable);
|
||||
}
|
||||
|
||||
public ExponentialBackoff(
|
||||
long initialDelayMs,
|
||||
@@ -57,14 +82,14 @@ public class ExponentialBackoff {
|
||||
public void start() {
|
||||
mRetryCounter = 0;
|
||||
mCurrentDelayMs = mStartDelayMs;
|
||||
mHandler.removeCallbacks(mRunnable);
|
||||
mHandler.postDelayed(mRunnable, mCurrentDelayMs);
|
||||
mHandlerAdapter.removeCallbacks(mRunnable);
|
||||
mHandlerAdapter.postDelayed(mRunnable, mCurrentDelayMs);
|
||||
}
|
||||
|
||||
/** Stops the backoff, all pending messages will be removed from the message queue. */
|
||||
public void stop() {
|
||||
mRetryCounter = 0;
|
||||
mHandler.removeCallbacks(mRunnable);
|
||||
mHandlerAdapter.removeCallbacks(mRunnable);
|
||||
}
|
||||
|
||||
/** Should call when the retry action has failed and we want to retry after a longer delay. */
|
||||
@@ -73,12 +98,17 @@ public class ExponentialBackoff {
|
||||
long temp = Math.min(
|
||||
mMaximumDelayMs, (long) (mStartDelayMs * Math.pow(mMultiplier, mRetryCounter)));
|
||||
mCurrentDelayMs = (long) (((1 + Math.random()) / 2) * temp);
|
||||
mHandler.removeCallbacks(mRunnable);
|
||||
mHandler.postDelayed(mRunnable, mCurrentDelayMs);
|
||||
mHandlerAdapter.removeCallbacks(mRunnable);
|
||||
mHandlerAdapter.postDelayed(mRunnable, mCurrentDelayMs);
|
||||
}
|
||||
|
||||
/** Returns the delay for the most recently posted message. */
|
||||
public long getCurrentDelay() {
|
||||
return mCurrentDelayMs;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setHandlerAdapter(HandlerAdapter a) {
|
||||
mHandlerAdapter = a;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,10 @@ import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.TelephonyHistogram;
|
||||
import android.telephony.VisualVoicemailSmsFilterSettings;
|
||||
import com.android.ims.internal.IImsMMTelFeature;
|
||||
import com.android.ims.internal.IImsRcsFeature;
|
||||
import com.android.ims.internal.IImsRegistration;
|
||||
import android.telephony.ims.aidl.IImsConfig;
|
||||
import android.telephony.ims.aidl.IImsMmTelFeature;
|
||||
import android.telephony.ims.aidl.IImsRcsFeature;
|
||||
import android.telephony.ims.aidl.IImsRegistration;
|
||||
import com.android.ims.internal.IImsServiceFeatureCallback;
|
||||
import com.android.internal.telephony.CellNetworkScanResult;
|
||||
import com.android.internal.telephony.OperatorInfo;
|
||||
@@ -788,20 +789,21 @@ interface ITelephony {
|
||||
int getTetherApnRequired();
|
||||
|
||||
/**
|
||||
* Get IImsMMTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature
|
||||
* as well as registering the MMTelFeature for callbacks using the IImsServiceFeatureCallback
|
||||
* interface.
|
||||
*/
|
||||
IImsMMTelFeature getMMTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback);
|
||||
* Enables framework IMS and triggers IMS Registration.
|
||||
*/
|
||||
void enableIms(int slotId);
|
||||
|
||||
/**
|
||||
* Get IImsMMTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature
|
||||
* as well as registering the MMTelFeature for callbacks using the IImsServiceFeatureCallback
|
||||
* Disables framework IMS and triggers IMS deregistration.
|
||||
*/
|
||||
void disableIms(int slotId);
|
||||
|
||||
/**
|
||||
* Get IImsMmTelFeature binder from ImsResolver that corresponds to the subId and MMTel feature
|
||||
* as well as registering the MmTelFeature for callbacks using the IImsServiceFeatureCallback
|
||||
* interface.
|
||||
* Used for emergency calling only.
|
||||
*/
|
||||
IImsMMTelFeature getEmergencyMMTelFeatureAndListen(int slotId,
|
||||
in IImsServiceFeatureCallback callback);
|
||||
IImsMmTelFeature getMmTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback);
|
||||
|
||||
/**
|
||||
* Get IImsRcsFeature binder from ImsResolver that corresponds to the subId and RCS feature
|
||||
@@ -815,6 +817,11 @@ interface ITelephony {
|
||||
*/
|
||||
IImsRegistration getImsRegistration(int slotId, int feature);
|
||||
|
||||
/**
|
||||
* Returns the IImsConfig associated with the slot and feature specified.
|
||||
*/
|
||||
IImsConfig getImsConfig(int slotId, int feature);
|
||||
|
||||
/**
|
||||
* Set the network selection mode to automatic.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user