Merge Android 14 QPR2 to AOSP main

Bug: 319669529
Merged-In: I2c966c41ab7e2f73bcfc4c8f82d9f13a8d57fc90
Change-Id: I00f069b0b3fdcf5bf32cd62e6ead7d032cbfb250
diff --git a/java/com/android/libraries/entitlement/CarrierConfig.java b/java/com/android/libraries/entitlement/CarrierConfig.java
index e75cddf..d0a63f8 100644
--- a/java/com/android/libraries/entitlement/CarrierConfig.java
+++ b/java/com/android/libraries/entitlement/CarrierConfig.java
@@ -46,6 +46,9 @@
      */
     public abstract String clientTs43();
 
+    /** Returns {@code true} if HTTP POST, instead of GET, should be used for TS.43 requests. */
+    public abstract boolean useHttpPost();
+
     /** Client side timeout for HTTP connection. See {@link Builder#setTimeoutInSec}. */
     public abstract int timeoutInSec();
 
@@ -58,6 +61,7 @@
         return new AutoValue_CarrierConfig.Builder()
                 .setServerUrl("")
                 .setClientTs43("")
+                .setUseHttpPost(false)
                 .setTimeoutInSec(DEFAULT_TIMEOUT_IN_SEC);
     }
 
@@ -75,6 +79,9 @@
         /** Sets the Client-ts43 attribute. Used to set the User-Agent header in HTTP requests. */
         public abstract Builder setClientTs43(String clientTs43);
 
+        /** Set to {@code true} to use HTTP POST instead of GET for TS.43 requests. */
+        public abstract Builder setUseHttpPost(boolean useHttpPost);
+
         /**
          * Sets the client side timeout for HTTP connection. Default to
          * {@link DEFAULT_TIMEOUT_IN_SEC}.
diff --git a/java/com/android/libraries/entitlement/ServiceEntitlementException.java b/java/com/android/libraries/entitlement/ServiceEntitlementException.java
index 9916c55..612e2e7 100644
--- a/java/com/android/libraries/entitlement/ServiceEntitlementException.java
+++ b/java/com/android/libraries/entitlement/ServiceEntitlementException.java
@@ -30,6 +30,11 @@
      */
     public static final int ERROR_UNKNOWN = 0;
 
+    /**
+     * Failure to compose JSON when making POST requests.
+     */
+    public static final int ERROR_JSON_COMPOSE_FAILURE = 1;
+
     // Android telephony related failures
     /**
      * Android telephony is unable to provide info like IMSI, e.g. when modem crashed.
diff --git a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
index 291384d..38206de 100644
--- a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
+++ b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
@@ -32,10 +32,9 @@
     public static final String ACCEPT_CONTENT_TYPE_XML = "text/vnd.wap.connectivity-xml";
     /** Accepts the content type in JSON format. */
     public static final String ACCEPT_CONTENT_TYPE_JSON =
-            "application/vnd.gsma.eap-relay.v1.0+json";
-    /** Accepts the content type in JSON or XML format. */
+            "application/json";
     public static final String ACCEPT_CONTENT_TYPE_JSON_AND_XML =
-            "application/vnd.gsma.eap-relay.v1.0+json, text/vnd.wap.connectivity-xml";
+            "application/json, text/vnd.wap.connectivity-xml";
     /** Default value of configuration version. */
     public static final int DEFAULT_CONFIGURATION_VERSION = 0;
 
diff --git a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
index 4590211..3029200 100644
--- a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
+++ b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
@@ -18,6 +18,7 @@
 
 import static com.android.libraries.entitlement.ServiceEntitlementException.ERROR_EAP_AKA_FAILURE;
 import static com.android.libraries.entitlement.ServiceEntitlementException.ERROR_EAP_AKA_SYNCHRONIZATION_FAILURE;
+import static com.android.libraries.entitlement.ServiceEntitlementException.ERROR_JSON_COMPOSE_FAILURE;
 import static com.android.libraries.entitlement.ServiceEntitlementException.ERROR_MALFORMED_HTTP_RESPONSE;
 
 import android.content.Context;
@@ -53,6 +54,8 @@
     private static final String TAG = "ServiceEntitlement";
 
     public static final String EAP_CHALLENGE_RESPONSE = "eap-relay-packet";
+    private static final String CONTENT_TYPE_EAP_RELAY_JSON =
+            "application/vnd.gsma.eap-relay.v1.0+json";
 
     private static final String VERS = "vers";
     private static final String ENTITLEMENT_VERSION = "entitlement_version";
@@ -115,6 +118,7 @@
     private final HttpClient mHttpClient;
     private final String mBypassEapAkaResponse;
     private final String mAppVersion;
