Merge "API Coverage - Fix UCE methods not covered" am: 73789acbe8 am: c76097d9f7 am: 31c66c515b

Original change: https://android-review.googlesource.com/c/platform/cts/+/1662059

Change-Id: Iaf143caf725f6ca269e9cc42737646bdf4d2bece
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index d3861c6..c530fe8 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -2309,6 +2309,21 @@
             automan.dropShellPermissionIdentity();
         }
 
+        // Remove availability changed listener
+        try {
+            automan.adoptShellPermissionIdentity();
+            imsRcsManager.removeOnAvailabilityChangedListener(callback);
+        } finally {
+            automan.dropShellPermissionIdentity();
+        }
+
+        // Notify capabilities status changes again.
+        sServiceConnector.getCarrierService().getRcsFeature()
+                .notifyCapabilitiesStatusChanged(optionsCap);
+
+        // The callback should not be called because the listener is removed.
+        assertTrue(availabilityChanged.isEmpty());
+
         overrideCarrierConfig(null);
     }
 
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/RcsContactUceCapabilityTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/RcsContactUceCapabilityTest.java
index 66bcf70..dfdcc6f 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/RcsContactUceCapabilityTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/RcsContactUceCapabilityTest.java
@@ -17,7 +17,9 @@
 package android.telephony.ims.cts;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.net.Uri;
 import android.os.Parcel;
@@ -32,6 +34,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.time.Instant;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -40,7 +44,7 @@
 @RunWith(AndroidJUnit4.class)
 public class RcsContactUceCapabilityTest {
 
-    private static final Uri TEST_CONTACT = Uri.fromParts("sip", "me.test", null);
+    private static final Uri TEST_CONTACT = Uri.fromParts("sip", "test1", null);
 
     public static final String FEATURE_TAG_CHAT_IM =
             "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.im\"";
@@ -60,29 +64,17 @@
             return;
         }
 
-        final boolean isAudioCapable = true;
-        final boolean isVideoCapable = true;
-        final String serviceVersion = "1.0";
-        final String serviceDescription = "service description test";
-
-        // Create the test capability
-        ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder(
-                isAudioCapable, isVideoCapable);
-        servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL);
-
-        RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
-                RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
-                RcsContactPresenceTuple.SERVICE_ID_MMTEL, serviceVersion);
-        tupleBuilder.setContactUri(TEST_CONTACT)
-                .setServiceDescription(serviceDescription)
-                .setServiceCapabilities(servCapsBuilder.build());
+        // Create two presence tuples for testing.
+        RcsContactPresenceTuple mmtelTuple = createPresenceMmtelTuple();
+        RcsContactPresenceTuple ftTuple = createPresenceFtTuple();
 
         PresenceBuilder presenceBuilder = new PresenceBuilder(TEST_CONTACT,
                 RcsContactUceCapability.SOURCE_TYPE_CACHED,
                 RcsContactUceCapability.REQUEST_RESULT_FOUND);
-        presenceBuilder.addCapabilityTuple(tupleBuilder.build());
+        presenceBuilder.addCapabilityTuple(mmtelTuple);
+        presenceBuilder.addCapabilityTuples(Collections.singletonList(ftTuple));
 
-        RcsContactUceCapability testCapability = presenceBuilder.build();
+        final RcsContactUceCapability testCapability = presenceBuilder.build();
 
         // parcel and unparcel
         Parcel infoParceled = Parcel.obtain();
@@ -92,36 +84,91 @@
                 RcsContactUceCapability.CREATOR.createFromParcel(infoParceled);
         infoParceled.recycle();
 
-        boolean unparceledVolteCapable = false;
-        boolean unparceledVtCapable = false;
-        String unparceledTupleStatus = RcsContactPresenceTuple.TUPLE_BASIC_STATUS_CLOSED;
-        String unparceledDuplexMode = ServiceCapabilities.DUPLEX_MODE_RECEIVE_ONLY;
+        assertEquals(unparceledCapability.getContactUri(), testCapability.getContactUri());
+        assertEquals(unparceledCapability.getSourceType(), testCapability.getSourceType());
+        assertEquals(unparceledCapability.getRequestResult(), testCapability.getRequestResult());
+        assertEquals(unparceledCapability.getCapabilityMechanism(),
+                testCapability.getCapabilityMechanism());
 
