ImsService Subscription Notifications
Provide a new API in ImsService that creates a new version of each ImsFeature and dependencies when a new subId is loaded. The ImsService handles ImsFeature setup and teardown procedures to happen on a per-subscription basis instead of on a per-slot basis. Provide the compatibility behavior for older devices that are not upgrading to using the new API. Bug: 197991451 Test: atest FrameworksTelephonyTests:ImsServiceTest, atest CtsTelephonyTestCases:ImsServiceTest Merged-In: I231da2f4479d4a4fb272edbf27e49f46833a082a Change-Id: I231da2f4479d4a4fb272edbf27e49f46833a082a
This commit is contained in:
committed by
Hakjun Choi
parent
e5c38399ec
commit
5e08b37786
@@ -12921,14 +12921,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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user