+    private final TelephonyManager mTelephonyManager;
 
     public EapAkaApi(
             Context context,
@@ -135,6 +139,9 @@
         this.mHttpClient = httpClient;
         this.mBypassEapAkaResponse = bypassEapAkaResponse;
         this.mAppVersion = getAppVersion(context);
+        this.mTelephonyManager =
+                mContext.getSystemService(TelephonyManager.class)
+                        .createForSubscriptionId(mSimSubscriptionId);
     }
 
     /**
@@ -150,30 +157,55 @@
             CarrierConfig carrierConfig,
             ServiceEntitlementRequest request)
             throws ServiceEntitlementException {
-        Uri.Builder urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
-        appendParametersForAuthentication(urlBuilder, request);
-        appendParametersForServiceEntitlementRequest(urlBuilder, appIds, request);
+        Uri.Builder urlBuilder = null;
+        JSONObject postData = null;
+        if (carrierConfig.useHttpPost()) {
+            postData = new JSONObject();
+            appendParametersForAuthentication(postData, request);
+            appendParametersForServiceEntitlementRequest(postData, appIds, request);
+        } else {
+            urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
+            appendParametersForAuthentication(urlBuilder, request);
+            appendParametersForServiceEntitlementRequest(urlBuilder, appIds, request);
+        }
+
         if (!TextUtils.isEmpty(request.authenticationToken())) {
             // Fast Re-Authentication flow with pre-existing auth token
             Log.d(TAG, "Fast Re-Authentication");
-            return httpGet(
-                    urlBuilder.toString(),
-                    carrierConfig,
-                    request.acceptContentType(),
-                    request.terminalVendor(),
-                    request.terminalModel(),
-                    request.terminalSoftwareVersion());
+            return carrierConfig.useHttpPost()
+                    ? httpPost(
+                            postData,
+                            carrierConfig,
+                            request.acceptContentType(),
+                            request.terminalVendor(),
+                            request.terminalModel(),
+                            request.terminalSoftwareVersion())
+                    : httpGet(
+                            urlBuilder.toString(),
+                            carrierConfig,
+                            request.acceptContentType(),
+                            request.terminalVendor(),
+                            request.terminalModel(),
+                            request.terminalSoftwareVersion());
         } else {
             // Full Authentication flow
             Log.d(TAG, "Full Authentication");
             HttpResponse challengeResponse =
-                    httpGet(
-                            urlBuilder.toString(),
-                            carrierConfig,
-                            ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON,
-                            request.terminalVendor(),
-                            request.terminalModel(),
-                            request.terminalSoftwareVersion());
+                    carrierConfig.useHttpPost()
+                            ? httpPost(
+                                    postData,
+                                    carrierConfig,
+                                    CONTENT_TYPE_EAP_RELAY_JSON,
+                                    request.terminalVendor(),
+                                    request.terminalModel(),
+                                    request.terminalSoftwareVersion())
+                            : httpGet(
+                                    urlBuilder.toString(),
+                                    carrierConfig,
+                                    CONTENT_TYPE_EAP_RELAY_JSON,
+                                    request.terminalVendor(),
+                                    request.terminalModel(),
+                                    request.terminalSoftwareVersion());
             String eapAkaChallenge = getEapAkaChallenge(challengeResponse);
             if (eapAkaChallenge == null) {
                 throw new ServiceEntitlementException(
@@ -217,7 +249,7 @@
             String eapAkaChallenge,
             ImmutableList<String> cookies,
             int remainingAttempts,
-            String contentType,
+            String acceptContentType,
             String terminalVendor,
             String terminalModel,
             String terminalSoftwareVersion)
@@ -227,7 +259,7 @@
                     mBypassEapAkaResponse,
                     carrierConfig,
                     cookies,
-                    contentType,
+                    CONTENT_TYPE_EAP_RELAY_JSON + ", " + acceptContentType,
                     terminalVendor,
                     terminalModel,
                     terminalSoftwareVersion);
@@ -243,7 +275,7 @@
                             eapAkaResponse.response(),
                             carrierConfig,
                             cookies,
-                            contentType,
+                            CONTENT_TYPE_EAP_RELAY_JSON + ", " + acceptContentType,
                             terminalVendor,
                             terminalModel,
                             terminalSoftwareVersion);
@@ -260,7 +292,7 @@
                         nextEapAkaChallenge,
                         cookies,
                         remainingAttempts - 1,
-                        contentType,
+                        acceptContentType,
                         terminalVendor,
                         terminalModel,
                         terminalSoftwareVersion);
@@ -275,7 +307,7 @@
                             eapAkaResponse.synchronizationFailureResponse(),
                             carrierConfig,
                             cookies,
-                            ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON,
+                            CONTENT_TYPE_EAP_RELAY_JSON,
                             terminalVendor,
                             terminalModel,
                             terminalSoftwareVersion);
@@ -291,7 +323,7 @@
                         nextEapAkaChallenge,
                         cookies,
                         remainingAttempts - 1,
-                        contentType,
+                        acceptContentType,
                         terminalVendor,
                         terminalModel,
                         terminalSoftwareVersion);
@@ -310,12 +342,11 @@
             String eapAkaChallengeResponse,
             CarrierConfig carrierConfig,
             ImmutableList<String> cookies,
-            String contentType,
+            String acceptContentType,
             String terminalVendor,
             String terminalModel,
             String terminalSoftwareVersion)
             throws ServiceEntitlementException {
-        Log.d(TAG, "challengeResponse");
         JSONObject postData = new JSONObject();
         try {
             postData.put(EAP_CHALLENGE_RESPONSE, eapAkaChallengeResponse);
@@ -323,33 +354,20 @@
             throw new ServiceEntitlementException(
                     ERROR_MALFORMED_HTTP_RESPONSE, "Failed to put post data", jsonException);
         }
-        HttpRequest.Builder builder =
-                HttpRequest.builder()
-                        .setUrl(carrierConfig.serverUrl())
-                        .setRequestMethod(RequestMethod.POST)
-                        .setPostData(postData)
-                        .addRequestProperty(HttpHeaders.ACCEPT, contentType)
-                        .addRequestProperty(
-                                HttpHeaders.CONTENT_TYPE,
-                                ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON)
-                        .addRequestProperty(HttpHeaders.COOKIE, cookies)
-                        .setTimeoutInSec(carrierConfig.timeoutInSec())
-                        .setNetwork(carrierConfig.network());
-            String userAgent =
-                    getUserAgent(
-                            carrierConfig.clientTs43(),
-                            terminalVendor,
-                            terminalModel,
-                            terminalSoftwareVersion);
-        if (!TextUtils.isEmpty(userAgent)) {
-            builder.addRequestProperty(HttpHeaders.USER_AGENT, userAgent);
-        }
-        return mHttpClient.request(builder.build());
+        return httpPost(
+                postData,
+                carrierConfig,
+                acceptContentType,
+                terminalVendor,
+                terminalModel,
+                terminalSoftwareVersion,
+                CONTENT_TYPE_EAP_RELAY_JSON,
+                cookies);
     }
 
     /**
-     * Retrieves HTTP response from performing ODSA operations.
-     * For operation type, see {@link EsimOdsaOperation}.
+     * Retrieves HTTP response from performing ODSA operations. For operation type, see {@link
+     * EsimOdsaOperation}.
      *
      * <p>Implementation based on GSMA TS.43-v5.0 6.1.
      */
