aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeng Wang <mewan@google.com>2021-05-25 17:47:52 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-05-25 17:47:52 +0000
commitc987171036cf68df973d20fdb0301b6f3ef291f8 (patch)
tree0909cfc97f66cbd81b43d7005885fe13b5a284ba
parent04517003517b29f25cc8dc69b455b1cbcfd451aa (diff)
parentdb18ed256b703a0d61c436fa3d42f3eb4bf7fc82 (diff)
downloadservice_entitlement-c987171036cf68df973d20fdb0301b6f3ef291f8.tar.gz
Merge "Support specifying accept configuration document type XML or JSON" into sc-dev am: 8f2bf45bd0 am: adc146b7af am: db18ed256b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/libs/service_entitlement/+/14623351 Change-Id: I9e29da60352844e3333858cf5e6199da493fca58
-rw-r--r--java/com/android/libraries/entitlement/ServiceEntitlementRequest.java54
-rw-r--r--java/com/android/libraries/entitlement/eapaka/EapAkaApi.java91
-rw-r--r--tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java83
3 files changed, 149 insertions, 79 deletions
diff --git a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
index 9db5246..c7b0ad3 100644
--- a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
+++ b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java
@@ -26,14 +26,23 @@ import com.google.auto.value.AutoValue;
*/
@AutoValue
public abstract class ServiceEntitlementRequest {
- /**
- * Disables notification token.
- */
+ /** Disables notification token. */
public static final int NOTICATION_ACTION_DISABLE = 0;
- /**
- * Enables FCM notification token.
- */
+ /** Enables FCM notification token. */
public static final int NOTICATION_ACTION_ENABLE_FCM = 2;
+ /** Accepts the content type in XML format. */
+ 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. */
+ public static final String ACCEPT_CONTENT_TYPE_JSON_AND_XML =
+ "application/vnd.gsma.eap-relay.v1.0+json, text/vnd.wap.connectivity-xml";
+ /** Default value of configuration version. */
+ public static final int DEFAULT_CONFIGURATION_VERSION = 0;
+ /** Default value of entitlement version. */
+ public static final String DEFAULT_ENTITLEMENT_VERSION = "2.0";
+
/**
* Returns the version of configuration currently stored on the client. Used by HTTP parameter
@@ -100,12 +109,21 @@ public abstract class ServiceEntitlementRequest {
public abstract int notificationAction();
/**
+ * Returns the accepted content type of http response.
+ *
+ * @see #ACCEPT_CONTENT_TYPE_XML
+ * @see #ACCEPT_CONTENT_TYPE_JSON
+ * @see #ACCEPT_CONTENT_TYPE_JSON_AND_XML
+ */
+ public abstract String acceptContentType();
+
+ /**
* Returns a new {@link Builder} object.
*/
public static Builder builder() {
return new AutoValue_ServiceEntitlementRequest.Builder()
- .setConfigurationVersion(0)
- .setEntitlementVersion("2.0")
+ .setConfigurationVersion(DEFAULT_CONFIGURATION_VERSION)
+ .setEntitlementVersion(DEFAULT_ENTITLEMENT_VERSION)
.setAuthenticationToken("")
.setTerminalId("")
.setTerminalVendor(Build.MANUFACTURER)
@@ -114,7 +132,8 @@ public abstract class ServiceEntitlementRequest {
.setAppName("")
.setAppVersion("")
.setNotificationToken("")
- .setNotificationAction(NOTICATION_ACTION_ENABLE_FCM);
+ .setNotificationAction(NOTICATION_ACTION_ENABLE_FCM)
+ .setAcceptContentType(ACCEPT_CONTENT_TYPE_JSON_AND_XML);
}
/**
@@ -126,7 +145,8 @@ public abstract class ServiceEntitlementRequest {
* Sets the version of configuration currently stored on the client. Used by HTTP parameter
* "vers".
*
- * <p>If not set, default to 0 indicating no existing configuration.
+ * <p>If not set, default to {@link #DEFAULT_CONFIGURATION_VERSION} indicating no existing
+ * configuration.
*/
public abstract Builder setConfigurationVersion(int value);
@@ -134,7 +154,7 @@ public abstract class ServiceEntitlementRequest {
* Sets the current version of the entitlement specification. Used by HTTP parameter
* "entitlement_version".
*
- * <p>If not set, default to "2.0" base on TS.43-v5.0.
+ * <p>If not set, default to {@link #DEFAULT_ENTITLEMENT_VERSION} base on TS.43-v5.0.
*/
public abstract Builder setEntitlementVersion(String value);
@@ -211,6 +231,18 @@ public abstract class ServiceEntitlementRequest {
*/
public abstract Builder setNotificationAction(int value);
+ /**
+ * Sets the configuration document format the caller accepts, e.g. XML or JSON. Used by HTTP
+ * request header "Accept".
+ *
+ * <p>If not set, will use {@link #ACCEPT_CONTENT_TYPE_JSON_AND_XML}.
+ *
+ * @see #ACCEPT_CONTENT_TYPE_XML
+ * @see #ACCEPT_CONTENT_TYPE_JSON
+ * @see #ACCEPT_CONTENT_TYPE_JSON_AND_XML
+ */
+ public abstract Builder setAcceptContentType(String contentType);
+
public abstract ServiceEntitlementRequest build();
}
}
diff --git a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
index bf53d87..2e337e4 100644
--- a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
+++ b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java
@@ -33,7 +33,6 @@ import com.android.libraries.entitlement.EsimOdsaOperation;
import com.android.libraries.entitlement.ServiceEntitlementException;
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;
@@ -64,11 +63,6 @@ public class EapAkaApi {
private static final String APP_VERSION = "app_version";
private static final String APP_NAME = "app_name";
- 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 REQUEST_CONTENT_TYPE_JSON =
- "application/vnd.gsma.eap-relay.v1.0+json";
-
private static final String OPERATION = "operation";
private static final String OPERATION_TYPE = "operation_type";
private static final String COMPANION_TERMINAL_ID = "companion_terminal_id";
@@ -119,16 +113,26 @@ public class EapAkaApi {
throws ServiceEntitlementException {
Uri.Builder urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon();
appendParametersForServiceEntitlementRequest(urlBuilder, appIds, request);
- HttpResponse response = httpGet(urlBuilder.toString(), carrierConfig);
- if (!request.authenticationToken().isEmpty()) {
+ if (!TextUtils.isEmpty(request.authenticationToken())) {
// Fast Re-Authentication flow with pre-existing auth token
Log.d(TAG, "Fast Re-Authentication");
- return response.body();
+ return httpGet(
+ urlBuilder.toString(), carrierConfig, request.acceptContentType()).body();
+ } else {
+ // Full Authentication flow
+ Log.d(TAG, "Full Authentication");
+ HttpResponse challengeResponse =
+ httpGet(
+ urlBuilder.toString(),
+ carrierConfig,
+ ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON);
+ return respondToEapAkaChallenge(
+ carrierConfig,
+ challengeResponse,
+ FOLLOW_SYNC_FAILURE_MAX_COUNT,
+ request.acceptContentType())
+ .body();
}
- // Full Authentication flow
- Log.d(TAG, "Full Authentication");
- return respondToEapAkaChallenge(carrierConfig, response, FOLLOW_SYNC_FAILURE_MAX_COUNT)
- .body();
}
/**
@@ -147,14 +151,15 @@ public class EapAkaApi {
* is greater than zero. When this method call itself {@code followSyncFailureCount} is
* reduced by one to prevent infinite loop (unlikely in practice, but just in case).
* </ul>
+ *
+ * @param response Challenge response from server which its content type is JSON
*/
private HttpResponse respondToEapAkaChallenge(
- CarrierConfig carrierConfig, HttpResponse response, int followSyncFailureCount)
+ CarrierConfig carrierConfig,
+ HttpResponse response,
+ int followSyncFailureCount,
+ String contentType)
throws ServiceEntitlementException {
- if (response.contentType() != ContentType.JSON) {
- throw new ServiceEntitlementException(
- ERROR_MALFORMED_HTTP_RESPONSE, "Unexpected http ContentType");
- }
String eapAkaChallenge;
try {
eapAkaChallenge = new JSONObject(response.body()).getString(EAP_CHALLENGE_RESPONSE);
@@ -167,17 +172,22 @@ public class EapAkaApi {
EapAkaResponse.respondToEapAkaChallenge(mContext, mSimSubscriptionId, challenge);
// This could be a successful authentication, or synchronization failure.
if (eapAkaResponse.response() != null) { // successful authentication
- return challengeResponse(eapAkaResponse.response(), carrierConfig, response.cookie());
+ return challengeResponse(
+ eapAkaResponse.response(),
+ carrierConfig,
+ response.cookie(),
+ contentType);
} else if (eapAkaResponse.synchronizationFailureResponse() != null) {
Log.d(TAG, "synchronization failure");
HttpResponse newChallenge =
challengeResponse(
eapAkaResponse.synchronizationFailureResponse(),
carrierConfig,
- response.cookie());
+ response.cookie(),
+ ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON);
if (followSyncFailureCount > 0) {
return respondToEapAkaChallenge(
- carrierConfig, newChallenge, followSyncFailureCount - 1);
+ carrierConfig, newChallenge, followSyncFailureCount - 1, contentType);
} else {
throw new ServiceEntitlementException(
ERROR_EAP_AKA_SYNCHRONIZATION_FAILURE,
@@ -189,7 +199,10 @@ public class EapAkaApi {
}
private HttpResponse challengeResponse(
- String eapAkaChallengeResponse, CarrierConfig carrierConfig, String cookie)
+ String eapAkaChallengeResponse,
+ CarrierConfig carrierConfig,
+ String cookie,
+ String contentType)
throws ServiceEntitlementException {
Log.d(TAG, "challengeResponse");
JSONObject postData = new JSONObject();
@@ -204,8 +217,10 @@ public class EapAkaApi {
.setUrl(carrierConfig.serverUrl())
.setRequestMethod(RequestMethod.POST)
.setPostData(postData)
- .addRequestProperty(HttpHeaders.ACCEPT, ACCEPT_CONTENT_TYPE_JSON_AND_XML)
- .addRequestProperty(HttpHeaders.CONTENT_TYPE, REQUEST_CONTENT_TYPE_JSON)
+ .addRequestProperty(HttpHeaders.ACCEPT, contentType)
+ .addRequestProperty(
+ HttpHeaders.CONTENT_TYPE,
+ ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON)
.addRequestProperty(HttpHeaders.COOKIE, cookie)
.setTimeoutInSec(carrierConfig.timeoutInSec())
.setNetwork(carrierConfig.network())
@@ -226,16 +241,26 @@ public class EapAkaApi {
appendParametersForServiceEntitlementRequest(urlBuilder, ImmutableList.of(appId), request);
appendParametersForEsimOdsaOperation(urlBuilder, odsaOperation);
- HttpResponse response = httpGet(urlBuilder.toString(), carrierConfig);
- if (!request.authenticationToken().isEmpty()) {
+ if (!TextUtils.isEmpty(request.authenticationToken())) {
// Fast Re-Authentication flow with pre-existing auth token
Log.d(TAG, "Fast Re-Authentication");
- return response.body();
+ return httpGet(
+ urlBuilder.toString(), carrierConfig, request.acceptContentType()).body();
+ } else {
+ // Full Authentication flow
+ Log.d(TAG, "Full Authentication");
+ HttpResponse challengeResponse =
+ httpGet(
+ urlBuilder.toString(),
+ carrierConfig,
+ ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON);
+ return respondToEapAkaChallenge(
+ carrierConfig,
+ challengeResponse,
+ FOLLOW_SYNC_FAILURE_MAX_COUNT,
+ request.acceptContentType())
+ .body();
}
- // Full Authentication flow
- Log.d(TAG, "Full Authentication");
- return respondToEapAkaChallenge(carrierConfig, response, FOLLOW_SYNC_FAILURE_MAX_COUNT)
- .body();
}
private void appendParametersForServiceEntitlementRequest(
@@ -322,13 +347,13 @@ public class EapAkaApi {
odsaOperation.targetTerminalEid());
}
- private HttpResponse httpGet(String url, CarrierConfig carrierConfig)
+ private HttpResponse httpGet(String url, CarrierConfig carrierConfig, String contentType)
throws ServiceEntitlementException {
HttpRequest httpRequest =
HttpRequest.builder()
.setUrl(url)
.setRequestMethod(RequestMethod.GET)
- .addRequestProperty(HttpHeaders.ACCEPT, ACCEPT_CONTENT_TYPE_JSON_AND_XML)
+ .addRequestProperty(HttpHeaders.ACCEPT, contentType)
.setTimeoutInSec(carrierConfig.timeoutInSec())
.setNetwork(carrierConfig.network())
.build();
diff --git a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java
index 99e8cfa..f289c04 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.http.HttpRequest;
import com.android.libraries.entitlement.http.HttpResponse;
import com.google.common.collect.ImmutableList;
+import com.google.common.net.HttpHeaders;
import org.json.JSONException;
import org.junit.Before;
@@ -93,19 +94,13 @@ public class EapAkaApiTest {
private static final String ACCEPT_CONTENT_TYPE_JSON_AND_XML =
"application/vnd.gsma.eap-relay.v1.0+json, text/vnd.wap.connectivity-xml";
- @Rule
- public final MockitoRule rule = MockitoJUnit.rule();
+ @Rule public final MockitoRule rule = MockitoJUnit.rule();
- @Mock
- private HttpClient mMockHttpClient;
- @Mock
- private Network mMockNetwork;
- @Mock
- private TelephonyManager mMockTelephonyManager;
- @Mock
- private TelephonyManager mMockTelephonyManagerForSubId;
- @Captor
- private ArgumentCaptor<HttpRequest> mHttpRequestCaptor;
+ @Mock private HttpClient mMockHttpClient;
+ @Mock private Network mMockNetwork;
+ @Mock private TelephonyManager mMockTelephonyManager;
+ @Mock private TelephonyManager mMockTelephonyManagerForSubId;
+ @Captor private ArgumentCaptor<HttpRequest> mHttpRequestCaptor;
private Context mContext;
private EapAkaApi mEapAkaApi;
@@ -203,29 +198,6 @@ public class EapAkaApiTest {
}
@Test
- public void queryEntitlementStatus_noAuthenticationToken_contentTypeNotJson_throwException()
- 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();
- ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build();
-
- 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.getMessage()).isEqualTo("Unexpected http ContentType");
- }
-
- @Test
public void queryEntitlementStatus_noAuthenticationToken_emptyResponseBody_throwException()
throws Exception {
HttpResponse eapChallengeResponse =
@@ -285,6 +257,47 @@ public class EapAkaApiTest {
}
@Test
+ public void queryEntitlementStatus_acceptContentTypeSpecified_verfityAcceptContentType()
+ throws Exception {
+ HttpResponse response = HttpResponse.builder().setBody(RESPONSE_XML).build();
+ when(mMockHttpClient.request(any())).thenReturn(response);
+ CarrierConfig carrierConfig = CarrierConfig.builder().build();
+ ServiceEntitlementRequest request =
+ ServiceEntitlementRequest
+ .builder()
+ .setAuthenticationToken(TOKEN)
+ .setAcceptContentType(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML)
+ .build();
+
+ mEapAkaApi.queryEntitlementStatus(
+ ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
+
+ verify(mMockHttpClient).request(mHttpRequestCaptor.capture());
+ assertThat(mHttpRequestCaptor.getValue().requestProperties().get(HttpHeaders.ACCEPT))
+ .isEqualTo(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML);
+ }
+
+ @Test
+ public void queryEntitlementStatus_acceptContentTypeNotSpecified_defaultAcceptContentType()
+ throws Exception {
+ HttpResponse response = HttpResponse.builder().setBody(RESPONSE_XML).build();
+ when(mMockHttpClient.request(any())).thenReturn(response);
+ CarrierConfig carrierConfig = CarrierConfig.builder().build();
+ ServiceEntitlementRequest request =
+ ServiceEntitlementRequest
+ .builder()
+ .setAuthenticationToken(TOKEN)
+ .build();
+
+ mEapAkaApi.queryEntitlementStatus(
+ ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request);
+
+ verify(mMockHttpClient).request(mHttpRequestCaptor.capture());
+ assertThat(mHttpRequestCaptor.getValue().requestProperties().get(HttpHeaders.ACCEPT))
+ .isEqualTo(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON_AND_XML);
+ }
+
+ @Test
public void performEsimOdsaOperation_noAuthenticationToken_returnsResult() throws Exception {
when(mMockTelephonyManagerForSubId.getIccAuthentication(
TelephonyManager.APPTYPE_USIM,