N1_MODE_CAPABILITY Exclusion for Emergency Session am: 62a52056a5

Original change: https://android-review.googlesource.com/c/platform/packages/services/Iwlan/+/2935533

Change-Id: Id870a9ba5ed9245c8281ae6ab9819ebec7e0d59c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/com/google/android/iwlan/IwlanCarrierConfig.java b/src/com/google/android/iwlan/IwlanCarrierConfig.java
index 34ac4c2..bb3a20f 100644
--- a/src/com/google/android/iwlan/IwlanCarrierConfig.java
+++ b/src/com/google/android/iwlan/IwlanCarrierConfig.java
@@ -23,6 +23,7 @@
 
 /** Class for handling IWLAN carrier configuration. */
 public class IwlanCarrierConfig {
+    static final String PREFIX = "iwlan.";
 
     /**
      * Key for setting the delay in seconds to release the IWLAN connection after a handover to
@@ -30,7 +31,15 @@
      * value.
      */
     public static final String KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT =
-            "iwlan.handover_to_wwan_release_delay_second_int";
+            PREFIX + "handover_to_wwan_release_delay_second_int";
+
+    /**
+     * Key to exclude IKE N1_MODE_CAPABILITY Notify payload during emergency session setup without
+     * affecting normal sessions. See {@link #DEFAULT_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL}
+     * for the default value.
+     */
+    public static final String KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL =
+            PREFIX + "n1_mode_exclusion_for_emergency_session";
 
     /**
      * Default delay in seconds for releasing the IWLAN connection after a WWAN handover. This is
@@ -38,6 +47,12 @@
      */
     public static final int DEFAULT_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT = 0;
 
+    /**
+     * The default value for determining whether the IKE N1_MODE_CAPABILITY Notify payload is
+     * excluded during emergency session setup.
+     */
+    public static final boolean DEFAULT_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL = false;
+
     private static PersistableBundle mHiddenBundle = new PersistableBundle();
 
     static {
@@ -54,6 +69,9 @@
         bundle.putInt(
                 KEY_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT,
                 DEFAULT_HANDOVER_TO_WWAN_RELEASE_DELAY_SECOND_INT);
+        bundle.putBoolean(
+                KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL,
+                DEFAULT_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL);
         return bundle;
     }
 
diff --git a/src/com/google/android/iwlan/IwlanDataService.java b/src/com/google/android/iwlan/IwlanDataService.java
index cd43ece..2bf967a 100644
--- a/src/com/google/android/iwlan/IwlanDataService.java
+++ b/src/com/google/android/iwlan/IwlanDataService.java
@@ -1653,22 +1653,40 @@
                         return;
                     }
 
+                    int apnTypeBitmask = dataProfile.getApnSetting().getApnTypeBitmask();
+                    boolean isIms = hasApnTypes(apnTypeBitmask, ApnSetting.TYPE_IMS);
+                    boolean isEmergency = hasApnTypes(apnTypeBitmask, ApnSetting.TYPE_EMERGENCY);
+
                     boolean isDataCallSetupWithN1 =
                             iwlanDataServiceProvider.needIncludeN1ModeCapability();
 
+                    // Override N1_MODE_CAPABILITY exclusion only for Emergency PDN due to carrier
+                    // network limitations
+                    if (IwlanCarrierConfig.getConfigBoolean(
+                                    mContext,
+                                    slotId,
+                                    IwlanCarrierConfig
+                                            .KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL)
+                            && isEmergency) {
+                        isDataCallSetupWithN1 = false;
+                    }
+
                     TunnelSetupRequest.Builder tunnelReqBuilder =
                             TunnelSetupRequest.builder()
                                     .setApnName(dataProfile.getApnSetting().getApnName())
                                     .setIsRoaming(isRoaming)
                                     .setPduSessionId(
                                             isDataCallSetupWithN1
-                                                    ? pduSessionId : PDU_SESSION_ID_UNSET)
+                                                    ? pduSessionId
+                                                    : PDU_SESSION_ID_UNSET)
                                     .setApnIpProtocol(
                                             isRoaming
                                                     ? dataProfile
                                                             .getApnSetting()
                                                             .getRoamingProtocol()
-                                                    : dataProfile.getApnSetting().getProtocol());
+                                                    : dataProfile.getApnSetting().getProtocol())
+                                    .setRequestPcscf(isIms || isEmergency)
+                                    .setIsEmergency(isEmergency);
 
                     if (reason == DataService.REQUEST_REASON_HANDOVER) {
                         // for now assume that, at max,  only one address of eachtype (v4/v6).
@@ -1684,12 +1702,6 @@
                         }
                     }
 