@@ -360,33 +378,60 @@
             ServiceEntitlementRequest request,
             EsimOdsaOperation odsaOperation)
             throws ServiceEntitlementException {
-        Uri.Builder urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
-        appendParametersForAuthentication(urlBuilder, request);
-        appendParametersForServiceEntitlementRequest(urlBuilder, ImmutableList.of(appId), request);
-        appendParametersForEsimOdsaOperation(urlBuilder, odsaOperation);
+        Uri.Builder urlBuilder = null;
+        JSONObject postData = null;
+        if (carrierConfig.useHttpPost()) {
+            postData = new JSONObject();
+            appendParametersForAuthentication(postData, request);
+            appendParametersForServiceEntitlementRequest(
+                    postData, ImmutableList.of(appId), request);
+            appendParametersForEsimOdsaOperation(postData, odsaOperation);
+        } else {
+            urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
+            appendParametersForAuthentication(urlBuilder, request);
+            appendParametersForServiceEntitlementRequest(
+                    urlBuilder, ImmutableList.of(appId), request);
+            appendParametersForEsimOdsaOperation(urlBuilder, odsaOperation);
+        }
 
         if (!TextUtils.isEmpty(request.authenticationToken())
                 || !TextUtils.isEmpty(request.temporaryToken())) {
             // Fast Re-Authentication flow with pre-existing auth token
             Log.d(TAG, "Fast Re-Authentication");
-            return httpGet(
-                    urlBuilder.toString(),
-                    carrierConfig,
-                    request.acceptContentType(),
-                    request.terminalVendor(),
-                    request.terminalModel(),
-                    request.terminalSoftwareVersion());
+            return carrierConfig.useHttpPost()
+                    ? httpPost(
+                            postData,
+                            carrierConfig,
+                            request.acceptContentType(),
+                            request.terminalVendor(),
+                            request.terminalModel(),
+                            request.terminalSoftwareVersion())
+                    : httpGet(
+                            urlBuilder.toString(),
+                            carrierConfig,
+                            request.acceptContentType(),
+                            request.terminalVendor(),
+                            request.terminalModel(),
+                            request.terminalSoftwareVersion());
         } else {
             // Full Authentication flow
             Log.d(TAG, "Full Authentication");
             HttpResponse challengeResponse =
-                    httpGet(
-                            urlBuilder.toString(),
-                            carrierConfig,
-                            ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON,
-                            request.terminalVendor(),
-                            request.terminalModel(),
-                            request.terminalSoftwareVersion());
+                    carrierConfig.useHttpPost()
+                            ? httpPost(
+                                    postData,
+                                    carrierConfig,
+                                    CONTENT_TYPE_EAP_RELAY_JSON,
+                                    request.terminalVendor(),
+                                    request.terminalModel(),
+                                    request.terminalSoftwareVersion())
+                            : httpGet(
+                                    urlBuilder.toString(),
+                                    carrierConfig,
+                                    CONTENT_TYPE_EAP_RELAY_JSON,
+                                    request.terminalVendor(),
+                                    request.terminalModel(),
+                                    request.terminalSoftwareVersion());
             String eapAkaChallenge = getEapAkaChallenge(challengeResponse);
             if (eapAkaChallenge == null) {
                 throw new ServiceEntitlementException(
@@ -417,16 +462,34 @@
     public String acquireOidcAuthenticationEndpoint(
             String appId, CarrierConfig carrierConfig, ServiceEntitlementRequest request)
             throws ServiceEntitlementException {
-        Uri.Builder urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
-        appendParametersForServiceEntitlementRequest(urlBuilder, ImmutableList.of(appId), request);
+        Uri.Builder urlBuilder = null;
+        JSONObject postData = null;
+        if (carrierConfig.useHttpPost()) {
+            postData = new JSONObject();
+            appendParametersForServiceEntitlementRequest(
+                    postData, ImmutableList.of(appId), request);
+        } else {
+            urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
+            appendParametersForServiceEntitlementRequest(
+                    urlBuilder, ImmutableList.of(appId), request);
+        }
+
         HttpResponse response =
-                httpGet(
-                        urlBuilder.toString(),
-                        carrierConfig,
-                        request.acceptContentType(),
-                        request.terminalVendor(),
-                        request.terminalModel(),
-                        request.terminalSoftwareVersion());
+                carrierConfig.useHttpPost()
+                        ? httpPost(
+                                postData,
+                                carrierConfig,
+                                request.acceptContentType(),
+                                request.terminalVendor(),
+                                request.terminalModel(),
+                                request.terminalSoftwareVersion())
+                        : httpGet(
+                                urlBuilder.toString(),
+                                carrierConfig,
+                                request.acceptContentType(),
+                                request.terminalVendor(),
+                                request.terminalModel(),
+                                request.terminalSoftwareVersion());
         return response.location();
     }
 
@@ -452,15 +515,13 @@
                 request.terminalSoftwareVersion());
     }
 
+    @SuppressWarnings("HardwareIds")
     private void appendParametersForAuthentication(
             Uri.Builder urlBuilder, ServiceEntitlementRequest request) {
-        TelephonyManager telephonyManager =
-                mContext.getSystemService(TelephonyManager.class)
-                        .createForSubscriptionId(mSimSubscriptionId);
         if (!TextUtils.isEmpty(request.authenticationToken())) {
             // IMSI and token required for fast AuthN.
             urlBuilder
-                    .appendQueryParameter(IMSI, telephonyManager.getSubscriberId())
+                    .appendQueryParameter(IMSI, mTelephonyManager.getSubscriberId())
                     .appendQueryParameter(TOKEN, request.authenticationToken());
         } else if (!TextUtils.isEmpty(request.temporaryToken())) {
             // temporary_token required for fast AuthN.
@@ -470,7 +531,35 @@
             urlBuilder.appendQueryParameter(
                     EAP_ID,
                     getImsiEap(
-                            telephonyManager.getSimOperator(), telephonyManager.getSubscriberId()));
+                            mTelephonyManager.getSimOperator(),
+                            mTelephonyManager.getSubscriberId()));
+        }
+    }
+
+    @SuppressWarnings("HardwareIds")
+    private void appendParametersForAuthentication(
+            JSONObject postData, ServiceEntitlementRequest request)
+            throws ServiceEntitlementException {
+        try {
+            if (!TextUtils.isEmpty(request.authenticationToken())) {
+                // IMSI and token required for fast AuthN.
+                postData.put(IMSI, mTelephonyManager.getSubscriberId());
+                postData.put(TOKEN, request.authenticationToken());
+            } else if (!TextUtils.isEmpty(request.temporaryToken())) {
+                // temporary_token required for fast AuthN.
+                postData.put(TEMPORARY_TOKEN, request.temporaryToken());
+            } else {
+                // EAP_ID required for initial AuthN
+                postData.put(
+                        EAP_ID,
+                        getImsiEap(
+                                mTelephonyManager.getSimOperator(),
+                                mTelephonyManager.getSubscriberId()));
+            }
+        } catch (JSONException jsonException) {
+            // Should never happen
+            throw new ServiceEntitlementException(
+                    ERROR_JSON_COMPOSE_FAILURE, "Failed to compose JSON", jsonException);
         }
     }
 
@@ -485,12 +574,9 @@
                     .appendQueryParameter(NOTIF_TOKEN, request.notificationToken());
         }
 
-        TelephonyManager telephonyManager =
-                mContext.getSystemService(TelephonyManager.class)
-                        .createForSubscriptionId(mSimSubscriptionId);
         // Assign terminal ID with device IMEI if not set.
         if (TextUtils.isEmpty(request.terminalId())) {
-            urlBuilder.appendQueryParameter(TERMINAL_ID, telephonyManager.getImei());
+            urlBuilder.appendQueryParameter(TERMINAL_ID, mTelephonyManager.getImei());
         } else {
             urlBuilder.appendQueryParameter(TERMINAL_ID, request.terminalId());
         }
@@ -522,12 +608,65 @@
                 .appendQueryParameter(ENTITLEMENT_VERSION, request.entitlementVersion());
     }
 