-        RcsContactPresenceTuple unparceledTuple =
+        // Verify mmtel tuple
+        RcsContactPresenceTuple unparceledMMtelTuple =
                 unparceledCapability.getCapabilityTuple(RcsContactPresenceTuple.SERVICE_ID_MMTEL);
+        verifyUnparceledTuple(unparceledMMtelTuple, mmtelTuple);
 
-        if (unparceledTuple != null) {
-            unparceledTupleStatus = unparceledTuple.getStatus();
+        // Verify File transfer tuple
+        RcsContactPresenceTuple unparceledFtTuple =
+                unparceledCapability.getCapabilityTuple(RcsContactPresenceTuple.SERVICE_ID_FT);
+        verifyUnparceledTuple(unparceledFtTuple, ftTuple);
 
-            ServiceCapabilities serviceCaps = unparceledTuple.getServiceCapabilities();
-            if (serviceCaps != null) {
-                unparceledVolteCapable = serviceCaps.isAudioCapable();
-                unparceledVtCapable = serviceCaps.isVideoCapable();
-                List<String> duplexModes = serviceCaps.getSupportedDuplexModes();
-                if (duplexModes != null && !duplexModes.isEmpty()) {
-                    unparceledDuplexMode = duplexModes.get(0);
-                }
+        // Verify all the tuples from the API getCapabilityTuples
+        List<RcsContactPresenceTuple> unparceledTuples = unparceledCapability.getCapabilityTuples();
+        assertNotNull(unparceledTuples);
+        assertEquals(2, unparceledTuples.size());
+        for (RcsContactPresenceTuple unparcelTuple : unparceledTuples) {
+            String serverId = unparcelTuple.getServiceId();
+            if (RcsContactPresenceTuple.SERVICE_ID_MMTEL.equals(serverId)) {
+                verifyUnparceledTuple(unparcelTuple, mmtelTuple);
+            } else if (RcsContactPresenceTuple.SERVICE_ID_FT.equals(serverId)) {
+                verifyUnparceledTuple(unparcelTuple, ftTuple);
+            } else {
+                fail("Invalid service ID: " + serverId);
             }
         }
+    }
 
-        assertEquals(TEST_CONTACT, unparceledCapability.getContactUri());
-        assertTrue(unparceledVolteCapable);
-        assertTrue(unparceledVtCapable);
-        assertEquals(RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN, unparceledTupleStatus);
-        assertEquals(ServiceCapabilities.DUPLEX_MODE_FULL, unparceledDuplexMode);
-        assertEquals(RcsContactPresenceTuple.SERVICE_ID_MMTEL, unparceledTuple.getServiceId());
-        assertEquals(serviceVersion, unparceledTuple.getServiceVersion());
-        assertEquals(serviceDescription, unparceledTuple.getServiceDescription());
+    private RcsContactPresenceTuple createPresenceMmtelTuple() {
+        ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder(true, true);
+        servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL);
+
+        RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
+                RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
+                RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0");
+        tupleBuilder.setContactUri(TEST_CONTACT)
+                .setTime(Instant.now())
+                .setServiceDescription("service description for contact 1")
+                .setServiceCapabilities(servCapsBuilder.build());
+        return tupleBuilder.build();
+    }
+
+    private RcsContactPresenceTuple createPresenceFtTuple() {
+        ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder(true, true);
+        servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL);
+
+        RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
+                RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
+                RcsContactPresenceTuple.SERVICE_ID_FT, "1.0");
+        tupleBuilder.setContactUri(TEST_CONTACT)
+                .setServiceDescription("service description for contact2")
+                .setServiceCapabilities(servCapsBuilder.build());
+        return tupleBuilder.build();
+    }
+
+    private void verifyUnparceledTuple(RcsContactPresenceTuple unparceledTuple,
+            RcsContactPresenceTuple expectedTuple) {
+        assertNotNull(unparceledTuple);
+        assertEquals(unparceledTuple.getStatus(), expectedTuple.getStatus());
+        assertEquals(unparceledTuple.getServiceId(), expectedTuple.getServiceId());
+        assertEquals(unparceledTuple.getServiceDescription(),
+                expectedTuple.getServiceDescription());
+        assertEquals(unparceledTuple.getServiceVersion(), expectedTuple.getServiceVersion());
+        assertEquals(unparceledTuple.getContactUri(), expectedTuple.getContactUri());
+        assertEquals(unparceledTuple.getTime(), expectedTuple.getTime());
+
+        ServiceCapabilities unparceledServiceCaps = unparceledTuple.getServiceCapabilities();
+        ServiceCapabilities expectedServiceCaps = unparceledTuple.getServiceCapabilities();
+        assertNotNull(unparceledServiceCaps);
+        assertEquals(unparceledServiceCaps.isAudioCapable(), expectedServiceCaps.isAudioCapable());
+        assertEquals(unparceledServiceCaps.isVideoCapable(), expectedServiceCaps.isVideoCapable());
+
+        List<String> unparceledDuplexModes = unparceledServiceCaps.getSupportedDuplexModes();
+        List<String> expectedDuplexModes = expectedServiceCaps.getSupportedDuplexModes();
+        assertEquals(unparceledDuplexModes.size(), expectedDuplexModes.size());
+        assertTrue(unparceledDuplexModes.containsAll(expectedDuplexModes));
+
+        List<String> unparceledUnsupportedModes = unparceledServiceCaps.getUnsupportedDuplexModes();
+        List<String> expectedUnsupportedModes = expectedServiceCaps.getUnsupportedDuplexModes();
+        assertEquals(unparceledUnsupportedModes.size(), expectedUnsupportedModes.size());
+        assertTrue(unparceledUnsupportedModes.containsAll(expectedUnsupportedModes));
     }
 
     @Test
