CTS for Emergency Registration State feature

Bug: 312101946
Test: atest CtsTelephonyTestCases
Change-Id: Ic805f809cea16c5445aabf3fce00d094dd990b5b
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsRegistrationAttributesTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsRegistrationAttributesTest.java
index 8710ea1..e1a5101 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsRegistrationAttributesTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsRegistrationAttributesTest.java
@@ -21,6 +21,9 @@
 import static org.junit.Assert.assertNull;
 
 import android.os.Parcel;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.SipDetails;
@@ -29,12 +32,19 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.internal.telephony.flags.Flags;
+
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
 public class ImsRegistrationAttributesTest {
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Test
     public void testRegistrationTypeToTransportAttr() {
         int cseq = 1;
@@ -121,6 +131,52 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_EMERGENCY_REGISTRATION_STATE)
+    public void testRegistrationTypeToTransportAttrForEmergency() {
+        // emergency call with emergency registration
+        ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE)
+                .setFlagRegistrationTypeEmergency()
+                .build();
+        assertEquals(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                attr.getRegistrationTechnology());
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                attr.getTransportType());
+        assertEquals(0, (attr.getAttributeFlags()
+                & ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET));
+        assertEquals(ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY,
+                (attr.getAttributeFlags()
+                        & ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY));
+        assertEquals(0, (attr.getAttributeFlags()
+                & ImsRegistrationAttributes.ATTR_VIRTUAL_FOR_ANONYMOUS_EMERGENCY_CALL));
+        assertNotNull(attr.getFeatureTags());
+        assertEquals(0, attr.getFeatureTags().size());
+        assertNull(attr.getSipDetails());
+
+        // emergency call without emergency registration
+        attr = new ImsRegistrationAttributes.Builder(
+            ImsRegistrationImplBase.REGISTRATION_TECH_LTE)
+            .setFlagRegistrationTypeEmergency()
+            .setFlagVirtualRegistrationForEmergencyCall()
+            .build();
+        assertEquals(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                attr.getRegistrationTechnology());
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                attr.getTransportType());
+        assertEquals(0, (attr.getAttributeFlags()
+                & ImsRegistrationAttributes.ATTR_EPDG_OVER_CELL_INTERNET));
+        assertEquals(ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY,
+                (attr.getAttributeFlags()
+                        & ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY));
+        assertEquals(ImsRegistrationAttributes.ATTR_VIRTUAL_FOR_ANONYMOUS_EMERGENCY_CALL,
+                (attr.getAttributeFlags()
+                        & ImsRegistrationAttributes.ATTR_VIRTUAL_FOR_ANONYMOUS_EMERGENCY_CALL));
+        assertNotNull(attr.getFeatureTags());
+        assertEquals(0, attr.getFeatureTags().size());
+        assertNull(attr.getSipDetails());
+    }
+
+    @Test
     public void testParcelUnparcel() {
         ArraySet<String> featureTags = new ArraySet<>();
         featureTags.add("+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.msg\"");
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 57083a5..d2aa3cd 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
@@ -1212,6 +1212,129 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_EMERGENCY_REGISTRATION_STATE)
+    public void testMmTelManagerEmergencyRegistrationCallback() throws Exception {
+        if (!ImsUtils.shouldTestImsService()) {
+            return;
+        }
+
+        final ArraySet<String> featureTags = new ArraySet<>();
+        featureTags.add("featureTag1");
+        featureTags.add("featureTag2");
+
+        triggerFrameworkConnectToCarrierImsService();
+
+        // Start deregistered for emergency registration
+        sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(
+            new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED,
+                ImsReasonInfo.CODE_UNSPECIFIED, ""), SUGGESTED_ACTION_NONE,
+            new ImsRegistrationAttributes.Builder(IMS_REGI_TECH_LTE)
+                .setFlagRegistrationTypeEmergency().build());
+
+        LinkedBlockingQueue<ImsRegistrationAttributes> mEmerRegQueue =
+                new LinkedBlockingQueue<>();
+
+        LinkedBlockingQueue<Integer> mEmerDeregQueue =
+                new LinkedBlockingQueue<>();
+
+        RegistrationManager.RegistrationCallback emerRegCallback =
+                new RegistrationManager.RegistrationCallback() {
+                    @Override
+                    public void onRegistered(ImsRegistrationAttributes attributes) {
+                        mEmerRegQueue.offer(attributes);
+                    }
+
+                    @Override
+                    public void onRegistering(ImsRegistrationAttributes attributes) {
+                        mEmerRegQueue.offer(attributes);
+                    }
+
+                    @Override
+                    public void onUnregistered(ImsReasonInfo info, int suggestedAction,
+                            int imsRadioTech) {
+                        mEmerDeregQueue.offer(info.getCode());
+                    }
+                    @Override
+                    public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
+                        mEmerDeregQueue.offer(imsTransportType);
+                        mEmerDeregQueue.offer(info.getCode());
+                    }
+                };
+
+        ImsManager imsManager = getContext().getSystemService(ImsManager.class);
+        ImsMmTelManager mmTelManager = imsManager.getImsMmTelManager(sTestSub);
+        try {
+            // First try without the correct permissions.
+            mmTelManager.registerImsEmergencyRegistrationCallback(getContext().getMainExecutor(),
+                    emerRegCallback);
+            fail("registerImsEmergencyRegistrationCallback requires READ_PRECISE_PHONE_STATE "
+                    + "permission.");
+        } catch (SecurityException e) {
+            //expected
+        }
+
+        // Latch will count down here (we callback on the state during registration).
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+                mmTelManager, (mm) -> {
+                        try {
+                            mm.registerImsEmergencyRegistrationCallback(
+                                    getContext().getMainExecutor(), emerRegCallback);
+                        } catch (ImsException e) {
+                            fail("registerImsEmergencyRegistrationCallback failed " + e);
+                        }
+                });
+
+        assertEquals(ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED, waitForIntResult(mEmerDeregQueue));
+
+        // Start registration for emergency registration
+        verifyEmergencyRegistering(IMS_REGI_TECH_LTE, featureTags, mEmerRegQueue,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
+
+        // Complete registration for emergency registration
+        verifyEmergencyRegistered(IMS_REGI_TECH_LTE, featureTags, mEmerRegQueue,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
+
+        // fail handover to IWLAN for emergency registration
+        sServiceConnector.getCarrierService().getImsRegistration().onTechnologyChangeFailed(
+            new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE,
+                ImsReasonInfo.CODE_UNSPECIFIED, ""), new ImsRegistrationAttributes.Builder(
+                IMS_REGI_TECH_IWLAN).setFlagRegistrationTypeEmergency().build());
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, waitForIntResult(mEmerDeregQueue));
+        assertEquals(ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE, waitForIntResult(mEmerDeregQueue));
+
+        // handover to NR successfully for emergency registration
+        verifyEmergencyRegistering(IMS_REGI_TECH_NR, featureTags, mEmerRegQueue,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
+
+        verifyEmergencyRegistered(IMS_REGI_TECH_NR, featureTags, mEmerRegQueue,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY);
+
+        // Deregister registration for emergency registration with null reason info
+        sServiceConnector.getCarrierService().getImsRegistration().onDeregistered(null,
+                SUGGESTED_ACTION_NONE, new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE).setFlagRegistrationTypeEmergency()
+                .build());
+        assertEquals(ImsReasonInfo.CODE_UNSPECIFIED, waitForIntResult(mEmerDeregQueue));
+
+        ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(
+                mmTelManager, (mm) -> {
+                    mm.unregisterImsEmergencyRegistrationCallback(emerRegCallback);
+                });
+
+        try {
+            mmTelManager.unregisterImsEmergencyRegistrationCallback(emerRegCallback);
+            fail("unregisterImsEmergencyRegistrationCallback requires READ_PRECISE_PHONE_STATE "
+                    + "permission.");
+        } catch (SecurityException e) {
+            //expected
+        }
+    }
+
+    @Test
     public void testMmTelManagerRegistrationCallback() throws Exception {
         if (!ImsUtils.shouldTestImsService()) {
             return;
@@ -6018,6 +6141,33 @@
         assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
         assertEquals(featureTags, attrResult.getFeatureTags());
     }
+    private void verifyEmergencyRegistering(int tech, ArraySet<String> featureTags,
+            LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
+            int expectedAttrFlags) throws Exception {
+        ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
+                    .setFeatureTags(featureTags).setFlagRegistrationTypeEmergency().build();
+        sServiceConnector.getCarrierService().getImsRegistration().onRegistering(attr);
+        ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
+        assertNotNull(attrResult);
+        assertEquals(tech, attrResult.getRegistrationTechnology());
+        assertEquals(expectedTransport, attrResult.getTransportType());
+        assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
+        assertEquals(featureTags, attrResult.getFeatureTags());
+    }
+
+    private void verifyEmergencyRegistered(int tech, ArraySet<String> featureTags,
+            LinkedBlockingQueue<ImsRegistrationAttributes> attrQueue, int expectedTransport,
+            int expectedAttrFlags) throws Exception {
+        ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(tech)
+                    .setFeatureTags(featureTags).setFlagRegistrationTypeEmergency().build();
+        sServiceConnector.getCarrierService().getImsRegistration().onRegistered(attr);
+        ImsRegistrationAttributes attrResult = waitForResult(attrQueue);
+        assertNotNull(attrResult);
+        assertEquals(tech, attrResult.getRegistrationTechnology());
+        assertEquals(expectedTransport, attrResult.getTransportType());
+        assertEquals(expectedAttrFlags, attrResult.getAttributeFlags());
+        assertEquals(featureTags, attrResult.getFeatureTags());
+    }
 
     private <T> boolean waitForParam(LinkedBlockingQueue<T> queue, T waitParam) throws Exception {
         T result;