+    private void appendParametersForServiceEntitlementRequest(
+            JSONObject postData, ImmutableList<String> appIds, ServiceEntitlementRequest request)
+            throws ServiceEntitlementException {
+        try {
+            if (!TextUtils.isEmpty(request.notificationToken())) {
+                postData.put(NOTIF_ACTION, Integer.toString(request.notificationAction()));
+                postData.put(NOTIF_TOKEN, request.notificationToken());
+            }
+
+            // Assign terminal ID with device IMEI if not set.
+            if (TextUtils.isEmpty(request.terminalId())) {
+                postData.put(TERMINAL_ID, mTelephonyManager.getImei());
+            } else {
+                postData.put(TERMINAL_ID, request.terminalId());
+            }
+
+            // Optional query parameters, append them if not empty
+            appendOptionalQueryParameter(postData, APP_VERSION, request.appVersion());
+            appendOptionalQueryParameter(postData, APP_NAME, request.appName());
+            appendOptionalQueryParameter(postData, BOOST_TYPE, request.boostType());
+
+            if (appIds.size() == 1) {
+                appendOptionalQueryParameter(postData, APP, appIds.get(0));
+            } else {
+                appendOptionalQueryParameter(
+                        postData, APP, "[" + TextUtils.join(",", appIds) + "]");
+            }
+
+            appendOptionalQueryParameter(
+                    postData,
+                    TERMINAL_VENDOR,
+                    trimString(request.terminalVendor(), MAX_TERMINAL_VENDOR_LENGTH));
+            appendOptionalQueryParameter(
+                    postData,
+                    TERMINAL_MODEL,
+                    trimString(request.terminalModel(), MAX_TERMINAL_MODEL_LENGTH));
+            appendOptionalQueryParameter(
+                    postData,
+                    TERMIAL_SW_VERSION,
+                    trimString(
+                            request.terminalSoftwareVersion(),
+                            MAX_TERMINAL_SOFTWARE_VERSION_LENGTH));
+            appendOptionalQueryParameter(
+                    postData, VERS, Integer.toString(request.configurationVersion()));
+            appendOptionalQueryParameter(
+                    postData, ENTITLEMENT_VERSION, request.entitlementVersion());
+        } catch (JSONException jsonException) {
+            // Should never happen
+            throw new ServiceEntitlementException(
+                    ERROR_JSON_COMPOSE_FAILURE, "Failed to compose JSON", jsonException);
+        }
+    }
+
     private void appendParametersForEsimOdsaOperation(
             Uri.Builder urlBuilder, EsimOdsaOperation odsaOperation) {
         urlBuilder.appendQueryParameter(OPERATION, odsaOperation.operation());
         if (odsaOperation.operationType() != EsimOdsaOperation.OPERATION_TYPE_NOT_SET) {
-            urlBuilder.appendQueryParameter(OPERATION_TYPE,
-                    Integer.toString(odsaOperation.operationType()));
+            urlBuilder.appendQueryParameter(
+                    OPERATION_TYPE, Integer.toString(odsaOperation.operationType()));
         }
         appendOptionalQueryParameter(
                 urlBuilder,
@@ -574,11 +713,100 @@
         appendOptionalQueryParameter(urlBuilder, OLD_TERMINAL_ID, odsaOperation.oldTerminalId());
     }
 
+    private void appendParametersForEsimOdsaOperation(
+            JSONObject postData, EsimOdsaOperation odsaOperation)
+            throws ServiceEntitlementException {
+        try {
+            postData.put(OPERATION, odsaOperation.operation());
+            if (odsaOperation.operationType() != EsimOdsaOperation.OPERATION_TYPE_NOT_SET) {
+                postData.put(OPERATION_TYPE, Integer.toString(odsaOperation.operationType()));
+            }
+            appendOptionalQueryParameter(
+                    postData,
+                    OPERATION_TARGETS,
+                    TextUtils.join(",", odsaOperation.operationTargets()));
+            appendOptionalQueryParameter(
+                    postData, COMPANION_TERMINAL_ID, odsaOperation.companionTerminalId());
+            appendOptionalQueryParameter(
+                    postData, COMPANION_TERMINAL_VENDOR, odsaOperation.companionTerminalVendor());
+            appendOptionalQueryParameter(
+                    postData, COMPANION_TERMINAL_MODEL, odsaOperation.companionTerminalModel());
+            appendOptionalQueryParameter(
+                    postData,
+                    COMPANION_TERMINAL_SW_VERSION,
+                    odsaOperation.companionTerminalSoftwareVersion());
+            appendOptionalQueryParameter(
+                    postData,
+                    COMPANION_TERMINAL_FRIENDLY_NAME,
+                    odsaOperation.companionTerminalFriendlyName());
+            appendOptionalQueryParameter(
+                    postData, COMPANION_TERMINAL_SERVICE, odsaOperation.companionTerminalService());
+            appendOptionalQueryParameter(
+                    postData, COMPANION_TERMINAL_ICCID, odsaOperation.companionTerminalIccid());
+            appendOptionalQueryParameter(
+                    postData, COMPANION_TERMINAL_EID, odsaOperation.companionTerminalEid());
+            appendOptionalQueryParameter(postData, TERMINAL_ICCID, odsaOperation.terminalIccid());
+            appendOptionalQueryParameter(postData, TERMINAL_EID, odsaOperation.terminalEid());
+            appendOptionalQueryParameter(
+                    postData, TARGET_TERMINAL_ID, odsaOperation.targetTerminalId());
+            appendOptionalQueryParameter(
+                    postData, TARGET_TERMINAL_IDS, odsaOperation.targetTerminalIds());
+            appendOptionalQueryParameter(
+                    postData, TARGET_TERMINAL_ICCID, odsaOperation.targetTerminalIccid());
+            appendOptionalQueryParameter(
+                    postData, TARGET_TERMINAL_EID, odsaOperation.targetTerminalEid());
+            appendOptionalQueryParameter(
+                    postData,
+                    TARGET_TERMINAL_SERIAL_NUMBER,
+                    odsaOperation.targetTerminalSerialNumber());
+            appendOptionalQueryParameter(
+                    postData, TARGET_TERMINAL_MODEL, odsaOperation.targetTerminalModel());
+            appendOptionalQueryParameter(
+                    postData, OLD_TERMINAL_ICCID, odsaOperation.oldTerminalIccid());
+            appendOptionalQueryParameter(postData, OLD_TERMINAL_ID, odsaOperation.oldTerminalId());
+        } catch (JSONException jsonException) {
+            // Should never happen
+            throw new ServiceEntitlementException(
+                    ERROR_JSON_COMPOSE_FAILURE, "Failed to compose JSON", jsonException);
+        }
+    }
+
+    private void appendOptionalQueryParameter(Uri.Builder urlBuilder, String key, String value) {
+        if (!TextUtils.isEmpty(value)) {
+            urlBuilder.appendQueryParameter(key, value);
+        }
+    }
+
+    private void appendOptionalQueryParameter(JSONObject postData, String key, String value)
+            throws JSONException {
+        if (!TextUtils.isEmpty(value)) {
+            postData.put(key, value);
+        }
+    }
+
+    private void appendOptionalQueryParameter(
+            Uri.Builder urlBuilder, String key, ImmutableList<String> values) {
+        for (String value : values) {
+            if (!TextUtils.isEmpty(value)) {
+                urlBuilder.appendQueryParameter(key, value);
+            }
+        }
+    }
+
+    private void appendOptionalQueryParameter(
+            JSONObject postData, String key, ImmutableList<String> values) throws JSONException {
+        for (String value : values) {
+            if (!TextUtils.isEmpty(value)) {
+                postData.put(key, value);
+            }
+        }
+    }
+
     @NonNull
     private HttpResponse httpGet(
             String url,
             CarrierConfig carrierConfig,
-            String contentType,
+            String acceptContentType,
             String terminalVendor,
             String terminalModel,
             String terminalSoftwareVersion)
@@ -587,7 +815,7 @@
                 HttpRequest.builder()
                         .setUrl(url)
                         .setRequestMethod(RequestMethod.GET)
-                        .addRequestProperty(HttpHeaders.ACCEPT, contentType)
+                        .addRequestProperty(HttpHeaders.ACCEPT, acceptContentType)
                         .setTimeoutInSec(carrierConfig.timeoutInSec())
                         .setNetwork(carrierConfig.network());
         String userAgent =
@@ -602,21 +830,57 @@
         return mHttpClient.request(builder.build());
     }
 