@@ -130,16 +177,15 @@
             return;
         }
 
-        final int requestResult = RcsContactUceCapability.REQUEST_RESULT_FOUND;
         final Set<String> featureTags = new HashSet<>();
         featureTags.add(FEATURE_TAG_CHAT_IM);
         featureTags.add(FEATURE_TAG_CHAT_SESSION);
         featureTags.add(FEATURE_TAG_FILE_TRANSFER);
 
         OptionsBuilder optionsBuilder = new OptionsBuilder(TEST_CONTACT);
-        optionsBuilder.setRequestResult(requestResult);
         optionsBuilder.addFeatureTags(featureTags);
         optionsBuilder.addFeatureTag(FEATURE_TAG_POST_CALL);
+        optionsBuilder.setRequestResult(RcsContactUceCapability.REQUEST_RESULT_FOUND);
 
         RcsContactUceCapability testCapability = optionsBuilder.build();
 
@@ -151,16 +197,20 @@
                 RcsContactUceCapability.CREATOR.createFromParcel(infoParceled);
         infoParceled.recycle();
 
-        Set<String> verifiedFeatureTags = new HashSet<>(featureTags);
-        verifiedFeatureTags.add(FEATURE_TAG_POST_CALL);
+        assertEquals(unparceledCapability.getContactUri(), testCapability.getContactUri());
+        assertEquals(unparceledCapability.getSourceType(), testCapability.getSourceType());
+        assertEquals(unparceledCapability.getRequestResult(), testCapability.getRequestResult());
+        assertEquals(unparceledCapability.getCapabilityMechanism(),
+                testCapability.getCapabilityMechanism());
 
-        int unparceledRequestResult = unparceledCapability.getRequestResult();
+        Set<String> expectedFeatureTags = new HashSet<>(featureTags);
+        expectedFeatureTags.add(FEATURE_TAG_POST_CALL);
+
         Set<String> unparceledFeatureTags = unparceledCapability.getFeatureTags();
