Add the ability to remove FeatureConnection callbacks
FeatureConnection status callbacks were not being cleaned up and
were staying around indefinitely, even after the FeatureConnection
was destroyed.
Bug: 156893040
Test: atest FrameworksTelephonyTests
Change-Id: I28dc51b10dc230bc8f7a03b7373510cf3a29e93a
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index 50b0954..2d293a1 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -767,6 +767,22 @@
return null;
}
+ /**
+ * Unregister a previously registered IImsServiceFeatureCallback through
+ * {@link #getImsServiceControllerAndListen(int, int, IImsServiceFeatureCallback)} .
+ * @param slotId The slot id associated with the ImsFeature.
+ * @param feature The {@link ImsFeature.FeatureType}
+ * @param callback The callback to be unregistered.
+ */
+ public void unregisterImsFeatureCallback(int slotId, int feature,
+ IImsServiceFeatureCallback callback) {
+ ImsServiceController controller = getImsServiceController(slotId, feature);
+
+ if (controller != null) {
+ controller.removeImsServiceFeatureCallback(callback);
+ }
+ }
+
// Used for testing only.
public boolean overrideImsServiceConfiguration(int slotId, boolean isCarrierService,
Map<Integer, String> featureConfig) {
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceController.java b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
index 52fc666..bc5ddbe 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -504,19 +504,28 @@
*/
public void addImsServiceFeatureCallback(IImsServiceFeatureCallback callback) {
mImsStatusCallbacks.add(callback);
+ Set<ImsFeatureConfiguration.FeatureSlotPair> features;
synchronized (mLock) {
if (mImsFeatures == null || mImsFeatures.isEmpty()) {
return;
}
- // notify the new status callback of the features that are available.
- try {
- for (ImsFeatureConfiguration.FeatureSlotPair i : mImsFeatures) {
- callback.imsFeatureCreated(i.slotId, i.featureType);
- }
- } catch (RemoteException e) {
- Log.w(LOG_TAG, "addImsServiceFeatureCallback: exception notifying callback");
- }
+ features = new HashSet<>(mImsFeatures);
}
+ // notify the new status callback of the features that are available.
+ try {
+ for (ImsFeatureConfiguration.FeatureSlotPair i : features) {
+ callback.imsFeatureCreated(i.slotId, i.featureType);
+ }
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "addImsServiceFeatureCallback: exception notifying callback");
+ }
+ }
+
+ /**
+ * Removes a previously registered callback if it was associated with this feature.
+ */
+ public void removeImsServiceFeatureCallback(IImsServiceFeatureCallback callback) {
+ mImsStatusCallbacks.remove(callback);
}
public void enableIms(int slotId) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/FeatureConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/FeatureConnectionTest.java
index 267f1f9..bac45ef 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/FeatureConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/FeatureConnectionTest.java
@@ -28,7 +28,9 @@
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;
+import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.FeatureConnection;
@@ -59,8 +61,8 @@
public boolean isFeatureRemovedCalled = false;
public int mNewStatus = ImsFeature.STATE_UNAVAILABLE;
- TestFeatureConnection(Context context, int slotId, int featureType) {
- super(context, slotId, featureType);
+ TestFeatureConnection(Context context, int slotId) {
+ super(context, slotId);
if (!ImsManager.isImsSupportedOnDevice(context)) {
sImsSupportedOnDevice = false;
}
@@ -91,6 +93,11 @@
return mFeatureState;
}
+ @Override
+ protected IImsRegistration getRegistrationBinder() {
+ return getTestRegistrationBinder();
+ }
+
public void setFeatureState(int state) {
mFeatureState = state;
}
@@ -99,6 +106,7 @@
private int mPhoneId;
private TestFeatureConnection mTestFeatureConnection;
@Mock IBinder mBinder;
+ @Mock IImsRegistration mRegistrationBinder;
@Before
public void setUp() throws Exception {
@@ -108,8 +116,7 @@
doReturn(null).when(mContext).getMainLooper();
doReturn(true).when(mPackageManager).hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS);
- mTestFeatureConnection = new TestFeatureConnection(
- mContext, mPhoneId, ImsFeature.FEATURE_RCS);
+ mTestFeatureConnection = new TestFeatureConnection(mContext, mPhoneId);
mTestFeatureConnection.mExecutor = mSimpleExecutor;
mTestFeatureConnection.setBinder(mBinder);
}
@@ -164,6 +171,20 @@
}
/**
+ * Test registration tech callbacks.
+ */
+ @Test
+ @SmallTest
+ public void testRegistrationTech() throws Exception {
+ when(mRegistrationBinder.getRegistrationTechnology()).thenReturn(
+ ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
+
+ assertEquals(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+ mTestFeatureConnection.getRegistrationTech());
+
+ }
+
+ /**
* Test callback is called when IMS feature created/removed/changed.
*/
@Test
@@ -192,4 +213,8 @@
throw new AssertionFailedError("testListenerCallback(Changed): " + e);
}
}
+
+ private IImsRegistration getTestRegistrationBinder() {
+ return mRegistrationBinder;
+ }
}