-    private void appendOptionalQueryParameter(Uri.Builder urlBuilder, String key, String value) {
-        if (!TextUtils.isEmpty(value)) {
-            urlBuilder.appendQueryParameter(key, value);
-        }
+    @NonNull
+    private HttpResponse httpPost(
+            JSONObject postData,
+            CarrierConfig carrierConfig,
+            String acceptContentType,
+            String terminalVendor,
+            String terminalModel,
+            String terminalSoftwareVersion)
+            throws ServiceEntitlementException {
+        return httpPost(
+                postData,
+                carrierConfig,
+                acceptContentType,
+                terminalVendor,
+                terminalModel,
+                terminalSoftwareVersion,
+                ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON,
+                ImmutableList.of());
     }
 
-    private void appendOptionalQueryParameter(
-            Uri.Builder urlBuilder, String key, ImmutableList<String> values) {
-        if (values != null) {
-            for (String value : values) {
-                if (!TextUtils.isEmpty(value)) {
-                    urlBuilder.appendQueryParameter(key, value);
-                }
-            }
+    @NonNull
+    private HttpResponse httpPost(
+            JSONObject postData,
+            CarrierConfig carrierConfig,
+            String acceptContentType,
+            String terminalVendor,
+            String terminalModel,
+            String terminalSoftwareVersion,
+            String contentType,
+            ImmutableList<String> cookies)
+            throws ServiceEntitlementException {
+        HttpRequest.Builder builder =
+                HttpRequest.builder()
+                        .setUrl(carrierConfig.serverUrl())
+                        .setRequestMethod(RequestMethod.POST)
+                        .setPostData(postData)
+                        .addRequestProperty(HttpHeaders.ACCEPT, acceptContentType)
+                        .addRequestProperty(HttpHeaders.CONTENT_TYPE, contentType)
+                        .addRequestProperty(HttpHeaders.COOKIE, cookies)
+                        .setTimeoutInSec(carrierConfig.timeoutInSec())
+                        .setNetwork(carrierConfig.network());
+        String userAgent =
+                getUserAgent(
+                        carrierConfig.clientTs43(),
+                        terminalVendor,
+                        terminalModel,
+                        terminalSoftwareVersion);
+        if (!TextUtils.isEmpty(userAgent)) {
+            builder.addRequestProperty(HttpHeaders.USER_AGENT, userAgent);
         }
+        return mHttpClient.request(builder.build());
     }
 
     @Nullable
@@ -634,7 +898,7 @@
                         jsonException);
             }
         } else if (response.contentType() == ContentType.XML) {
-            // TODO: possibly support parsing eap-relay-packet in XML format
+            // EAP-AKA challenge is always in JSON format.
             return null;
         } else {
             throw new ServiceEntitlementException(
diff --git a/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java b/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java
index 4fc2e30..25812a9 100644
--- a/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java
+++ b/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java
@@ -71,6 +71,11 @@
         mCarrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         mServiceEntitlement = new ServiceEntitlement(mCarrierConfig, mMockEapAkaApi);
         mContext = spy(ApplicationProvider.getApplicationContext());
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mMockTelephonyManager);
+        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
+                .thenReturn(mMockTelephonyManagerForSubId);
+        when(mMockTelephonyManagerForSubId.getSubscriberId()).thenReturn(IMSI);
+        when(mMockTelephonyManagerForSubId.getSimOperator()).thenReturn(MCCMNC);
     }
 
     @Test
@@ -78,20 +83,16 @@
         CarrierConfig config = CarrierConfig.builder().build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         ServiceEntitlement serviceEntitlement = new ServiceEntitlement(mContext, config, SUB_ID);
-        when(mContext.getSystemService(TelephonyManager.class))
-                .thenReturn(mMockTelephonyManager);
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManagerForSubId);
-        when(mMockTelephonyManagerForSubId.getSubscriberId()).thenReturn(IMSI);
-        when(mMockTelephonyManagerForSubId.getSimOperator()).thenReturn(MCCMNC);
 
-        ServiceEntitlementException exception = expectThrows(
-                ServiceEntitlementException.class,
-                () -> serviceEntitlement.queryEntitlementStatus(
-                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI), request));
+        ServiceEntitlementException exception =
+                expectThrows(
+                        ServiceEntitlementException.class,
+                        () ->
+                                serviceEntitlement.queryEntitlementStatus(
+                                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI), request));
 
-        assertThat(exception.getErrorCode()).isEqualTo(
-                ServiceEntitlementException.ERROR_SERVER_NOT_CONNECTABLE);
+        assertThat(exception.getErrorCode())
+                .isEqualTo(ServiceEntitlementException.ERROR_SERVER_NOT_CONNECTABLE);
         assertThat(exception.getMessage()).isEqualTo("Configure connection failed!");
         assertThat(exception.getHttpStatus()).isEqualTo(0);
         assertThat(exception.getRetryAfter()).isEmpty();
@@ -101,14 +102,16 @@
     public void queryEntitlementStatus_appVolte_returnResult() throws Exception {
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         when(mMockEapAkaApi.queryEntitlementStatus(
-                ImmutableList.of(ServiceEntitlement.APP_VOLTE), mCarrierConfig, request))
-                .thenAnswer(invocation -> {
-                    when(mMockHttpResponse.body()).thenReturn(QUERY_APP_VOLTE_RESULT);
-                    return mMockHttpResponse;
-                });
+                        ImmutableList.of(ServiceEntitlement.APP_VOLTE), mCarrierConfig, request))
+                .thenAnswer(
+                        invocation -> {
+                            when(mMockHttpResponse.body()).thenReturn(QUERY_APP_VOLTE_RESULT);
+                            return mMockHttpResponse;
+                        });
 
         assertThat(
-                mServiceEntitlement.queryEntitlementStatus(ServiceEntitlement.APP_VOLTE, request))
+                        mServiceEntitlement.queryEntitlementStatus(
+                                ServiceEntitlement.APP_VOLTE, request))
                 .isEqualTo(QUERY_APP_VOLTE_RESULT);
     }
 
@@ -116,16 +119,16 @@
     public void queryEntitlementStatus_appVowifi_returnResult() throws Exception {
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         when(mMockEapAkaApi.queryEntitlementStatus(
-                ImmutableList.of(ServiceEntitlement.APP_VOWIFI), mCarrierConfig, request))
-                .thenAnswer(invocation -> {
-                    when(mMockHttpResponse.body()).thenReturn(QUERY_APP_VOWIFI_RESULT);
-                    return mMockHttpResponse;
-                });
+                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI), mCarrierConfig, request))
+                .thenAnswer(
+                        invocation -> {
+                            when(mMockHttpResponse.body()).thenReturn(QUERY_APP_VOWIFI_RESULT);
+                            return mMockHttpResponse;
+                        });
 
         assertThat(
-                mServiceEntitlement.queryEntitlementStatus(
-                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI),
-                        request))
+                        mServiceEntitlement.queryEntitlementStatus(
+                                ImmutableList.of(ServiceEntitlement.APP_VOWIFI), request))
                 .isEqualTo(QUERY_APP_VOWIFI_RESULT);
     }
 
@@ -134,15 +137,20 @@
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         EsimOdsaOperation odsaOperation = EsimOdsaOperation.builder().build();
         when(mMockEapAkaApi.performEsimOdsaOperation(
-                ServiceEntitlement.APP_ODSA_COMPANION, mCarrierConfig, request, odsaOperation))
-                .thenAnswer(invocation -> {
-                    when(mMockHttpResponse.body()).thenReturn(QUERY_APP_ODSA_COMPANION_RESULT);
-                    return mMockHttpResponse;
-                });
+                        ServiceEntitlement.APP_ODSA_COMPANION,
+                        mCarrierConfig,
+                        request,
+                        odsaOperation))
+                .thenAnswer(
+                        invocation -> {
+                            when(mMockHttpResponse.body())
+                                    .thenReturn(QUERY_APP_ODSA_COMPANION_RESULT);
+                            return mMockHttpResponse;
+                        });
 
         assertThat(
-                mServiceEntitlement.performEsimOdsa(
-                        ServiceEntitlement.APP_ODSA_COMPANION, request, odsaOperation))
+                        mServiceEntitlement.performEsimOdsa(
+                                ServiceEntitlement.APP_ODSA_COMPANION, request, odsaOperation))
                 .isEqualTo(QUERY_APP_ODSA_COMPANION_RESULT);
     }
 
@@ -151,15 +159,20 @@
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         EsimOdsaOperation odsaOperation = EsimOdsaOperation.builder().build();
         when(mMockEapAkaApi.performEsimOdsaOperation(
-                ServiceEntitlement.APP_ODSA_PRIMARY, mCarrierConfig, request, odsaOperation))
-                .thenAnswer(invocation -> {
-                    when(mMockHttpResponse.body()).thenReturn(QUERY_APP_ODSA_PRIMARY_RESULT);
-                    return mMockHttpResponse;
-                });
+                        ServiceEntitlement.APP_ODSA_PRIMARY,
+                        mCarrierConfig,
+                        request,
+                        odsaOperation))
+                .thenAnswer(
+                        invocation -> {
+                            when(mMockHttpResponse.body())
+                                    .thenReturn(QUERY_APP_ODSA_PRIMARY_RESULT);
+                            return mMockHttpResponse;
+                        });
 
         assertThat(
-                mServiceEntitlement.performEsimOdsa(
-                        ServiceEntitlement.APP_ODSA_PRIMARY, request, odsaOperation))
+                        mServiceEntitlement.performEsimOdsa(
+                                ServiceEntitlement.APP_ODSA_PRIMARY, request, odsaOperation))
                 .isEqualTo(QUERY_APP_ODSA_PRIMARY_RESULT);
     }
 
