aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiwon Park <kiwonp@google.com>2022-10-04 18:47:38 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-10-04 18:47:38 +0000
commitcbcefac55fc855a5343697b300af608e340ac4d8 (patch)
treea5d361969f46760c52b1311e45f94e1b5a2c2e53
parent614cfe2baa356e9b0aafa251bf1e7c3ca4513d05 (diff)
parent6afa16ed2833d2fc2916b84995cf0adbd9336f18 (diff)
downloadservice_entitlement-cbcefac55fc855a5343697b300af608e340ac4d8.tar.gz
Merge changes from topic "bypass"
* changes: Add back ServiceEntitlement constructor with four arguments Add ability to bypass EAP-AKA authentication. Add ability to save the HTTP request/responses. Replace String.join with TextUtils.join in forming operationTargets Support the new fields in EsimOdsOperation and ServiceEntitlementRequest for CR1052.
-rw-r--r--Android.bp3
-rw-r--r--java/com/android/libraries/entitlement/EsimOdsaOperation.java49
-rw-r--r--java/com/android/libraries/entitlement/ServiceEntitlement.java74
-rw-r--r--java/com/android/libraries/entitlement/ServiceEntitlementRequest.java13
-rw-r--r--java/com/android/libraries/entitlement/eapaka/EapAkaApi.java72
-rw-r--r--java/com/android/libraries/entitlement/http/HttpClient.java28
-rw-r--r--java/com/android/libraries/entitlement/http/HttpResponse.java18
-rw-r--r--tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java49
-rw-r--r--tests/src/com/android/libraries/entitlement/http/HttpClientTest.java39
9 files changed, 312 insertions, 33 deletions
diff --git a/Android.bp b/Android.bp
index b45b167..e339fd9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -84,4 +84,7 @@ java_library {
"java/com/android/libraries/entitlement/ServiceEntitlementException.java",
"java/com/android/libraries/entitlement/ServiceEntitlementRequest.java",
],
+ static_libs: [
+ "guava",
+ ],
}
diff --git a/java/com/android/libraries/entitlement/EsimOdsaOperation.java b/java/com/android/libraries/entitlement/EsimOdsaOperation.java
index 20f4fa3..9a3eae6 100644
--- a/java/com/android/libraries/entitlement/EsimOdsaOperation.java
+++ b/java/com/android/libraries/entitlement/EsimOdsaOperation.java
@@ -17,6 +17,7 @@
package com.android.libraries.entitlement;
import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
/**
* HTTP request parameters specific to on device service actiavation (ODSA). See GSMA spec TS.43
@@ -40,6 +41,10 @@ public abstract class EsimOdsaOperation {
* OSDA operation: AcquireConfiguration.
*/
public static final String OPERATION_ACQUIRE_CONFIGURATION = "AcquireConfiguration";
+ /**
+ * OSDA operation: AcquireTemporaryToken.
+ */
+ public static final String OPERATION_ACQUIRE_TEMPORARY_TOKEN = "AcquireTemporaryToken";
/**
* Indicates that operation_type is not set.
@@ -97,6 +102,12 @@ public abstract class EsimOdsaOperation {
public abstract int operationType();
/**
+ * Returns the comma separated list of operation targets used with temporary token from
+ * AcquireTemporaryToken operation. Used by HTTP parameter "operation_targets".
+ */
+ public abstract ImmutableList<String> operationTargets();
+
+ /**
* Returns the unique identifier of the companion device, like IMEI. Used by HTTP parameter
* "companion_terminal_id".
*/
@@ -170,6 +181,18 @@ public abstract class EsimOdsaOperation {
*/
public abstract String targetTerminalEid();
+
+ /**
+ * Returns the unique identifier of the old device eSIM, like the IMEI associated with the
+ * eSIM. Used by HTTP parameter "old_terminal_id".
+ */
+ public abstract String oldTerminalId();
+
+ /**
+ * Returns the ICCID of old device eSIM. Used by HTTP parameter "old_terminal_iccid".
+ */
+ public abstract String oldTerminalIccid();
+
/**
* Returns a new {@link Builder} object.
*/
@@ -177,6 +200,7 @@ public abstract class EsimOdsaOperation {
return new AutoValue_EsimOdsaOperation.Builder()
.setOperation("")
.setOperationType(OPERATION_TYPE_NOT_SET)
+ .setOperationTargets(ImmutableList.of())
.setCompanionTerminalId("")
.setCompanionTerminalVendor("")
.setCompanionTerminalModel("")
@@ -189,7 +213,9 @@ public abstract class EsimOdsaOperation {
.setTerminalEid("")
.setTargetTerminalId("")
.setTargetTerminalIccid("")
- .setTargetTerminalEid("");
+ .setTargetTerminalEid("")
+ .setOldTerminalId("")
+ .setOldTerminalIccid("");
}
/**
@@ -230,6 +256,12 @@ public abstract class EsimOdsaOperation {
public abstract Builder setOperationType(int value);
/**
+ * Sets the operation targets to be used with temporary token from AcquireTemporaryToken
+ * operation. Used by HTTP parameter "operation_targets" if set.
+ */
+ public abstract Builder setOperationTargets(ImmutableList<String> value);
+
+ /**
* Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter
* "companion_terminal_id" if set.
*
@@ -336,6 +368,21 @@ public abstract class EsimOdsaOperation {
*/
public abstract Builder setTargetTerminalEid(String value);
+ /**
+ * Sets the unique identifier of the old device eSIM, like the IMEI associated with the
+ * eSIM. Used by HTTP parameter "old_terminal_id" if set.
+ *
+ * <p>Used by primary device ODSA operation.
+ */
+ public abstract Builder setOldTerminalId(String value);
+
+ /**
+ * Sets the ICCID old device eSIM. Used by HTTP parameter "old_terminal_iccid" if set.
+ *
+ * <p>Used by primary device ODSA operation.
+ */
+ public abstract Builder setOldTerminalIccid(String value);
+
public abstract EsimOdsaOperation build();
}
}
diff --git a/java/com/android/libraries/entitlement/ServiceEntitlement.java b/java/com/android/libraries/entitlement/ServiceEntitlement.java
index b52cd1f..e050cd3 100644
--- a/java/com/android/libraries/entitlement/ServiceEntitlement.java
+++ b/java/com/android/libraries/entitlement/ServiceEntitlement.java
@@ -25,6 +25,8 @@ import com.android.libraries.entitlement.eapaka.EapAkaApi;
import com.google.common.collect.ImmutableList;
+import java.util.List;
+
/**
* Implemnets protocol for carrier service entitlement configuration query and operation, based on
* GSMA TS.43 spec.
@@ -71,8 +73,63 @@ public class ServiceEntitlement {
* for how to get the subscroption ID.
*/
public ServiceEntitlement(Context context, CarrierConfig carrierConfig, int simSubscriptionId) {
+ this(
+ context,
+ carrierConfig,
+ simSubscriptionId,
+ /* saveHttpHistory= */ false,
+ /* bypassEapAkaResponse= */ "");
+ }
+
+ /**
+ * Creates an instance for service entitlement configuration query and operation for the
+ * carrier.
+ *
+ * @param context context of application
+ * @param carrierConfig carrier specific configs used in the queries and operations.
+ * @param simSubscriptionId the subscroption ID of the carrier's SIM on device. This indicates
+ * which SIM to retrieve IMEI/IMSI from and perform EAP-AKA authentication with. See {@link
+ * android.telephony.SubscriptionManager} for how to get the subscroption ID.
+ * @param saveHttpHistory set to {@code true} to save the history of request and response which
+ * can later be retrieved by {@code getHistory()}. Intended for debugging.
+ */
+ public ServiceEntitlement(
+ Context context,
+ CarrierConfig carrierConfig,
+ int simSubscriptionId,
+ boolean saveHttpHistory) {
+ this(
+ context,
+ carrierConfig,
+ simSubscriptionId,
+ saveHttpHistory,
+ /* bypassEapAkaResponse= */ "");
+ }
+
+ /**
+ * Creates an instance for service entitlement configuration query and operation for the
+ * carrier.
+ *
+ * @param context context of application
+ * @param carrierConfig carrier specific configs used in the queries and operations.
+ * @param simSubscriptionId the subscroption ID of the carrier's SIM on device. This indicates
+ * which SIM to retrieve IMEI/IMSI from and perform EAP-AKA authentication with. See {@link
+ * android.telephony.SubscriptionManager} for how to get the subscroption ID.
+ * @param saveHttpHistory set to {@code true} to save the history of request and response which
+ * can later be retrieved by {@code getHistory()}. Intended for debugging.
+ * @param bypassEapAkaResponse set to non empty string to bypass EAP-AKA authentication.
+ * The client will accept any challenge from the server and return this string as a
+ * response. Must not be {@code null}. Intended for testing.
+ */
+ public ServiceEntitlement(
+ Context context,
+ CarrierConfig carrierConfig,
+ int simSubscriptionId,
+ boolean saveHttpHistory,
+ String bypassEapAkaResponse) {
this.carrierConfig = carrierConfig;
- this.eapAkaApi = new EapAkaApi(context, simSubscriptionId);
+ this.eapAkaApi =
+ new EapAkaApi(context, simSubscriptionId, saveHttpHistory, bypassEapAkaResponse);
}
@VisibleForTesting
@@ -155,4 +212,19 @@ public class ServiceEntitlement {
throws ServiceEntitlementException {
return eapAkaApi.performEsimOdsaOperation(appId, carrierConfig, request, operation);
}
+
+ /**
+ * Retrieves the history of past HTTP request and responses if {@code saveHttpHistory} was set
+ * in constructor.
+ */
+ public List<String> getHistory() {
+ return eapAkaApi.getHistory();
+ }
+
+ /**
+ * Clears the history of past HTTP request and responses.
+ */
+ public void clearHistory() {
+ eapAkaApi.clearHistory();
+ }
}
diff --git a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
index 92e6729..59e70ef 100644
--- a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
+++ b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
@@ -62,6 +62,11 @@ public abstract class ServiceEntitlementRequest {
public abstract String authenticationToken();
/**
+ * Returns the temporary token. Used by HTTP parameter "temporary_token".
+ */
+ public abstract String temporaryToken();
+
+ /**
* Returns the unique identifier of the device like IMEI. Used by HTTP parameter "terminal_id".
*/
public abstract String terminalId();
@@ -131,6 +136,7 @@ public abstract class ServiceEntitlementRequest {
.setConfigurationVersion(DEFAULT_CONFIGURATION_VERSION)
.setEntitlementVersion(DEFAULT_ENTITLEMENT_VERSION)
.setAuthenticationToken("")
+ .setTemporaryToken("")
.setTerminalId("")
.setTerminalVendor(Build.MANUFACTURER)
.setTerminalModel(Build.MODEL)
@@ -174,6 +180,13 @@ public abstract class ServiceEntitlementRequest {
public abstract Builder setAuthenticationToken(String value);
/**
+ * Sets the temporary token. Used by HTTP parameter "temporary_token".
+ *
+ * <p>Optional.
+ */
+ public abstract Builder setTemporaryToken(String value);
+
+ /**
* Sets the unique identifier of the device like IMEI. Used by HTTP parameter
* "terminal_id".
*
diff --git a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
index 4482bf7..c761daa 100644
--- a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
+++ b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
@@ -43,6 +43,8 @@ import com.google.common.net.HttpHeaders;
import org.json.JSONException;
import org.json.JSONObject;
+import java.util.List;
+
public class EapAkaApi {
private static final String TAG = "ServiceEntitlement";
@@ -58,6 +60,7 @@ public class EapAkaApi {
private static final String EAP_ID = "EAP_ID";
private static final String IMSI = "IMSI";
private static final String TOKEN = "token";
+ private static final String TEMPORARY_TOKEN = "temporary_token";
private static final String NOTIF_ACTION = "notif_action";
private static final String NOTIF_TOKEN = "notif_token";
private static final String APP_VERSION = "app_version";
@@ -65,6 +68,7 @@ public class EapAkaApi {
private static final String OPERATION = "operation";
private static final String OPERATION_TYPE = "operation_type";
+ private static final String OPERATION_TARGETS = "operation_targets";
private static final String COMPANION_TERMINAL_ID = "companion_terminal_id";
private static final String COMPANION_TERMINAL_VENDOR = "companion_terminal_vendor";
private static final String COMPANION_TERMINAL_MODEL = "companion_terminal_model";
@@ -82,22 +86,35 @@ public class EapAkaApi {
private static final String TARGET_TERMINAL_ICCID = "target_terminal_iccid";
private static final String TARGET_TERMINAL_EID = "target_terminal_eid";
+ private static final String OLD_TERMINAL_ID = "old_terminal_id";
+ private static final String OLD_TERMINAL_ICCID = "old_terminal_iccid";
+
// In case of EAP-AKA synchronization failure, we try to recover for at most two times.
private static final int FOLLOW_SYNC_FAILURE_MAX_COUNT = 2;
private final Context mContext;
private final int mSimSubscriptionId;
private final HttpClient mHttpClient;
-
- public EapAkaApi(Context context, int simSubscriptionId) {
- this(context, simSubscriptionId, new HttpClient());
+ private final String mBypassEapAkaResponse;
+
+ public EapAkaApi(
+ Context context,
+ int simSubscriptionId,
+ boolean saveHistory,
+ String bypassEapAkaResponse) {
+ this(context, simSubscriptionId, new HttpClient(saveHistory), bypassEapAkaResponse);
}
@VisibleForTesting
- EapAkaApi(Context context, int simSubscriptionId, HttpClient httpClient) {
+ EapAkaApi(
+ Context context,
+ int simSubscriptionId,
+ HttpClient httpClient,
+ String bypassEapAkaResponse) {
this.mContext = context;
this.mSimSubscriptionId = simSubscriptionId;
this.mHttpClient = httpClient;
+ this.mBypassEapAkaResponse = bypassEapAkaResponse;
}
/**
@@ -167,6 +184,13 @@ public class EapAkaApi {
throw new ServiceEntitlementException(
ERROR_MALFORMED_HTTP_RESPONSE, "Failed to parse json object", jsonException);
}
+ if (!mBypassEapAkaResponse.isEmpty()) {
+ return challengeResponse(
+ mBypassEapAkaResponse,
+ carrierConfig,
+ response.cookies(),
+ contentType);
+ }
EapAkaChallenge challenge = EapAkaChallenge.parseEapAkaChallenge(eapAkaChallenge);
EapAkaResponse eapAkaResponse =
EapAkaResponse.respondToEapAkaChallenge(mContext, mSimSubscriptionId, challenge);
@@ -241,7 +265,8 @@ public class EapAkaApi {
appendParametersForServiceEntitlementRequest(urlBuilder, ImmutableList.of(appId), request);
appendParametersForEsimOdsaOperation(urlBuilder, odsaOperation);
- if (!TextUtils.isEmpty(request.authenticationToken())) {
+ 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(
@@ -268,17 +293,20 @@ public class EapAkaApi {
ServiceEntitlementRequest request) {
TelephonyManager telephonyManager = mContext.getSystemService(
TelephonyManager.class).createForSubscriptionId(mSimSubscriptionId);
- if (TextUtils.isEmpty(request.authenticationToken())) {
+ if (!TextUtils.isEmpty(request.authenticationToken())) {
+ // IMSI and token required for fast AuthN.
+ urlBuilder
+ .appendQueryParameter(IMSI, telephonyManager.getSubscriberId())
+ .appendQueryParameter(TOKEN, request.authenticationToken());
+ } else if (!TextUtils.isEmpty(request.temporaryToken())) {
+ // temporary_token required for fast AuthN.
+ urlBuilder.appendQueryParameter(TEMPORARY_TOKEN, request.temporaryToken());
+ } else {
// EAP_ID required for initial AuthN
urlBuilder.appendQueryParameter(
EAP_ID,
getImsiEap(telephonyManager.getSimOperator(),
telephonyManager.getSubscriberId()));
- } else {
- // IMSI and token required for fast AuthN.
- urlBuilder
- .appendQueryParameter(IMSI, telephonyManager.getSubscriberId())
- .appendQueryParameter(TOKEN, request.authenticationToken());
}
if (!TextUtils.isEmpty(request.notificationToken())) {
@@ -320,6 +348,10 @@ public class EapAkaApi {
urlBuilder.appendQueryParameter(OPERATION_TYPE,
Integer.toString(odsaOperation.operationType()));
}
+ appendOptionalQueryParameter(
+ urlBuilder,
+ OPERATION_TARGETS,
+ TextUtils.join(",", odsaOperation.operationTargets()));
appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_ID,
odsaOperation.companionTerminalId());
appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_VENDOR,
@@ -345,6 +377,10 @@ public class EapAkaApi {
odsaOperation.targetTerminalIccid());
appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_EID,
odsaOperation.targetTerminalEid());
+ appendOptionalQueryParameter(urlBuilder, OLD_TERMINAL_ICCID,
+ odsaOperation.oldTerminalIccid());
+ appendOptionalQueryParameter(urlBuilder, OLD_TERMINAL_ID,
+ odsaOperation.oldTerminalId());
}
private HttpResponse httpGet(String url, CarrierConfig carrierConfig, String contentType)
@@ -385,4 +421,18 @@ public class EapAkaApi {
}
return "0" + imsi + "@nai.epc.mnc" + mnc + ".mcc" + mcc + ".3gppnetwork.org";
}
+
+ /**
+ * Retrieves the history of past HTTP request and responses.
+ */
+ public List<String> getHistory() {
+ return mHttpClient.getHistory();
+ }
+
+ /**
+ * Clears the history of past HTTP request and responses.
+ */
+ public void clearHistory() {
+ mHttpClient.clearHistory();
+ }
}
diff --git a/java/com/android/libraries/entitlement/http/HttpClient.java b/java/com/android/libraries/entitlement/http/HttpClient.java
index 9ccb5ee..39275e8 100644
--- a/java/com/android/libraries/entitlement/http/HttpClient.java
+++ b/java/com/android/libraries/entitlement/http/HttpClient.java
@@ -47,6 +47,7 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -55,9 +56,19 @@ public class HttpClient {
private static final String TAG = "ServiceEntitlement";
private HttpURLConnection mConnection;
+ private boolean mSaveHistory;
+ private ArrayList<String> mHistory;
+
+ public HttpClient(boolean saveHistory) {
+ mSaveHistory = saveHistory;
+ mHistory = new ArrayList<>();
+ }
@WorkerThread
public HttpResponse request(HttpRequest request) throws ServiceEntitlementException {
+ if (mSaveHistory) {
+ mHistory.add(request.toString());
+ }
logPii("HttpClient.request url: " + request.url());
createConnection(request);
logPii("HttpClient.request headers (partial): " + mConnection.getRequestProperties());
@@ -74,6 +85,9 @@ public class HttpClient {
mConnection.connect(); // This is to trigger SocketTimeoutException early
HttpResponse response = getHttpResponse(mConnection);
Log.d(TAG, "HttpClient.response : " + response);
+ if (mSaveHistory) {
+ mHistory.add(response.toString());
+ }
return response;
} catch (IOException ioe) {
throw new ServiceEntitlementException(
@@ -85,6 +99,20 @@ public class HttpClient {
}
}
+ /**
+ * Retrieves the history of past HTTP request and responses.
+ */
+ public List<String> getHistory() {
+ return mHistory;
+ }
+
+ /**
+ * Clears the history of past HTTP request and responses.
+ */
+ public void clearHistory() {
+ mHistory.clear();
+ }
+
private void createConnection(HttpRequest request) throws ServiceEntitlementException {
try {
URL url = new URL(request.url());
diff --git a/java/com/android/libraries/entitlement/http/HttpResponse.java b/java/com/android/libraries/entitlement/http/HttpResponse.java
index f495578..f76fdd6 100644
--- a/java/com/android/libraries/entitlement/http/HttpResponse.java
+++ b/java/com/android/libraries/entitlement/http/HttpResponse.java
@@ -73,22 +73,4 @@ public abstract class HttpResponse {
.setResponseMessage("")
.setCookies(ImmutableList.of());
}
-
- @Override
- public final String toString() {
- return new StringBuilder("HttpResponse{")
- .append("contentType=")
- .append(contentType())
- .append(" body=(")
- .append(body().length())
- .append(" characters)")
- .append(" responseCode=")
- .append(responseCode())
- .append(" responseMessage=")
- .append(responseMessage())
- .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 b837695..8e331f3 100644
--- a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
+++ b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
@@ -24,6 +24,7 @@ import static com.android.libraries.entitlement.eapaka.EapAkaResponseTest.EAP_AK
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -94,6 +95,7 @@ public class EapAkaApiTest {
private static final int SUB_ID = 1;
private static final String ACCEPT_CONTENT_TYPE_JSON_AND_XML =
"application/vnd.gsma.eap-relay.v1.0+json, text/vnd.wap.connectivity-xml";
+ private static final String BYPASS_EAP_AKA_RESPONSE = "abc";
@Rule public final MockitoRule rule = MockitoJUnit.rule();
@@ -105,11 +107,14 @@ public class EapAkaApiTest {
private Context mContext;
private EapAkaApi mEapAkaApi;
+ private EapAkaApi mEapAkaApiBypassAuthentication;
@Before
public void setUp() {
mContext = spy(ApplicationProvider.getApplicationContext());
- mEapAkaApi = new EapAkaApi(mContext, SUB_ID, mMockHttpClient);
+ 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(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
@@ -261,6 +266,48 @@ public class EapAkaApiTest {
}
@Test
+ 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 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).build();
+ ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
+
+ String respopnse =
+ mEapAkaApiBypassAuthentication.queryEntitlementStatus(
+ ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
+
+ assertThat(respopnse).isEqualTo(RESPONSE_XML);
+ // 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);
+ 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();
+ verify(mMockTelephonyManagerForSubId, times(0))
+ .getIccAuthentication(anyInt(), anyInt(), any());
+ assertThat(
+ mHttpRequestCaptor
+ .getAllValues()
+ .get(1)
+ .postData()
+ .get(EapAkaApi.EAP_CHALLENGE_RESPONSE))
+ .isEqualTo(BYPASS_EAP_AKA_RESPONSE);
+ }
+
+ @Test
public void queryEntitlementStatus_acceptContentTypeSpecified_verfityAcceptContentType()
throws Exception {
HttpResponse response = HttpResponse.builder().setBody(RESPONSE_XML).build();
diff --git a/tests/src/com/android/libraries/entitlement/http/HttpClientTest.java b/tests/src/com/android/libraries/entitlement/http/HttpClientTest.java
index 505e8b5..9f05828 100644
--- a/tests/src/com/android/libraries/entitlement/http/HttpClientTest.java
+++ b/tests/src/com/android/libraries/entitlement/http/HttpClientTest.java
@@ -46,6 +46,7 @@ import org.junit.runner.RunWith;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.util.List;
import java.util.Map;
@RunWith(AndroidJUnit4.class)
@@ -70,7 +71,7 @@ public class HttpClientTest {
// Reset sFakeURLStreamHandler
sFakeURLStreamHandler.stubResponse(ImmutableMap.of());
- mHttpClient = new HttpClient();
+ mHttpClient = new HttpClient(true);
}
@Test
@@ -244,4 +245,40 @@ public class HttpClientTest {
assertThat(exception.getHttpStatus()).isEqualTo(0);
assertThat(exception.getRetryAfter()).isEmpty();
}
+
+ @Test
+ public void history() throws Exception {
+ FakeResponse responseContent =
+ FakeResponse.builder()
+ .setResponseCode(HttpURLConnection.HTTP_OK)
+ .setResponseLocation(null)
+ .setResponseBody(TEST_RESPONSE_BODY.getBytes(UTF_8))
+ .setContentType(CONTENT_TYPE_STRING_JSON)
+ .build();
+ Map<String, FakeResponse> response = ImmutableMap.of(TEST_URL, responseContent);
+ sFakeURLStreamHandler.stubResponse(response);
+ HttpRequest request =
+ HttpRequest.builder()
+ .setUrl(TEST_URL)
+ .setRequestMethod(RequestMethod.GET)
+ .setTimeoutInSec(70)
+ .build();
+
+ HttpResponse httpResponse0 = mHttpClient.request(request);
+ HttpResponse httpResponse1 = mHttpClient.request(request);
+ List<String> history = mHttpClient.getHistory();
+
+ assertThat(history)
+ .containsExactly(
+ request.toString(),
+ httpResponse0.toString(),
+ request.toString(),
+ httpResponse1.toString())
+ .inOrder();
+
+ mHttpClient.clearHistory();
+ history = mHttpClient.getHistory();
+
+ assertThat(history).isEmpty();
+ }
}