-        assertEquals(requestResult, unparceledRequestResult);
-        assertEquals(verifiedFeatureTags.size(), unparceledFeatureTags.size());
-        Iterator<String> featureTag = verifiedFeatureTags.iterator();
-        while (featureTag.hasNext()) {
-            assertTrue(unparceledFeatureTags.contains(featureTag.next()));
+        assertEquals(unparceledFeatureTags.size(), expectedFeatureTags.size());
+        Iterator<String> expectedFeatureTag = expectedFeatureTags.iterator();
+        while (expectedFeatureTag.hasNext()) {
+            assertTrue(unparceledFeatureTags.contains(expectedFeatureTag.next()));
         }
     }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java
index 1712686..a012513 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestImsService.java
@@ -88,7 +88,7 @@
     interface CapabilitiesSetListener {
         void onSet();
     }
-    interface RcsCapabilitySetListener {
+    interface RcsCapabilityExchangeEventListener {
         void onSet();
     }
     interface DeviceCapPublishListener {
@@ -148,7 +148,7 @@
         public RcsFeature createRcsFeature(int slotId) {
             synchronized (mLock) {
                 countDownLatch(LATCH_CREATE_RCS);
-                mTestRcsFeature = new TestRcsFeature(
+                mTestRcsFeature = new TestRcsFeature(getBaseContext(),
                         //onReady
                         () -> {
                             synchronized (mLock) {
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java
index 0f6c54a..08eaa85 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/TestRcsFeature.java
@@ -16,16 +16,15 @@
 
 package android.telephony.ims.cts;
 
+import android.content.Context;
 import android.telephony.ims.feature.CapabilityChangeRequest;
-import android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair;
-import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.CapabilityExchangeEventListener;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
 import android.util.Log;
 
 import java.util.List;
-import java.util.Optional;
 import java.util.concurrent.Executor;
 
 public class TestRcsFeature extends RcsFeature {
@@ -34,24 +33,30 @@
 
     private final TestImsService.ReadyListener mReadyListener;
     private final TestImsService.RemovedListener mRemovedListener;
-    private final TestImsService.CapabilitiesSetListener mCapSetListener;
-    private final TestImsService.RcsCapabilitySetListener mRcsCapabilitySetListener;
+    private final TestImsService.RcsCapabilityExchangeEventListener mCapExchangeEventListener;
+
+    private final RcsImsCapabilities mRcsCapabilitiesLte;
+    private final RcsImsCapabilities mRcsCapabilitiesIWan;
+    private final TestImsService.CapabilitiesSetListener mRcsCapabilityChangedListener;
 
     private TestRcsCapabilityExchangeImpl mCapExchangeImpl;
     private CapabilityExchangeEventListener mCapEventListener;
     private TestImsService.DeviceCapPublishListener mDeviceCapPublishListener;
 
-    private CapabilityChangeRequest mCapabilityChangeRequest;
-    private int mCapabilitiesChangedResult = ImsFeature.CAPABILITY_SUCCESS;
-
-    TestRcsFeature(TestImsService.ReadyListener readyListener,
-            TestImsService.RemovedListener listener,
+    TestRcsFeature(Context context,
+            TestImsService.ReadyListener readyListener,
+            TestImsService.RemovedListener removedListener,
             TestImsService.CapabilitiesSetListener setListener,
-            TestImsService.RcsCapabilitySetListener uceCallbackListener) {
+            TestImsService.RcsCapabilityExchangeEventListener capExchangeEventListener) {
+        super(context.getMainExecutor());
+
         mReadyListener = readyListener;
-        mRemovedListener = listener;
-        mCapSetListener = setListener;
-        mRcsCapabilitySetListener = uceCallbackListener;
+        mRemovedListener = removedListener;
+        mCapExchangeEventListener = capExchangeEventListener;
+
+        mRcsCapabilityChangedListener = setListener;
+        mRcsCapabilitiesLte = new RcsImsCapabilities(RcsImsCapabilities.CAPABILITY_TYPE_NONE);
+        mRcsCapabilitiesIWan = new RcsImsCapabilities(RcsImsCapabilities.CAPABILITY_TYPE_NONE);
 
         setFeatureState(STATE_READY);
     }
@@ -60,10 +65,6 @@
         mDeviceCapPublishListener = listener;
     }
 
-    public void overrideCapabilitiesEnabledResult(int result) {
-        mCapabilitiesChangedResult = result;
-    }
-
     @Override
     public void onFeatureReady() {
         if (ImsUtils.VDBG) {
@@ -93,15 +94,17 @@
         }
         mCapEventListener = listener;
         mCapExchangeImpl = new TestRcsCapabilityExchangeImpl(mDeviceCapPublishListener);
-        mRcsCapabilitySetListener.onSet();
+        mCapExchangeEventListener.onSet();
         return mCapExchangeImpl;
     }
 
+    @Override
     public void destroyCapabilityExchangeImpl(RcsCapabilityExchangeImplBase capExchangeImpl) {
         if (ImsUtils.VDBG) {
             Log.d(TAG, "TestRcsFeature.destroyCapabilityExchangeImpl called");
         }
-        mRcsCapabilitySetListener.onSet();
+        mCapEventListener = null;
+        mCapExchangeEventListener.onSet();
     }
 
     public CapabilityExchangeEventListener getEventListener() {
@@ -115,26 +118,39 @@
     @Override
     public void changeEnabledCapabilities(CapabilityChangeRequest request,
             CapabilityCallbackProxy c) {
-        // Trigger the error callback if the result is failed
-        if (mCapabilitiesChangedResult != ImsFeature.CAPABILITY_SUCCESS) {
-            CapabilityChangeRequest.CapabilityPair capPair = request.getCapabilitiesToEnable()
-                    .get(0);
-            c.onChangeCapabilityConfigurationError(capPair.getCapability(), capPair.getRadioTech(),
-                    ImsFeature.CAPABILITY_ERROR_GENERIC);
-            return;
+
+        // Enabled RCS capabilities
+        List<CapabilityChangeRequest.CapabilityPair> pairs = request.getCapabilitiesToEnable();
+        for (CapabilityChangeRequest.CapabilityPair pair : pairs) {
+            if (pair.getRadioTech() == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
+                mRcsCapabilitiesLte.addCapabilities(pair.getCapability());
+            } else if (pair.getRadioTech() == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
+                mRcsCapabilitiesIWan.addCapabilities(pair.getCapability());
+            }
         }
-        mCapabilityChangeRequest = request;
-        // Notify that the capabilities is changed.
-        mCapSetListener.onSet();
+
+        // Disabled RCS capabilities
+        pairs = request.getCapabilitiesToDisable();
+        for (CapabilityChangeRequest.CapabilityPair pair : pairs) {
+            if (pair.getRadioTech() == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
+                mRcsCapabilitiesLte.removeCapabilities(pair.getCapability());
+            } else if (pair.getRadioTech() == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
+                mRcsCapabilitiesIWan.removeCapabilities(pair.getCapability());
+            }
+        }
+        mRcsCapabilityChangedListener.onSet();
     }
 
     @Override
     public boolean queryCapabilityConfiguration(int capability, int radioTech) {
-        List<CapabilityPair> pairList =  mCapabilityChangeRequest.getCapabilitiesToEnable();
-        if (pairList == null) return false;
-        Optional<CapabilityPair> queryResult = pairList.stream().filter(pair -> {
-            return (pair.getCapability() == capability) && (pair.getRadioTech() == radioTech);
-        }).findAny();
-        return queryResult.isPresent();
+        if (ImsUtils.VDBG) {
+            Log.d(TAG, "TestRcsFeature.queryCapabilityConfiguration capability: " + capability);
+        }
+        if (radioTech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
+            return mRcsCapabilitiesLte.isCapable(capability);
+        } else if (radioTech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
+            return mRcsCapabilitiesIWan.isCapable(capability);
+        }
+        return false;
     }
 }