@@ -167,27 +180,29 @@
     public void acquireOidcAuthenticationEndpoint_returnResult() throws Exception {
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         when(mMockEapAkaApi.acquireOidcAuthenticationEndpoint(
-                ServiceEntitlement.APP_ODSA_COMPANION, mCarrierConfig, request))
+                        ServiceEntitlement.APP_ODSA_COMPANION, mCarrierConfig, request))
                 .thenReturn(QUERY_OIDC_RESULT);
 
         assertThat(
-                mServiceEntitlement.acquireOidcAuthenticationEndpoint(
-                        ServiceEntitlement.APP_ODSA_COMPANION, request))
+                        mServiceEntitlement.acquireOidcAuthenticationEndpoint(
+                                ServiceEntitlement.APP_ODSA_COMPANION, request))
                 .isEqualTo(QUERY_OIDC_RESULT);
     }
 
     @Test
     public void queryEntitlementStatusFromOidc_returnResult() throws Exception {
         when(mMockEapAkaApi.queryEntitlementStatusFromOidc(
-                ServiceEntitlement.APP_ODSA_PRIMARY, mCarrierConfig, null))
-                .thenAnswer(invocation -> {
-                    when(mMockHttpResponse.body()).thenReturn(QUERY_ENTITLEMENT_STATUS_FROM_OIDC);
-                    return mMockHttpResponse;
-                });
+                        ServiceEntitlement.APP_ODSA_PRIMARY, mCarrierConfig, null))
+                .thenAnswer(
+                        invocation -> {
+                            when(mMockHttpResponse.body())
+                                    .thenReturn(QUERY_ENTITLEMENT_STATUS_FROM_OIDC);
+                            return mMockHttpResponse;
+                        });
 
         assertThat(
-                mServiceEntitlement.queryEntitlementStatusFromOidc(
-                        ServiceEntitlement.APP_ODSA_PRIMARY))
+                        mServiceEntitlement.queryEntitlementStatusFromOidc(
+                                ServiceEntitlement.APP_ODSA_PRIMARY))
                 .isEqualTo(QUERY_ENTITLEMENT_STATUS_FROM_OIDC);
     }
 }
diff --git a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
index 6dafef3..8a4a185 100644
--- a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
+++ b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
@@ -48,6 +48,7 @@
 import com.android.libraries.entitlement.ServiceEntitlementRequest;
 import com.android.libraries.entitlement.http.HttpClient;
 import com.android.libraries.entitlement.http.HttpConstants.ContentType;
+import com.android.libraries.entitlement.http.HttpConstants.RequestMethod;
 import com.android.libraries.entitlement.http.HttpRequest;
 import com.android.libraries.entitlement.http.HttpResponse;
 
@@ -134,21 +135,22 @@
         mMockPackageInfo.versionName = APP_VERSION;
         when(mMockPackageManager.getPackageInfo(anyString(), anyInt()))
                 .thenReturn(mMockPackageInfo);
-        mEapAkaApi = new EapAkaApi(mContext, SUB_ID, mMockHttpClient, "");
-        mEapAkaApiBypassAuthentication =
-                new EapAkaApi(mContext, SUB_ID, mMockHttpClient, BYPASS_EAP_AKA_RESPONSE);
-        when(mContext.getSystemService(TelephonyManager.class))
-                .thenReturn(mMockTelephonyManager);
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mMockTelephonyManager);
         when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
                 .thenReturn(mMockTelephonyManagerForSubId);
         when(mMockTelephonyManagerForSubId.getSubscriberId()).thenReturn(IMSI);
         when(mMockTelephonyManagerForSubId.getSimOperator()).thenReturn(MCCMNC);
+        mEapAkaApi = new EapAkaApi(mContext, SUB_ID, mMockHttpClient, "");
+        mEapAkaApiBypassAuthentication =
+                new EapAkaApi(mContext, SUB_ID, mMockHttpClient, BYPASS_EAP_AKA_RESPONSE);
     }
 
     @Test
     public void queryEntitlementStatus_hasAuthenticationToken() throws Exception {
         HttpResponse httpResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any())).thenReturn(httpResponse);
         CarrierConfig carrierConfig =
@@ -165,24 +167,59 @@
         assertThat(mHttpRequestCaptor.getValue().timeoutInSec())
                 .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
         assertThat(mHttpRequestCaptor.getValue().network()).isEqualTo(mMockNetwork);
+        assertThat(mHttpRequestCaptor.getValue().requestMethod()).isEqualTo(RequestMethod.GET);
+    }
+
+    @Test
+    public void queryEntitlementStatus_hasAuthenticationToken_useHttpPost() throws Exception {
+        HttpResponse httpResponse =
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
+                        .build();
+        when(mMockHttpClient.request(any())).thenReturn(httpResponse);
+        CarrierConfig carrierConfig =
+                CarrierConfig.builder()
+                        .setServerUrl(TEST_URL)
+                        .setNetwork(mMockNetwork)
+                        .setUseHttpPost(true)
+                        .build();
+        ServiceEntitlementRequest request =
+                ServiceEntitlementRequest.builder().setAuthenticationToken(TOKEN).build();
+
+        HttpResponse response =
+                mEapAkaApi.queryEntitlementStatus(
+                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
+
+        assertThat(response).isEqualTo(httpResponse);
+        verify(mMockHttpClient).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getValue().timeoutInSec())
+                .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
+        assertThat(mHttpRequestCaptor.getValue().network()).isEqualTo(mMockNetwork);
+        assertThat(mHttpRequestCaptor.getValue().requestMethod()).isEqualTo(RequestMethod.POST);
     }
 
     @Test
     public void queryEntitlementStatus_noAuthenticationToken() throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1))
+                        .build();
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any()))
-                .thenReturn(eapChallengeResponse).thenReturn(xmlResponse);
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
 
@@ -192,10 +229,63 @@
 
         assertThat(response).isEqualTo(xmlResponse);
         verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.GET);
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).requestMethod())
+                .isEqualTo(RequestMethod.POST);
         // Verify that the 2nd request has cookies set by the 1st response
         assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties())
-                .containsAtLeast(HTTP_HEADER_COOKIE, COOKIE_VALUE,
-                                 HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
+                .containsAtLeast(
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE,
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).timeoutInSec())
+                .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).network()).isNull();
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).timeoutInSec())
+                .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).network()).isNull();
+    }
+
+    @Test
+    public void queryEntitlementStatus_noAuthenticationToken_useHttpPost() throws Exception {
+        when(mMockTelephonyManagerForSubId.getIccAuthentication(
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
+        HttpResponse eapChallengeResponse =
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1))
+                        .build();
+        HttpResponse xmlResponse =
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
+                        .build();
+        when(mMockHttpClient.request(any()))
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
+        CarrierConfig carrierConfig =
+                CarrierConfig.builder().setServerUrl(TEST_URL).setUseHttpPost(true).build();
+        ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
+
+        HttpResponse response =
+                mEapAkaApi.queryEntitlementStatus(
+                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
+
+        assertThat(response).isEqualTo(xmlResponse);
+        verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.POST);
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).requestMethod())
+                .isEqualTo(RequestMethod.POST);
+        // Verify that the 2nd request has cookies set by the 1st response
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties())
+                .containsAtLeast(
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE,
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).timeoutInSec())
                 .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).network()).isNull();