-                    int apnTypeBitmask = dataProfile.getApnSetting().getApnTypeBitmask();
-                    boolean isIMS = hasApnTypes(apnTypeBitmask, ApnSetting.TYPE_IMS);
-                    boolean isEmergency = hasApnTypes(apnTypeBitmask, ApnSetting.TYPE_EMERGENCY);
-                    tunnelReqBuilder.setRequestPcscf(isIMS || isEmergency);
-                    tunnelReqBuilder.setIsEmergency(isEmergency);
-
                     iwlanDataServiceProvider.setTunnelState(
                             dataProfile,
                             callback,
@@ -1697,7 +1709,7 @@
                             null,
                             (reason == DataService.REQUEST_REASON_HANDOVER),
                             pduSessionId,
-                            isIMS || isEmergency,
+                            isIms || isEmergency,
                             isDataCallSetupWithN1);
 
                     boolean result =
diff --git a/test/com/google/android/iwlan/IwlanDataServiceTest.java b/test/com/google/android/iwlan/IwlanDataServiceTest.java
index dc2b2cf..f5914d9 100644
--- a/test/com/google/android/iwlan/IwlanDataServiceTest.java
+++ b/test/com/google/android/iwlan/IwlanDataServiceTest.java
@@ -2294,6 +2294,11 @@
 
     private void mockSetupDataCallWithPduSessionId(int pduSessionId) {
         DataProfile dp = buildImsDataProfile();
+
+        verifySetupDataCallRequestHandled(pduSessionId, dp);
+    }
+
+    private void verifySetupDataCallRequestHandled(int pduSessionId, DataProfile dp) {
         onSystemDefaultNetworkConnected(
                 mMockNetwork, mLinkProperties, TRANSPORT_WIFI, INVALID_SUB_INDEX);
         mSpyIwlanDataServiceProvider.setupDataCall(
@@ -2316,4 +2321,36 @@
                         any(IwlanTunnelCallback.class),
                         any(IwlanTunnelMetricsImpl.class));
     }
+
+    @Test
+    public void testN1ModeForEmergencySession() {
+        int pduSessionId = 5;
+        DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
+        verifySetupDataCallRequestHandled(pduSessionId, dp);
+
+        ArgumentCaptor<TunnelSetupRequest> tunnelSetupRequestCaptor =
+                ArgumentCaptor.forClass(TunnelSetupRequest.class);
+        verify(mMockEpdgTunnelManager, times(1))
+                .bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
+        TunnelSetupRequest tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
+        assertEquals(pduSessionId, tunnelSetupRequest.getPduSessionId());
+    }
+
+    @Test
+    public void testN1ModeExclusionForEmergencySession() {
+        when(IwlanCarrierConfig.getConfigBoolean(
+                        mMockContext,
+                        DEFAULT_SLOT_INDEX,
+                        IwlanCarrierConfig.KEY_N1_MODE_EXCLUSION_FOR_EMERGENCY_SESSION_BOOL))
+                .thenReturn(true);
+        DataProfile dp = buildDataProfile(ApnSetting.TYPE_EMERGENCY);
+        verifySetupDataCallRequestHandled(5 /* pduSessionId */, dp);
+
+        ArgumentCaptor<TunnelSetupRequest> tunnelSetupRequestCaptor =
+                ArgumentCaptor.forClass(TunnelSetupRequest.class);
+        verify(mMockEpdgTunnelManager, times(1))
+                .bringUpTunnel(tunnelSetupRequestCaptor.capture(), any(), any());
+        TunnelSetupRequest tunnelSetupRequest = tunnelSetupRequestCaptor.getValue();
+        assertEquals(PDU_SESSION_ID_UNSET, tunnelSetupRequest.getPduSessionId());
+    }
 }