Merge "ImsService Subscription Notifications"

This commit is contained in:
Jonggeon Kim
2022-01-18 06:20:43 +00:00
committed by Android (Google) Code Review
4 changed files with 232 additions and 42 deletions

View File

@@ -14054,14 +14054,21 @@ package android.telephony.ims {
public class ImsService extends android.app.Service {
ctor public ImsService();
method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
method public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
method public void disableIms(int);
method public void enableIms(int);
method public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
method @Nullable public android.telephony.ims.feature.MmTelFeature createEmergencyOnlyMmTelFeature(int);
method @Deprecated public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
method @Nullable public android.telephony.ims.feature.MmTelFeature createMmTelFeatureForSubscription(int, int);
method @Deprecated public android.telephony.ims.feature.RcsFeature createRcsFeature(int);
method @Nullable public android.telephony.ims.feature.RcsFeature createRcsFeatureForSubscription(int, int);
method @Deprecated public void disableIms(int);
method public void disableImsForSubscription(int, int);
method @Deprecated public void enableIms(int);
method public void enableImsForSubscription(int, int);
method @Deprecated public android.telephony.ims.stub.ImsConfigImplBase getConfig(int);
method @NonNull public android.telephony.ims.stub.ImsConfigImplBase getConfigForSubscription(int, int);
method @NonNull public java.util.concurrent.Executor getExecutor();
method public long getImsServiceCapabilities();
method public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
method @Deprecated public android.telephony.ims.stub.ImsRegistrationImplBase getRegistration(int);
method @NonNull public android.telephony.ims.stub.ImsRegistrationImplBase getRegistrationForSubscription(int, int);
method @Nullable public android.telephony.ims.stub.SipTransportImplBase getSipTransport(int);
method public final void onUpdateSupportedImsFeatures(android.telephony.ims.stub.ImsFeatureConfiguration) throws android.os.RemoteException;
method public android.telephony.ims.stub.ImsFeatureConfiguration querySupportedImsFeatures();

View File

@@ -42,6 +42,7 @@ import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.ims.stub.SipTransportImplBase;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import com.android.ims.internal.IImsFeatureStatusCallback;
import com.android.internal.annotations.VisibleForTesting;
@@ -180,6 +181,12 @@ public class ImsService extends Service {
// call ImsFeature#onFeatureRemoved.
private final SparseArray<SparseArray<ImsFeature>> mFeaturesBySlot = new SparseArray<>();
// A map of slot id -> boolean array, where each entry in the boolean array corresponds to an
// ImsFeature that was created for a slot id and not a sub id for backwards compatibility
// purposes.
private final SparseArray<SparseBooleanArray> mCreateImsFeatureWithSlotIdFlagMap =
new SparseArray<>();
private IImsServiceControllerListener mListener;
private Executor mExecutor;
@@ -222,15 +229,36 @@ public class ImsService extends Service {
}
@Override
public IImsMmTelFeature createMmTelFeature(int slotId) {
return executeMethodAsyncForResult(() -> createMmTelFeatureInternal(slotId),
"createMmTelFeature");
public IImsMmTelFeature createMmTelFeature(int slotId, int subId) {
MmTelFeature f = (MmTelFeature) getImsFeature(slotId, ImsFeature.FEATURE_MMTEL);
if (f == null) {
return executeMethodAsyncForResult(() -> createMmTelFeatureInternal(slotId, subId),
"createMmTelFeature");
} else {
return f.getBinder();
}
}
@Override
public IImsRcsFeature createRcsFeature(int slotId) {
return executeMethodAsyncForResult(() -> createRcsFeatureInternal(slotId),
"createRcsFeature");
public IImsMmTelFeature createEmergencyOnlyMmTelFeature(int slotId) {
MmTelFeature f = (MmTelFeature) getImsFeature(slotId, ImsFeature.FEATURE_MMTEL);
if (f == null) {
return executeMethodAsyncForResult(() -> createEmergencyOnlyMmTelFeatureInternal(
slotId), "createEmergencyOnlyMmTelFeature");
} else {
return f.getBinder();
}
}
@Override
public IImsRcsFeature createRcsFeature(int slotId, int subId) {
RcsFeature f = (RcsFeature) getImsFeature(slotId, ImsFeature.FEATURE_RCS);
if (f == null) {
return executeMethodAsyncForResult(() ->
createRcsFeatureInternal(slotId, subId), "createRcsFeature");
} else {
return f.getBinder();
}
}
@Override
@@ -248,9 +276,14 @@ public class ImsService extends Service {
}
@Override
public void removeImsFeature(int slotId, int featureType) {
public void removeImsFeature(int slotId, int featureType, boolean changeSubId) {
if (changeSubId && isImsFeatureCreatedForSlot(slotId, featureType)) {
Log.w(LOG_TAG, "Do not remove Ims feature for compatibility");
return;
}
executeMethodAsync(() -> ImsService.this.removeImsFeature(slotId, featureType),
"removeImsFeature");
setImsFeatureCreatedForSlot(slotId, featureType, false);
}
@Override
@@ -279,9 +312,10 @@ public class ImsService extends Service {
}
@Override
public IImsConfig getConfig(int slotId) {
public IImsConfig getConfig(int slotId, int subId) {
return executeMethodAsyncForResult(() -> {
ImsConfigImplBase c = ImsService.this.getConfig(slotId);
ImsConfigImplBase c =
ImsService.this.getConfigForSubscription(slotId, subId);
if (c != null) {
c.setDefaultExecutor(mExecutor);
return c.getIImsConfig();
@@ -292,9 +326,10 @@ public class ImsService extends Service {
}
@Override
public IImsRegistration getRegistration(int slotId) {
public IImsRegistration getRegistration(int slotId, int subId) {
return executeMethodAsyncForResult(() -> {
ImsRegistrationImplBase r = ImsService.this.getRegistration(slotId);
ImsRegistrationImplBase r =
ImsService.this.getRegistrationForSubscription(slotId, subId);
if (r != null) {
r.setDefaultExecutor(mExecutor);
return r.getBinder();
@@ -318,13 +353,15 @@ public class ImsService extends Service {
}
@Override
public void enableIms(int slotId) {
executeMethodAsync(() -> ImsService.this.enableIms(slotId), "enableIms");
public void enableIms(int slotId, int subId) {
executeMethodAsync(() ->
ImsService.this.enableImsForSubscription(slotId, subId), "enableIms");
}
@Override
public void disableIms(int slotId) {
executeMethodAsync(() -> ImsService.this.disableIms(slotId), "disableIms");
public void disableIms(int slotId, int subId) {
executeMethodAsync(() ->
ImsService.this.disableImsForSubscription(slotId, subId), "disableIms");
}
// Call the methods with a clean calling identity on the executor and wait indefinitely for
@@ -364,16 +401,8 @@ public class ImsService extends Service {
return null;
}
/**
* @hide
*/
@VisibleForTesting
public SparseArray<ImsFeature> getFeatures(int slotId) {
return mFeaturesBySlot.get(slotId);
}
private IImsMmTelFeature createMmTelFeatureInternal(int slotId) {
MmTelFeature f = createMmTelFeature(slotId);
private IImsMmTelFeature createMmTelFeatureInternal(int slotId, int subscriptionId) {
MmTelFeature f = createMmTelFeatureForSubscription(slotId, subscriptionId);
if (f != null) {
setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL);
f.setDefaultExecutor(mExecutor);
@@ -384,8 +413,20 @@ public class ImsService extends Service {
}
}
private IImsRcsFeature createRcsFeatureInternal(int slotId) {
RcsFeature f = createRcsFeature(slotId);
private IImsMmTelFeature createEmergencyOnlyMmTelFeatureInternal(int slotId) {
MmTelFeature f = createEmergencyOnlyMmTelFeature(slotId);
if (f != null) {
setupFeature(f, slotId, ImsFeature.FEATURE_MMTEL);
f.setDefaultExecutor(mExecutor);
return f.getBinder();
} else {
Log.e(LOG_TAG, "createEmergencyOnlyMmTelFeatureInternal: null feature returned.");
return null;
}
}
private IImsRcsFeature createRcsFeatureInternal(int slotId, int subI) {
RcsFeature f = createRcsFeatureForSubscription(slotId, subI);
if (f != null) {
f.setDefaultExecutor(mExecutor);
setupFeature(f, slotId, ImsFeature.FEATURE_RCS);
@@ -466,6 +507,49 @@ public class ImsService extends Service {
f.onFeatureRemoved();
features.remove(featureType);
}
}
/**
* @hide
*/
@VisibleForTesting
public ImsFeature getImsFeature(int slotId, int featureType) {
synchronized (mFeaturesBySlot) {
// Get SparseArray for Features, by querying slot Id
SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
if (features == null) {
return null;
}
return features.get(featureType);
}
}
private void setImsFeatureCreatedForSlot(int slotId,
@ImsFeature.FeatureType int featureType, boolean createdForSlot) {
synchronized (mCreateImsFeatureWithSlotIdFlagMap) {
getImsFeatureCreatedForSlot(slotId).put(featureType, createdForSlot);
}
}
/**
* @hide
*/
@VisibleForTesting
public boolean isImsFeatureCreatedForSlot(int slotId,
@ImsFeature.FeatureType int featureType) {
synchronized (mCreateImsFeatureWithSlotIdFlagMap) {
return getImsFeatureCreatedForSlot(slotId).get(featureType);
}
}
private SparseBooleanArray getImsFeatureCreatedForSlot(int slotId) {
SparseBooleanArray createFlag = mCreateImsFeatureWithSlotIdFlagMap.get(slotId);
if (createFlag == null) {
createFlag = new SparseBooleanArray();
mCreateImsFeatureWithSlotIdFlagMap.put(slotId, createFlag);
}
return createFlag;
}
/**
@@ -523,28 +607,96 @@ public class ImsService extends Service {
public void readyForFeatureCreation() {
}
/**
* The framework has enabled IMS for the subscription specified, the ImsService should register
* for IMS and perform all appropriate initialization to bring up all ImsFeatures.
*
* @param slotId The slot ID that IMS will be enabled for.
* @param subscriptionId The subscription ID that IMS will be enabled for.
*/
public void enableImsForSubscription(int slotId, int subscriptionId) {
enableIms(slotId);
}
/**
* The framework has disabled IMS for the subscription specified. The ImsService must deregister
* for IMS and set capability status to false for all ImsFeatures.
* @param slotId The slot ID that IMS will be disabled for.
* @param subscriptionId The subscription ID that IMS will be disabled for.
*/
public void disableImsForSubscription(int slotId, int subscriptionId) {
disableIms(slotId);
}
/**
* 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.
* @deprecated Use {@link #enableImsForSubscription} instead.
*/
@Deprecated
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.
* @deprecated Use {@link #disableImsForSubscription} instead.
*/
@Deprecated
public void disableIms(int slotId) {
}
/**
* When called, the framework is requesting that a new {@link MmTelFeature} is created for the
* specified subscription.
*
* @param subscriptionId The subscription ID that the MMTEL Feature is being created for.
* @return The newly created {@link MmTelFeature} associated with the subscription or null if
* the feature is not supported.
*/
public @Nullable MmTelFeature createMmTelFeatureForSubscription(int slotId,
int subscriptionId) {
setImsFeatureCreatedForSlot(slotId, ImsFeature.FEATURE_MMTEL, true);
return createMmTelFeature(slotId);
}
/**
* When called, the framework is requesting that a new {@link RcsFeature} is created for the
* specified subscription.
*
* @param subscriptionId The subscription ID that the RCS Feature is being created for.
* @return The newly created {@link RcsFeature} associated with the subscription or null if the
* feature is not supported.
*/
public @Nullable RcsFeature createRcsFeatureForSubscription(int slotId, int subscriptionId) {
setImsFeatureCreatedForSlot(slotId, ImsFeature.FEATURE_RCS, true);
return createRcsFeature(slotId);
}
/**
* When called, the framework is requesting that a new emergency-only {@link MmTelFeature} is
* created for the specified slot. For emergency calls, there is no known Subscription Id.
*
* @param slotId The slot ID that the MMTEL Feature is being created for.
* @return An MmTelFeature instance to be used for the slot ID when there is not
* subscription inserted. Only requested when there is no subscription active on
* the specified slot.
*/
public @Nullable MmTelFeature createEmergencyOnlyMmTelFeature(int slotId) {
setImsFeatureCreatedForSlot(slotId, ImsFeature.FEATURE_MMTEL, true);
return createMmTelFeature(slotId);
}
/**
* When called, the framework is requesting that a new {@link MmTelFeature} is created for the
* specified slot.
* @deprecated Use {@link #createMmTelFeatureForSubscription} instead
*
* @param slotId The slot ID that the MMTEL Feature is being created for.
* @return The newly created {@link MmTelFeature} associated with the slot or null if the
* feature is not supported.
*/
@Deprecated
public MmTelFeature createMmTelFeature(int slotId) {
return null;
}
@@ -552,32 +704,62 @@ public class ImsService extends Service {
/**
* When called, the framework is requesting that a new {@link RcsFeature} is created for the
* specified slot.
* @deprecated Use {@link #createRcsFeatureForSubscription} instead
*
* @param slotId The slot ID that the RCS Feature is being created for.
* @return The newly created {@link RcsFeature} associated with the slot or null if the feature
* is not supported.
*/
@Deprecated
public RcsFeature createRcsFeature(int slotId) {
return null;
}
/**
* Return the {@link ImsConfigImplBase} implementation associated with the provided
* subscription. This will be used by the platform to get/set specific IMS related
* configurations.
*
* @param subscriptionId The subscription ID that the IMS configuration is associated with.
* @return ImsConfig implementation that is associated with the specified subscription.
*/
public @NonNull ImsConfigImplBase getConfigForSubscription(int slotId, int subscriptionId) {
return getConfig(slotId);
}
/**
* Return the {@link ImsRegistrationImplBase} implementation associated with the provided
* subscription.
*
* @param subscriptionId The subscription ID that is associated with the IMS Registration.
* @return the ImsRegistration implementation associated with the subscription.
*/
public @NonNull ImsRegistrationImplBase getRegistrationForSubscription(int slotId,
int subscriptionId) {
return getRegistration(slotId);
}
/**
* Return the {@link ImsConfigImplBase} implementation associated with the provided slot. This
* will be used by the platform to get/set specific IMS related configurations.
* @deprecated use {@link #getConfigForSubscription} instead.
*
* @param slotId The slot that the IMS configuration is associated with.
* @return ImsConfig implementation that is associated with the specified slot.
*/
@Deprecated
public ImsConfigImplBase getConfig(int slotId) {
return new ImsConfigImplBase();
}
/**
* Return the {@link ImsRegistrationImplBase} implementation associated with the provided slot.
* @deprecated use {@link #getRegistrationForSubscription} instead.
*
* @param slotId The slot that is associated with the IMS Registration.
* @return the ImsRegistration implementation associated with the slot.
*/
@Deprecated
public ImsRegistrationImplBase getRegistration(int slotId) {
return new ImsRegistrationImplBase();
}

View File

@@ -32,18 +32,19 @@ import com.android.ims.internal.IImsFeatureStatusCallback;
*/
interface IImsServiceController {
void setListener(IImsServiceControllerListener l);
IImsMmTelFeature createMmTelFeature(int slotId);
IImsRcsFeature createRcsFeature(int slotId);
IImsMmTelFeature createMmTelFeature(int slotId, int subId);
IImsMmTelFeature createEmergencyOnlyMmTelFeature(int slotId);
IImsRcsFeature createRcsFeature(int slotId, int subId);
ImsFeatureConfiguration querySupportedImsFeatures();
long getImsServiceCapabilities();
void addFeatureStatusCallback(int slotId, int featureType, in IImsFeatureStatusCallback c);
void removeFeatureStatusCallback(int slotId, int featureType, in IImsFeatureStatusCallback c);
// Synchronous call to ensure the ImsService is ready before continuing with feature creation.
void notifyImsServiceReadyForFeatureCreation();
void removeImsFeature(int slotId, int featureType);
IImsConfig getConfig(int slotId);
IImsRegistration getRegistration(int slotId);
void removeImsFeature(int slotId, int featureType, boolean changeSubId);
IImsConfig getConfig(int slotId, int subId);
IImsRegistration getRegistration(int slotId, int subId);
ISipTransport getSipTransport(int slotId);
oneway void enableIms(int slotId);
oneway void disableIms(int slotId);
oneway void enableIms(int slotId, int subId);
oneway void disableIms(int slotId, int subId);
}

View File

@@ -23,11 +23,11 @@ import com.android.ims.ImsFeatureContainer;
* {@hide}
*/
oneway interface IImsServiceFeatureCallback {
void imsFeatureCreated(in ImsFeatureContainer feature);
void imsFeatureCreated(in ImsFeatureContainer feature, int subId);
// Reason defined in FeatureConnector.UnavailableReason
void imsFeatureRemoved(int reason);
// Status defined in ImsFeature.ImsState.
void imsStatusChanged(int status);
void imsStatusChanged(int status, int subId);
//Capabilities defined in ImsService.ImsServiceCapability
void updateCapabilities(long capabilities);
}