@@ -207,9 +297,9 @@
     @Test
     public void queryEntitlementStatus_noAuthenticationToken_invalidChallenge() throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
         HttpResponse eapChallengeResponse =
                 HttpResponse.builder()
@@ -218,10 +308,13 @@
                         .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1))
                         .build();
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any()))
-                .thenReturn(eapChallengeResponse).thenReturn(xmlResponse);
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
 
@@ -276,8 +369,9 @@
         // Verify that the subsequent requests have cookies set by the 1st response
         verify(mMockHttpClient, times(3)).request(mHttpRequestCaptor.capture());
         assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties())
-                .containsAtLeast(HTTP_HEADER_COOKIE, COOKIE_VALUE,
-                                 HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
+                .containsAtLeast(
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE,
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).timeoutInSec())
                 .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).network()).isNull();
@@ -323,8 +417,9 @@
         // Verify that the subsequent requests have cookies set by the 1st response
         verify(mMockHttpClient, times(4)).request(mHttpRequestCaptor.capture());
         assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties())
-                .containsAtLeast(HTTP_HEADER_COOKIE, COOKIE_VALUE,
-                                 HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
+                .containsAtLeast(
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE,
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).timeoutInSec())
                 .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).network()).isNull();
@@ -381,11 +476,13 @@
     @Test
     public void queryEntitlementStatus_hasAuthenticationToken_multipleAppIds() throws Exception {
         HttpResponse response =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any())).thenReturn(response);
-        ImmutableList<String> appIds = ImmutableList.of(ServiceEntitlement.APP_VOWIFI,
-                ServiceEntitlement.APP_VOLTE);
+        ImmutableList<String> appIds =
+                ImmutableList.of(ServiceEntitlement.APP_VOWIFI, ServiceEntitlement.APP_VOLTE);
         CarrierConfig carrierConfig =
                 CarrierConfig.builder().setServerUrl(TEST_URL).setTimeoutInSec(70).build();
         ServiceEntitlementRequest request =
@@ -406,19 +503,20 @@
         HttpResponse eapChallengeResponse =
                 HttpResponse.builder().setContentType(ContentType.JSON).build();
         when(mMockHttpClient.request(any())).thenReturn(eapChallengeResponse);
-        CarrierConfig carrierConfig =
-                CarrierConfig.builder().setServerUrl(TEST_URL).build();
+        CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
 
-        ServiceEntitlementException exception = expectThrows(
-                ServiceEntitlementException.class,
-                () -> mEapAkaApi.queryEntitlementStatus(
-                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI),
-                        carrierConfig,
-                        request));
+        ServiceEntitlementException exception =
+                expectThrows(
+                        ServiceEntitlementException.class,
+                        () ->
+                                mEapAkaApi.queryEntitlementStatus(
+                                        ImmutableList.of(ServiceEntitlement.APP_VOWIFI),
+                                        carrierConfig,
+                                        request));
 
-        assertThat(exception.getErrorCode()).isEqualTo(
-                ServiceEntitlementException.ERROR_MALFORMED_HTTP_RESPONSE);
+        assertThat(exception.getErrorCode())
+                .isEqualTo(ServiceEntitlementException.ERROR_MALFORMED_HTTP_RESPONSE);
         assertThat(exception.getMessage()).isEqualTo("Failed to parse json object");
         assertThat(exception.getCause()).isInstanceOf(JSONException.class);
         assertThat(exception.getHttpStatus()).isEqualTo(0);
@@ -429,17 +527,21 @@
     public void queryEntitlementStatus_noAuthenticationToken_handleEapAkaSyncFailure()
             throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SYNC_FAILURE)
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE))
+                        .build();
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any()))
                 .thenReturn(eapChallengeResponse)
@@ -465,14 +567,16 @@
     public void queryEntitlementStatus_noAuthenticationToken_eapAkaSyncFailure_invalidChallenge()
             throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SYNC_FAILURE);
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE))
+                        .build();
         HttpResponse invalidEapChallengeResponse =
                 HttpResponse.builder()
                         .setContentType(ContentType.JSON)
@@ -507,17 +611,19 @@
     public void queryEntitlementStatus_noAuthenticationToken_fourthEapAkaSyncFailure()
             throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SYNC_FAILURE)
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SYNC_FAILURE)
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SYNC_FAILURE)
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SYNC_FAILURE);
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE))
+                        .build();
         when(mMockHttpClient.request(any()))
                 .thenReturn(eapChallengeResponse)
                 .thenReturn(eapChallengeResponse)
@@ -548,14 +654,19 @@
     public void queryEntitlementStatus_hasNoAuthenticationToken_bypassAuthentication()
             throws Exception {
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1))
+                        .build();
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any()))
-                .thenReturn(eapChallengeResponse).thenReturn(xmlResponse);
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
 
@@ -567,8 +678,9 @@
         // Verify that the 2nd request has cookies set by the 1st response
         verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture());
         assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties())
-                .containsAtLeast(HTTP_HEADER_COOKIE, COOKIE_VALUE,
-                                 HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
+                .containsAtLeast(
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE,
+                        HTTP_HEADER_COOKIE, COOKIE_VALUE_1);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).timeoutInSec())
                 .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
         assertThat(mHttpRequestCaptor.getAllValues().get(0).network()).isNull();
@@ -593,8 +705,7 @@
         when(mMockHttpClient.request(any())).thenReturn(response);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request =
-                ServiceEntitlementRequest
-                        .builder()
+                ServiceEntitlementRequest.builder()
                         .setAuthenticationToken(TOKEN)
                         .setAcceptContentType(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML)
                         .build();
@@ -614,10 +725,7 @@
         when(mMockHttpClient.request(any())).thenReturn(response);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request =
-                ServiceEntitlementRequest
-                        .builder()
-                        .setAuthenticationToken(TOKEN)
-                        .build();
+                ServiceEntitlementRequest.builder().setAuthenticationToken(TOKEN).build();
 
         mEapAkaApi.queryEntitlementStatus(
                 ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
@@ -650,11 +758,7 @@
                 String.format(
                         "terminal_vendor=%s&terminal_model=%s&terminal_sw_version=%s",
                         LONG_VENDOR_TRIMMED, LONG_MODEL_TRIMMED, LONG_SW_VERSION_TRIMMED);
-        assertThat(
-                        mHttpRequestCaptor
-                                .getValue()
-                                .url())
-                .contains(urlParams);
+        assertThat(mHttpRequestCaptor.getValue().url()).contains(urlParams);
     }
 
     @Test
@@ -692,19 +796,24 @@
     @Test
     public void queryEntitlementStatus_userAgentSet_duringEapAka() throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE))
+                        .build();
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any()))
-                .thenReturn(eapChallengeResponse).thenReturn(xmlResponse);
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
         CarrierConfig carrierConfig =
                 CarrierConfig.builder()
                         .setServerUrl(TEST_URL)
@@ -727,14 +836,16 @@
                         VENDOR, MODEL, carrierConfig.clientTs43(), APP_VERSION, SW_VERSION);
         assertThat(
                         mHttpRequestCaptor
-                                .getAllValues().get(0)
+                                .getAllValues()
+                                .get(0)
                                 .requestProperties()
                                 .get(HttpHeaders.USER_AGENT)
                                 .get(0))
                 .isEqualTo(userAgent);
         assertThat(
                         mHttpRequestCaptor
-                                .getAllValues().get(1)
+                                .getAllValues()
+                                .get(1)
                                 .requestProperties()
                                 .get(HttpHeaders.USER_AGENT)
                                 .get(0))
