Snap for 7592383 from 1c2e272efcf8c9db34fa832ff1a955250d0e41e3 to sc-release

Change-Id: Idba3ba5cb6d818cfb063a963f5fc6c89f45d58b8
diff --git a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
index 2e337e4..4482bf7 100644
--- a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
+++ b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
@@ -175,7 +175,7 @@
             return challengeResponse(
                             eapAkaResponse.response(),
                             carrierConfig,
-                            response.cookie(),
+                            response.cookies(),
                             contentType);
         } else if (eapAkaResponse.synchronizationFailureResponse() != null) {
             Log.d(TAG, "synchronization failure");
@@ -183,7 +183,7 @@
                     challengeResponse(
                             eapAkaResponse.synchronizationFailureResponse(),
                             carrierConfig,
-                            response.cookie(),
+                            response.cookies(),
                             ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON);
             if (followSyncFailureCount > 0) {
                 return respondToEapAkaChallenge(
@@ -201,7 +201,7 @@
     private HttpResponse challengeResponse(
             String eapAkaChallengeResponse,
             CarrierConfig carrierConfig,
-            String cookie,
+            ImmutableList<String> cookies,
             String contentType)
             throws ServiceEntitlementException {
         Log.d(TAG, "challengeResponse");
@@ -221,7 +221,7 @@
                         .addRequestProperty(
                                 HttpHeaders.CONTENT_TYPE,
                                 ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON)
-                        .addRequestProperty(HttpHeaders.COOKIE, cookie)
+                        .addRequestProperty(HttpHeaders.COOKIE, cookies)
                         .setTimeoutInSec(carrierConfig.timeoutInSec())
                         .setNetwork(carrierConfig.network())
                         .build();
diff --git a/java/com/android/libraries/entitlement/http/HttpClient.java b/java/com/android/libraries/entitlement/http/HttpClient.java
index 76eeaec..9ccb5ee 100644
--- a/java/com/android/libraries/entitlement/http/HttpClient.java
+++ b/java/com/android/libraries/entitlement/http/HttpClient.java
@@ -37,6 +37,7 @@
 import com.android.libraries.entitlement.http.HttpConstants.ContentType;
 import com.android.libraries.entitlement.utils.StreamUtils;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.net.HttpHeaders;
 
 import java.io.DataOutputStream;
@@ -46,6 +47,7 @@
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.List;
 import java.util.Map;
 
 /** Implement the HTTP request method according to TS.43 specification. */
@@ -94,7 +96,7 @@
             }
 
             // add HTTP headers
-            for (Map.Entry<String, String> entry : request.requestProperties().entrySet()) {
+            for (Map.Entry<String, String> entry : request.requestProperties().entries()) {
                 mConnection.addRequestProperty(entry.getKey(), entry.getValue());
             }
 
@@ -136,7 +138,7 @@
             throw new ServiceEntitlementException(
                     ERROR_HTTP_STATUS_NOT_SUCCESS, "Read response code failed!", e);
         }
-        responseBuilder.setCookie(nullToEmpty(getCookie(connection)));
+        responseBuilder.setCookies(getCookies(connection));
         try {
             String responseBody = readResponse(connection);
             logPii("HttpClient.response body: " + responseBody);
@@ -171,7 +173,8 @@
         return ContentType.UNKNOWN;
     }
 
-    private static String getCookie(URLConnection connection) {
-        return connection.getHeaderField(HttpHeaders.SET_COOKIE);
+    private static List<String> getCookies(URLConnection connection) {
+        List<String> cookies = connection.getHeaderFields().get(HttpHeaders.SET_COOKIE);
+        return cookies == null ? ImmutableList.of() : cookies;
     }
 }
diff --git a/java/com/android/libraries/entitlement/http/HttpRequest.java b/java/com/android/libraries/entitlement/http/HttpRequest.java
index af567db..b6cd771 100644
--- a/java/com/android/libraries/entitlement/http/HttpRequest.java
+++ b/java/com/android/libraries/entitlement/http/HttpRequest.java
@@ -17,18 +17,17 @@
 package com.android.libraries.entitlement.http;
 
 import android.net.Network;
-import android.util.ArrayMap;
 
 import androidx.annotation.Nullable;
 
 import com.android.libraries.entitlement.CarrierConfig;
 
 import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableListMultimap;
 
 import org.json.JSONObject;
 
-import java.util.Map;
+import java.util.List;
 
 /** The parameters of an http request. */
 @AutoValue
@@ -42,11 +41,8 @@
     /** For "POST" request method, the body of the request in JSON format. */
     public abstract JSONObject postData();
 
-    /** For "GET" request method, the parameters to be encoded into the URL. */
-    public abstract ImmutableMap<String, String> requestValues();
-
     /** HTTP header fields. */
-    public abstract ImmutableMap<String, String> requestProperties();
+    public abstract ImmutableListMultimap<String, String> requestProperties();
 
     /** The client side timeout, in seconds. See {@link Builder#setTimeoutInSec}. */
     public abstract int timeoutInSec();
@@ -58,9 +54,6 @@
     /** Builder of {@link HttpRequest}. */
     @AutoValue.Builder
     public abstract static class Builder {
-        private final Map<String, String> values = new ArrayMap<>();
-        private final Map<String, String> properties = new ArrayMap<>();
-
         public abstract HttpRequest build();
 
         /** Sets the URL. */
@@ -76,20 +69,22 @@
         /** For "POST" request method, sets the body of the request in JSON format. */
         public abstract Builder setPostData(JSONObject postData);
 
-        abstract Builder setRequestValues(ImmutableMap<String, String> value);
-
-        abstract Builder setRequestProperties(ImmutableMap<String, String> properties);
-
-        /** For "GET" request method, adds a parameter to be encoded into the URL. */
-        public Builder addRequestValues(String key, String value) {
-            values.put(key, value);
-            return this.setRequestValues(ImmutableMap.copyOf(values));
-        }
+        abstract ImmutableListMultimap.Builder<String, String> requestPropertiesBuilder();
 
         /** Adds an HTTP header field. */
         public Builder addRequestProperty(String key, String value) {
-            properties.put(key, value);
-            return this.setRequestProperties(ImmutableMap.copyOf(properties));
+            requestPropertiesBuilder().put(key, value);
+            return this;
+        }
+
+        /**
+          * Adds an HTTP header field with multiple values. Equivalent to calling
+          * {@link #addRequestProperty(String, String)} multiple times with the same key and
+          * one value at a time.
+          */
+        public Builder addRequestProperty(String key, List<String> value) {
+            requestPropertiesBuilder().putAll(key, value);
+            return this;
         }
 
         /**
@@ -113,8 +108,6 @@
                 .setUrl("")
                 .setRequestMethod("")
                 .setPostData(new JSONObject())
-                .setRequestValues(ImmutableMap.of())
-                .setRequestProperties(ImmutableMap.of())
                 .setTimeoutInSec(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC);
     }
 }
diff --git a/java/com/android/libraries/entitlement/http/HttpResponse.java b/java/com/android/libraries/entitlement/http/HttpResponse.java
index e331b99..f495578 100644
--- a/java/com/android/libraries/entitlement/http/HttpResponse.java
+++ b/java/com/android/libraries/entitlement/http/HttpResponse.java
@@ -19,6 +19,9 @@
 import com.android.libraries.entitlement.http.HttpConstants.ContentType;
 
 import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
 
 /**
  * The response of the http request.
@@ -39,7 +42,7 @@
     /**
      * Content of the "Set-Cookie" response header.
      */
-    public abstract String cookie();
+    public abstract ImmutableList<String> cookies();
 
     /**
      * Builder of {@link HttpResponse}.
@@ -57,9 +60,9 @@
         public abstract Builder setResponseMessage(String responseMessage);
 
         /**
-         * Content of the "Set-Cookie" response header.
+         * Sets the content of the "Set-Cookie" response headers.
          */
-        public abstract Builder setCookie(String cookie);
+        public abstract Builder setCookies(List<String> cookies);
     }
 
     public static Builder builder() {
@@ -68,7 +71,7 @@
                 .setBody("")
                 .setResponseCode(0)
                 .setResponseMessage("")
-                .setCookie("");
+                .setCookies(ImmutableList.of());
     }
 
     @Override
@@ -83,9 +86,9 @@
                 .append(responseCode())
                 .append(" responseMessage=")
                 .append(responseMessage())
-                .append(" cookie=(")
-                .append(cookie().length())
-                .append(" characters)}")
+                .append(" cookies=[")
+                .append(cookies().size())
+                .append(" cookies]}")
                 .toString();
     }
 }
diff --git a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
index f289c04..f655258 100644
--- a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
+++ b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
@@ -69,6 +69,7 @@
     // com.google.common.net.HttpHeaders.COOKIE
     private static final String HTTP_HEADER_COOKIE = "Cookie";
     private static final String COOKIE_VALUE = "COOKIE=abcdefg";
+    private static final String COOKIE_VALUE_1 = "COOKIE=hijklmn";
     private static final String RESPONSE_XML =
             "<wap-provisioningdoc version=\"1.1\">\n"
                     + "    <characteristic type=\"TOKEN\">\n"
@@ -149,7 +150,7 @@
         HttpResponse eapChallengeResponse =
                 HttpResponse
                         .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookie(COOKIE_VALUE).build();
+                        .setCookies(ImmutableList.of(COOKIE_VALUE, COOKIE_VALUE_1)).build();
         HttpResponse xmlResponse =
                 HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
                         .build();
@@ -163,10 +164,11 @@
                         ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
 
         assertThat(respopnse).isEqualTo(RESPONSE_XML);
-        // Verify that the 2nd request has cookie set by the 1st response
+        // 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())
-                .containsEntry(HTTP_HEADER_COOKIE, COOKIE_VALUE);
+                .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();
@@ -232,7 +234,7 @@
         HttpResponse eapChallengeResponse =
                 HttpResponse
                         .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookie(COOKIE_VALUE).build();
+                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
         HttpResponse xmlResponse =
                 HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
                         .build();
@@ -274,7 +276,7 @@
 
         verify(mMockHttpClient).request(mHttpRequestCaptor.capture());
         assertThat(mHttpRequestCaptor.getValue().requestProperties().get(HttpHeaders.ACCEPT))
-                .isEqualTo(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML);
+                .containsExactly(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML);
     }
 
     @Test
@@ -294,7 +296,7 @@
 
         verify(mMockHttpClient).request(mHttpRequestCaptor.capture());
         assertThat(mHttpRequestCaptor.getValue().requestProperties().get(HttpHeaders.ACCEPT))
-                .isEqualTo(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON_AND_XML);
+                .containsExactly(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON_AND_XML);
     }
 
     @Test
@@ -307,7 +309,7 @@
         HttpResponse eapChallengeResponse =
                 HttpResponse
                         .builder().setContentType(ContentType.JSON).setBody(EAP_AKA_CHALLENGE)
-                        .setCookie(COOKIE_VALUE).build();
+                        .setCookies(ImmutableList.of(COOKIE_VALUE)).build();
         HttpResponse xmlResponse =
                 HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML)
                         .build();