@@ -780,52 +891,133 @@
     @Test
     public void performEsimOdsaOperation_noAuthenticationToken_returnsResult() throws Exception {
         when(mMockTelephonyManagerForSubId.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
                 .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
         HttpResponse eapChallengeResponse =
-                HttpResponse
-                        .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE))
+                        .build();
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any()))
-                .thenReturn(eapChallengeResponse).thenReturn(xmlResponse);
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
         EsimOdsaOperation operation = EsimOdsaOperation.builder().build();
 
         HttpResponse response =
-                mEapAkaApi.performEsimOdsaOperation(ServiceEntitlement.APP_ODSA_COMPANION,
-                        carrierConfig, request, operation);
+                mEapAkaApi.performEsimOdsaOperation(
+                        ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request, operation);
 
         assertThat(response).isEqualTo(xmlResponse);
-        verify(mMockHttpClient, times(2)).request(any());
+        verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.GET);
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).requestMethod())
+                .isEqualTo(RequestMethod.POST);
+    }
+
+    @Test
+    public void performEsimOdsaOperation_noAuthenticationToken_useHttpPost_returnsResult()
+            throws Exception {
+        when(mMockTelephonyManagerForSubId.getIccAuthentication(
+                        TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA,
+                        EAP_AKA_SECURITY_CONTEXT_REQUEST_EXPECTED))
+                .thenReturn(EAP_AKA_SECURITY_CONTEXT_RESPONSE_SUCCESS);
+        HttpResponse eapChallengeResponse =
+                HttpResponse.builder()
+                        .setContentType(ContentType.JSON)
+                        .setBody(EAP_AKA_CHALLENGE)
+                        .setCookies(ImmutableList.of(COOKIE_VALUE))
+                        .build();
+        HttpResponse xmlResponse =
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
+                        .build();
+        when(mMockHttpClient.request(any()))
+                .thenReturn(eapChallengeResponse)
+                .thenReturn(xmlResponse);
+        CarrierConfig carrierConfig =
+                CarrierConfig.builder().setServerUrl(TEST_URL).setUseHttpPost(true).build();
+        ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
+        EsimOdsaOperation operation = EsimOdsaOperation.builder().build();
+
+        HttpResponse response =
+                mEapAkaApi.performEsimOdsaOperation(
+                        ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request, operation);
+
+        assertThat(response).isEqualTo(xmlResponse);
+        verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.POST);
+        assertThat(mHttpRequestCaptor.getAllValues().get(1).requestMethod())
+                .isEqualTo(RequestMethod.POST);
     }
 
     @Test
     public void performEsimOdsaOperation_manageSubscription_returnsResult() throws Exception {
         HttpResponse xmlResponse =
-                HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
+                        .build();
+        when(mMockHttpClient.request(any())).thenReturn(xmlResponse);
+        CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
+        ServiceEntitlementRequest request =
+                ServiceEntitlementRequest.builder().setAuthenticationToken(TOKEN).build();
+        EsimOdsaOperation operation =
+                EsimOdsaOperation.builder()
+                        .setOperation(EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION)
+                        .setOperationType(EsimOdsaOperation.OPERATION_TYPE_SUBSCRIBE)
+                        .build();
+
+        HttpResponse response =
+                mEapAkaApi.performEsimOdsaOperation(
+                        ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request, operation);
+
+        assertThat(response).isEqualTo(xmlResponse);
+        verify(mMockHttpClient, times(1)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.GET);
+    }
+
+    @Test
+    public void performEsimOdsaOperation_manageSubscription_useHttpPost_returnsResult()
+            throws Exception {
+        HttpResponse xmlResponse =
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setBody(RESPONSE_XML)
                         .build();
         when(mMockHttpClient.request(any())).thenReturn(xmlResponse);
         CarrierConfig carrierConfig =
-                CarrierConfig.builder().setServerUrl(TEST_URL).build();
+                CarrierConfig.builder().setServerUrl(TEST_URL).setUseHttpPost(true).build();
         ServiceEntitlementRequest request =
                 ServiceEntitlementRequest.builder().setAuthenticationToken(TOKEN).build();
-        EsimOdsaOperation operation = EsimOdsaOperation.builder()
-                .setOperation(EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION)
-                .setOperationType(EsimOdsaOperation.OPERATION_TYPE_SUBSCRIBE)
-                .build();
+        EsimOdsaOperation operation =
+                EsimOdsaOperation.builder()
+                        .setOperation(EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION)
+                        .setOperationType(EsimOdsaOperation.OPERATION_TYPE_SUBSCRIBE)
+                        .build();
 
         HttpResponse response =
-                mEapAkaApi.performEsimOdsaOperation(ServiceEntitlement.APP_ODSA_COMPANION,
-                        carrierConfig, request, operation);
+                mEapAkaApi.performEsimOdsaOperation(
+                        ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request, operation);
 
         assertThat(response).isEqualTo(xmlResponse);
-        verify(mMockHttpClient, times(1)).request(any());
+        verify(mMockHttpClient, times(1)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.POST);
     }
 
     @Test
@@ -879,17 +1071,40 @@
                         .setContentType(ContentType.XML)
                         .setLocation(HTTP_HEADER_LOCATION)
                         .build();
-        when(mMockHttpClient.request(any()))
-                .thenReturn(response);
+        when(mMockHttpClient.request(any())).thenReturn(response);
         CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build();
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
 
         String endpoint =
-                mEapAkaApi.acquireOidcAuthenticationEndpoint(ServiceEntitlement.APP_ODSA_COMPANION,
-                        carrierConfig, request);
+                mEapAkaApi.acquireOidcAuthenticationEndpoint(
+                        ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request);
 
         assertThat(endpoint).isEqualTo(HTTP_HEADER_LOCATION);
-        verify(mMockHttpClient, times(1)).request(any());
+        verify(mMockHttpClient, times(1)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.GET);
+    }
+
+    @Test
+    public void acquireOidcAuthenticationEndpoint_useHttpPost() throws Exception {
+        HttpResponse response =
+                HttpResponse.builder()
+                        .setContentType(ContentType.XML)
+                        .setLocation(HTTP_HEADER_LOCATION)
+                        .build();
+        when(mMockHttpClient.request(any())).thenReturn(response);
+        CarrierConfig carrierConfig =
+                CarrierConfig.builder().setServerUrl(TEST_URL).setUseHttpPost(true).build();
+        ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
+
+        String endpoint =
+                mEapAkaApi.acquireOidcAuthenticationEndpoint(
+                        ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request);
+
+        assertThat(endpoint).isEqualTo(HTTP_HEADER_LOCATION);
+        verify(mMockHttpClient, times(1)).request(mHttpRequestCaptor.capture());
+        assertThat(mHttpRequestCaptor.getAllValues().get(0).requestMethod())
+                .isEqualTo(RequestMethod.POST);
     }
 
     @Test
@@ -904,8 +1119,7 @@
         ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
 
         HttpResponse response =
-                mEapAkaApi.queryEntitlementStatusFromOidc(
-                        TEST_URL, carrierConfig, request);
+                mEapAkaApi.queryEntitlementStatusFromOidc(TEST_URL, carrierConfig, request);
 
         assertThat(response).isEqualTo(xmlResponse);
         verify(mMockHttpClient, times(1)).request(any());