diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-04 14:53:58 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-10-04 14:53:58 +0000 |
commit | eb8475e4c61719ea9549a227ac08b99c6f05e5c8 (patch) | |
tree | 62ac0f7564a7981742b8bbc3aadc6e647fe1f84a | |
parent | b9dbd578a1f9af1c7c32c0d8638f0fc49df395e3 (diff) | |
parent | 8bfb8ba163d338f5b67ef2cfc516f4b1fea89a50 (diff) | |
download | service_entitlement-eb8475e4c61719ea9549a227ac08b99c6f05e5c8.tar.gz |
Snap for 10900817 from 8bfb8ba163d338f5b67ef2cfc516f4b1fea89a50 to sdk-releaseplatform-tools-34.0.5
Change-Id: I8e7cf1f7128ec7b07e790f57610c4b9941c15d1d
27 files changed, 1978 insertions, 1339 deletions
@@ -22,6 +22,7 @@ java_defaults { libs: [ "androidx.annotation_annotation", "auto_value_annotations", + "error_prone_annotations", ], plugins: ["auto_value_plugin"], sdk_version: "system_current", @@ -93,6 +94,7 @@ java_library { ], srcs: [ "java/com/android/libraries/entitlement/CarrierConfig.java", + "java/com/android/libraries/entitlement/EsimOdsaOperation.java", "java/com/android/libraries/entitlement/ServiceEntitlementException.java", "java/com/android/libraries/entitlement/ServiceEntitlementRequest.java", "java/com/android/libraries/entitlement/odsa/*.java", diff --git a/java/com/android/libraries/entitlement/CarrierConfig.java b/java/com/android/libraries/entitlement/CarrierConfig.java index 44a4170..e75cddf 100644 --- a/java/com/android/libraries/entitlement/CarrierConfig.java +++ b/java/com/android/libraries/entitlement/CarrierConfig.java @@ -32,9 +32,20 @@ public abstract class CarrierConfig { /** Default value of {@link #timeoutInSec} if not set. */ public static final int DEFAULT_TIMEOUT_IN_SEC = 30; + public static final String CLIENT_TS_43_IMS_ENTITLEMENT = "IMS-Entitlement"; + public static final String CLIENT_TS_43_COMPANION_ODSA = "Companion-ODSA"; + public static final String CLIENT_TS_43_PRIMARY_ODSA = "Primary-ODSA"; + public static final String CLIENT_TS_43_SERVER_ODSA = "Server-ODSA"; + /** The carrier's entitlement server URL. See {@link Builder#setServerUrl}. */ public abstract String serverUrl(); + /** + * Client-ts43 attribute. Used to set the User-Agent header in HTTP requests as defined in TS.43 + * section 2.2. + */ + public abstract String clientTs43(); + /** Client side timeout for HTTP connection. See {@link Builder#setTimeoutInSec}. */ public abstract int timeoutInSec(); @@ -46,6 +57,7 @@ public abstract class CarrierConfig { public static Builder builder() { return new AutoValue_CarrierConfig.Builder() .setServerUrl("") + .setClientTs43("") .setTimeoutInSec(DEFAULT_TIMEOUT_IN_SEC); } @@ -60,6 +72,9 @@ public abstract class CarrierConfig { */ public abstract Builder setServerUrl(String url); + /** Sets the Client-ts43 attribute. Used to set the User-Agent header in HTTP requests. */ + public abstract Builder setClientTs43(String clientTs43); + /** * Sets the client side timeout for HTTP connection. Default to * {@link DEFAULT_TIMEOUT_IN_SEC}. diff --git a/java/com/android/libraries/entitlement/EapAkaHelper.java b/java/com/android/libraries/entitlement/EapAkaHelper.java index e5af73e..f29cb0f 100644 --- a/java/com/android/libraries/entitlement/EapAkaHelper.java +++ b/java/com/android/libraries/entitlement/EapAkaHelper.java @@ -87,7 +87,7 @@ public class EapAkaHelper { EapAkaResponse eapAkaResponse = getEapAkaResponse(challenge); return (eapAkaResponse == null) ? null - : eapAkaResponse.response(); // Would be null on synchrinization failure + : eapAkaResponse.response(); // Would be null on synchronization failure } /** diff --git a/java/com/android/libraries/entitlement/odsa/OdsaOperation.java b/java/com/android/libraries/entitlement/EsimOdsaOperation.java index 8de2122..e7b28f6 100644 --- a/java/com/android/libraries/entitlement/odsa/OdsaOperation.java +++ b/java/com/android/libraries/entitlement/EsimOdsaOperation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.libraries.entitlement.odsa; +package com.android.libraries.entitlement; import androidx.annotation.IntDef; import androidx.annotation.NonNull; @@ -31,53 +31,44 @@ import java.lang.annotation.RetentionPolicy; * section 6.2. */ @AutoValue -public abstract class OdsaOperation { - /** - * ODSA operation: CheckEligibility. - */ +public abstract class EsimOdsaOperation { + /** ODSA operation unknown. For initialization only. */ + public static final String OPERATION_UNKNOWN = ""; + + /** ODSA operation: CheckEligibility. */ public static final String OPERATION_CHECK_ELIGIBILITY = "CheckEligibility"; - /** - * ODSA operation: ManageSubscription. - */ + /** ODSA operation: ManageSubscription. */ public static final String OPERATION_MANAGE_SUBSCRIPTION = "ManageSubscription"; - /** - * ODSA operation: ManageService. - */ + /** ODSA operation: ManageService. */ public static final String OPERATION_MANAGE_SERVICE = "ManageService"; - /** - * ODSA operation: AcquireConfiguration. - */ + /** ODSA operation: AcquireConfiguration. */ public static final String OPERATION_ACQUIRE_CONFIGURATION = "AcquireConfiguration"; - /** - * ODSA operation: AcquireTemporaryToken. - */ + /** ODSA operation: AcquireTemporaryToken. */ public static final String OPERATION_ACQUIRE_TEMPORARY_TOKEN = "AcquireTemporaryToken"; - /** - * ODSA operation: GetPhoneNumber - */ + /** ODSA operation: GetPhoneNumber */ public static final String OPERATION_GET_PHONE_NUMBER = "GetPhoneNumber"; - /** - * ODSA operation: AcquirePlan - */ + /** ODSA operation: AcquirePlan */ public static final String OPERATION_ACQUIRE_PLAN = "AcquirePlan"; @Retention(RetentionPolicy.SOURCE) @StringDef({ - OPERATION_CHECK_ELIGIBILITY, - OPERATION_MANAGE_SUBSCRIPTION, - OPERATION_MANAGE_SERVICE, - OPERATION_ACQUIRE_CONFIGURATION, - OPERATION_ACQUIRE_PLAN, - OPERATION_ACQUIRE_TEMPORARY_TOKEN, - OPERATION_GET_PHONE_NUMBER + OPERATION_UNKNOWN, + OPERATION_CHECK_ELIGIBILITY, + OPERATION_MANAGE_SUBSCRIPTION, + OPERATION_MANAGE_SERVICE, + OPERATION_ACQUIRE_CONFIGURATION, + OPERATION_ACQUIRE_PLAN, + OPERATION_ACQUIRE_TEMPORARY_TOKEN, + OPERATION_GET_PHONE_NUMBER }) - public @interface Operation {} + public @interface OdsaOperation { + } /** eSIM device’s service is unknown. */ public static final int SERVICE_STATUS_UNKNOWN = -1; @@ -96,37 +87,30 @@ public abstract class OdsaOperation { @Retention(RetentionPolicy.SOURCE) @IntDef({ - SERVICE_STATUS_UNKNOWN, - SERVICE_STATUS_ACTIVATED, - SERVICE_STATUS_ACTIVATING, - SERVICE_STATUS_DEACTIVATED, - SERVICE_STATUS_DEACTIVATED_NO_REUSE + SERVICE_STATUS_UNKNOWN, + SERVICE_STATUS_ACTIVATED, + SERVICE_STATUS_ACTIVATING, + SERVICE_STATUS_DEACTIVATED, + SERVICE_STATUS_DEACTIVATED_NO_REUSE }) - public @interface ServiceStatus {} + public @interface OdsaServiceStatus { + } - /** - * Indicates that operation_type is not set. - */ + /** Indicates that operation_type is not set. */ public static final int OPERATION_TYPE_NOT_SET = -1; - /** - * To activate a subscription, used by {@link #OPERATION_MANAGE_SUBSCRIPTION}. - */ + /** To activate a subscription, used by {@link #OPERATION_MANAGE_SUBSCRIPTION}. */ public static final int OPERATION_TYPE_SUBSCRIBE = 0; - /** - * To cancel a subscription, used by {@link #OPERATION_MANAGE_SUBSCRIPTION}. - */ + /** To cancel a subscription, used by {@link #OPERATION_MANAGE_SUBSCRIPTION}. */ public static final int OPERATION_TYPE_UNSUBSCRIBE = 1; - /** - * To manage an existing subscription, for {@link #OPERATION_MANAGE_SUBSCRIPTION}. - */ + /** To manage an existing subscription, for {@link #OPERATION_MANAGE_SUBSCRIPTION}. */ public static final int OPERATION_TYPE_CHANGE_SUBSCRIPTION = 2; /** - * To transfer a subscription from an existing device, used by - * {@link #OPERATION_MANAGE_SUBSCRIPTION}. + * To transfer a subscription from an existing device, used by {@link + * #OPERATION_MANAGE_SUBSCRIPTION}. */ public static final int OPERATION_TYPE_TRANSFER_SUBSCRIPTION = 3; @@ -136,52 +120,39 @@ public abstract class OdsaOperation { */ public static final int OPERATION_TYPE_UPDATE_SUBSCRIPTION = 4; - /** - * To activate a service, used by {@link #OPERATION_MANAGE_SERVICE}. - */ + /** To activate a service, used by {@link #OPERATION_MANAGE_SERVICE}. */ public static final int OPERATION_TYPE_ACTIVATE_SERVICE = 10; - /** - * To deactivate a service, used by {@link #OPERATION_MANAGE_SERVICE}. - */ + /** To deactivate a service, used by {@link #OPERATION_MANAGE_SERVICE}. */ public static final int OPERATION_TYPE_DEACTIVATE_SERVICE = 11; @Retention(RetentionPolicy.SOURCE) @IntDef({ - OPERATION_TYPE_NOT_SET, - OPERATION_TYPE_SUBSCRIBE, - OPERATION_TYPE_UNSUBSCRIBE, - OPERATION_TYPE_CHANGE_SUBSCRIPTION, - OPERATION_TYPE_TRANSFER_SUBSCRIPTION, - OPERATION_TYPE_UPDATE_SUBSCRIPTION, - OPERATION_TYPE_ACTIVATE_SERVICE, - OPERATION_TYPE_DEACTIVATE_SERVICE + OPERATION_TYPE_NOT_SET, + OPERATION_TYPE_SUBSCRIBE, + OPERATION_TYPE_UNSUBSCRIBE, + OPERATION_TYPE_CHANGE_SUBSCRIPTION, + OPERATION_TYPE_TRANSFER_SUBSCRIPTION, + OPERATION_TYPE_UPDATE_SUBSCRIPTION, + OPERATION_TYPE_ACTIVATE_SERVICE, + OPERATION_TYPE_DEACTIVATE_SERVICE }) - public @interface OperationType {} + public @interface OdsaOperationType { + } - /** - * Operation result unknown. - */ + /** Operation result unknown. */ public static final int OPERATION_RESULT_UNKNOWN = -1; - /** - * Operation was a success. - */ + /** Operation was a success. */ public static final int OPERATION_RESULT_SUCCESS = 1; - /** - * There was a general error during processing. - */ + /** There was a general error during processing. */ public static final int OPERATION_RESULT_ERROR_GENERAL = 100; - /** - * An invalid operation value was provided in request. - */ + /** An invalid operation value was provided in request. */ public static final int OPERATION_RESULT_ERROR_INVALID_OPERATION = 101; - /** - * An invalid parameter name or value was provided in request. - */ + /** An invalid parameter name or value was provided in request. */ public static final int OPERATION_RESULT_ERROR_INVALID_PARAMETER = 102; /** @@ -199,28 +170,28 @@ public abstract class OdsaOperation { OPERATION_RESULT_ERROR_INVALID_PARAMETER, OPERATION_RESULT_WARNING_NOT_SUPPORTED_OPERATION }) - public @interface OperationResult {} + public @interface OdsaOperationResult { + } - /** - * Indicates the companion device carries the same MSISDN as the primary device. - */ + /** Companion service unknown. For initialization only. */ + public static final String COMPANION_SERVICE_UNKNOWN = ""; + + /** Indicates the companion device carries the same MSISDN as the primary device. */ public static final String COMPANION_SERVICE_SHARED_NUMBER = "SharedNumber"; - /** - * Indicates the companion device carries a different MSISDN as the primary device. - */ + /** Indicates the companion device carries a different MSISDN as the primary device. */ public static final String COMPANION_SERVICE_DIFFERENT_NUMBER = "DiffNumber"; @Retention(RetentionPolicy.SOURCE) @StringDef({ - COMPANION_SERVICE_SHARED_NUMBER, - COMPANION_SERVICE_DIFFERENT_NUMBER + COMPANION_SERVICE_UNKNOWN, + COMPANION_SERVICE_SHARED_NUMBER, + COMPANION_SERVICE_DIFFERENT_NUMBER }) - public @interface CompanionService {} + public @interface CompanionService { + } - /** - * Returns the ODSA operation. Used by HTTP parameter {@code operation}. - */ + /** Returns the ODSA operation. Used by HTTP parameter {@code operation}. */ public abstract String operation(); /** @@ -237,31 +208,32 @@ public abstract class OdsaOperation { /** * Returns the unique identifier of the companion device, like IMEI. Used by HTTP parameter - * {@code companion_terminal_id}. + * {@code + * companion_terminal_id}. */ public abstract String companionTerminalId(); /** - * Returns the OEM of the companion device. Used by HTTP parameter - * {@code companion_terminal_vendor}. + * Returns the OEM of the companion device. Used by HTTP parameter {@code + * companion_terminal_vendor}. */ public abstract String companionTerminalVendor(); /** - * Returns the model of the companion device. Used by HTTP parameter - * {@code companion_terminal_model}. + * Returns the model of the companion device. Used by HTTP parameter {@code + * companion_terminal_model}. */ public abstract String companionTerminalModel(); /** - * Returns the software version of the companion device. Used by HTTP parameter - * {@code companion_terminal_sw_version}. + * Returns the software version of the companion device. Used by HTTP parameter {@code + * companion_terminal_sw_version}. */ public abstract String companionTerminalSoftwareVersion(); /** - * Returns the user-friendly version of the companion device. Used by HTTP parameter - * {@code companion_terminal_friendly_name}. + * Returns the user-friendly version of the companion device. Used by HTTP parameter {@code + * companion_terminal_friendly_name}. */ public abstract String companionTerminalFriendlyName(); @@ -272,8 +244,8 @@ public abstract class OdsaOperation { public abstract String companionTerminalService(); /** - * Returns the ICCID of the companion device. Used by HTTP parameter - * {@code companion_terminal_iccid}. + * Returns the ICCID of the companion device. Used by HTTP parameter {@code + * companion_terminal_iccid}. */ public abstract String companionTerminalIccid(); @@ -289,8 +261,8 @@ public abstract class OdsaOperation { public abstract String terminalIccid(); /** - * Returns the eUICC identifier (EID) of the primary device eSIM. Used by HTTP parameter - * {@code terminal_eid}. + * Returns the eUICC identifier (EID) of the primary device eSIM. Used by HTTP parameter {@code + * terminal_eid}. */ public abstract String terminalEid(); @@ -301,10 +273,10 @@ public abstract class OdsaOperation { public abstract String targetTerminalId(); /** - * Returns the unique identifiers of the primary device eSIM if more than one, like the - * IMEIs on dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis}. + * Returns the unique identifiers of the primary device eSIM if more than one, like the IMEIs on + * dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis}. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. */ @NonNull public abstract ImmutableList<String> targetTerminalIds(); @@ -315,8 +287,8 @@ public abstract class OdsaOperation { public abstract String targetTerminalIccid(); /** - * Returns the eUICC identifier (EID) of the primary device eSIM. Used by HTTP parameter - * {@code target_terminal_eid}. + * Returns the eUICC identifier (EID) of the primary device eSIM. Used by HTTP parameter {@code + * target_terminal_eid}. */ public abstract String targetTerminalEid(); @@ -324,37 +296,32 @@ public abstract class OdsaOperation { * Returns the serial number of primary device. Used by HTTP parameter * {@code target_terminal_sn}. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. */ @NonNull public abstract String targetTerminalSerialNumber(); /** - * Returns the model of primary device. Used by HTTP parameter - * {@code target_terminal_model}. + * Returns the model of primary device. Used by HTTP parameter {@code target_terminal_model}. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. */ @NonNull public abstract String targetTerminalModel(); /** - * Returns the unique identifier of the old device eSIM, like the IMEI associated with the - * eSIM. Used by HTTP parameter {@code old_terminal_id}. + * Returns the unique identifier of the old device eSIM, like the IMEI associated with the eSIM. + * Used by HTTP parameter {@code old_terminal_id}. */ public abstract String oldTerminalId(); - /** - * Returns the ICCID of old device eSIM. Used by HTTP parameter {@code old_terminal_iccid}. - */ + /** Returns the ICCID of old device eSIM. Used by HTTP parameter {@code old_terminal_iccid}. */ public abstract String oldTerminalIccid(); - /** - * Returns a new {@link Builder} object. - */ + /** Returns a new {@link Builder} object. */ public static Builder builder() { - return new AutoValue_OdsaOperation.Builder() - .setOperation("") + return new AutoValue_EsimOdsaOperation.Builder() + .setOperation(OPERATION_UNKNOWN) .setOperationType(OPERATION_TYPE_NOT_SET) .setOperationTargets(ImmutableList.of()) .setCompanionTerminalId("") @@ -362,7 +329,7 @@ public abstract class OdsaOperation { .setCompanionTerminalModel("") .setCompanionTerminalSoftwareVersion("") .setCompanionTerminalFriendlyName("") - .setCompanionTerminalService("") + .setCompanionTerminalService(COMPANION_SERVICE_UNKNOWN) .setCompanionTerminalIccid("") .setCompanionTerminalEid("") .setTerminalIccid("") @@ -381,8 +348,10 @@ public abstract class OdsaOperation { * Builder. * * <p>For ODSA, the rule of which parameters are required varies or each - * operation/operation_type. The Javadoc below gives high-level description, but please refer to - * GSMA spec TS.43 section 6.2 for details. + * operation/operation_type. + * The Javadoc below gives high-level description, but please refer to GSMA spec TS.43 section + * 6.2 + * for details. */ @AutoValue.Builder public abstract static class Builder { @@ -390,9 +359,7 @@ public abstract class OdsaOperation { * Sets the eSIM ODSA operation. Used by HTTP parameter {@code operation}. * * @param operation ODSA operation. - * * @return The builder. - * * @see #OPERATION_CHECK_ELIGIBILITY * @see #OPERATION_MANAGE_SUBSCRIPTION * @see #OPERATION_MANAGE_SERVICE @@ -402,11 +369,12 @@ public abstract class OdsaOperation { * @see #OPERATION_ACQUIRE_PLAN */ @NonNull - public abstract Builder setOperation(@NonNull @Operation String operation); + public abstract Builder setOperation(@NonNull @OdsaOperation String operation); /** * Sets the detailed type of the eSIM ODSA operation. Used by HTTP parameter - * "operation_type" if set. + * "operation_type" if + * set. * * <p>Required by some operation. * @@ -419,7 +387,7 @@ public abstract class OdsaOperation { * @see #OPERATION_TYPE_DEACTIVATE_SERVICE */ @NonNull - public abstract Builder setOperationType(@OperationType int operationType); + public abstract Builder setOperationType(@OdsaOperationType int operationType); /** * Sets the operation targets to be used with temporary token from AcquireTemporaryToken @@ -427,55 +395,52 @@ public abstract class OdsaOperation { */ @NonNull public abstract Builder setOperationTargets( - @NonNull @Operation ImmutableList<String> operationTargets); + @NonNull @OdsaOperation ImmutableList<String> operationTargets); /** * Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter - * {@code companion_terminal_id} if set. + * {@code + * companion_terminal_id} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalId The unique identifier of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalId(@NonNull String companionTerminalId); /** - * Sets the OEM of the companion device. Used by HTTP parameter - * {@code companion_terminal_vendor} if set. + * Sets the OEM of the companion device. Used by HTTP parameter {@code + * companion_terminal_vendor} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalVendor The OEM of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalVendor(@NonNull String companionTerminalVendor); /** - * Sets the model of the companion device. Used by HTTP parameter - * {@code companion_terminal_model} if set. + * Sets the model of the companion device. Used by HTTP parameter {@code + * companion_terminal_model} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalModel The model of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalModel(@NonNull String companionTerminalModel); /** - * Sets the software version of the companion device. Used by HTTP parameter - * {@code companion_terminal_sw_version} if set. + * Sets the software version of the companion device. Used by HTTP parameter {@code + * companion_terminal_sw_version} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalSoftwareVersion The software version of the companion device. - * * @return The builder. */ @NonNull @@ -483,13 +448,12 @@ public abstract class OdsaOperation { @NonNull String companionTerminalSoftwareVersion); /** - * Sets the user-friendly version of the companion device. Used by HTTP parameter - * {@code companion_terminal_friendly_name} if set. + * Sets the user-friendly version of the companion device. Used by HTTP parameter {@code + * companion_terminal_friendly_name} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalFriendlyName The user-friendly version of the companion device. - * * @return The builder. */ @NonNull @@ -500,40 +464,36 @@ public abstract class OdsaOperation { * Sets the service type of the companion device, e.g. if the MSISDN is same as the primary * device. Used by HTTP parameter {@code companion_terminal_service} if set. * - * Used by companion device ODSA operation. - * - * @see #COMPANION_SERVICE_SHARED_NUMBER - * @see #COMPANION_SERVICE_DIFFERENT_NUMBER + * <p>Used by companion device ODSA operation. * * @param companionTerminalService The service type of the companion device. - * * @return The builder. + * @see #COMPANION_SERVICE_SHARED_NUMBER + * @see #COMPANION_SERVICE_DIFFERENT_NUMBER */ @NonNull public abstract Builder setCompanionTerminalService( @NonNull @CompanionService String companionTerminalService); /** - * Sets the ICCID of the companion device. Used by HTTP parameter - * {@code companion_terminal_iccid} if set. + * Sets the ICCID of the companion device. Used by HTTP parameter {@code + * companion_terminal_iccid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalIccid The ICCID of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalIccid(@NonNull String companionTerminalIccid); /** - * Sets the eUICC identifier (EID) of the companion device. Used by HTTP parameter - * {@code companion_terminal_eid} if set. + * Sets the eUICC identifier (EID) of the companion device. Used by HTTP parameter {@code + * companion_terminal_eid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalEid The eUICC identifier (EID) of the companion device. - * * @return The builder. */ @NonNull @@ -541,13 +501,13 @@ public abstract class OdsaOperation { /** * Sets the ICCID of the primary device eSIM in case of primary SIM not present. Used by - * HTTP parameter {@code terminal_eid} if set. + * HTTP + * parameter {@code terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalIccid The ICCID of the primary device eSIM in case of primary SIM not - * present. - * + * present. * @return The builder. */ @NonNull @@ -557,11 +517,11 @@ public abstract class OdsaOperation { * Sets the eUICC identifier (EID) of the primary device eSIM in case of primary SIM not * present. Used by HTTP parameter {@code terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalEid The eUICC identifier (EID) of the primary device eSIM in case of - * primary SIM not present. - * + * primary + * SIM not present. * @return The builder. */ @NonNull @@ -569,40 +529,40 @@ public abstract class OdsaOperation { /** * Sets the unique identifier of the primary device eSIM in case of multiple SIM, like the - * IMEI associated with the eSIM. Used by HTTP parameter {@code target_terminal_id} if set. + * IMEI + * associated with the eSIM. Used by HTTP parameter {@code target_terminal_id} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalId The unique identifier of the primary device eSIM in case of - * multiple SIM. - * + * multiple + * SIM. * @return The builder. */ @NonNull public abstract Builder setTargetTerminalId(@NonNull String targetTerminalId); /** - * Sets the unique identifiers of the primary device eSIM if more than one, like the - * IMEIs on dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis}. - * - * This is a non-standard params required by some carriers. + * Sets the unique identifiers of the primary device eSIM if more than one, like the IMEIs + * on + * dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis}. * - * @param targetTerminalIds The unique identifiers of the primary device eSIM if more - * than one. + * <p>This is a non-standard params required by some carriers. * + * @param targetTerminalIds The unique identifiers of the primary device eSIM if more than + * one. * @return The builder. */ public abstract Builder setTargetTerminalIds( @NonNull ImmutableList<String> targetTerminalIds); /** - * Sets the ICCID primary device eSIM in case of multiple SIM. Used by HTTP parameter - * {@code target_terminal_iccid} if set. + * Sets the ICCID primary device eSIM in case of multiple SIM. Used by HTTP parameter {@code + * target_terminal_iccid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalIccid The ICCID primary device eSIM in case of multiple SIM. - * * @return The builder. */ @NonNull @@ -610,13 +570,14 @@ public abstract class OdsaOperation { /** * Sets the eUICC identifier (EID) of the primary device eSIM in case of multiple SIM. Used - * by HTTP parameter {@code target_terminal_eid} if set. + * by + * HTTP parameter {@code target_terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalEid The eUICC identifier (EID) of the primary device eSIM in case of - * multiple SIM. - * + * multiple + * SIM. * @return The builder. */ @NonNull @@ -627,9 +588,8 @@ public abstract class OdsaOperation { * {@code target_terminal_sn}. * * @param targetTerminalSerialNumber The serial number of primary device. - * - * This is a non-standard params required by some carriers. - * + * <p>This is a non-standard params required by some + * carriers. * @return The builder. */ @NonNull @@ -637,13 +597,10 @@ public abstract class OdsaOperation { @NonNull String targetTerminalSerialNumber); /** - * Sets the model of primary device. Used by HTTP parameter - * {@code target_terminal_model}. + * Sets the model of primary device. Used by HTTP parameter {@code target_terminal_model}. * * @param targetTerminalModel The model of primary device. - * - * This is a non-standard params required by some carriers. - * + * <p>This is a non-standard params required by some carriers. * @return The builder. */ @NonNull @@ -651,12 +608,12 @@ public abstract class OdsaOperation { /** * Sets the unique identifier of the old device eSIM, like the IMEI associated with the - * eSIM. Used by HTTP parameter {@code old_terminal_id} if set. + * eSIM. + * Used by HTTP parameter {@code old_terminal_id} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param oldTerminalId The unique identifier of the old device eSIM. - * * @return The builder. */ @NonNull @@ -665,19 +622,16 @@ public abstract class OdsaOperation { /** * Sets the ICCID old device eSIM. Used by HTTP parameter {@code old_terminal_iccid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param oldTerminalIccid The ICCID old device eSIM. - * * @return The builder. */ @NonNull public abstract Builder setOldTerminalIccid(@NonNull String oldTerminalIccid); - /** - * @return The {@link OdsaOperation} object. - */ + /** Returns the {@link EsimOdsaOperation} object. */ @NonNull - public abstract OdsaOperation build(); + public abstract EsimOdsaOperation build(); } } diff --git a/java/com/android/libraries/entitlement/ServiceEntitlement.java b/java/com/android/libraries/entitlement/ServiceEntitlement.java index 82fc3d5..5151c32 100644 --- a/java/com/android/libraries/entitlement/ServiceEntitlement.java +++ b/java/com/android/libraries/entitlement/ServiceEntitlement.java @@ -18,11 +18,11 @@ package com.android.libraries.entitlement; import android.content.Context; -import androidx.annotation.Nullable; +import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import com.android.libraries.entitlement.eapaka.EapAkaApi; -import com.android.libraries.entitlement.odsa.OdsaOperation; +import com.android.libraries.entitlement.http.HttpResponse; import com.android.libraries.entitlement.utils.Ts43Constants; import com.google.common.collect.ImmutableList; @@ -84,7 +84,7 @@ public class ServiceEntitlement { private final CarrierConfig carrierConfig; private final EapAkaApi eapAkaApi; - private String mOidcAcceptContentType; + private ServiceEntitlementRequest mOidcRequest; /** * Creates an instance for service entitlement configuration query and operation for the * carrier. @@ -201,10 +201,10 @@ public class ServiceEntitlement { * @param appId an app ID string defined in TS.43 section 2.2, e.g. {@link #APP_VOWIFI}. * @param request contains parameters that can be used in the HTTP request. */ - @Nullable + @NonNull public String queryEntitlementStatus(String appId, ServiceEntitlementRequest request) throws ServiceEntitlementException { - return eapAkaApi.queryEntitlementStatus(ImmutableList.of(appId), carrierConfig, request); + return queryEntitlementStatus(ImmutableList.of(appId), request); } /** @@ -212,13 +212,29 @@ public class ServiceEntitlement { * request/response. For on device service activation (ODSA) of eSIM for companion/primary * devices, use {@link #performEsimOdsa} instead. * - * <p>Same with {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)} except that + * <p>Same as {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)} except that * multiple "app" parameters will be set in the HTTP request, in the order as they appear in * parameter {@code appIds}. */ + @NonNull public String queryEntitlementStatus(ImmutableList<String> appIds, ServiceEntitlementRequest request) throws ServiceEntitlementException { + return getEntitlementStatusResponse(appIds, request).body(); + } + + /** + * Retrieves service entitlement configurations for multiple app IDs in one HTTP + * request/response. For on device service activation (ODSA) of eSIM for companion/primary + * devices, use {@link #performEsimOdsa} instead. + * + * <p>Same as {@link #queryEntitlementStatus(ImmutableList, ServiceEntitlementRequest)} + * except that it returns the full HTTP response instead of just the body. + */ + @NonNull + public HttpResponse getEntitlementStatusResponse(ImmutableList<String> appIds, + ServiceEntitlementRequest request) + throws ServiceEntitlementException { return eapAkaApi.queryEntitlementStatus(appIds, carrierConfig, request); } @@ -230,10 +246,25 @@ public class ServiceEntitlement { * <p>Similar to {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)}, this * method sends an HTTP GET request to entitlement server, responds to EAP-AKA challenge if * needed, and returns the raw configuration doc as a string. Additional parameters from {@code - * operation} are set to the HTTP request. See {@link OdsaOperation} for details. + * operation} are set to the HTTP request. See {@link EsimOdsaOperation} for details. */ + @NonNull public String performEsimOdsa( - String appId, ServiceEntitlementRequest request, OdsaOperation operation) + String appId, ServiceEntitlementRequest request, EsimOdsaOperation operation) + throws ServiceEntitlementException { + return getEsimOdsaResponse(appId, request, operation).body(); + } + + /** + * Retrieves the HTTP response after performing on device service activation (ODSA) of eSIM for + * companion/primary devices. + * + * <p>Same as {@link #performEsimOdsa(String, ServiceEntitlementRequest, EsimOdsaOperation)} + * except that it returns the full HTTP response instead of just the body. + */ + @NonNull + public HttpResponse getEsimOdsaResponse( + String appId, ServiceEntitlementRequest request, EsimOdsaOperation operation) throws ServiceEntitlementException { return eapAkaApi.performEsimOdsaOperation(appId, carrierConfig, request, operation); } @@ -249,9 +280,10 @@ public class ServiceEntitlement { * @param appId an app ID string defined in TS.43 section 2.2 * @param request contains parameters that can be used in the HTTP request */ + @NonNull public String acquireOidcAuthenticationEndpoint(String appId, ServiceEntitlementRequest request) throws ServiceEntitlementException { - mOidcAcceptContentType = request.acceptContentType(); + mOidcRequest = request; return eapAkaApi.acquireOidcAuthenticationEndpoint(appId, carrierConfig, request); } @@ -264,14 +296,31 @@ public class ServiceEntitlement { * * @param url the redirect url from OIDC authentication result. */ + @NonNull public String queryEntitlementStatusFromOidc(String url) throws ServiceEntitlementException { - return eapAkaApi.queryEntitlementStatusFromOidc(url, carrierConfig, mOidcAcceptContentType); + return getEntitlementStatusResponseFromOidc(url).body(); + } + + /** + * Retrieves the HTTP response containing the service entitlement configuration from + * OIDC authentication result. + * + * <p>Same as {@link #queryEntitlementStatusFromOidc(String)} except that it returns the + * full HTTP response instead of just the body. + * + * @param url the redirect url from OIDC authentication result. + */ + @NonNull + public HttpResponse getEntitlementStatusResponseFromOidc(String url) + throws ServiceEntitlementException { + return eapAkaApi.queryEntitlementStatusFromOidc(url, carrierConfig, mOidcRequest); } /** * Retrieves the history of past HTTP request and responses if {@code saveHttpHistory} was set * in constructor. */ + @NonNull public List<String> getHistory() { return eapAkaApi.getHistory(); } diff --git a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java index 78c44ef..291384d 100644 --- a/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java +++ b/java/com/android/libraries/entitlement/ServiceEntitlementRequest.java @@ -24,14 +24,10 @@ import com.android.libraries.entitlement.utils.Ts43Constants; import com.google.auto.value.AutoValue; /** - * Service entitlement HTTP request parameters, as defiend in GSMA spec TS.43 section 2.2. + * Service entitlement HTTP request parameters, as defined in GSMA spec TS.43 section 2.2. */ @AutoValue public abstract class ServiceEntitlementRequest { - /** Disables notification token. */ - public static final int NOTICATION_ACTION_DISABLE = 0; - /** 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. */ @@ -43,7 +39,6 @@ public abstract class ServiceEntitlementRequest { /** Default value of configuration version. */ public static final int DEFAULT_CONFIGURATION_VERSION = 0; - /** * Returns the version of configuration currently stored on the client. Used by HTTP parameter * "vers". @@ -107,10 +102,8 @@ public abstract class ServiceEntitlementRequest { /** * Returns the action associated with the FCM registration token. Used by HTTP parameter * "notif_action". - * - * @see #NOTICATION_ACTION_ENABLE_FCM - * @see #NOTICATION_ACTION_DISABLE */ + @Ts43Constants.NotificationAction public abstract int notificationAction(); /** @@ -139,11 +132,11 @@ public abstract class ServiceEntitlementRequest { .setTerminalId("") .setTerminalVendor(Build.MANUFACTURER) .setTerminalModel(Build.MODEL) - .setTerminalSoftwareVersion(VERSION.BASE_OS) + .setTerminalSoftwareVersion(VERSION.RELEASE) .setAppName("") .setAppVersion("") .setNotificationToken("") - .setNotificationAction(NOTICATION_ACTION_ENABLE_FCM) + .setNotificationAction(Ts43Constants.NOTIFICATION_ACTION_ENABLE_FCM) .setAcceptContentType(ACCEPT_CONTENT_TYPE_JSON_AND_XML) .setBoostType(""); } @@ -243,13 +236,10 @@ public abstract class ServiceEntitlementRequest { * Sets the action associated with the FCM registration token. Used by HTTP parameter * "notif_action". * - * <p>Required if a token is set with {@link #setNotificationToken}, and default to {@link - * #NOTICATION_ACTION_ENABLE_FCM}; otherwise ignored. - * - * @see #NOTICATION_ACTION_ENABLE_FCM - * @see #NOTICATION_ACTION_DISABLE + * <p>Required if a token is set with {@link #setNotificationToken}, and default to + * {@link Ts43Constants#NOTIFICATION_ACTION_ENABLE_FCM}; otherwise ignored. */ - public abstract Builder setNotificationAction(int value); + public abstract Builder setNotificationAction(@Ts43Constants.NotificationAction int value); /** * Sets the configuration document format the caller accepts, e.g. XML or JSON. Used by HTTP diff --git a/java/com/android/libraries/entitlement/Ts43Authentication.java b/java/com/android/libraries/entitlement/Ts43Authentication.java index 3af6790..29d0cb9 100644 --- a/java/com/android/libraries/entitlement/Ts43Authentication.java +++ b/java/com/android/libraries/entitlement/Ts43Authentication.java @@ -29,6 +29,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import com.android.libraries.entitlement.http.HttpResponse; import com.android.libraries.entitlement.utils.Ts43Constants; import com.android.libraries.entitlement.utils.Ts43Constants.AppId; import com.android.libraries.entitlement.utils.Ts43XmlDoc; @@ -62,6 +63,12 @@ public class Ts43Authentication { public abstract String token(); /** + * The list of cookies from the {@code Set-Cookie} header of the TS.43 response. + */ + @NonNull + public abstract ImmutableList<String> cookies(); + + /** * Indicates the validity of the token. Note this value is server dependent. The client is * expected to interpret this value itself. */ @@ -71,13 +78,15 @@ public class Ts43Authentication { * Create the {@link Ts43AuthToken} object. * * @param token The authentication token for TS.43 operations. + * @param cookie The list of cookies from the {@code Set-Cookie} header. * @param validity Indicates the validity of the token. Note this value is server * dependent. If not available, set to {@link #VALIDITY_NOT_AVAILABLE}. * * @return The {@link Ts43AuthToken} object. */ - public static Ts43AuthToken create(@NonNull String token, long validity) { - return new AutoValue_Ts43Authentication_Ts43AuthToken(token, validity); + public static Ts43AuthToken create(@NonNull String token, + @NonNull ImmutableList<String> cookie, long validity) { + return new AutoValue_Ts43Authentication_Ts43AuthToken(token, cookie, validity); } } @@ -192,17 +201,23 @@ public class Ts43Authentication { SubscriptionManager.getSubscriptionId(slotIndex)); } + // Get the full HTTP response instead of just the body so we can reuse the same cookies. + HttpResponse response; String rawXml; try { - rawXml = mServiceEntitlement.queryEntitlementStatus(ImmutableList.of(appId), request); + response = mServiceEntitlement.getEntitlementStatusResponse( + ImmutableList.of(appId), request); + rawXml = response == null ? null : response.body(); Log.d(TAG, "getAuthToken: rawXml=" + rawXml); } catch (ServiceEntitlementException e) { Log.w(TAG, "Failed to get authentication token. e=" + e); throw e; } - Ts43XmlDoc ts43xmlDoc = new Ts43XmlDoc(rawXml); - String authToken = ts43xmlDoc.get( + ImmutableList<String> cookies = response == null ? ImmutableList.of() : response.cookies(); + + Ts43XmlDoc ts43XmlDoc = new Ts43XmlDoc(rawXml); + String authToken = ts43XmlDoc.get( ImmutableList.of(Ts43XmlDoc.CharacteristicType.TOKEN), Ts43XmlDoc.Parm.TOKEN); if (TextUtils.isEmpty(authToken)) { Log.w(TAG, "Failed to parse authentication token"); @@ -211,7 +226,7 @@ public class Ts43Authentication { "Failed to parse authentication token"); } - String validityString = nullToEmpty(ts43xmlDoc.get(ImmutableList.of( + String validityString = nullToEmpty(ts43XmlDoc.get(ImmutableList.of( Ts43XmlDoc.CharacteristicType.TOKEN), Ts43XmlDoc.Parm.VALIDITY)); long validity; try { @@ -219,7 +234,8 @@ public class Ts43Authentication { } catch (NumberFormatException e) { validity = Ts43AuthToken.VALIDITY_NOT_AVAILABLE; } - return Ts43AuthToken.create(authToken, validity); + + return Ts43AuthToken.create(authToken, cookies, validity); } /** diff --git a/java/com/android/libraries/entitlement/Ts43Operation.java b/java/com/android/libraries/entitlement/Ts43Operation.java index 23cb03e..e603e86 100644 --- a/java/com/android/libraries/entitlement/Ts43Operation.java +++ b/java/com/android/libraries/entitlement/Ts43Operation.java @@ -26,6 +26,7 @@ import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaServiceStatus; import com.android.libraries.entitlement.http.HttpConstants; import com.android.libraries.entitlement.odsa.AcquireConfigurationOperation.AcquireConfigurationRequest; import com.android.libraries.entitlement.odsa.AcquireConfigurationOperation.AcquireConfigurationResponse; @@ -35,12 +36,12 @@ import com.android.libraries.entitlement.odsa.CheckEligibilityOperation; import com.android.libraries.entitlement.odsa.CheckEligibilityOperation.CheckEligibilityRequest; import com.android.libraries.entitlement.odsa.CheckEligibilityOperation.CheckEligibilityResponse; import com.android.libraries.entitlement.odsa.DownloadInfo; +import com.android.libraries.entitlement.odsa.GetPhoneNumberOperation.GetPhoneNumberRequest; +import com.android.libraries.entitlement.odsa.GetPhoneNumberOperation.GetPhoneNumberResponse; import com.android.libraries.entitlement.odsa.ManageServiceOperation.ManageServiceRequest; import com.android.libraries.entitlement.odsa.ManageServiceOperation.ManageServiceResponse; import com.android.libraries.entitlement.odsa.ManageSubscriptionOperation.ManageSubscriptionRequest; import com.android.libraries.entitlement.odsa.ManageSubscriptionOperation.ManageSubscriptionResponse; -import com.android.libraries.entitlement.odsa.OdsaOperation; -import com.android.libraries.entitlement.odsa.OdsaOperation.ServiceStatus; import com.android.libraries.entitlement.odsa.OdsaResponse; import com.android.libraries.entitlement.odsa.PlanOffer; import com.android.libraries.entitlement.utils.Ts43Constants; @@ -62,31 +63,26 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -/** - * TS43 operations described in GSMA Service Entitlement Configuration spec. - */ +/** TS43 operations described in GSMA Service Entitlement Configuration spec. */ public class Ts43Operation { private static final String TAG = "Ts43"; /** - * The normal token retrieved via - * {@link Ts43Authentication#getAuthToken(int, String, String, String)} - * or {@link Ts43Authentication#getAuthToken(URL)}. + * The normal token retrieved via {@link Ts43Authentication#getAuthToken(int, String, String, + * String)} or {@link Ts43Authentication#getAuthToken(URL)}. */ public static final int TOKEN_TYPE_NORMAL = 1; /** - * The temporary token retrieved via - * {@link Ts43Operation#acquireTemporaryToken(AcquireTemporaryTokenRequest)}. + * The temporary token retrieved via {@link + * Ts43Operation#acquireTemporaryToken(AcquireTemporaryTokenRequest)}. */ public static final int TOKEN_TYPE_TEMPORARY = 2; @Retention(RetentionPolicy.SOURCE) - @IntDef({ - TOKEN_TYPE_NORMAL, - TOKEN_TYPE_TEMPORARY - }) - public @interface TokenType {} + @IntDef({TOKEN_TYPE_NORMAL, TOKEN_TYPE_TEMPORARY}) + public @interface TokenType { + } /** The application context. */ @NonNull @@ -99,9 +95,7 @@ public class Ts43Operation { @NonNull private final String mEntitlementVersion; - /** - * The entitlement server address. - */ + /** The entitlement server address. */ @NonNull private final URL mEntitlementServerAddress; @@ -114,8 +108,8 @@ public class Ts43Operation { private String mAuthToken; /** - * The temporary token retrieved from - * {@link #acquireTemporaryToken(AcquireTemporaryTokenRequest)}. + * The temporary token retrieved from {@link + * #acquireTemporaryToken(AcquireTemporaryTokenRequest)}. */ @Nullable private String mTemporaryToken; @@ -137,15 +131,20 @@ public class Ts43Operation { * * @param slotIndex The logical SIM slot index involved in ODSA operation. * @param entitlementServerAddress The entitlement server address. - * @param entitlementVersion The TS.43 entitlement version to use. For example, {@code "9.0"}. - * If {@code null}, version {@code "2.0"} will be used by default. + * @param entitlementVersion The TS.43 entitlement version to use. For example, + * {@code "9.0"}. If {@code null}, version {@code "2.0"} will be used + * by default. * @param authToken The authentication token. * @param tokenType The token type. Can be {@link #TOKEN_TYPE_NORMAL} or - * {@link #TOKEN_TYPE_TEMPORARY}. + * {@link #TOKEN_TYPE_TEMPORARY}. */ - public Ts43Operation(@NonNull Context context, int slotIndex, - @NonNull URL entitlementServerAddress, @Nullable String entitlementVersion, - @NonNull String authToken, @TokenType int tokenType) { + public Ts43Operation( + @NonNull Context context, + int slotIndex, + @NonNull URL entitlementServerAddress, + @Nullable String entitlementVersion, + @NonNull String authToken, + @TokenType int tokenType) { mContext = context; mEntitlementServerAddress = entitlementServerAddress; if (entitlementVersion != null) { @@ -161,13 +160,14 @@ public class Ts43Operation { } else { throw new IllegalArgumentException("Invalid token type " + tokenType); } + mTokenType = tokenType; - CarrierConfig carrierConfig = CarrierConfig.builder() - .setServerUrl(mEntitlementServerAddress.toString()) - .build(); + CarrierConfig carrierConfig = + CarrierConfig.builder().setServerUrl(mEntitlementServerAddress.toString()).build(); - mServiceEntitlement = new ServiceEntitlement(mContext, carrierConfig, - SubscriptionManager.getSubscriptionId(slotIndex)); + mServiceEntitlement = + new ServiceEntitlement( + mContext, carrierConfig, SubscriptionManager.getSubscriptionId(slotIndex)); String imei = null; TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); @@ -185,10 +185,9 @@ public class Ts43Operation { * Entitlement Configuration section 6.2 and 6.5.2. * * @return {@code true} if the end-user is allowed to perform ODSA operation. - * * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull public CheckEligibilityResponse checkEligibility( @@ -196,9 +195,10 @@ public class Ts43Operation { throws ServiceEntitlementException { Objects.requireNonNull(checkEligibilityRequest); - ServiceEntitlementRequest.Builder builder = ServiceEntitlementRequest.builder() - .setEntitlementVersion(mEntitlementVersion) - .setTerminalId(mImei); + ServiceEntitlementRequest.Builder builder = + ServiceEntitlementRequest.builder() + .setEntitlementVersion(mEntitlementVersion) + .setTerminalId(mImei); if (mTokenType == TOKEN_TYPE_NORMAL) { builder.setAuthenticationToken(mAuthToken); @@ -206,23 +206,35 @@ public class Ts43Operation { builder.setTemporaryToken(mTemporaryToken); } + String notificationToken = checkEligibilityRequest.notificationToken(); + if (!TextUtils.isEmpty(notificationToken)) { + builder.setNotificationToken(notificationToken); + } + int notificationAction = checkEligibilityRequest.notificationAction(); + if (Ts43Constants.isValidNotificationAction(notificationAction)) { + builder.setNotificationAction(notificationAction); + } + ServiceEntitlementRequest request = builder.build(); - OdsaOperation operation = OdsaOperation.builder() - .setOperation(OdsaOperation.OPERATION_CHECK_ELIGIBILITY) - .setCompanionTerminalId(checkEligibilityRequest.companionTerminalId()) - .setCompanionTerminalVendor(checkEligibilityRequest.companionTerminalVendor()) - .setCompanionTerminalModel(checkEligibilityRequest.companionTerminalModel()) - .setCompanionTerminalSoftwareVersion(checkEligibilityRequest - .companionTerminalSoftwareVersion()) - .setCompanionTerminalFriendlyName(checkEligibilityRequest - .companionTerminalFriendlyName()) - .build(); + EsimOdsaOperation operation = + EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_CHECK_ELIGIBILITY) + .setCompanionTerminalId(checkEligibilityRequest.companionTerminalId()) + .setCompanionTerminalVendor( + checkEligibilityRequest.companionTerminalVendor()) + .setCompanionTerminalModel(checkEligibilityRequest.companionTerminalModel()) + .setCompanionTerminalSoftwareVersion( + checkEligibilityRequest.companionTerminalSoftwareVersion()) + .setCompanionTerminalFriendlyName( + checkEligibilityRequest.companionTerminalFriendlyName()) + .build(); String rawXml; try { - rawXml = mServiceEntitlement.performEsimOdsa(checkEligibilityRequest.appId(), - request, operation); + rawXml = + mServiceEntitlement.performEsimOdsa(checkEligibilityRequest.appId(), request, + operation); } catch (ServiceEntitlementException e) { Log.w(TAG, "manageSubscription: Failed to perform ODSA operation. e=" + e); throw e; @@ -243,13 +255,15 @@ public class Ts43Operation { } // Parse the eligibility - String eligibilityString = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.PRIMARY_APP_ELIGIBILITY); + String eligibilityString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.PRIMARY_APP_ELIGIBILITY); if (TextUtils.isEmpty(eligibilityString)) { - eligibilityString = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.COMPANION_APP_ELIGIBILITY); + eligibilityString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.COMPANION_APP_ELIGIBILITY); } int eligibility = CheckEligibilityOperation.ELIGIBILITY_RESULT_UNKNOWN; @@ -269,43 +283,47 @@ public class Ts43Operation { responseBuilder.setAppEligibility(eligibility); // Parse companion device services - String companionDeviceServices = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.COMPANION_DEVICE_SERVICES); + String companionDeviceServices = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.COMPANION_DEVICE_SERVICES); if (!TextUtils.isEmpty(companionDeviceServices)) { - List<String> companionDeviceServicesList = Arrays.asList( - companionDeviceServices.split("\\s*,\\s*")); + List<String> companionDeviceServicesList = + Arrays.asList(companionDeviceServices.split("\\s*,\\s*")); responseBuilder.setCompanionDeviceServices( ImmutableList.copyOf(companionDeviceServicesList)); } // Parse notEnabledURL URL notEnabledURL = null; - String notEnabledURLString = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.NOT_ENABLED_URL); + String notEnabledURLString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.NOT_ENABLED_URL); try { notEnabledURL = new URL(notEnabledURLString); - responseBuilder.setNotEnabledURL(notEnabledURL); + responseBuilder.setNotEnabledUrl(notEnabledURL); } catch (MalformedURLException e) { Log.w(TAG, "checkEligibility: malformed URL " + notEnabledURLString); } // Parse notEnabledUserData - String notEnabledUserData = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.NOT_ENABLED_USER_DATA); + String notEnabledUserData = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.NOT_ENABLED_USER_DATA); if (!TextUtils.isEmpty(notEnabledUserData)) { responseBuilder.setNotEnabledUserData(notEnabledUserData); } // Parse notEnabledContentsType - String notEnabledContentsTypeString = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.NOT_ENABLED_CONTENTS_TYPE); + String notEnabledContentsTypeString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.NOT_ENABLED_CONTENTS_TYPE); int notEnabledContentsType = HttpConstants.ContentType.UNKNOWN; if (!TextUtils.isEmpty(notEnabledContentsTypeString)) { @@ -324,15 +342,14 @@ public class Ts43Operation { } /** - * To request for subscription-related action on a primary or companion device as described - * in GSMA Service Entitlement Configuration section 6.2 and 6.5.3. + * To request for subscription-related action on a primary or companion device as described in + * GSMA Service Entitlement Configuration section 6.2 and 6.5.3. * * @param manageSubscriptionRequest The manage subscription request. * @return The response of manage subscription request. - * * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull public ManageSubscriptionResponse manageSubscription( @@ -340,51 +357,68 @@ public class Ts43Operation { throws ServiceEntitlementException { Objects.requireNonNull(manageSubscriptionRequest); - ServiceEntitlementRequest.Builder builder = ServiceEntitlementRequest.builder() + ServiceEntitlementRequest.Builder builder = + ServiceEntitlementRequest.builder() .setEntitlementVersion(mEntitlementVersion) .setTerminalId(mImei) .setAcceptContentType(ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML); + if (mTokenType == TOKEN_TYPE_NORMAL) { builder.setAuthenticationToken(mAuthToken); } else if (mTokenType == TOKEN_TYPE_TEMPORARY) { builder.setTemporaryToken(mTemporaryToken); } + String notificationToken = manageSubscriptionRequest.notificationToken(); + if (!TextUtils.isEmpty(notificationToken)) { + builder.setNotificationToken(notificationToken); + } + int notificationAction = manageSubscriptionRequest.notificationAction(); + if (Ts43Constants.isValidNotificationAction(notificationAction)) { + builder.setNotificationAction(notificationAction); + } + ServiceEntitlementRequest request = builder.build(); - OdsaOperation operation = OdsaOperation.builder() - .setOperation(OdsaOperation.OPERATION_MANAGE_SUBSCRIPTION) - .setOperationType(manageSubscriptionRequest.operationType()) - .setCompanionTerminalId(manageSubscriptionRequest.companionTerminalId()) - .setCompanionTerminalVendor(manageSubscriptionRequest.companionTerminalVendor()) - .setCompanionTerminalModel(manageSubscriptionRequest.companionTerminalModel()) - .setCompanionTerminalSoftwareVersion( - manageSubscriptionRequest.companionTerminalSoftwareVersion()) - .setCompanionTerminalFriendlyName( - manageSubscriptionRequest.companionTerminalFriendlyName()) - .setCompanionTerminalService(manageSubscriptionRequest.companionTerminalService()) - .setCompanionTerminalIccid(manageSubscriptionRequest.companionTerminalIccid()) - .setCompanionTerminalEid(manageSubscriptionRequest.companionTerminalEid()) - .setTerminalIccid(manageSubscriptionRequest.terminalIccid()) - .setTerminalEid(manageSubscriptionRequest.terminalEid()) - .setTargetTerminalId(manageSubscriptionRequest.targetTerminalId()) - // non TS.43 standard support - .setTargetTerminalIds(manageSubscriptionRequest.targetTerminalIds()) - .setTargetTerminalIccid(manageSubscriptionRequest.targetTerminalIccid()) - .setTargetTerminalEid(manageSubscriptionRequest.targetTerminalEid()) - // non TS.43 standard support - .setTargetTerminalSerialNumber(manageSubscriptionRequest - .targetTerminalSerialNumber()) - // non TS.43 standard support - .setTargetTerminalModel(manageSubscriptionRequest.targetTerminalModel()) - .setOldTerminalId(manageSubscriptionRequest.oldTerminalId()) - .setOldTerminalIccid(manageSubscriptionRequest.oldTerminalIccid()) - .build(); + EsimOdsaOperation operation = + EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION) + .setOperationType(manageSubscriptionRequest.operationType()) + .setCompanionTerminalId(manageSubscriptionRequest.companionTerminalId()) + .setCompanionTerminalVendor( + manageSubscriptionRequest.companionTerminalVendor()) + .setCompanionTerminalModel( + manageSubscriptionRequest.companionTerminalModel()) + .setCompanionTerminalSoftwareVersion( + manageSubscriptionRequest.companionTerminalSoftwareVersion()) + .setCompanionTerminalFriendlyName( + manageSubscriptionRequest.companionTerminalFriendlyName()) + .setCompanionTerminalService( + manageSubscriptionRequest.companionTerminalService()) + .setCompanionTerminalIccid( + manageSubscriptionRequest.companionTerminalIccid()) + .setCompanionTerminalEid(manageSubscriptionRequest.companionTerminalEid()) + .setTerminalIccid(manageSubscriptionRequest.terminalIccid()) + .setTerminalEid(manageSubscriptionRequest.terminalEid()) + .setTargetTerminalId(manageSubscriptionRequest.targetTerminalId()) + // non TS.43 standard support + .setTargetTerminalIds(manageSubscriptionRequest.targetTerminalIds()) + .setTargetTerminalIccid(manageSubscriptionRequest.targetTerminalIccid()) + .setTargetTerminalEid(manageSubscriptionRequest.targetTerminalEid()) + // non TS.43 standard support + .setTargetTerminalSerialNumber( + manageSubscriptionRequest.targetTerminalSerialNumber()) + // non TS.43 standard support + .setTargetTerminalModel(manageSubscriptionRequest.targetTerminalModel()) + .setOldTerminalId(manageSubscriptionRequest.oldTerminalId()) + .setOldTerminalIccid(manageSubscriptionRequest.oldTerminalIccid()) + .build(); String rawXml; try { - rawXml = mServiceEntitlement.performEsimOdsa(manageSubscriptionRequest.appId(), - request, operation); + rawXml = + mServiceEntitlement.performEsimOdsa( + manageSubscriptionRequest.appId(), request, operation); } catch (ServiceEntitlementException e) { Log.w(TAG, "manageSubscription: Failed to perform ODSA operation. e=" + e); throw e; @@ -407,38 +441,42 @@ public class Ts43Operation { int subscriptionResult = ManageSubscriptionResponse.SUBSCRIPTION_RESULT_UNKNOWN; // Parse subscription result. - String subscriptionResultString = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.SUBSCRIPTION_RESULT); + String subscriptionResultString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.SUBSCRIPTION_RESULT); if (!TextUtils.isEmpty(subscriptionResultString)) { switch (subscriptionResultString) { case Ts43XmlDoc.ParmValues.SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET: - subscriptionResult = ManageSubscriptionResponse - .SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET; + subscriptionResult = + ManageSubscriptionResponse.SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET; - String subscriptionServiceURLString = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.SUBSCRIPTION_SERVICE_URL); + String subscriptionServiceURLString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.SUBSCRIPTION_SERVICE_URL); if (!TextUtils.isEmpty(subscriptionServiceURLString)) { try { - responseBuilder.setSubscriptionServiceURL( + responseBuilder.setSubscriptionServiceUrl( new URL(subscriptionServiceURLString)); - String subscriptionServiceUserDataString = ts43XmlDoc.get( - ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.SUBSCRIPTION_SERVICE_USER_DATA); + String subscriptionServiceUserDataString = + ts43XmlDoc.get( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.SUBSCRIPTION_SERVICE_USER_DATA); if (!TextUtils.isEmpty(subscriptionServiceUserDataString)) { responseBuilder.setSubscriptionServiceUserData( subscriptionServiceUserDataString); } - String subscriptionServiceContentsTypeString = ts43XmlDoc.get( - ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.SUBSCRIPTION_SERVICE_CONTENTS_TYPE); + String subscriptionServiceContentsTypeString = + ts43XmlDoc.get( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.SUBSCRIPTION_SERVICE_CONTENTS_TYPE); if (!TextUtils.isEmpty(subscriptionServiceContentsTypeString)) { int contentsType = HttpConstants.ContentType.UNKNOWN; switch (subscriptionServiceContentsTypeString) { @@ -457,13 +495,14 @@ public class Ts43Operation { } break; case Ts43XmlDoc.ParmValues.SUBSCRIPTION_RESULT_DOWNLOAD_PROFILE: - subscriptionResult = ManageSubscriptionResponse - .SUBSCRIPTION_RESULT_DOWNLOAD_PROFILE; - DownloadInfo downloadInfo = parseDownloadInfo( - ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION, - Ts43XmlDoc.CharacteristicType.DOWNLOAD_INFO), - ts43XmlDoc); + subscriptionResult = + ManageSubscriptionResponse.SUBSCRIPTION_RESULT_DOWNLOAD_PROFILE; + DownloadInfo downloadInfo = + parseDownloadInfo( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION, + Ts43XmlDoc.CharacteristicType.DOWNLOAD_INFO), + ts43XmlDoc); if (downloadInfo != null) { responseBuilder.setDownloadInfo(downloadInfo); } @@ -472,15 +511,15 @@ public class Ts43Operation { subscriptionResult = ManageSubscriptionResponse.SUBSCRIPTION_RESULT_DONE; break; case Ts43XmlDoc.ParmValues.SUBSCRIPTION_RESULT_DELAYED_DOWNLOAD: - subscriptionResult = ManageSubscriptionResponse - .SUBSCRIPTION_RESULT_DELAYED_DOWNLOAD; + subscriptionResult = + ManageSubscriptionResponse.SUBSCRIPTION_RESULT_DELAYED_DOWNLOAD; break; case Ts43XmlDoc.ParmValues.SUBSCRIPTION_RESULT_DISMISS: subscriptionResult = ManageSubscriptionResponse.SUBSCRIPTION_RESULT_DISMISS; break; case Ts43XmlDoc.ParmValues.SUBSCRIPTION_RESULT_DELETE_PROFILE_IN_USE: - subscriptionResult = ManageSubscriptionResponse - .SUBSCRIPTION_RESULT_DELETE_PROFILE_IN_USE; + subscriptionResult = + ManageSubscriptionResponse.SUBSCRIPTION_RESULT_DELETE_PROFILE_IN_USE; break; } } @@ -495,19 +534,19 @@ public class Ts43Operation { * * @param manageServiceRequest The manage service request. * @return The response of manage service request. - * * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull public ManageServiceResponse manageService(@NonNull ManageServiceRequest manageServiceRequest) throws ServiceEntitlementException { Objects.requireNonNull(manageServiceRequest); - ServiceEntitlementRequest.Builder builder = ServiceEntitlementRequest.builder() - .setEntitlementVersion(mEntitlementVersion) - .setTerminalId(mImei); + ServiceEntitlementRequest.Builder builder = + ServiceEntitlementRequest.builder() + .setEntitlementVersion(mEntitlementVersion) + .setTerminalId(mImei); if (mTokenType == TOKEN_TYPE_NORMAL) { builder.setAuthenticationToken(mAuthToken); @@ -517,24 +556,27 @@ public class Ts43Operation { ServiceEntitlementRequest request = builder.build(); - OdsaOperation operation = OdsaOperation.builder() - .setOperation(OdsaOperation.OPERATION_MANAGE_SERVICE) - .setOperationType(manageServiceRequest.operationType()) - .setCompanionTerminalId(manageServiceRequest.companionTerminalId()) - .setCompanionTerminalVendor(manageServiceRequest.companionTerminalVendor()) - .setCompanionTerminalModel(manageServiceRequest.companionTerminalModel()) - .setCompanionTerminalSoftwareVersion( - manageServiceRequest.companionTerminalSoftwareVersion()) - .setCompanionTerminalFriendlyName( - manageServiceRequest.companionTerminalFriendlyName()) - .setCompanionTerminalService(manageServiceRequest.companionTerminalService()) - .setCompanionTerminalIccid(manageServiceRequest.companionTerminalIccid()) - .build(); + EsimOdsaOperation operation = + EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_MANAGE_SERVICE) + .setOperationType(manageServiceRequest.operationType()) + .setCompanionTerminalId(manageServiceRequest.companionTerminalId()) + .setCompanionTerminalVendor(manageServiceRequest.companionTerminalVendor()) + .setCompanionTerminalModel(manageServiceRequest.companionTerminalModel()) + .setCompanionTerminalSoftwareVersion( + manageServiceRequest.companionTerminalSoftwareVersion()) + .setCompanionTerminalFriendlyName( + manageServiceRequest.companionTerminalFriendlyName()) + .setCompanionTerminalService( + manageServiceRequest.companionTerminalService()) + .setCompanionTerminalIccid(manageServiceRequest.companionTerminalIccid()) + .build(); String rawXml; try { - rawXml = mServiceEntitlement.performEsimOdsa(manageServiceRequest.appId(), - request, operation); + rawXml = + mServiceEntitlement.performEsimOdsa(manageServiceRequest.appId(), request, + operation); } catch (ServiceEntitlementException e) { Log.w(TAG, "manageService: Failed to perform ODSA operation. e=" + e); throw e; @@ -555,9 +597,10 @@ public class Ts43Operation { } // Parse service status. - String serviceStatusString = ts43XmlDoc.get(ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.SERVICE_STATUS); + String serviceStatusString = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.SERVICE_STATUS); if (!TextUtils.isEmpty(serviceStatusString)) { responseBuilder.setServiceStatus(getServiceStatusFromString(serviceStatusString)); @@ -572,10 +615,9 @@ public class Ts43Operation { * * @param acquireConfigurationRequest The acquire configuration request. * @return The response of acquire configuration request. - * * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull public AcquireConfigurationResponse acquireConfiguration( @@ -583,28 +625,41 @@ public class Ts43Operation { throws ServiceEntitlementException { Objects.requireNonNull(acquireConfigurationRequest); - ServiceEntitlementRequest request = ServiceEntitlementRequest.builder() + ServiceEntitlementRequest.Builder builder = ServiceEntitlementRequest.builder() .setEntitlementVersion(mEntitlementVersion) .setTerminalId(mImei) - .setAuthenticationToken(mAuthToken) - .build(); - - OdsaOperation operation = OdsaOperation.builder() - .setOperation(OdsaOperation.OPERATION_ACQUIRE_CONFIGURATION) - .setCompanionTerminalId(acquireConfigurationRequest.companionTerminalId()) - .setCompanionTerminalIccid(acquireConfigurationRequest.companionTerminalIccid()) - .setCompanionTerminalEid(acquireConfigurationRequest.companionTerminalEid()) - .setTerminalIccid(acquireConfigurationRequest.terminalIccid()) - .setTerminalEid(acquireConfigurationRequest.terminalEid()) - .setTargetTerminalId(acquireConfigurationRequest.targetTerminalId()) - .setTargetTerminalIccid(acquireConfigurationRequest.targetTerminalIccid()) - .setTargetTerminalEid(acquireConfigurationRequest.targetTerminalEid()) - .build(); + .setAuthenticationToken(mAuthToken); + + String notificationToken = acquireConfigurationRequest.notificationToken(); + if (!TextUtils.isEmpty(notificationToken)) { + builder.setNotificationToken(notificationToken); + } + int notificationAction = acquireConfigurationRequest.notificationAction(); + if (Ts43Constants.isValidNotificationAction(notificationAction)) { + builder.setNotificationAction(notificationAction); + } + + ServiceEntitlementRequest request = builder.build(); + + EsimOdsaOperation operation = + EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_ACQUIRE_CONFIGURATION) + .setCompanionTerminalId(acquireConfigurationRequest.companionTerminalId()) + .setCompanionTerminalIccid( + acquireConfigurationRequest.companionTerminalIccid()) + .setCompanionTerminalEid(acquireConfigurationRequest.companionTerminalEid()) + .setTerminalIccid(acquireConfigurationRequest.terminalIccid()) + .setTerminalEid(acquireConfigurationRequest.terminalEid()) + .setTargetTerminalId(acquireConfigurationRequest.targetTerminalId()) + .setTargetTerminalIccid(acquireConfigurationRequest.targetTerminalIccid()) + .setTargetTerminalEid(acquireConfigurationRequest.targetTerminalEid()) + .build(); String rawXml; try { - rawXml = mServiceEntitlement.performEsimOdsa(acquireConfigurationRequest.appId(), - request, operation); + rawXml = + mServiceEntitlement.performEsimOdsa( + acquireConfigurationRequest.appId(), request, operation); } catch (ServiceEntitlementException e) { Log.w(TAG, "acquireConfiguration: Failed to perform ODSA operation. e=" + e); throw e; @@ -626,47 +681,55 @@ public class Ts43Operation { } // Parse service status. - String serviceStatusString = ts43XmlDoc.get(ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION, - Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION), - Ts43XmlDoc.Parm.SERVICE_STATUS); + String serviceStatusString = + ts43XmlDoc.get( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION, + Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION), + Ts43XmlDoc.Parm.SERVICE_STATUS); if (!TextUtils.isEmpty(serviceStatusString)) { configBuilder.setServiceStatus(getServiceStatusFromString(serviceStatusString)); } // Parse ICCID - String iccIdString = ts43XmlDoc.get(ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION, - Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION), - Ts43XmlDoc.Parm.ICCID); + String iccIdString = + ts43XmlDoc.get( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION, + Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION), + Ts43XmlDoc.Parm.ICCID); if (!TextUtils.isEmpty(iccIdString)) { configBuilder.setIccid(iccIdString); } // Parse polling interval - String pollingIntervalString = ts43XmlDoc.get(ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION, - Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION), - Ts43XmlDoc.Parm.POLLING_INTERVAL); + String pollingIntervalString = + ts43XmlDoc.get( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION, + Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION), + Ts43XmlDoc.Parm.POLLING_INTERVAL); if (!TextUtils.isEmpty(pollingIntervalString)) { try { configBuilder.setPollingInterval(Integer.parseInt(pollingIntervalString)); } catch (NumberFormatException e) { - Log.w(TAG, "acquireConfiguration: Failed to parse polling interval " - + pollingIntervalString); + Log.w( + TAG, "acquireConfiguration: Failed to parse polling interval " + + pollingIntervalString); } } // Parse download info - DownloadInfo downloadInfo = parseDownloadInfo( - ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION, - Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION, - Ts43XmlDoc.CharacteristicType.DOWNLOAD_INFO), - ts43XmlDoc); + DownloadInfo downloadInfo = + parseDownloadInfo( + ImmutableList.of( + Ts43XmlDoc.CharacteristicType.APPLICATION, + Ts43XmlDoc.CharacteristicType.PRIMARY_CONFIGURATION, + Ts43XmlDoc.CharacteristicType.DOWNLOAD_INFO), + ts43XmlDoc); if (downloadInfo != null) { configBuilder.setDownloadInfo(downloadInfo); } @@ -684,10 +747,9 @@ public class Ts43Operation { * described in GSMA Service Entitlement Configuration section 6.2 and 6.5.6. * * @return List of mobile plans. Empty list if not available. - * * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull public List<PlanOffer> acquirePlans() throws ServiceEntitlementException { @@ -699,35 +761,37 @@ public class Ts43Operation { * in GSMA Service Entitlement Configuration section 6.2 and 6.5.7. * * @param acquireTemporaryTokenRequest The acquire temporary token request. - * * @return The temporary token response. - * * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull + @SuppressWarnings("AndroidJdkLibsChecker") // java.time.Instant public AcquireTemporaryTokenResponse acquireTemporaryToken( @NonNull AcquireTemporaryTokenRequest acquireTemporaryTokenRequest) throws ServiceEntitlementException { Objects.requireNonNull(acquireTemporaryTokenRequest); - ServiceEntitlementRequest request = ServiceEntitlementRequest.builder() - .setEntitlementVersion(mEntitlementVersion) - .setTerminalId(mImei) - .setAuthenticationToken(mAuthToken) - .build(); + ServiceEntitlementRequest request = + ServiceEntitlementRequest.builder() + .setEntitlementVersion(mEntitlementVersion) + .setTerminalId(mImei) + .setAuthenticationToken(mAuthToken) + .build(); - OdsaOperation operation = OdsaOperation.builder() - .setOperation(OdsaOperation.OPERATION_ACQUIRE_TEMPORARY_TOKEN) - .setOperationTargets(acquireTemporaryTokenRequest.operationTargets()) - .setCompanionTerminalId(acquireTemporaryTokenRequest.companionTerminalId()) - .build(); + EsimOdsaOperation operation = + EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_ACQUIRE_TEMPORARY_TOKEN) + .setOperationTargets(acquireTemporaryTokenRequest.operationTargets()) + .setCompanionTerminalId(acquireTemporaryTokenRequest.companionTerminalId()) + .build(); String rawXml; try { - rawXml = mServiceEntitlement.performEsimOdsa(acquireTemporaryTokenRequest.appId(), - request, operation); + rawXml = + mServiceEntitlement.performEsimOdsa( + acquireTemporaryTokenRequest.appId(), request, operation); } catch (ServiceEntitlementException e) { Log.w(TAG, "acquireTemporaryToken: Failed to perform ODSA operation. e=" + e); throw e; @@ -746,9 +810,11 @@ public class Ts43Operation { } // Parse the operation targets. - String operationTargets = Strings.nullToEmpty(ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.OPERATION_TARGETS)); + String operationTargets = + Strings.nullToEmpty( + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.OPERATION_TARGETS)); if (operationTargets != null) { List<String> operationTargetsList = Arrays.asList(operationTargets.split("\\s*,\\s*")); @@ -756,9 +822,10 @@ public class Ts43Operation { } // Parse the temporary token - String temporaryToken = ts43XmlDoc.get(ImmutableList.of( - Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.TEMPORARY_TOKEN); + String temporaryToken = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.TEMPORARY_TOKEN); if (temporaryToken == null) { throw new ServiceEntitlementException( @@ -768,9 +835,10 @@ public class Ts43Operation { responseBuilder.setTemporaryToken(temporaryToken); - String temporaryTokenExpiry = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.TEMPORARY_TOKEN_EXPIRY); + String temporaryTokenExpiry = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.TEMPORARY_TOKEN_EXPIRY); // Parse the token expiration time. Instant expiry; @@ -785,18 +853,77 @@ public class Ts43Operation { } /** - * Get the phone number as described in GSMA Service Entitlement Configuration section - * 6.2 and 6.5.8. - * - * @return The phone number in E.164 format. + * Get the phone number as described in GSMA Service Entitlement Configuration section 6.2 and + * 6.5.8. * + * @param getPhoneNumberRequest The get phone number request. + * @return The phone number response from the network. * @throws ServiceEntitlementException The exception for error case. If it's an HTTP response - * error from the server, the error code can be retrieved by - * {@link ServiceEntitlementException#getHttpStatus()} + * error from the server, the error code can be retrieved by + * {@link ServiceEntitlementException#getHttpStatus()} */ @NonNull - public String getPhoneNumber() throws ServiceEntitlementException { - return ""; + public GetPhoneNumberResponse getPhoneNumber( + @NonNull GetPhoneNumberRequest getPhoneNumberRequest) + throws ServiceEntitlementException { + ServiceEntitlementRequest.Builder builder = + ServiceEntitlementRequest.builder() + .setEntitlementVersion(mEntitlementVersion); + + if (!TextUtils.isEmpty(getPhoneNumberRequest.terminalId())) { + builder.setTerminalId(getPhoneNumberRequest.terminalId()); + } else { + builder.setTerminalId(mImei); + } + + if (mTokenType == TOKEN_TYPE_NORMAL) { + builder.setAuthenticationToken(mAuthToken); + } else if (mTokenType == TOKEN_TYPE_TEMPORARY) { + builder.setTemporaryToken(mTemporaryToken); + } + + ServiceEntitlementRequest request = builder.build(); + + EsimOdsaOperation operation = + EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_GET_PHONE_NUMBER) + .build(); + + String rawXml; + try { + rawXml = + mServiceEntitlement.performEsimOdsa( + Ts43Constants.APP_PHONE_NUMBER_INFORMATION, request, operation); + } catch (ServiceEntitlementException e) { + Log.w(TAG, "getPhoneNumber: Failed to perform ODSA operation. e=" + e); + throw e; + } + + // Build the response of get phone number operation. Refer to GSMA Service Entitlement + // Configuration section 6.5.8. + GetPhoneNumberResponse.Builder responseBuilder = GetPhoneNumberResponse.builder(); + + Ts43XmlDoc ts43XmlDoc = new Ts43XmlDoc(rawXml); + + try { + processGeneralResult(ts43XmlDoc, responseBuilder); + } catch (MalformedURLException e) { + throw new ServiceEntitlementException( + ServiceEntitlementException.ERROR_MALFORMED_HTTP_RESPONSE, + "getPhoneNumber: Malformed URL " + rawXml); + } + + // Parse msisdn. + String msisdn = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.MSISDN); + + if (!TextUtils.isEmpty(msisdn)) { + responseBuilder.setMsisdn(msisdn); + } + + return responseBuilder.build(); } /** @@ -804,18 +931,20 @@ public class Ts43Operation { * * @param characteristics The XML nodes to search activation code. * @param ts43XmlDoc The XML format http response. - * * @return The download info. */ @Nullable - private DownloadInfo parseDownloadInfo(@NonNull ImmutableList<String> characteristics, - @NonNull Ts43XmlDoc ts43XmlDoc) { - String activationCode = Strings.nullToEmpty(ts43XmlDoc.get(characteristics, - Ts43XmlDoc.Parm.PROFILE_ACTIVATION_CODE)); - String smdpAddress = Strings.nullToEmpty(ts43XmlDoc.get(characteristics, - Ts43XmlDoc.Parm.PROFILE_SMDP_ADDRESS)); - String iccid = Strings.nullToEmpty(ts43XmlDoc.get(characteristics, - Ts43XmlDoc.Parm.PROFILE_ICCID)); + @SuppressWarnings("AndroidJdkLibsChecker") // java.util.Base64 + private DownloadInfo parseDownloadInfo( + @NonNull ImmutableList<String> characteristics, @NonNull Ts43XmlDoc ts43XmlDoc) { + String activationCode = + Strings.nullToEmpty( + ts43XmlDoc.get(characteristics, Ts43XmlDoc.Parm.PROFILE_ACTIVATION_CODE)); + String smdpAddress = + Strings.nullToEmpty( + ts43XmlDoc.get(characteristics, Ts43XmlDoc.Parm.PROFILE_SMDP_ADDRESS)); + String iccid = + Strings.nullToEmpty(ts43XmlDoc.get(characteristics, Ts43XmlDoc.Parm.PROFILE_ICCID)); // DownloadInfo should contain either activationCode or smdpAddress + iccid if (!activationCode.isEmpty()) { @@ -833,12 +962,18 @@ public class Ts43Operation { } else if (!smdpAddress.isEmpty() && !iccid.isEmpty()) { return DownloadInfo.builder() .setProfileIccid(iccid) - .setProfileSmdpAddresses(ImmutableList.copyOf( - Arrays.asList(smdpAddress.split("\\s*,\\s*")))) + .setProfileSmdpAddresses( + ImmutableList.copyOf(Arrays.asList(smdpAddress.split("\\s*,\\s*")))) .build(); } else { - Log.w(TAG, "Failed to parse download info. activationCode=" + activationCode - + ", smdpAddress=" + smdpAddress + ", iccid=" + iccid); + Log.w( + TAG, + "Failed to parse download info. activationCode=" + + activationCode + + ", smdpAddress=" + + smdpAddress + + ", iccid=" + + iccid); return null; } } @@ -848,61 +983,65 @@ public class Ts43Operation { * * @param ts43XmlDoc The TS.43 ODSA operation response in XLM format. * @param builder The response builder. - * * @throws MalformedURLException when HTTP response is not well formatted. */ - private void processGeneralResult(@NonNull Ts43XmlDoc ts43XmlDoc, - @NonNull OdsaResponse.Builder builder) throws MalformedURLException { + private void processGeneralResult( + @NonNull Ts43XmlDoc ts43XmlDoc, @NonNull OdsaResponse.Builder builder) + throws MalformedURLException { // Now start to parse the result from HTTP response. // Parse the operation result. - String operationResult = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.OPERATION_RESULT); + String operationResult = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.OPERATION_RESULT); - builder.setOperationResult(OdsaOperation.OPERATION_RESULT_UNKNOWN); + builder.setOperationResult(EsimOdsaOperation.OPERATION_RESULT_UNKNOWN); if (!TextUtils.isEmpty(operationResult)) { switch (operationResult) { case Ts43XmlDoc.ParmValues.OPERATION_RESULT_SUCCESS: - builder.setOperationResult(OdsaOperation.OPERATION_RESULT_SUCCESS); + builder.setOperationResult(EsimOdsaOperation.OPERATION_RESULT_SUCCESS); break; case Ts43XmlDoc.ParmValues.OPERATION_RESULT_ERROR_GENERAL: - builder.setOperationResult(OdsaOperation.OPERATION_RESULT_ERROR_GENERAL); + builder.setOperationResult(EsimOdsaOperation.OPERATION_RESULT_ERROR_GENERAL); break; case Ts43XmlDoc.ParmValues.OPERATION_RESULT_ERROR_INVALID_OPERATION: builder.setOperationResult( - OdsaOperation.OPERATION_RESULT_ERROR_INVALID_OPERATION); + EsimOdsaOperation.OPERATION_RESULT_ERROR_INVALID_OPERATION); break; case Ts43XmlDoc.ParmValues.OPERATION_RESULT_ERROR_INVALID_PARAMETER: builder.setOperationResult( - OdsaOperation.OPERATION_RESULT_ERROR_INVALID_PARAMETER); + EsimOdsaOperation.OPERATION_RESULT_ERROR_INVALID_PARAMETER); break; case Ts43XmlDoc.ParmValues.OPERATION_RESULT_WARNING_NOT_SUPPORTED_OPERATION: builder.setOperationResult( - OdsaOperation.OPERATION_RESULT_WARNING_NOT_SUPPORTED_OPERATION); + EsimOdsaOperation.OPERATION_RESULT_WARNING_NOT_SUPPORTED_OPERATION); break; } } // Parse the general error URL - String generalErrorUrl = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.GENERAL_ERROR_URL); + String generalErrorUrl = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.GENERAL_ERROR_URL); if (!TextUtils.isEmpty(generalErrorUrl)) { builder.setGeneralErrorUrl(new URL(generalErrorUrl)); } // Parse the general error URL user data - String generalErrorUserData = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), - Ts43XmlDoc.Parm.GENERAL_ERROR_USER_DATA); + String generalErrorUserData = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.APPLICATION), + Ts43XmlDoc.Parm.GENERAL_ERROR_USER_DATA); if (!TextUtils.isEmpty(generalErrorUserData)) { builder.setGeneralErrorUserData(generalErrorUserData); } // Parse the token for next operation. - String token = ts43XmlDoc.get( - ImmutableList.of(Ts43XmlDoc.CharacteristicType.TOKEN), - Ts43XmlDoc.Parm.TOKEN); + String token = + ts43XmlDoc.get( + ImmutableList.of(Ts43XmlDoc.CharacteristicType.TOKEN), + Ts43XmlDoc.Parm.TOKEN); if (!TextUtils.isEmpty(token)) { // Some servers issue the new token in operation result for next operation to use. // We need to save it. @@ -916,23 +1055,22 @@ public class Ts43Operation { * section 6.5.4. * * @param serviceStatusString Service status in string format defined in GSMA Service - * Entitlement Configuration section 6.5.4. - * - * @return The converted service status. {@link OdsaOperation#SERVICE_STATUS_UNKNOWN} if not + * Entitlement Configuration section 6.5.4. + * @return The converted service status. {@link EsimOdsaOperation#SERVICE_STATUS_UNKNOWN} if not * able to convert. */ - @ServiceStatus + @OdsaServiceStatus private int getServiceStatusFromString(@NonNull String serviceStatusString) { switch (serviceStatusString) { case Ts43XmlDoc.ParmValues.SERVICE_STATUS_ACTIVATED: - return OdsaOperation.SERVICE_STATUS_ACTIVATED; + return EsimOdsaOperation.SERVICE_STATUS_ACTIVATED; case Ts43XmlDoc.ParmValues.SERVICE_STATUS_ACTIVATING: - return OdsaOperation.SERVICE_STATUS_ACTIVATING; + return EsimOdsaOperation.SERVICE_STATUS_ACTIVATING; case Ts43XmlDoc.ParmValues.SERVICE_STATUS_DEACTIVATED: - return OdsaOperation.SERVICE_STATUS_DEACTIVATED; + return EsimOdsaOperation.SERVICE_STATUS_DEACTIVATED; case Ts43XmlDoc.ParmValues.SERVICE_STATUS_DEACTIVATED_NO_REUSE: - return OdsaOperation.SERVICE_STATUS_DEACTIVATED_NO_REUSE; + return EsimOdsaOperation.SERVICE_STATUS_DEACTIVATED_NO_REUSE; } - return OdsaOperation.SERVICE_STATUS_UNKNOWN; + return EsimOdsaOperation.SERVICE_STATUS_UNKNOWN; } -} +}
\ No newline at end of file diff --git a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java index c9294fd..4590211 100644 --- a/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java +++ b/java/com/android/libraries/entitlement/eapaka/EapAkaApi.java @@ -21,15 +21,18 @@ import static com.android.libraries.entitlement.ServiceEntitlementException.ERRO import static com.android.libraries.entitlement.ServiceEntitlementException.ERROR_MALFORMED_HTTP_RESPONSE; import android.content.Context; +import android.content.pm.PackageInfo; import android.net.Uri; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.libraries.entitlement.CarrierConfig; +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; @@ -37,7 +40,6 @@ 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; -import com.android.libraries.entitlement.odsa.OdsaOperation; import com.google.common.collect.ImmutableList; import com.google.common.net.HttpHeaders; @@ -103,10 +105,16 @@ public class EapAkaApi { // at most three times. private static final int MAX_EAP_AKA_ATTEMPTS = 3; + // Max TERMINAL_* string length according to GSMA RCC.14 section 2.4 + private static final int MAX_TERMINAL_VENDOR_LENGTH = 4; + private static final int MAX_TERMINAL_MODEL_LENGTH = 10; + private static final int MAX_TERMINAL_SOFTWARE_VERSION_LENGTH = 20; + private final Context mContext; private final int mSimSubscriptionId; private final HttpClient mHttpClient; private final String mBypassEapAkaResponse; + private final String mAppVersion; public EapAkaApi( Context context, @@ -126,18 +134,21 @@ public class EapAkaApi { this.mSimSubscriptionId = simSubscriptionId; this.mHttpClient = httpClient; this.mBypassEapAkaResponse = bypassEapAkaResponse; + this.mAppVersion = getAppVersion(context); } /** - * Retrieves raw entitlement configuration doc though EAP-AKA authentication. + * Retrieves HTTP response with the entitlement configuration doc though EAP-AKA authentication. * * <p>Implementation based on GSMA TS.43-v5.0 2.6.1. * * @throws ServiceEntitlementException when getting an unexpected http response. */ - @Nullable - public String queryEntitlementStatus(ImmutableList<String> appIds, - CarrierConfig carrierConfig, ServiceEntitlementRequest request) + @NonNull + public HttpResponse queryEntitlementStatus( + ImmutableList<String> appIds, + CarrierConfig carrierConfig, + ServiceEntitlementRequest request) throws ServiceEntitlementException { Uri.Builder urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon(); appendParametersForAuthentication(urlBuilder, request); @@ -146,15 +157,23 @@ public class EapAkaApi { // Fast Re-Authentication flow with pre-existing auth token Log.d(TAG, "Fast Re-Authentication"); return httpGet( - urlBuilder.toString(), carrierConfig, request.acceptContentType()).body(); + 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); + urlBuilder.toString(), + carrierConfig, + ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON, + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); String eapAkaChallenge = getEapAkaChallenge(challengeResponse); if (eapAkaChallenge == null) { throw new ServiceEntitlementException( @@ -166,8 +185,10 @@ public class EapAkaApi { eapAkaChallenge, challengeResponse.cookies(), MAX_EAP_AKA_ATTEMPTS, - request.acceptContentType()) - .body(); + request.acceptContentType(), + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); } } @@ -188,17 +209,28 @@ public class EapAkaApi { * and return a new response, as long as {@code remainingAttempts} is greater than zero. * </ul> * - * @param response Challenge response from server which its content type is JSON + * @return Challenge response from server whose content type is JSON */ + @NonNull private HttpResponse respondToEapAkaChallenge( CarrierConfig carrierConfig, String eapAkaChallenge, ImmutableList<String> cookies, int remainingAttempts, - String contentType) + String contentType, + String terminalVendor, + String terminalModel, + String terminalSoftwareVersion) throws ServiceEntitlementException { if (!mBypassEapAkaResponse.isEmpty()) { - return challengeResponse(mBypassEapAkaResponse, carrierConfig, cookies, contentType); + return challengeResponse( + mBypassEapAkaResponse, + carrierConfig, + cookies, + contentType, + terminalVendor, + terminalModel, + terminalSoftwareVersion); } EapAkaChallenge challenge = EapAkaChallenge.parseEapAkaChallenge(eapAkaChallenge); @@ -208,7 +240,13 @@ public class EapAkaApi { if (eapAkaResponse.response() != null) { HttpResponse response = challengeResponse( - eapAkaResponse.response(), carrierConfig, cookies, contentType); + eapAkaResponse.response(), + carrierConfig, + cookies, + contentType, + terminalVendor, + terminalModel, + terminalSoftwareVersion); String nextEapAkaChallenge = getEapAkaChallenge(response); // successful authentication if (nextEapAkaChallenge == null) { @@ -222,7 +260,10 @@ public class EapAkaApi { nextEapAkaChallenge, cookies, remainingAttempts - 1, - contentType); + contentType, + terminalVendor, + terminalModel, + terminalSoftwareVersion); } else { throw new ServiceEntitlementException( ERROR_EAP_AKA_FAILURE, "Unable to EAP-AKA authenticate"); @@ -234,7 +275,10 @@ public class EapAkaApi { eapAkaResponse.synchronizationFailureResponse(), carrierConfig, cookies, - ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON); + ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON, + terminalVendor, + terminalModel, + terminalSoftwareVersion); String nextEapAkaChallenge = getEapAkaChallenge(newChallenge); if (nextEapAkaChallenge == null) { throw new ServiceEntitlementException( @@ -247,7 +291,10 @@ public class EapAkaApi { nextEapAkaChallenge, cookies, remainingAttempts - 1, - contentType); + contentType, + terminalVendor, + terminalModel, + terminalSoftwareVersion); } else { throw new ServiceEntitlementException( ERROR_EAP_AKA_SYNCHRONIZATION_FAILURE, @@ -258,11 +305,15 @@ public class EapAkaApi { } } + @NonNull private HttpResponse challengeResponse( String eapAkaChallengeResponse, CarrierConfig carrierConfig, ImmutableList<String> cookies, - String contentType) + String contentType, + String terminalVendor, + String terminalModel, + String terminalSoftwareVersion) throws ServiceEntitlementException { Log.d(TAG, "challengeResponse"); JSONObject postData = new JSONObject(); @@ -272,7 +323,7 @@ public class EapAkaApi { throw new ServiceEntitlementException( ERROR_MALFORMED_HTTP_RESPONSE, "Failed to put post data", jsonException); } - HttpRequest request = + HttpRequest.Builder builder = HttpRequest.builder() .setUrl(carrierConfig.serverUrl()) .setRequestMethod(RequestMethod.POST) @@ -283,19 +334,31 @@ public class EapAkaApi { ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON) .addRequestProperty(HttpHeaders.COOKIE, cookies) .setTimeoutInSec(carrierConfig.timeoutInSec()) - .setNetwork(carrierConfig.network()) - .build(); - return mHttpClient.request(request); + .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()); } /** - * Retrieves raw doc of performing ODSA operations. For operation type, see {@link - * OdsaOperation}. + * Retrieves HTTP response from performing ODSA operations. + * For operation type, see {@link EsimOdsaOperation}. * * <p>Implementation based on GSMA TS.43-v5.0 6.1. */ - public String performEsimOdsaOperation(String appId, CarrierConfig carrierConfig, - ServiceEntitlementRequest request, OdsaOperation odsaOperation) + @NonNull + public HttpResponse performEsimOdsaOperation( + String appId, + CarrierConfig carrierConfig, + ServiceEntitlementRequest request, + EsimOdsaOperation odsaOperation) throws ServiceEntitlementException { Uri.Builder urlBuilder = Uri.parse(carrierConfig.serverUrl()).buildUpon(); appendParametersForAuthentication(urlBuilder, request); @@ -307,7 +370,12 @@ public class EapAkaApi { // Fast Re-Authentication flow with pre-existing auth token Log.d(TAG, "Fast Re-Authentication"); return httpGet( - urlBuilder.toString(), carrierConfig, request.acceptContentType()).body(); + urlBuilder.toString(), + carrierConfig, + request.acceptContentType(), + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); } else { // Full Authentication flow Log.d(TAG, "Full Authentication"); @@ -315,7 +383,10 @@ public class EapAkaApi { httpGet( urlBuilder.toString(), carrierConfig, - ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON); + ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_JSON, + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); String eapAkaChallenge = getEapAkaChallenge(challengeResponse); if (eapAkaChallenge == null) { throw new ServiceEntitlementException( @@ -327,8 +398,10 @@ public class EapAkaApi { eapAkaChallenge, challengeResponse.cookies(), MAX_EAP_AKA_ATTEMPTS, - request.acceptContentType()) - .body(); + request.acceptContentType(), + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); } } @@ -337,37 +410,53 @@ public class EapAkaApi { * * <p>Implementation based on section 2.8.2 of TS.43 * - * <p>The user should call {@link #queryEntitlementStatusFromOidc(String url)} with the - * authentication result to retrieve the service entitlement configuration. + * <p>The user should call {@link #queryEntitlementStatusFromOidc(String, CarrierConfig, + * String)} with the authentication result to retrieve the service entitlement configuration. */ - public String acquireOidcAuthenticationEndpoint(String appId, CarrierConfig carrierConfig, - ServiceEntitlementRequest request) throws ServiceEntitlementException { + @NonNull + 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); - HttpResponse response = httpGet( - urlBuilder.toString(), carrierConfig, request.acceptContentType()); + HttpResponse response = + httpGet( + urlBuilder.toString(), + carrierConfig, + request.acceptContentType(), + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); return response.location(); } /** - * Retrieves the service entitlement configuration from OIDC authentication result. + * Retrieves the HTTP response with the service entitlement configuration from OIDC + * authentication result. * * <p>Implementation based on section 2.8.2 of TS.43. * * <p>{@link #acquireOidcAuthenticationEndpoint} must be called before calling this method. */ - public String queryEntitlementStatusFromOidc( - String url, CarrierConfig carrierConfig, String acceptContentType) + @NonNull + public HttpResponse queryEntitlementStatusFromOidc( + String url, CarrierConfig carrierConfig, ServiceEntitlementRequest request) throws ServiceEntitlementException { Uri.Builder urlBuilder = Uri.parse(url).buildUpon(); return httpGet( - urlBuilder.toString(), carrierConfig, acceptContentType).body(); + urlBuilder.toString(), + carrierConfig, + request.acceptContentType(), + request.terminalVendor(), + request.terminalModel(), + request.terminalSoftwareVersion()); } - private void appendParametersForAuthentication(Uri.Builder urlBuilder, - ServiceEntitlementRequest request) { - TelephonyManager telephonyManager = mContext.getSystemService( - TelephonyManager.class).createForSubscriptionId(mSimSubscriptionId); + 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 @@ -380,23 +469,25 @@ public class EapAkaApi { // EAP_ID required for initial AuthN urlBuilder.appendQueryParameter( EAP_ID, - getImsiEap(telephonyManager.getSimOperator(), - telephonyManager.getSubscriberId())); + getImsiEap( + telephonyManager.getSimOperator(), telephonyManager.getSubscriberId())); } } private void appendParametersForServiceEntitlementRequest( - Uri.Builder urlBuilder, ImmutableList<String> appIds, + Uri.Builder urlBuilder, + ImmutableList<String> appIds, ServiceEntitlementRequest request) { if (!TextUtils.isEmpty(request.notificationToken())) { urlBuilder - .appendQueryParameter(NOTIF_ACTION, - Integer.toString(request.notificationAction())) + .appendQueryParameter( + NOTIF_ACTION, Integer.toString(request.notificationAction())) .appendQueryParameter(NOTIF_TOKEN, request.notificationToken()); } - TelephonyManager telephonyManager = mContext.getSystemService( - TelephonyManager.class).createForSubscriptionId(mSimSubscriptionId); + 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()); @@ -415,18 +506,26 @@ public class EapAkaApi { urlBuilder // Identity and Authentication parameters - .appendQueryParameter(TERMINAL_VENDOR, request.terminalVendor()) - .appendQueryParameter(TERMINAL_MODEL, request.terminalModel()) - .appendQueryParameter(TERMIAL_SW_VERSION, request.terminalSoftwareVersion()) + .appendQueryParameter( + TERMINAL_VENDOR, + trimString(request.terminalVendor(), MAX_TERMINAL_VENDOR_LENGTH)) + .appendQueryParameter( + TERMINAL_MODEL, + trimString(request.terminalModel(), MAX_TERMINAL_MODEL_LENGTH)) + .appendQueryParameter( + TERMIAL_SW_VERSION, + trimString( + request.terminalSoftwareVersion(), + MAX_TERMINAL_SOFTWARE_VERSION_LENGTH)) // General Service parameters .appendQueryParameter(VERS, Integer.toString(request.configurationVersion())) .appendQueryParameter(ENTITLEMENT_VERSION, request.entitlementVersion()); } private void appendParametersForEsimOdsaOperation( - Uri.Builder urlBuilder, OdsaOperation odsaOperation) { + Uri.Builder urlBuilder, EsimOdsaOperation odsaOperation) { urlBuilder.appendQueryParameter(OPERATION, odsaOperation.operation()); - if (odsaOperation.operationType() != OdsaOperation.OPERATION_TYPE_NOT_SET) { + if (odsaOperation.operationType() != EsimOdsaOperation.OPERATION_TYPE_NOT_SET) { urlBuilder.appendQueryParameter(OPERATION_TYPE, Integer.toString(odsaOperation.operationType())); } @@ -434,54 +533,73 @@ public class EapAkaApi { urlBuilder, OPERATION_TARGETS, TextUtils.join(",", odsaOperation.operationTargets())); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_ID, - odsaOperation.companionTerminalId()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_VENDOR, - odsaOperation.companionTerminalVendor()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_MODEL, - odsaOperation.companionTerminalModel()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_SW_VERSION, + appendOptionalQueryParameter( + urlBuilder, COMPANION_TERMINAL_ID, odsaOperation.companionTerminalId()); + appendOptionalQueryParameter( + urlBuilder, COMPANION_TERMINAL_VENDOR, odsaOperation.companionTerminalVendor()); + appendOptionalQueryParameter( + urlBuilder, COMPANION_TERMINAL_MODEL, odsaOperation.companionTerminalModel()); + appendOptionalQueryParameter( + urlBuilder, + COMPANION_TERMINAL_SW_VERSION, odsaOperation.companionTerminalSoftwareVersion()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_FRIENDLY_NAME, + appendOptionalQueryParameter( + urlBuilder, + COMPANION_TERMINAL_FRIENDLY_NAME, odsaOperation.companionTerminalFriendlyName()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_SERVICE, - odsaOperation.companionTerminalService()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_ICCID, - odsaOperation.companionTerminalIccid()); - appendOptionalQueryParameter(urlBuilder, COMPANION_TERMINAL_EID, - odsaOperation.companionTerminalEid()); - appendOptionalQueryParameter(urlBuilder, TERMINAL_ICCID, - odsaOperation.terminalIccid()); + appendOptionalQueryParameter( + urlBuilder, COMPANION_TERMINAL_SERVICE, odsaOperation.companionTerminalService()); + appendOptionalQueryParameter( + urlBuilder, COMPANION_TERMINAL_ICCID, odsaOperation.companionTerminalIccid()); + appendOptionalQueryParameter( + urlBuilder, COMPANION_TERMINAL_EID, odsaOperation.companionTerminalEid()); + appendOptionalQueryParameter(urlBuilder, TERMINAL_ICCID, odsaOperation.terminalIccid()); appendOptionalQueryParameter(urlBuilder, TERMINAL_EID, odsaOperation.terminalEid()); - appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_ID, - odsaOperation.targetTerminalId()); - appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_IDS, - odsaOperation.targetTerminalIds()); - appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_ICCID, - odsaOperation.targetTerminalIccid()); - appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_EID, - odsaOperation.targetTerminalEid()); - appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_SERIAL_NUMBER, + appendOptionalQueryParameter( + urlBuilder, TARGET_TERMINAL_ID, odsaOperation.targetTerminalId()); + appendOptionalQueryParameter( + urlBuilder, TARGET_TERMINAL_IDS, odsaOperation.targetTerminalIds()); + appendOptionalQueryParameter( + urlBuilder, TARGET_TERMINAL_ICCID, odsaOperation.targetTerminalIccid()); + appendOptionalQueryParameter( + urlBuilder, TARGET_TERMINAL_EID, odsaOperation.targetTerminalEid()); + appendOptionalQueryParameter( + urlBuilder, + TARGET_TERMINAL_SERIAL_NUMBER, odsaOperation.targetTerminalSerialNumber()); - appendOptionalQueryParameter(urlBuilder, TARGET_TERMINAL_MODEL, - odsaOperation.targetTerminalModel()); - appendOptionalQueryParameter(urlBuilder, OLD_TERMINAL_ICCID, - odsaOperation.oldTerminalIccid()); - appendOptionalQueryParameter(urlBuilder, OLD_TERMINAL_ID, - odsaOperation.oldTerminalId()); + appendOptionalQueryParameter( + urlBuilder, TARGET_TERMINAL_MODEL, odsaOperation.targetTerminalModel()); + appendOptionalQueryParameter( + urlBuilder, OLD_TERMINAL_ICCID, odsaOperation.oldTerminalIccid()); + appendOptionalQueryParameter(urlBuilder, OLD_TERMINAL_ID, odsaOperation.oldTerminalId()); } - private HttpResponse httpGet(String url, CarrierConfig carrierConfig, String contentType) + @NonNull + private HttpResponse httpGet( + String url, + CarrierConfig carrierConfig, + String contentType, + String terminalVendor, + String terminalModel, + String terminalSoftwareVersion) throws ServiceEntitlementException { - HttpRequest httpRequest = + HttpRequest.Builder builder = HttpRequest.builder() .setUrl(url) .setRequestMethod(RequestMethod.GET) .addRequestProperty(HttpHeaders.ACCEPT, contentType) .setTimeoutInSec(carrierConfig.timeoutInSec()) - .setNetwork(carrierConfig.network()) - .build(); - return mHttpClient.request(httpRequest); + .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()); } private void appendOptionalQueryParameter(Uri.Builder urlBuilder, String key, String value) { @@ -490,8 +608,8 @@ public class EapAkaApi { } } - private void appendOptionalQueryParameter(Uri.Builder urlBuilder, String key, - ImmutableList<String> values) { + private void appendOptionalQueryParameter( + Uri.Builder urlBuilder, String key, ImmutableList<String> values) { if (values != null) { for (String value : values) { if (!TextUtils.isEmpty(value)) { @@ -525,6 +643,41 @@ public class EapAkaApi { return eapAkaChallenge; } + private String getAppVersion(Context context) { + try { + PackageInfo packageInfo = + context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + return packageInfo.versionName; + } catch (Exception e) { + // should be impossible + } + return ""; + } + + private String getUserAgent( + String clientTs43, + String terminalVendor, + String terminalModel, + String terminalSoftwareVersion) { + if (!TextUtils.isEmpty(clientTs43) + && !TextUtils.isEmpty(terminalVendor) + && !TextUtils.isEmpty(terminalModel) + && !TextUtils.isEmpty(terminalSoftwareVersion)) { + return String.format( + "PRD-TS43 term-%s/%s %s/%s OS-Android/%s", + trimString(terminalVendor, MAX_TERMINAL_VENDOR_LENGTH), + trimString(terminalModel, MAX_TERMINAL_MODEL_LENGTH), + clientTs43, + mAppVersion, + trimString(terminalSoftwareVersion, MAX_TERMINAL_SOFTWARE_VERSION_LENGTH)); + } + return ""; + } + + private String trimString(String s, int maxLength) { + return s.substring(0, Math.min(s.length(), maxLength)); + } + /** * Returns the IMSI EAP value. The resulting realm part of the Root NAI in 3GPP TS 23.003 clause * 19.3.2 will be in the form: @@ -545,16 +698,13 @@ public class EapAkaApi { return "0" + imsi + "@nai.epc.mnc" + mnc + ".mcc" + mcc + ".3gppnetwork.org"; } - /** - * Retrieves the history of past HTTP request and responses. - */ + /** Retrieves the history of past HTTP request and responses. */ + @NonNull public List<String> getHistory() { return mHttpClient.getHistory(); } - /** - * Clears the history of past HTTP request and responses. - */ + /** Clears the history of past HTTP request and responses. */ public void clearHistory() { mHttpClient.clearHistory(); } diff --git a/java/com/android/libraries/entitlement/http/HttpRequest.java b/java/com/android/libraries/entitlement/http/HttpRequest.java index b6cd771..ec5ca7a 100644 --- a/java/com/android/libraries/entitlement/http/HttpRequest.java +++ b/java/com/android/libraries/entitlement/http/HttpRequest.java @@ -16,6 +16,7 @@ package com.android.libraries.entitlement.http; +import android.content.res.Resources; import android.net.Network; import androidx.annotation.Nullable; @@ -24,6 +25,8 @@ import com.android.libraries.entitlement.CarrierConfig; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableListMultimap; +import com.google.common.net.HttpHeaders; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import org.json.JSONObject; @@ -72,6 +75,7 @@ public abstract class HttpRequest { abstract ImmutableListMultimap.Builder<String, String> requestPropertiesBuilder(); /** Adds an HTTP header field. */ + @CanIgnoreReturnValue public Builder addRequestProperty(String key, String value) { requestPropertiesBuilder().put(key, value); return this; @@ -82,6 +86,7 @@ public abstract class HttpRequest { * {@link #addRequestProperty(String, String)} multiple times with the same key and * one value at a time. */ + @CanIgnoreReturnValue public Builder addRequestProperty(String key, List<String> value) { requestPropertiesBuilder().putAll(key, value); return this; @@ -108,6 +113,13 @@ public abstract class HttpRequest { .setUrl("") .setRequestMethod("") .setPostData(new JSONObject()) - .setTimeoutInSec(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC); + .setTimeoutInSec(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC) + .addRequestProperty( + HttpHeaders.ACCEPT_LANGUAGE, + Resources.getSystem() + .getConfiguration() + .getLocales() + .get(0) + .toLanguageTag()); } } diff --git a/java/com/android/libraries/entitlement/odsa/AcquireConfigurationOperation.java b/java/com/android/libraries/entitlement/odsa/AcquireConfigurationOperation.java index 0f50242..08a86b8 100644 --- a/java/com/android/libraries/entitlement/odsa/AcquireConfigurationOperation.java +++ b/java/com/android/libraries/entitlement/odsa/AcquireConfigurationOperation.java @@ -20,10 +20,12 @@ import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.libraries.entitlement.odsa.OdsaOperation.CompanionService; -import com.android.libraries.entitlement.odsa.OdsaOperation.ServiceStatus; +import com.android.libraries.entitlement.EsimOdsaOperation; +import com.android.libraries.entitlement.EsimOdsaOperation.CompanionService; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaServiceStatus; import com.android.libraries.entitlement.utils.Ts43Constants; import com.android.libraries.entitlement.utils.Ts43Constants.AppId; +import com.android.libraries.entitlement.utils.Ts43Constants.NotificationAction; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; @@ -34,7 +36,7 @@ import java.lang.annotation.RetentionPolicy; /** * Acquire configuration operation described in GSMA Service Entitlement Configuration section 6. */ -public class AcquireConfigurationOperation { +public final class AcquireConfigurationOperation { /** Indicating polling interval not available. */ public static final int POLLING_INTERVAL_NOT_AVAILABLE = -1; @@ -51,6 +53,7 @@ public class AcquireConfigurationOperation { */ @AppId public abstract String appId(); + /** * Returns the unique identifier of the companion device, like IMEI. Used by HTTP parameter * {@code companion_terminal_id}. @@ -108,11 +111,24 @@ public class AcquireConfigurationOperation { public abstract String targetTerminalEid(); /** - * Returns a new {@link Builder} object. + * Returns the notification token used to register for entitlement configuration request + * from network. Used by HTTP parameter {@code notif_token}. */ @NonNull + public abstract String notificationToken(); + + /** + * Returns the action associated with the notification token. Used by HTTP parameter + * {@code notif_action}. + */ + @NotificationAction + public abstract int notificationAction(); + + /** Returns a new {@link Builder} object. */ + @NonNull public static Builder builder() { - return new AutoValue_AcquireConfigurationOperation_AcquireConfigurationRequest.Builder() + return new AutoValue_AcquireConfigurationOperation_AcquireConfigurationRequest + .Builder() .setCompanionTerminalId("") .setCompanionTerminalIccid("") .setCompanionTerminalEid("") @@ -120,33 +136,33 @@ public class AcquireConfigurationOperation { .setTerminalEid("") .setTargetTerminalId("") .setTargetTerminalIccid("") - .setTargetTerminalEid(""); + .setTargetTerminalEid("") + .setNotificationToken("") + .setNotificationAction(Ts43Constants.NOTIFICATION_ACTION_ENABLE_FCM); } - /** - * Builder - */ + /** Builder */ @AutoValue.Builder public abstract static class Builder { /** * Sets the application id. * * @param appId The application id. Can only be - * {@link Ts43Constants#APP_ODSA_COMPANION}, {@link Ts43Constants#APP_ODSA_PRIMARY}, or - * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. - * + * {@link Ts43Constants#APP_ODSA_COMPANION}, + * {@link Ts43Constants#APP_ODSA_PRIMARY}, or + * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. * @return The builder. */ @NonNull public abstract Builder setAppId(@NonNull @AppId String appId); + /** * Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter * {@code companion_terminal_id} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalId The unique identifier of the companion device. - * * @return The builder. */ @NonNull @@ -156,10 +172,9 @@ public class AcquireConfigurationOperation { * Sets the ICCID of the companion device. Used by HTTP parameter * {@code companion_terminal_iccid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalIccid The ICCID of the companion device. - * * @return The builder. */ @NonNull @@ -170,10 +185,9 @@ public class AcquireConfigurationOperation { * Sets the eUICC identifier (EID) of the companion device. Used by HTTP parameter * {@code companion_terminal_eid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalEid The eUICC identifier (EID) of the companion device. - * * @return The builder. */ @NonNull @@ -183,11 +197,10 @@ public class AcquireConfigurationOperation { * Sets the ICCID of the primary device eSIM in case of primary SIM not present. Used by * HTTP parameter {@code terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalIccid The ICCID of the primary device eSIM in case of primary SIM not - * present. - * + * present. * @return The builder. */ @NonNull @@ -197,11 +210,10 @@ public class AcquireConfigurationOperation { * Sets the eUICC identifier (EID) of the primary device eSIM in case of primary SIM not * present. Used by HTTP parameter {@code terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalEid The eUICC identifier (EID) of the primary device eSIM in case of - * primary SIM not present. - * + * primary SIM not present. * @return The builder. */ @NonNull @@ -212,11 +224,10 @@ public class AcquireConfigurationOperation { * the IMEI associated with the eSIM. Used by HTTP parameter {@code target_terminal_id} * if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalId The unique identifier of the primary device eSIM in case of - * multiple SIM. - * + * multiple SIM. * @return The builder. */ @NonNull @@ -226,10 +237,9 @@ public class AcquireConfigurationOperation { * Sets the ICCID primary device eSIM in case of multiple SIM. Used by HTTP parameter * {@code target_terminal_iccid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalIccid The ICCID primary device eSIM in case of multiple SIM. - * * @return The builder. */ @NonNull @@ -239,20 +249,43 @@ public class AcquireConfigurationOperation { * Sets the eUICC identifier (EID) of the primary device eSIM in case of multiple SIM. * Used by HTTP parameter {@code target_terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalEid The eUICC identifier (EID) of the primary device eSIM in - * case of multiple SIM. - * + * case of multiple SIM. * @return The builder. */ @NonNull public abstract Builder setTargetTerminalEid(@NonNull String targetTerminalEid); /** - * @return Build the {@link AcquireConfigurationRequest} object. + * Sets the notification token used to register for entitlement configuration request + * from network. Used by HTTP parameter {@code notif_token} if set. + * + * <p>Used by primary device ODSA operation. + * + * @param notificationToken The notification token used to register for entitlement + * configuration request from network. + * @return The builder. */ @NonNull + public abstract Builder setNotificationToken(@NonNull String notificationToken); + + /** + * Sets the action associated with the notification token. Used by HTTP parameter + * {@code notif_action} if set. + * + * <p>Used by primary device ODSA operation. + * + * @param notificationAction The action associated with the notification token. + * @return The builder. + */ + @NonNull + public abstract Builder setNotificationAction( + @NotificationAction int notificationAction); + + /** Returns build the {@link AcquireConfigurationRequest} object. */ + @NonNull public abstract AcquireConfigurationRequest build(); } } @@ -263,29 +296,19 @@ public class AcquireConfigurationOperation { */ @AutoValue public abstract static class AcquireConfigurationResponse extends OdsaResponse { - /** - * Configuration - */ + /** Configuration */ @AutoValue public abstract static class Configuration { - /** - * The configuration type is unknown. - */ + /** The configuration type is unknown. */ public static final int CONFIGURATION_TYPE_UNKNOWN = -1; - /** - * The configuration is for ODSA primary device. - */ + /** The configuration is for ODSA primary device. */ public static final int CONFIGURATION_TYPE_PRIMARY = 1; - /** - * The configuration is for companion device. - */ + /** The configuration is for companion device. */ public static final int CONFIGURATION_TYPE_COMPANION = 2; - /** - * The configuration is for server-initiated ODSA. - */ + /** The configuration is for server-initiated ODSA. */ public static final int CONFIGURATION_TYPE_ENTERPRISE = 3; @Retention(RetentionPolicy.SOURCE) @@ -295,11 +318,10 @@ public class AcquireConfigurationOperation { CONFIGURATION_TYPE_COMPANION, CONFIGURATION_TYPE_ENTERPRISE }) - public @interface ConfigurationType {} + public @interface ConfigurationType { + } - /** - * Indicates the configuration type. - */ + /** Indicates the configuration type. */ @ConfigurationType public abstract int type(); @@ -321,29 +343,28 @@ public class AcquireConfigurationOperation { /** * Service status. * - * @see OdsaOperation#SERVICE_STATUS_UNKNOWN - * @see OdsaOperation#SERVICE_STATUS_ACTIVATED - * @see OdsaOperation#SERVICE_STATUS_ACTIVATING - * @see OdsaOperation#SERVICE_STATUS_DEACTIVATED - * @see OdsaOperation#SERVICE_STATUS_DEACTIVATED_NO_REUSE + * @see EsimOdsaOperation#SERVICE_STATUS_UNKNOWN + * @see EsimOdsaOperation#SERVICE_STATUS_ACTIVATED + * @see EsimOdsaOperation#SERVICE_STATUS_ACTIVATING + * @see EsimOdsaOperation#SERVICE_STATUS_DEACTIVATED + * @see EsimOdsaOperation#SERVICE_STATUS_DEACTIVATED_NO_REUSE */ - @ServiceStatus + @OdsaServiceStatus public abstract int serviceStatus(); /** * Specifies the minimum interval (in minutes) with which the device application may - * poll the ECS to refresh the current {@link #serviceStatus()} using - * {@link AcquireConfigurationRequest}. This parameter will be present only when - * {@link #serviceStatus()} is {@link OdsaOperation#SERVICE_STATUS_ACTIVATING}. If + * poll the ECS to refresh the current {@link #serviceStatus()} using {@link + * AcquireConfigurationRequest}. This parameter will be present only when {@link + * #serviceStatus()} is {@link EsimOdsaOperation#SERVICE_STATUS_ACTIVATING}. If * parameter is not present or value is 0, this polling procedure is not triggered and * ODSA app will keep waiting for any external action to continue the flow. * - * The maximum number of {@link AcquireConfigurationRequest} before sending a - * {@link #serviceStatus()} with - * {@link OdsaOperation#SERVICE_STATUS_DEACTIVATED_NO_REUSE} will be defined as an ECS - * configuration variable (MaxRefreshRequest). + * <p>The maximum number of {@link AcquireConfigurationRequest} before sending a {@link + * #serviceStatus()} with {@link EsimOdsaOperation#SERVICE_STATUS_DEACTIVATED_NO_REUSE} + * will be defined as an ECS configuration variable (MaxRefreshRequest). * - * {@link #POLLING_INTERVAL_NOT_AVAILABLE} when polling inverval is not available. + * <p>{@link #POLLING_INTERVAL_NOT_AVAILABLE} when polling interval is not available. */ public abstract int pollingInterval(); @@ -354,45 +375,38 @@ public class AcquireConfigurationOperation { @Nullable public abstract DownloadInfo downloadInfo(); - /** - * Includes all information collected by the ES of the companion device. - */ + /** Includes all information collected by the ES of the companion device. */ @Nullable public abstract CompanionDeviceInfo companionDeviceInfo(); - /** - * @return The builder. - */ + /** Returns the builder. */ @NonNull public static Builder builder() { return new AutoValue_AcquireConfigurationOperation_AcquireConfigurationResponse_Configuration .Builder() .setType(CONFIGURATION_TYPE_UNKNOWN) .setIccid("") - .setServiceStatus(OdsaOperation.SERVICE_STATUS_UNKNOWN) + .setServiceStatus(EsimOdsaOperation.SERVICE_STATUS_UNKNOWN) .setPollingInterval(POLLING_INTERVAL_NOT_AVAILABLE); } - /** - * The builder of {@link Configuration} - */ + /** The builder of {@link Configuration} */ @AutoValue.Builder public abstract static class Builder { /** - * Set the configuration type + * Set the configuration type. * * @param configType The configuration type. - * * @return The builder. */ @NonNull public abstract Builder setType(@ConfigurationType int configType); + /** * Set the iccid. * * @param iccid Integrated Circuit Card Identification - Identifier of the eSIM - * profile on the device’s eSIM. - * + * profile on the device’s eSIM. * @return The builder. */ @NonNull @@ -402,7 +416,6 @@ public class AcquireConfigurationOperation { * Set the applicable companion device service. * * @param companionDeviceService Indicates the applicable companion device service. - * * @return The builder. */ @NonNull @@ -413,19 +426,18 @@ public class AcquireConfigurationOperation { * Set the service status. * * @param serviceStatus Service status. - * * @return The builder. */ @NonNull - public abstract Builder setServiceStatus(@ServiceStatus int serviceStatus); + public abstract Builder setServiceStatus(@OdsaServiceStatus int serviceStatus); /** * Set the polling interval. * * @param pollingInterval The minimum interval (in minutes) with which the device - * application may poll the ECS to refresh the current {@link #serviceStatus()} - * using {@link AcquireConfigurationRequest}. - * + * application may poll the ECS to refresh the current + * {@link #serviceStatus()} using + * {@link AcquireConfigurationRequest}. * @return The builder. */ @NonNull @@ -435,8 +447,7 @@ public class AcquireConfigurationOperation { * Set the download information. * * @param downloadInfo Specifies how and where to download the eSIM profile - * associated with the device. - * + * associated with the device. * @return The builder. */ @NonNull @@ -446,17 +457,14 @@ public class AcquireConfigurationOperation { * Set the companion device info. * * @param companionDeviceInfo Includes all information collected by the ES of the - * companion device. - * + * companion device. * @return The builder. */ @NonNull public abstract Builder setCompanionDeviceInfo( @NonNull CompanionDeviceInfo companionDeviceInfo); - /** - * @return Build the {@link Configuration} object. - */ + /** Returns build the {@link Configuration} object. */ @NonNull public abstract Configuration build(); } @@ -470,9 +478,7 @@ public class AcquireConfigurationOperation { @NonNull public abstract ImmutableList<Configuration> configurations(); - /** - * @return The builder. - */ + /** Returns the builder. */ @NonNull public static Builder builder() { return new AutoValue_AcquireConfigurationOperation_AcquireConfigurationResponse @@ -480,29 +486,28 @@ public class AcquireConfigurationOperation { .setConfigurations(ImmutableList.of()); } - /** - * The builder of {@link AcquireConfigurationResponse} - */ + /** The builder of {@link AcquireConfigurationResponse} */ @AutoValue.Builder public abstract static class Builder extends OdsaResponse.Builder { /** * Set the configurations * * @param configs Configurations defined in GSMA Service Entitlement Configuration - * section 6.5.5. Could be more than one if multiple companion device(s) associated with - * the requesting device that carry a configuration for ODSA. - * + * section 6.5.5. Could be more than one if multiple companion device(s) + * associated with the requesting device that carry a configuration for + * ODSA. * @return The builder. */ @NonNull public abstract Builder setConfigurations( @NonNull ImmutableList<Configuration> configs); - /** - * @return Build the {@link AcquireConfigurationResponse} object. - */ + /** Returns build the {@link AcquireConfigurationResponse} object. */ @NonNull public abstract AcquireConfigurationResponse build(); } } + + private AcquireConfigurationOperation() { + } } diff --git a/java/com/android/libraries/entitlement/odsa/AcquireTemporaryTokenOperation.java b/java/com/android/libraries/entitlement/odsa/AcquireTemporaryTokenOperation.java index bd98d45..4f814b9 100644 --- a/java/com/android/libraries/entitlement/odsa/AcquireTemporaryTokenOperation.java +++ b/java/com/android/libraries/entitlement/odsa/AcquireTemporaryTokenOperation.java @@ -19,7 +19,7 @@ package com.android.libraries.entitlement.odsa; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.libraries.entitlement.odsa.OdsaOperation.Operation; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaOperation; import com.android.libraries.entitlement.utils.Ts43Constants; import com.android.libraries.entitlement.utils.Ts43Constants.AppId; @@ -31,7 +31,7 @@ import java.time.Instant; /** * Acquire temporary token operation described in GSMA Service Entitlement Configuration section 6. */ -public class AcquireTemporaryTokenOperation { +public final class AcquireTemporaryTokenOperation { /** * Acquire temporary token request described in GSMA Service Entitlement Configuration section * 6.2. @@ -39,8 +39,8 @@ public class AcquireTemporaryTokenOperation { @AutoValue public abstract static class AcquireTemporaryTokenRequest { /** - * Returns the application id. Can only be {@link Ts43Constants#APP_ODSA_COMPANION}, - * {@link Ts43Constants#APP_ODSA_PRIMARY}, or + * Returns the application id. Can only be {@link Ts43Constants#APP_ODSA_COMPANION}, {@link + * Ts43Constants#APP_ODSA_PRIMARY}, or * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. */ @NonNull @@ -53,7 +53,7 @@ public class AcquireTemporaryTokenOperation { * {@code operation_targets}. */ @NonNull - @Operation + @OdsaOperation public abstract ImmutableList<String> operationTargets(); /** @@ -63,65 +63,57 @@ public class AcquireTemporaryTokenOperation { @NonNull public abstract String companionTerminalId(); - /** - * Returns a new {@link Builder} object. - */ + /** Returns a new {@link Builder} object. */ @NonNull public static Builder builder() { return new AutoValue_AcquireTemporaryTokenOperation_AcquireTemporaryTokenRequest .Builder() - .setAppId("") + .setAppId(Ts43Constants.APP_UNKNOWN) .setOperationTargets(ImmutableList.of()) .setCompanionTerminalId(""); } - /** - * Builder. - */ + /** Builder. */ @AutoValue.Builder public abstract static class Builder { /** * Sets the application id. * * @param appId The application id. Can only be - * {@link Ts43Constants#APP_ODSA_COMPANION}, {@link Ts43Constants#APP_ODSA_PRIMARY}, or - * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. - * + * {@link Ts43Constants#APP_ODSA_COMPANION}, + * {@link Ts43Constants#APP_ODSA_PRIMARY}, or + * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. * @return The builder. */ @NonNull public abstract Builder setAppId(@NonNull @AppId String appId); /** - * Sets the operation targets to be used with temporary token from - * {@code AcquireTemporaryToken} operation. Used by HTTP parameter - * {@code operation_targets} if set. + * Sets the operation targets to be used with temporary token from {@code + * AcquireTemporaryToken} operation. Used by HTTP parameter {@code operation_targets} if + * set. * * @param operationTargets The operation targets to be used with temporary token from - * {@code AcquireTemporaryToken} operation. - * + * {@code AcquireTemporaryToken} operation. * @return The builder. */ @NonNull public abstract Builder setOperationTargets( - @NonNull @Operation ImmutableList<String> operationTargets); + @NonNull @OdsaOperation ImmutableList<String> operationTargets); /** * Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter * {@code companion_terminal_id} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalId The unique identifier of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalId(@NonNull String companionTerminalId); - /** - * @return The {@link AcquireTemporaryTokenRequest} object. - */ + /** Returns the {@link AcquireTemporaryTokenRequest} object. */ @NonNull public abstract AcquireTemporaryTokenRequest build(); } @@ -132,29 +124,26 @@ public class AcquireTemporaryTokenOperation { * 6.5.7. */ @AutoValue + @AutoValue.CopyAnnotations + @SuppressWarnings("AndroidJdkLibsChecker") // java.time.Instant public abstract static class AcquireTemporaryTokenResponse extends OdsaResponse { - /** - * The temporary token used to establish trust between ECS and the client. - */ + /** The temporary token used to establish trust between ECS and the client. */ @NonNull public abstract String temporaryToken(); - /** - * The expiration time (UTC time) of the token. {@code null} if not available. - */ + /** The expiration time (UTC time) of the token. {@code null} if not available. */ + @AutoValue.CopyAnnotations + @SuppressWarnings("AndroidJdkLibsChecker") // java.time.Instant + @Nullable public abstract Instant temporaryTokenExpiry(); - /** - * The allowed ODSA operations requested using {@link #temporaryToken()}. - */ + /** The allowed ODSA operations requested using {@link #temporaryToken()}. */ @NonNull - @Operation + @OdsaOperation public abstract ImmutableList<String> operationTargets(); - /** - * Returns a new {@link AcquireTemporaryTokenRequest.Builder} object. - */ + /** Returns a new {@link AcquireTemporaryTokenRequest.Builder} object. */ @NonNull public static Builder builder() { return new AutoValue_AcquireTemporaryTokenOperation_AcquireTemporaryTokenResponse @@ -164,16 +153,15 @@ public class AcquireTemporaryTokenOperation { .setOperationTargets(ImmutableList.of()); } - /** - * Builder. - */ + /** Builder. */ @AutoValue.Builder + @AutoValue.CopyAnnotations + @SuppressWarnings("AndroidJdkLibsChecker") // java.time.Instant public abstract static class Builder extends OdsaResponse.Builder { /** * Sets the temporary token. * * @param token The temporary token used to establish trust between ECS and the client. - * * @return The builder. */ @NonNull @@ -183,30 +171,30 @@ public class AcquireTemporaryTokenOperation { * Sets the expiration time of the token. * * @param expiry The expiration time (UTC time) of the token. - * * @return The builder. */ + @AutoValue.CopyAnnotations + @SuppressWarnings("AndroidJdkLibsChecker") // java.time.Instant @NonNull public abstract Builder setTemporaryTokenExpiry(@NonNull Instant expiry); /** * Sets the allowed ODSA operations requested using {@link #temporaryToken()}. * - * @param operationTargets The allowed ODSA operations requested using - * {@link #temporaryToken()}. - * + * @param operationTargets The allowed ODSA operations requested using {@link + * #temporaryToken()}. * @return The builder. */ @NonNull public abstract Builder setOperationTargets( - @NonNull @Operation ImmutableList<String> operationTargets); + @NonNull @OdsaOperation ImmutableList<String> operationTargets); - /** - * @return The {@link AcquireTemporaryTokenResponse} object. - */ + /** Returns the {@link AcquireTemporaryTokenResponse} object. */ @NonNull public abstract AcquireTemporaryTokenResponse build(); } } -} + private AcquireTemporaryTokenOperation() { + } +} diff --git a/java/com/android/libraries/entitlement/odsa/CheckEligibilityOperation.java b/java/com/android/libraries/entitlement/odsa/CheckEligibilityOperation.java index 4546b88..8dc8d97 100644 --- a/java/com/android/libraries/entitlement/odsa/CheckEligibilityOperation.java +++ b/java/com/android/libraries/entitlement/odsa/CheckEligibilityOperation.java @@ -20,11 +20,12 @@ import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.libraries.entitlement.odsa.OdsaOperation.CompanionService; +import com.android.libraries.entitlement.EsimOdsaOperation.CompanionService; import com.android.libraries.entitlement.utils.HttpConstants; import com.android.libraries.entitlement.utils.HttpConstants.ContentType; import com.android.libraries.entitlement.utils.Ts43Constants; import com.android.libraries.entitlement.utils.Ts43Constants.AppId; +import com.android.libraries.entitlement.utils.Ts43Constants.NotificationAction; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; @@ -33,27 +34,18 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.URL; -/** - * Check eligibility operation described in GSMA Service Entitlement Configuration section 6. - */ -public class CheckEligibilityOperation { - /** - * ODSA app check eligibility result unknown. - */ +/** Check eligibility operation described in GSMA Service Entitlement Configuration section 6. */ +public final class CheckEligibilityOperation { + /** ODSA app check eligibility result unknown. */ public static final int ELIGIBILITY_RESULT_UNKNOWN = -1; - /** - * ODSA app cannot be offered and invoked by the end-user. - */ + + /** ODSA app cannot be offered and invoked by the end-user. */ public static final int ELIGIBILITY_RESULT_DISABLED = 0; - /** - * ODSA app can be invoked by end-user or to activate a new subscription. - */ + /** ODSA app can be invoked by end-user or to activate a new subscription. */ public static final int ELIGIBILITY_RESULT_ENABLED = 1; - /** - * ODSA app is not compatible with the device or server. - */ + /** ODSA app is not compatible with the device or server. */ public static final int ELIGIBILITY_RESULT_INCOMPATIBLE = 2; @Retention(RetentionPolicy.SOURCE) @@ -63,11 +55,12 @@ public class CheckEligibilityOperation { ELIGIBILITY_RESULT_ENABLED, ELIGIBILITY_RESULT_INCOMPATIBLE }) - public @interface EligibilityResult {} + public @interface EligibilityResult { + } /** - * HTTP request parameters specific to on device service activation (ODSA). See GSMA spec TS.43 - * section 6.2. + * HTTP request parameters specific to on device service activation (ODSA). + * See GSMA spec TS.43 section 6.2. */ @AutoValue public abstract static class CheckEligibilityRequest { @@ -115,31 +108,43 @@ public class CheckEligibilityOperation { public abstract String companionTerminalFriendlyName(); /** - * Returns a new {@link Builder} object. + * Returns the notification token used to register for entitlement configuration request + * from network. Used by HTTP parameter {@code notif_token}. */ @NonNull + public abstract String notificationToken(); + + /** + * Returns the action associated with the notification token. Used by HTTP parameter + * {@code notif_action}. + */ + @NotificationAction + public abstract int notificationAction(); + + /** Returns a new {@link Builder} object. */ + @NonNull public static Builder builder() { return new AutoValue_CheckEligibilityOperation_CheckEligibilityRequest.Builder() - .setAppId("") + .setAppId(Ts43Constants.APP_UNKNOWN) .setCompanionTerminalId("") .setCompanionTerminalVendor("") .setCompanionTerminalModel("") .setCompanionTerminalSoftwareVersion("") - .setCompanionTerminalFriendlyName(""); + .setCompanionTerminalFriendlyName("") + .setNotificationToken("") + .setNotificationAction(Ts43Constants.NOTIFICATION_ACTION_ENABLE_FCM); } - /** - * Builder - */ + /** Builder */ @AutoValue.Builder public abstract static class Builder { /** * Sets the application id. * * @param appId The application id. Can only be - * {@link Ts43Constants#APP_ODSA_COMPANION}, {@link Ts43Constants#APP_ODSA_PRIMARY}, or - * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. - * + * {@link Ts43Constants#APP_ODSA_COMPANION}, + * {@link Ts43Constants#APP_ODSA_PRIMARY}, or {@link + * Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. * @return The builder. */ @NonNull @@ -149,10 +154,9 @@ public class CheckEligibilityOperation { * Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter * {@code companion_terminal_id} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalId The unique identifier of the companion device. - * * @return The builder. */ @NonNull @@ -160,13 +164,11 @@ public class CheckEligibilityOperation { /** * Sets the OEM of the companion device. Used by HTTP parameter - * {@code companion_terminal_vendor}. - * if set. + * {@code companion_terminal_vendor} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalVendor The OEM of the companion device. - * * @return The builder. */ @NonNull @@ -175,13 +177,11 @@ public class CheckEligibilityOperation { /** * Sets the model of the companion device. Used by HTTP parameter - * {@code companion_terminal_model}. - * if set. + * {@code companion_terminal_model} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalModel The model of the companion device. - * * @return The builder. */ @NonNull @@ -192,10 +192,9 @@ public class CheckEligibilityOperation { * Sets the software version of the companion device. Used by HTTP parameter * {@code companion_terminal_sw_version} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalSoftwareVersion The software version of the companion device. - * * @return The builder. */ @NonNull @@ -206,11 +205,10 @@ public class CheckEligibilityOperation { * Sets the user-friendly version of the companion device. Used by HTTP parameter * {@code companion_terminal_friendly_name} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalFriendlyName The user-friendly version of the companion - * device. - * + * device. * @return The builder. */ @NonNull @@ -218,9 +216,33 @@ public class CheckEligibilityOperation { @NonNull String companionTerminalFriendlyName); /** - * @return The {@link CheckEligibilityRequest} object. + * Sets the notification token used to register for entitlement configuration request + * from network. Used by HTTP parameter {@code notif_token} if set. + * + * <p>Used by primary device ODSA operation. + * + * @param notificationToken The notification token used to register for entitlement + * configuration request from network. + * @return The builder. */ @NonNull + public abstract Builder setNotificationToken(@NonNull String notificationToken); + + /** + * Sets the action associated with the notification token. Used by HTTP parameter + * {@code notif_action} if set. + * + * <p>Used by primary device ODSA operation. + * + * @param notificationAction The action associated with the notification token. + * @return The builder. + */ + @NonNull + public abstract Builder setNotificationAction( + @NotificationAction int notificationAction); + + /** Returns the {@link CheckEligibilityRequest} object. */ + @NonNull public abstract CheckEligibilityRequest build(); } } @@ -230,15 +252,11 @@ public class CheckEligibilityOperation { */ @AutoValue public abstract static class CheckEligibilityResponse extends OdsaResponse { - /** - * @return The result of check eligibility request. - */ + /** Returns the result of check eligibility request. */ @EligibilityResult public abstract int appEligibility(); - /** - * Indicates the applicable companion device services. - */ + /** Indicates the applicable companion device services. */ @NonNull @CompanionService public abstract ImmutableList<String> companionDeviceServices(); @@ -248,28 +266,26 @@ public class CheckEligibilityOperation { * cannot be used/invoked. */ @Nullable - public abstract URL notEnabledURL(); + public abstract URL notEnabledUrl(); /** - * User data sent to the Service Provider when requesting the {@link #notEnabledURL()} web + * User data sent to the Service Provider when requesting the {@link #notEnabledUrl()} web * view. It should contain user-specific attributes to improve user experience. The format * must follow the {@link #notEnabledContentsType()} parameter. For content types of - * {@code JSON} and {@code XML}, it is possible to provide the base64 encoding of the - * value by preceding it with {@code encodedValue=}. + * {@code JSON} and {@code XML}, it is possible to provide the base64 encoding of the value + * by preceding it with {@code encodedValue=}. */ @NonNull public abstract String notEnabledUserData(); /** * Specifies content and HTTP method to use when reaching out to the web server specified in - * {@link #notEnabledURL()}. + * {@link #notEnabledUrl()}. */ @ContentType public abstract int notEnabledContentsType(); - /** - * @return The builder. - */ + /** Returns the builder. */ public static Builder builder() { return new AutoValue_CheckEligibilityOperation_CheckEligibilityResponse.Builder() .setAppEligibility(ELIGIBILITY_RESULT_UNKNOWN) @@ -278,16 +294,13 @@ public class CheckEligibilityOperation { .setNotEnabledContentsType(HttpConstants.UNKNOWN); } - /** - * The builder. - */ + /** The builder. */ @AutoValue.Builder public abstract static class Builder extends OdsaResponse.Builder { /** * Set the eligibility. * * @param eligibility The result of check eligibility request. - * * @return The builder. */ @NonNull @@ -297,7 +310,6 @@ public class CheckEligibilityOperation { * Set the companion device services. * * @param companionDeviceServices The applicable companion device services. - * * @return The builder. */ @NonNull @@ -308,48 +320,48 @@ public class CheckEligibilityOperation { * Set the URL presenting a web view to user on the reason(s) why the ODSA app cannot be * used/invoked. * - * @param url The provided URL shall present a web view to user on the reason(s) why - * the ODSA app cannot be used/invoked. - * + * @param url The provided URL shall present a web view to user on the reason(s) why the + * ODSA app cannot be used/invoked. * @return The builder. */ @NonNull - public abstract Builder setNotEnabledURL(@NonNull URL url); + public abstract Builder setNotEnabledUrl(@NonNull URL url); /** * Set the user data sent to the Service Provider when requesting the - * {@link #notEnabledURL()} web view. - * - * @param notEnabledUserData User data sent to the Service Provider when requesting - * the {@link #notEnabledURL()} web view. It should contain user-specific attributes - * to improve user experience. The format must follow the - * {@link #notEnabledContentsType()} parameter. For content types of - * {@link HttpConstants#JSON} and {@link HttpConstants#XML}, it is possible to provide - * the base64 encoding of the value by preceding it with {@code encodedValue=}. + * {@link #notEnabledUrl()} web view. * + * @param notEnabledUserData User data sent to the Service Provider when requesting the + * {@link #notEnabledUrl()} web view. It should contain + * user-specific attributes to improve user experience. The + * format must follow the {@link #notEnabledContentsType()} + * parameter. For content types of {@link HttpConstants#JSON} + * and {@link HttpConstants#XML}, it is possible to provide + * the base64 encoding of the value by preceding it with + * {@code encodedValue=}. * @return The builder. */ @NonNull - public abstract Builder setNotEnabledUserData( - @NonNull String notEnabledUserData); + public abstract Builder setNotEnabledUserData(@NonNull String notEnabledUserData); /** * Set the content and HTTP method to use when reaching out to the web server specified - * in {@link #notEnabledURL()}. - * - * @param notEnabledContentsType Specifies content and HTTP method to use when - * reaching out to the web server specified in {@link #notEnabledURL()}. + * in {@link #notEnabledUrl()}. * + * @param notEnabledContentsType Specifies content and HTTP method to use when reaching + * out to the web server specified in + * {@link #notEnabledUrl()}. * @return The builder. */ @NonNull public abstract Builder setNotEnabledContentsType( @ContentType int notEnabledContentsType); - /** - * Build the {@link CheckEligibilityResponse} object. - */ + /** Build the {@link CheckEligibilityResponse} object. */ public abstract CheckEligibilityResponse build(); } } + + private CheckEligibilityOperation() { + } } diff --git a/java/com/android/libraries/entitlement/odsa/CompanionDeviceInfo.java b/java/com/android/libraries/entitlement/odsa/CompanionDeviceInfo.java index 9e2a200..6762e79 100644 --- a/java/com/android/libraries/entitlement/odsa/CompanionDeviceInfo.java +++ b/java/com/android/libraries/entitlement/odsa/CompanionDeviceInfo.java @@ -22,8 +22,7 @@ import androidx.annotation.Nullable; import com.google.auto.value.AutoValue; /** - * Companion device info described in GSMA Service Entitlement Configuration section 6.5.5 table - * 41. + * Companion device info described in GSMA Service Entitlement Configuration section 6.5.5 table 41. */ @AutoValue public abstract class CompanionDeviceInfo { @@ -34,43 +33,33 @@ public abstract class CompanionDeviceInfo { @NonNull public abstract String companionTerminalFriendlyName(); - /** - * Manufacturer of the companion device. - */ + /** Manufacturer of the companion device. */ @NonNull public abstract String companionTerminalVendor(); - /** - * Model of the companion device. - */ + /** Model of the companion device. */ @Nullable public abstract String companionTerminalModel(); - /** - * eUICC identifier (EID) of the companion device being managed. - */ + /** eUICC identifier (EID) of the companion device being managed. */ @Nullable public abstract String companionTerminalEid(); - /** - * @return The builder of {@link CompanionDeviceInfo}. - */ + /** Returns the builder of {@link CompanionDeviceInfo}. */ @NonNull public static Builder builder() { return new AutoValue_CompanionDeviceInfo.Builder(); } - /** - * The builder. - */ + /** The builder. */ @AutoValue.Builder public abstract static class Builder { /** * Set user friendly identification for the companion device. * * @param companionTerminalFriendlyName User friendly identification for the companion - * device which can be used by the Service Provider in Web Views. - * + * device which can be used by the Service Provider in + * Web Views. * @return The builder. */ @NonNull @@ -81,7 +70,6 @@ public abstract class CompanionDeviceInfo { * Set manufacturer of the companion device. * * @param companionTerminalVendor manufacturer of the companion device. - * * @return The builder. */ @NonNull @@ -91,7 +79,6 @@ public abstract class CompanionDeviceInfo { * Set model of the companion device. * * @param companionTerminalModel Model of the companion device. - * * @return The builder. */ @NonNull @@ -101,15 +88,12 @@ public abstract class CompanionDeviceInfo { * Set EID of the companion device. * * @param companionTerminalEid eUICC identifier (EID) of the companion device being managed. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalEid(@NonNull String companionTerminalEid); - /** - * Build the CompanionDeviceInfo object. - */ + /** Build the CompanionDeviceInfo object. */ @NonNull public abstract CompanionDeviceInfo build(); } diff --git a/java/com/android/libraries/entitlement/odsa/DownloadInfo.java b/java/com/android/libraries/entitlement/odsa/DownloadInfo.java index 1ad7ead..d087ec9 100644 --- a/java/com/android/libraries/entitlement/odsa/DownloadInfo.java +++ b/java/com/android/libraries/entitlement/odsa/DownloadInfo.java @@ -22,8 +22,7 @@ import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; /** - * Download information described in GSMA Service Entitlement Configuration section 6.5.3 table - * 38. + * Download information described in GSMA Service Entitlement Configuration section 6.5.3 table 38. */ @AutoValue public abstract class DownloadInfo { @@ -35,8 +34,8 @@ public abstract class DownloadInfo { public abstract String profileIccid(); /** - * Address(es) of SM-DP+ to obtain eSIM profile. It is an empty list if - * {@link #profileActivationCode()} is not empty. + * Address(es) of SM-DP+ to obtain eSIM profile. It is an empty list if {@link + * #profileActivationCode()} is not empty. */ @NonNull public abstract ImmutableList<String> profileSmdpAddresses(); @@ -48,10 +47,7 @@ public abstract class DownloadInfo { @NonNull public abstract String profileActivationCode(); - - /** - * @return Builder of {@link DownloadInfo}. - */ + /** Returns builder of {@link DownloadInfo}. */ @NonNull public static Builder builder() { return new AutoValue_DownloadInfo.Builder() @@ -60,16 +56,13 @@ public abstract class DownloadInfo { .setProfileIccid(""); } - /** - * Builder of DownloadInfo. - */ + /** Builder of DownloadInfo. */ @AutoValue.Builder public abstract static class Builder { /** * Set the ICCID of the download profile. * * @param iccid The ICCID of the eSIM profile to download from SM-DP+. - * * @return The builder. */ @NonNull @@ -78,9 +71,8 @@ public abstract class DownloadInfo { /** * Set the activation code. * - * @param activationCode Activation code as defined in SGP.22 to permit the download of - * an eSIM profile from an SM-DP+. - * + * @param activationCode Activation code as defined in SGP.22 to permit the download of an + * eSIM profile from an SM-DP+. * @return The builder. */ @NonNull @@ -90,15 +82,12 @@ public abstract class DownloadInfo { * Set address(es) of SM-DP+ to obtain eSIM profile. * * @param smdpAddress Address(es) of SM-DP+ to obtain eSIM profile. - * * @return The builder. */ @NonNull public abstract Builder setProfileSmdpAddresses(@NonNull ImmutableList<String> smdpAddress); - /** - * Build the DownloadInfo object. - */ + /** Build the DownloadInfo object. */ @NonNull public abstract DownloadInfo build(); } diff --git a/java/com/android/libraries/entitlement/odsa/GetPhoneNumberOperation.java b/java/com/android/libraries/entitlement/odsa/GetPhoneNumberOperation.java new file mode 100644 index 0000000..3a30f0a --- /dev/null +++ b/java/com/android/libraries/entitlement/odsa/GetPhoneNumberOperation.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.libraries.entitlement.odsa; + +import androidx.annotation.NonNull; + +import com.google.auto.value.AutoValue; + +/** + * Get phone number operation described in GSMA Service Entitlement Configuration section 6. + */ +public final class GetPhoneNumberOperation { + /** + * Get phone number request described in GSMA Service Entitlement Configuration section 6.4.8. + */ + @AutoValue + public abstract static class GetPhoneNumberRequest { + /** + * Returns the terminal id. + */ + @NonNull + public abstract String terminalId(); + + /** Returns a new {@link GetPhoneNumberRequest.Builder} object. */ + @NonNull + public static Builder builder() { + return new AutoValue_GetPhoneNumberOperation_GetPhoneNumberRequest + .Builder() + .setTerminalId(""); + } + + /** Builder. */ + @AutoValue.Builder + public abstract static class Builder { + /** + * Sets the terminal id. + * + * @param terminalId The terminal id. + * @return The builder. + */ + @NonNull + public abstract Builder setTerminalId(@NonNull String terminalId); + + /** Returns the {@link GetPhoneNumberRequest} object. */ + @NonNull + public abstract GetPhoneNumberRequest build(); + } + } + + /** + * Get phone number response described in GSMA Service Entitlement Configuration section + * 6.5.8. + */ + @AutoValue + public abstract static class GetPhoneNumberResponse extends OdsaResponse { + + /** The phone number of the subscriber in E.164 format. */ + public abstract String msisdn(); + + /** Returns a new {@link GetPhoneNumberResponse.Builder} object. */ + @NonNull + public static Builder builder() { + return new AutoValue_GetPhoneNumberOperation_GetPhoneNumberResponse + .Builder() + .setMsisdn(""); + } + + /** Builder. */ + @AutoValue.Builder + public abstract static class Builder extends OdsaResponse.Builder { + /** + * Sets the phone number of the subscriber. + * + * @param msisdn The phone number of the subscriber in E.164 format. + * @return The builder. + */ + @NonNull + public abstract Builder setMsisdn(@NonNull String msisdn); + + /** Returns the {@link GetPhoneNumberResponse} object. */ + @NonNull + public abstract GetPhoneNumberResponse build(); + } + } + + private GetPhoneNumberOperation() { + } +} diff --git a/java/com/android/libraries/entitlement/odsa/ManageServiceOperation.java b/java/com/android/libraries/entitlement/odsa/ManageServiceOperation.java index 9597e39..34868a4 100644 --- a/java/com/android/libraries/entitlement/odsa/ManageServiceOperation.java +++ b/java/com/android/libraries/entitlement/odsa/ManageServiceOperation.java @@ -18,18 +18,17 @@ package com.android.libraries.entitlement.odsa; import androidx.annotation.NonNull; -import com.android.libraries.entitlement.odsa.OdsaOperation.CompanionService; -import com.android.libraries.entitlement.odsa.OdsaOperation.OperationType; -import com.android.libraries.entitlement.odsa.OdsaOperation.ServiceStatus; +import com.android.libraries.entitlement.EsimOdsaOperation; +import com.android.libraries.entitlement.EsimOdsaOperation.CompanionService; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaOperationType; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaServiceStatus; import com.android.libraries.entitlement.utils.Ts43Constants; import com.android.libraries.entitlement.utils.Ts43Constants.AppId; import com.google.auto.value.AutoValue; -/** - * Manage service operation described in GSMA Service Entitlement Configuration section 6. - */ -public class ManageServiceOperation { +/** Manage service operation described in GSMA Service Entitlement Configuration section 6. */ +public final class ManageServiceOperation { /** * HTTP request parameters specific to on device service activation (ODSA) manage service * request. See GSMA spec TS.43 section 6.2. @@ -37,18 +36,18 @@ public class ManageServiceOperation { @AutoValue public abstract static class ManageServiceRequest { /** - * Returns the application id. Can only be {@link Ts43Constants#APP_ODSA_COMPANION}, - * {@link Ts43Constants#APP_ODSA_PRIMARY}, or + * Returns the application id. Can only be {@link Ts43Constants#APP_ODSA_COMPANION}, {@link + * Ts43Constants#APP_ODSA_PRIMARY}, or * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. */ @AppId public abstract String appId(); /** - * Returns the detailed type of the eSIM ODSA operation. Used by HTTP parameter - * {@code operation_type}. + * Returns the detailed type of the eSIM ODSA operation. Used by HTTP parameter {@code + * operation_type}. */ - @OperationType + @OdsaOperationType public abstract int operationType(); /** @@ -59,29 +58,29 @@ public class ManageServiceOperation { public abstract String companionTerminalId(); /** - * Returns the OEM of the companion device. Used by HTTP parameter - * {@code companion_terminal_vendor}. + * Returns the OEM of the companion device. Used by HTTP parameter {@code + * companion_terminal_vendor}. */ @NonNull public abstract String companionTerminalVendor(); /** - * Returns the model of the companion device. Used by HTTP parameter - * {@code companion_terminal_model}. + * Returns the model of the companion device. Used by HTTP parameter {@code + * companion_terminal_model}. */ @NonNull public abstract String companionTerminalModel(); /** - * Returns the software version of the companion device. Used by HTTP parameter - * {@code companion_terminal_sw_version}. + * Returns the software version of the companion device. Used by HTTP parameter {@code + * companion_terminal_sw_version}. */ @NonNull public abstract String companionTerminalSoftwareVersion(); /** - * Returns the user-friendly version of the companion device. Used by HTTP parameter - * {@code companion_terminal_friendly_name}. + * Returns the user-friendly version of the companion device. Used by HTTP parameter {@code + * companion_terminal_friendly_name}. */ @NonNull public abstract String companionTerminalFriendlyName(); @@ -95,41 +94,37 @@ public class ManageServiceOperation { public abstract String companionTerminalService(); /** - * Returns the ICCID of the companion device. Used by HTTP parameter - * {@code companion_terminal_iccid}. + * Returns the ICCID of the companion device. Used by HTTP parameter {@code + * companion_terminal_iccid}. */ @NonNull public abstract String companionTerminalIccid(); - /** - * Returns a new {@link Builder} object. - */ + /** Returns a new {@link Builder} object. */ @NonNull public static Builder builder() { return new AutoValue_ManageServiceOperation_ManageServiceRequest.Builder() - .setAppId("") - .setOperationType(OdsaOperation.OPERATION_TYPE_NOT_SET) + .setAppId(Ts43Constants.APP_UNKNOWN) + .setOperationType(EsimOdsaOperation.OPERATION_TYPE_NOT_SET) .setCompanionTerminalId("") .setCompanionTerminalVendor("") .setCompanionTerminalModel("") .setCompanionTerminalSoftwareVersion("") .setCompanionTerminalFriendlyName("") - .setCompanionTerminalService("") + .setCompanionTerminalService(EsimOdsaOperation.COMPANION_SERVICE_UNKNOWN) .setCompanionTerminalIccid(""); } - /** - * Builder - */ + /** Builder */ @AutoValue.Builder public abstract static class Builder { /** * Sets the application id. * * @param appId The application id. Can only be - * {@link Ts43Constants#APP_ODSA_COMPANION}, {@link Ts43Constants#APP_ODSA_PRIMARY}, or - * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. - * + * {@link Ts43Constants#APP_ODSA_COMPANION}, + * {@link Ts43Constants#APP_ODSA_PRIMARY}, or {@link + * Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. * @return The builder. */ @NonNull @@ -138,43 +133,40 @@ public class ManageServiceOperation { /** * Sets the detailed type of the eSIM ODSA operation. * - * @param operationType Operation type. Only - * {@link OdsaOperation#OPERATION_TYPE_ACTIVATE_SERVICE} and - * {@link OdsaOperation#OPERATION_TYPE_DEACTIVATE_SERVICE} are allowed. - * + * @param operationType Operation type. Only {@link + * EsimOdsaOperation#OPERATION_TYPE_ACTIVATE_SERVICE} and {@link + * EsimOdsaOperation#OPERATION_TYPE_DEACTIVATE_SERVICE} are + * allowed. * @return The builder. */ @NonNull - public abstract Builder setOperationType(@OperationType int operationType); + public abstract Builder setOperationType(@OdsaOperationType int operationType); /** * Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter * {@code companion_terminal_id} if set. * * @param companionTerminalId The unique identifier of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalId(String companionTerminalId); /** - * Sets the OEM of the companion device. Used by HTTP parameter - * {@code companion_terminal_vendor} if set. + * Sets the OEM of the companion device. Used by HTTP parameter {@code + * companion_terminal_vendor} if set. * * @param companionTerminalVendor The OEM of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalVendor(String companionTerminalVendor); /** - * Sets the model of the companion device. Used by HTTP parameter - * {@code companion_terminal_model} if set. + * Sets the model of the companion device. Used by HTTP parameter {@code + * companion_terminal_model} if set. * * @param companionTerminalModel The model of the companion device. - * * @return The builder. */ @NonNull @@ -182,11 +174,10 @@ public class ManageServiceOperation { @NonNull String companionTerminalModel); /** - * Sets the software version of the companion device. Used by HTTP parameter - * {@code companion_terminal_sw_version} if set. + * Sets the software version of the companion device. Used by HTTP parameter {@code + * companion_terminal_sw_version} if set. * * @param companionTerminalSoftwareVersion The software version of the companion device. - * * @return The builder. */ @NonNull @@ -194,14 +185,13 @@ public class ManageServiceOperation { @NonNull String companionTerminalSoftwareVersion); /** - * Sets the user-friendly version of the companion device. Used by HTTP parameter - * {@code companion_terminal_friendly_name} if set. + * Sets the user-friendly version of the companion device. Used by HTTP parameter {@code + * companion_terminal_friendly_name} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalFriendlyName The user-friendly version of the companion - * device. - * + * device. * @return The builder. */ @NonNull @@ -212,10 +202,9 @@ public class ManageServiceOperation { * Sets the service type of the companion device, e.g. if the MSISDN is same as the * primary device. Used by HTTP parameter {@code companion_terminal_service} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalService The service type of the companion device. - * * @return The builder. */ @NonNull @@ -223,68 +212,59 @@ public class ManageServiceOperation { @NonNull @CompanionService String companionTerminalService); /** - * Sets the ICCID of the companion device. Used by HTTP parameter - * {@code companion_terminal_iccid} if set. + * Sets the ICCID of the companion device. Used by HTTP parameter {@code + * companion_terminal_iccid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalIccid The ICCID of the companion device. - * * @return The builder. */ @NonNull public abstract Builder setCompanionTerminalIccid( @NonNull String companionTerminalIccid); - /** - * Build the {@link ManageServiceRequest} object. - */ + /** Build the {@link ManageServiceRequest} object. */ @NonNull public abstract ManageServiceRequest build(); } } /** - * Manage service response described in GSMA Service Entitlement Configuration section - * 6.5.4 table 39. + * Manage service response described in GSMA Service Entitlement Configuration section 6.5.4 + * table 39. */ @AutoValue public abstract static class ManageServiceResponse extends OdsaResponse { - /** - * Service status. - */ - @ServiceStatus + /** Service status. */ + @OdsaServiceStatus public abstract int serviceStatus(); - /** - * Returns a new {@link ManageServiceResponse.Builder} object. - */ + /** Returns a new {@link ManageServiceResponse.Builder} object. */ @NonNull public static Builder builder() { return new AutoValue_ManageServiceOperation_ManageServiceResponse.Builder() - .setServiceStatus(OdsaOperation.SERVICE_STATUS_UNKNOWN); + .setServiceStatus(EsimOdsaOperation.SERVICE_STATUS_UNKNOWN); } - /** - * Builder - */ + /** Builder */ @AutoValue.Builder public abstract static class Builder extends OdsaResponse.Builder { /** * Set the service status. * * @param serviceStatus Service status - * * @return The builder. */ @NonNull - public abstract Builder setServiceStatus(@ServiceStatus int serviceStatus); + public abstract Builder setServiceStatus(@OdsaServiceStatus int serviceStatus); - /** - * Build the {@link ManageServiceResponse} object. - */ + /** Build the {@link ManageServiceResponse} object. */ @NonNull public abstract ManageServiceResponse build(); } } + + private ManageServiceOperation() { + } } diff --git a/java/com/android/libraries/entitlement/odsa/ManageSubscriptionOperation.java b/java/com/android/libraries/entitlement/odsa/ManageSubscriptionOperation.java index 35ae95f..8c06b5f 100644 --- a/java/com/android/libraries/entitlement/odsa/ManageSubscriptionOperation.java +++ b/java/com/android/libraries/entitlement/odsa/ManageSubscriptionOperation.java @@ -20,12 +20,14 @@ import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.libraries.entitlement.odsa.OdsaOperation.CompanionService; -import com.android.libraries.entitlement.odsa.OdsaOperation.OperationType; +import com.android.libraries.entitlement.EsimOdsaOperation; +import com.android.libraries.entitlement.EsimOdsaOperation.CompanionService; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaOperationType; import com.android.libraries.entitlement.utils.HttpConstants; import com.android.libraries.entitlement.utils.HttpConstants.ContentType; import com.android.libraries.entitlement.utils.Ts43Constants; import com.android.libraries.entitlement.utils.Ts43Constants.AppId; +import com.android.libraries.entitlement.utils.Ts43Constants.NotificationAction; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; @@ -37,7 +39,7 @@ import java.net.URL; /** * Manage subscription operation described in GSMA Service Entitlement Configuration section 6.5.3. */ -public class ManageSubscriptionOperation { +public final class ManageSubscriptionOperation { /** * HTTP request parameters specific to on device service activation (ODSA) manage subscription * request. See GSMA spec TS.43 section 6.2. @@ -57,7 +59,7 @@ public class ManageSubscriptionOperation { * Returns the detailed type of the eSIM ODSA operation. Used by HTTP parameter * {@code operation_type}. */ - @OperationType + @OdsaOperationType public abstract int operationType(); /** @@ -142,7 +144,7 @@ public class ManageSubscriptionOperation { * Returns the unique identifiers of the primary device eSIM if more than one, like the * IMEIs on dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis}. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. */ @NonNull public abstract ImmutableList<String> targetTerminalIds(); @@ -165,7 +167,7 @@ public class ManageSubscriptionOperation { * Returns the serial number of primary device. Used by HTTP parameter * {@code target_terminal_sn}. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. */ @NonNull public abstract String targetTerminalSerialNumber(); @@ -174,12 +176,11 @@ public class ManageSubscriptionOperation { * Returns the model of primary device. Used by HTTP parameter * {@code target_terminal_model}. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. */ @NonNull public abstract String targetTerminalModel(); - /** * Returns the unique identifier of the old device eSIM, like the IMEI associated with the * eSIM. Used by HTTP parameter {@code old_terminal_id}. @@ -201,19 +202,31 @@ public class ManageSubscriptionOperation { public abstract String planId(); /** - * Returns a new {@link Builder} object. + * Returns the notification token used to register for entitlement configuration request + * from network. Used by HTTP parameter {@code notif_token}. */ @NonNull + public abstract String notificationToken(); + + /** + * Returns the action associated with the notification token. Used by HTTP parameter + * {@code notif_action}. + */ + @NotificationAction + public abstract int notificationAction(); + + /** Returns a new {@link Builder} object. */ + @NonNull public static Builder builder() { return new AutoValue_ManageSubscriptionOperation_ManageSubscriptionRequest.Builder() - .setAppId("") - .setOperationType(OdsaOperation.OPERATION_TYPE_NOT_SET) + .setAppId(Ts43Constants.APP_UNKNOWN) + .setOperationType(EsimOdsaOperation.OPERATION_TYPE_NOT_SET) .setCompanionTerminalId("") .setCompanionTerminalVendor("") .setCompanionTerminalModel("") .setCompanionTerminalSoftwareVersion("") .setCompanionTerminalFriendlyName("") - .setCompanionTerminalService("") + .setCompanionTerminalService(EsimOdsaOperation.COMPANION_SERVICE_UNKNOWN) .setCompanionTerminalIccid("") .setCompanionTerminalEid("") .setTerminalIccid("") @@ -226,21 +239,21 @@ public class ManageSubscriptionOperation { .setTargetTerminalModel("") .setOldTerminalId("") .setOldTerminalIccid("") - .setPlanId(""); + .setPlanId("") + .setNotificationToken("") + .setNotificationAction(Ts43Constants.NOTIFICATION_ACTION_ENABLE_FCM); } - /** - * Builder - */ + /** Builder */ @AutoValue.Builder public abstract static class Builder { /** * Sets the application id. * * @param appId The application id. Can only be - * {@link Ts43Constants#APP_ODSA_COMPANION}, {@link Ts43Constants#APP_ODSA_PRIMARY}, or - * {@link Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. - * + * {@link Ts43Constants#APP_ODSA_COMPANION}, + * {@link Ts43Constants#APP_ODSA_PRIMARY}, or {@link + * Ts43Constants#APP_ODSA_SERVER_INITIATED_REQUESTS}. * @return The builder. */ @NonNull @@ -251,18 +264,18 @@ public class ManageSubscriptionOperation { * {@code operation_type} if set. * * @param operationType The detailed type of the eSIM ODSA operation. - * * @return The builder. */ @NonNull - public abstract Builder setOperationType(@OperationType int operationType); + public abstract Builder setOperationType(@OdsaOperationType int operationType); /** * Sets the unique identifier of the companion device, like IMEI. Used by HTTP parameter * {@code companion_terminal_id} if set. * - * @param + * <p>Used by companion device ODSA operation. * + * @param companionTerminalId The unique identifier of the companion device. * @return The builder. */ @NonNull @@ -272,8 +285,9 @@ public class ManageSubscriptionOperation { * Sets the OEM of the companion device. Used by HTTP parameter * {@code companion_terminal_vendor} if set. * - * @param companionTerminalVendor The OEM of the companion device. + * <p>Used by companion device ODSA operation. * + * @param companionTerminalVendor The OEM of the companion device. * @return The builder. */ @NonNull @@ -284,10 +298,9 @@ public class ManageSubscriptionOperation { * Sets the model of the companion device. Used by HTTP parameter * {@code companion_terminal_model} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalModel The model of the companion device. - * * @return The builder. */ @NonNull @@ -298,10 +311,9 @@ public class ManageSubscriptionOperation { * Sets the software version of the companion device. Used by HTTP parameter * {@code companion_terminal_sw_version} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalSoftwareVersion The software version of the companion device. - * * @return The builder. */ @NonNull @@ -312,11 +324,10 @@ public class ManageSubscriptionOperation { * Sets the user-friendly version of the companion device. Used by HTTP parameter * {@code companion_terminal_friendly_name} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalFriendlyName The user-friendly version of the companion - * device. - * + * device. * @return The builder. */ @NonNull @@ -327,10 +338,9 @@ public class ManageSubscriptionOperation { * Sets the service type of the companion device, e.g. if the MSISDN is same as the * primary device. Used by HTTP parameter {@code companion_terminal_service} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalService The service type of the companion device. - * * @return The builder. */ @NonNull @@ -341,10 +351,9 @@ public class ManageSubscriptionOperation { * Sets the ICCID of the companion device. Used by HTTP parameter * {@code companion_terminal_iccid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalIccid The ICCID of the companion device. - * * @return The builder. */ @NonNull @@ -355,10 +364,9 @@ public class ManageSubscriptionOperation { * Sets the eUICC identifier (EID) of the companion device. Used by HTTP parameter * {@code companion_terminal_eid} if set. * - * Used by companion device ODSA operation. + * <p>Used by companion device ODSA operation. * * @param companionTerminalEid The eUICC identifier (EID) of the companion device. - * * @return The builder. */ @NonNull @@ -368,11 +376,10 @@ public class ManageSubscriptionOperation { * Sets the ICCID of the primary device eSIM in case of primary SIM not present. Used by * HTTP parameter {@code terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalIccid The ICCID of the primary device eSIM in case of primary SIM not - * present. - * + * present. * @return The builder. */ @NonNull @@ -382,11 +389,10 @@ public class ManageSubscriptionOperation { * Sets the eUICC identifier (EID) of the primary device eSIM in case of primary SIM not * present. Used by HTTP parameter {@code terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param terminalEid The eUICC identifier (EID) of the primary device eSIM in case of - * primary SIM not present. - * + * primary SIM not present. * @return The builder. */ @NonNull @@ -394,15 +400,16 @@ public class ManageSubscriptionOperation { /** * Sets the unique identifiers of the primary device eSIM if more than one, like the - * IMEIs on dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis}. + * IMEIs on dual-SIM devices. Used by HTTP parameter {@code target_terminal_imeis} + * if set. * - * This is a non-standard params required by some carriers. + * <p>This is a non-standard params required by some carriers. * * @param targetTerminalIds The unique identifiers of the primary device eSIM if more - * than one. - * + * than one. * @return The builder. */ + @NonNull public abstract Builder setTargetTerminalIds( @NonNull ImmutableList<String> targetTerminalIds); @@ -411,11 +418,10 @@ public class ManageSubscriptionOperation { * the IMEI associated with the eSIM. Used by HTTP parameter {@code target_terminal_id} * if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalId The unique identifier of the primary device eSIM in case of - * multiple SIM. - * + * multiple SIM. * @return The builder. */ @NonNull @@ -425,10 +431,9 @@ public class ManageSubscriptionOperation { * Sets the ICCID primary device eSIM in case of multiple SIM. Used by HTTP parameter * {@code target_terminal_iccid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalIccid The ICCID primary device eSIM in case of multiple SIM. - * * @return The builder. */ @NonNull @@ -438,11 +443,10 @@ public class ManageSubscriptionOperation { * Sets the eUICC identifier (EID) of the primary device eSIM in case of multiple SIM. * Used by HTTP parameter {@code target_terminal_eid} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param targetTerminalEid The eUICC identifier (EID) of the primary device eSIM in - * case of multiple SIM. - * + * case of multiple SIM. * @return The builder. */ @NonNull @@ -450,12 +454,12 @@ public class ManageSubscriptionOperation { /** * Sets the serial number of primary device. Used by HTTP parameter - * {@code target_terminal_sn}. + * {@code target_terminal_sn} if set. * - * @param targetTerminalSerialNumber The serial number of primary device. - * - * This is a non-standard params required by some carriers. + * <p>Used by primary device ODSA operation. * + * @param targetTerminalSerialNumber The serial number of primary device. This is a + * non-standard params required by some carriers. * @return The builder. */ @NonNull @@ -464,12 +468,12 @@ public class ManageSubscriptionOperation { /** * Sets the model of primary device. Used by HTTP parameter - * {@code target_terminal_model}. - * - * @param targetTerminalModel The model of primary device. + * {@code target_terminal_model} if set. * - * This is a non-standard params required by some carriers. + * <p>Used by primary device ODSA operation. * + * @param targetTerminalModel The model of primary device. This is a non-standard params + * required by some carriers. * @return The builder. */ @NonNull @@ -477,24 +481,23 @@ public class ManageSubscriptionOperation { /** * Sets the unique identifier of the old device eSIM, like the IMEI associated with the - * eSIM. Used by HTTP parameter {@code old_terminal_id} if set. + * eSIM.Used by HTTP parameter {@code old_terminal_id} if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param oldTerminalId The unique identifier of the old device eSIM. - * * @return The builder. */ @NonNull public abstract Builder setOldTerminalId(@NonNull String oldTerminalId); /** - * Sets the ICCID old device eSIM. Used by HTTP parameter "old_terminal_iccid" if set. + * Sets the ICCID old device eSIM. Used by HTTP parameter {@code old_terminal_iccid} + * if set. * - * Used by primary device ODSA operation. + * <p>Used by primary device ODSA operation. * * @param oldTerminalIccid The ICCID old device eSIM. - * * @return The builder. */ @NonNull @@ -502,19 +505,44 @@ public class ManageSubscriptionOperation { /** * Sets the identifier of the specific plan offered by an MNO. Used by HTTP parameter - * {@code plan_id}. + * {@code plan_id} if set. * - * @param planId The identifier of the specific plan offered by an MNO. + * <p>Used by primary device ODSA operation. * + * @param planId The identifier of the specific plan offered by an MNO. * @return The builder. */ @NonNull public abstract Builder setPlanId(@NonNull String planId); /** - * @return The {@link ManageSubscriptionRequest} object. + * Sets the notification token used to register for entitlement configuration request + * from network. Used by HTTP parameter {@code notif_token} if set. + * + * <p>Used by primary device ODSA operation. + * + * @param notificationToken The notification token used to register for entitlement + * configuration request from network. + * @return The builder. + */ + @NonNull + public abstract Builder setNotificationToken(@NonNull String notificationToken); + + /** + * Sets the action associated with the notification token. Used by HTTP parameter + * {@code notif_action} if set. + * + * <p>Used by primary device ODSA operation. + * + * @param notificationAction The action associated with the notification token. + * @return The builder. */ @NonNull + public abstract Builder setNotificationAction( + @NotificationAction int notificationAction); + + /** Returns the {@link ManageSubscriptionRequest} object. */ + @NonNull public abstract ManageSubscriptionRequest build(); } } @@ -525,10 +553,9 @@ public class ManageSubscriptionOperation { */ @AutoValue public abstract static class ManageSubscriptionResponse extends OdsaResponse { - /** - * Subscription result unknown. - */ + /** Subscription result unknown. */ public static final int SUBSCRIPTION_RESULT_UNKNOWN = -1; + /** * Indicates that end-user must go through the subscription web view procedure, using * information included below. @@ -576,41 +603,41 @@ public class ManageSubscriptionOperation { SUBSCRIPTION_RESULT_DISMISS, SUBSCRIPTION_RESULT_DELETE_PROFILE_IN_USE }) - public @interface SubscriptionResult {} + public @interface SubscriptionResult { + } - /** - * The subscription result. - */ + /** The subscription result. */ @SubscriptionResult public abstract int subscriptionResult(); /** * URL refers to web views responsible for a certain action on the eSIM device subscription. - * The Service Provider can provide different URL based on the operation_type input - * parameter ({@link OdsaOperation#OPERATION_TYPE_SUBSCRIBE}, - * {@link OdsaOperation#OPERATION_TYPE_UNSUBSCRIBE}, - * {@link OdsaOperation#OPERATION_TYPE_CHANGE_SUBSCRIPTION}). + * The + * Service Provider can provide different URL based on the operation_type input parameter + * ({@link EsimOdsaOperation#OPERATION_TYPE_SUBSCRIBE}, {@link + * EsimOdsaOperation#OPERATION_TYPE_UNSUBSCRIBE}, {@link + * EsimOdsaOperation#OPERATION_TYPE_CHANGE_SUBSCRIPTION}). * - * {@code null} if {@link #subscriptionResult()} is not - * {@link #SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET}. + * <p>{@code null} if {@link #subscriptionResult()} is not {@link + * #SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET}. */ @Nullable - public abstract URL subscriptionServiceURL(); + public abstract URL subscriptionServiceUrl(); /** * User data sent to the Service Provider when requesting the - * {@link #subscriptionServiceURL()} web view. It should contain user-specific attributes to - * improve user experience. + * {@link #subscriptionServiceUrl()} + * web view. It should contain user-specific attributes to improve user experience. * - * {@code null} if {@link #subscriptionResult()} is not - * {@link #SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET}. + * <p>{@code null} if {@link #subscriptionResult()} is not {@link + * #SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET}. */ @Nullable public abstract String subscriptionServiceUserData(); /** * Specifies content and HTTP method to use when reaching out to the web server specified by - * {@link #subscriptionServiceURL()}. + * {@link #subscriptionServiceUrl()}. */ @ContentType public abstract int subscriptionServiceContentsType(); @@ -619,15 +646,13 @@ public class ManageSubscriptionOperation { * Specifies how and where to download the eSIM profile associated with the companion or * primary device. * - * {@code null} if {@link #subscriptionResult()} is not - * {@link #SUBSCRIPTION_RESULT_DOWNLOAD_PROFILE}. + * <p>{@code null} if {@link #subscriptionResult()} is not {@link + * #SUBSCRIPTION_RESULT_DOWNLOAD_PROFILE}. */ @Nullable public abstract DownloadInfo downloadInfo(); - /** - * @return The builder - */ + /** Returns the builder. */ @NonNull public static Builder builder() { return new AutoValue_ManageSubscriptionOperation_ManageSubscriptionResponse.Builder() @@ -635,16 +660,13 @@ public class ManageSubscriptionOperation { .setSubscriptionServiceContentsType(HttpConstants.UNKNOWN); } - /** - * Builder - */ + /** Builder */ @AutoValue.Builder public abstract static class Builder extends OdsaResponse.Builder { /** * Set subscription result. * * @param subscriptionResult The subscription result. - * * @return The builder. */ @NonNull @@ -656,24 +678,22 @@ public class ManageSubscriptionOperation { * subscription. * * @param url URL refers to web views responsible for a certain action on the eSIM - * device subscription. The Service Provider can provide different URL based on the - * operation_type input parameter ( - * {@link OdsaOperation#OPERATION_TYPE_SUBSCRIBE}, - * {@link OdsaOperation#OPERATION_TYPE_UNSUBSCRIBE}, - * {@link OdsaOperation#OPERATION_TYPE_CHANGE_SUBSCRIPTION}). - * + * device subscription. The Service Provider can provide different URL based + * on the operation_type input parameter ( + * {@link EsimOdsaOperation#OPERATION_TYPE_SUBSCRIBE}, {@link + * EsimOdsaOperation#OPERATION_TYPE_UNSUBSCRIBE}, {@link + * EsimOdsaOperation#OPERATION_TYPE_CHANGE_SUBSCRIPTION}). * @return The builder. */ @NonNull - public abstract Builder setSubscriptionServiceURL(@NonNull URL url); + public abstract Builder setSubscriptionServiceUrl(@NonNull URL url); /** * Set user data sent to the Service Provider. * - * @param userData User data sent to the Service Provider when requesting the - * {@link #subscriptionServiceURL()} web view. It should contain user-specific - * attributes to improve user experience. - * + * @param userData User data sent to the Service Provider when requesting the {@link + * #subscriptionServiceUrl()} web view. It should contain user-specific + * attributes to improve user experience. * @return The builder. */ @NonNull @@ -682,9 +702,8 @@ public class ManageSubscriptionOperation { /** * Set the content type. * - * @param contentType Specifies content and HTTP method to use when reaching out to - * the web server specified by {@link #subscriptionServiceURL()}. - * + * @param contentType Specifies content and HTTP method to use when reaching out to the + * web server specified by {@link #subscriptionServiceUrl()}. * @return The builder. */ @NonNull @@ -696,18 +715,18 @@ public class ManageSubscriptionOperation { * device. * * @param downloadInfo Specifies how and where to download the eSIM profile associated - * with the companion or primary device. - * + * with the companion or primary device. * @return The builder. */ @NonNull public abstract Builder setDownloadInfo(@NonNull DownloadInfo downloadInfo); - /** - * @return The {@link ManageSubscriptionResponse} object. - */ + /** Returns the {@link ManageSubscriptionResponse} object. */ @NonNull public abstract ManageSubscriptionResponse build(); } } + + private ManageSubscriptionOperation() { + } } diff --git a/java/com/android/libraries/entitlement/odsa/OdsaResponse.java b/java/com/android/libraries/entitlement/odsa/OdsaResponse.java index cd6c2a0..f81a64b 100644 --- a/java/com/android/libraries/entitlement/odsa/OdsaResponse.java +++ b/java/com/android/libraries/entitlement/odsa/OdsaResponse.java @@ -19,18 +19,16 @@ package com.android.libraries.entitlement.odsa; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.libraries.entitlement.odsa.OdsaOperation.OperationResult; +import com.android.libraries.entitlement.EsimOdsaOperation.OdsaOperationResult; + +import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.net.URL; -/** - * ODSA general response described in GSMA Service Entitlement Configuration section 6.5.1. - */ +/** ODSA general response described in GSMA Service Entitlement Configuration section 6.5.1. */ public abstract class OdsaResponse { - /** - * Operation result. - */ - @OperationResult + /** Operation result. */ + @OdsaOperationResult public abstract int operationResult(); /** @@ -41,48 +39,46 @@ public abstract class OdsaResponse { public abstract URL generalErrorUrl(); /** - * User data sent to the Service Provider when requesting the {@link #generalErrorUrl()} - * web view. It should contain user-specific attributes to improve user experience. + * User data sent to the Service Provider when requesting the {@link #generalErrorUrl()} web + * view. It should contain user-specific attributes to improve user experience. */ @Nullable public abstract String generalErrorUserData(); - /** - * Builder - */ + /** Builder */ public abstract static class Builder { /** * Set the operation result. * * @param operationResult The operation result. - * * @return The builder. */ @NonNull - public abstract Builder setOperationResult(@OperationResult int operationResult); + @CanIgnoreReturnValue + public abstract Builder setOperationResult(@OdsaOperationResult int operationResult); /** * Set the URL to the web view to user on the reason(s) why the authentication failed. * - * @param url The provided URL shall present a web view to user on the reason(s) why - * the authentication failed. - * + * @param url The provided URL shall present a web view to user on the reason(s) why the + * authentication failed. * @return The builder. */ @NonNull + @CanIgnoreReturnValue public abstract Builder setGeneralErrorUrl(@NonNull URL url); /** * Set the user data of {@link #generalErrorUrl()}. * - * @param userData User data sent to the Service Provider when requesting the - * {@link #generalErrorUrl()} web view. It should contain user-specific attributes to - * improve user experience. - * + * @param userData User data sent to the Service Provider when requesting the {@link + * #generalErrorUrl()} web view. It should contain user-specific attributes + * to improve user + * experience. * @return The builder. */ @NonNull + @CanIgnoreReturnValue public abstract Builder setGeneralErrorUserData(@NonNull String userData); - } } diff --git a/java/com/android/libraries/entitlement/odsa/PlanOffer.java b/java/com/android/libraries/entitlement/odsa/PlanOffer.java index 90df527..123e5ec 100644 --- a/java/com/android/libraries/entitlement/odsa/PlanOffer.java +++ b/java/com/android/libraries/entitlement/odsa/PlanOffer.java @@ -21,48 +21,37 @@ import androidx.annotation.Nullable; import com.google.auto.value.AutoValue; -/** - * Mobile plan described in GSMA Service Entitlement Configuration section 6.5.6 table 43. - */ +/** Mobile plan described in GSMA Service Entitlement Configuration section 6.5.6 table 43. */ @AutoValue public abstract class PlanOffer { - /** - * ID for the plan offered by the MNO. - */ + /** ID for the plan offered by the MNO. */ @NonNull public abstract String planId(); /** - * Name of the plan offered by the MNO. It is considered as an optional parameter due to it - * is not required in any request, but it is recommended to make easier the plan - * identification. + * Name of the plan offered by the MNO. It is considered as an optional parameter due to it is + * not required in any request, but it is recommended to make easier the plan identification. */ @Nullable public abstract String planName(); /** - * Description of the plan offered by the MNO. It is considered as an optional parameter due - * to it is not required in any request, but it is recommended to make easier the plan + * Description of the plan offered by the MNO. It is considered as an optional parameter due to + * it is not required in any request, but it is recommended to make easier the plan * identification. */ @Nullable public abstract String planDescription(); - /** - * @return The builder of {@link PlanOffer}. - */ + /** Returns the builder of {@link PlanOffer}. */ public static Builder builder() { return new AutoValue_PlanOffer.Builder(); } - /** - * Builder of PlanOffer - */ + /** Builder of PlanOffer */ @AutoValue.Builder public abstract static class Builder { - /** - * Sets ID for the plan offered by the MNO. - */ + /** Sets ID for the plan offered by the MNO. */ @NonNull public abstract Builder setPlanId(@NonNull String planId); @@ -82,9 +71,7 @@ public abstract class PlanOffer { @NonNull public abstract Builder setPlanDescription(@NonNull String planDescription); - /** - * Build the {@link PlanOffer} object. - */ + /** Build the {@link PlanOffer} object. */ @NonNull public abstract PlanOffer build(); } diff --git a/java/com/android/libraries/entitlement/utils/HttpConstants.java b/java/com/android/libraries/entitlement/utils/HttpConstants.java index 46884b9..1cd194b 100644 --- a/java/com/android/libraries/entitlement/utils/HttpConstants.java +++ b/java/com/android/libraries/entitlement/utils/HttpConstants.java @@ -21,30 +21,20 @@ import androidx.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -/** - * Http constants using for entitlement flow of TS.43. - */ +/** Http constants using for entitlement flow of TS.43. */ public final class HttpConstants { - /** - * HTTP content is unknown. - */ + /** HTTP content is unknown. */ public static final int UNKNOWN = -1; - /** - * HTTP content is JSON. - */ + /** HTTP content is JSON. */ public static final int JSON = 0; - /** - * HTTP content is XML. - */ + /** HTTP content is XML. */ public static final int XML = 1; @Retention(RetentionPolicy.SOURCE) - @IntDef({ - UNKNOWN, - JSON, - XML - }) + @IntDef({UNKNOWN, JSON, XML}) public @interface ContentType {} -} + + private HttpConstants() {} +}
\ No newline at end of file diff --git a/java/com/android/libraries/entitlement/utils/Ts43Constants.java b/java/com/android/libraries/entitlement/utils/Ts43Constants.java index 7d10e2c..6eab0dc 100644 --- a/java/com/android/libraries/entitlement/utils/Ts43Constants.java +++ b/java/com/android/libraries/entitlement/utils/Ts43Constants.java @@ -16,86 +16,69 @@ package com.android.libraries.entitlement.utils; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.StringDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -/** - * Defines the constants used for TS43 operations. - */ +/** Defines the constants used for TS43 operations. */ public final class Ts43Constants { - /** - * App ID for Voice-Over-LTE entitlement. - */ + /** App ID unknown. For initialization only. */ + public static final String APP_UNKNOWN = ""; + + /** App ID for Voice-Over-LTE entitlement. */ public static final String APP_VOLTE = "ap2003"; - /** - * App ID for Voice-Over-WiFi entitlement. - */ + /** App ID for Voice-Over-WiFi entitlement. */ public static final String APP_VOWIFI = "ap2004"; - /** - * App ID for SMS-Over-IP entitlement. - */ + /** App ID for SMS-Over-IP entitlement. */ public static final String APP_SMSOIP = "ap2005"; - /** - * App ID for on device service activation (ODSA) for companion device. - */ + /** App ID for on device service activation (ODSA) for companion device. */ public static final String APP_ODSA_COMPANION = "ap2006"; - /** - * App ID for on device service activation (ODSA) for primary device. - */ + /** App ID for on device service activation (ODSA) for primary device. */ public static final String APP_ODSA_PRIMARY = "ap2009"; - /** - * App ID for data plan information entitlement. - */ + /** App ID for data plan information entitlement. */ public static final String APP_DATA_PLAN_BOOST = "ap2010"; - /** - * App ID for server initiated requests, entitlement and activation. - */ + /** App ID for server initiated requests, entitlement and activation. */ public static final String APP_ODSA_SERVER_INITIATED_REQUESTS = "ap2011"; - /** - * App ID for direct carrier billing. - */ + /** App ID for direct carrier billing. */ public static final String APP_DIRECT_CARRIER_BILLING = "ap2012"; - /** - * App ID for private user identity. - */ + /** App ID for private user identity. */ public static final String APP_PRIVATE_USER_IDENTITY = "ap2013"; - /** - * App ID for phone number information. - */ + /** App ID for phone number information. */ public static final String APP_PHONE_NUMBER_INFORMATION = "ap2014"; @Retention(RetentionPolicy.SOURCE) @StringDef({ - APP_VOLTE, - APP_VOWIFI, - APP_SMSOIP, - APP_ODSA_COMPANION, - APP_ODSA_PRIMARY, - APP_DATA_PLAN_BOOST, - APP_ODSA_SERVER_INITIATED_REQUESTS, - APP_DIRECT_CARRIER_BILLING, - APP_PRIVATE_USER_IDENTITY, - APP_PHONE_NUMBER_INFORMATION + APP_UNKNOWN, + APP_VOLTE, + APP_VOWIFI, + APP_SMSOIP, + APP_ODSA_COMPANION, + APP_ODSA_PRIMARY, + APP_DATA_PLAN_BOOST, + APP_ODSA_SERVER_INITIATED_REQUESTS, + APP_DIRECT_CARRIER_BILLING, + APP_PRIVATE_USER_IDENTITY, + APP_PHONE_NUMBER_INFORMATION }) - public @interface AppId {} + public @interface AppId { + } /** * Check if the application id is valid. * * @param appId The application id. - * * @return {@code true} if valid, otherwise {@code false}. */ public static boolean isValidAppId(@NonNull @AppId String appId) { @@ -111,10 +94,68 @@ public final class Ts43Constants { case APP_PRIVATE_USER_IDENTITY: case APP_PHONE_NUMBER_INFORMATION: return true; + default: // fall through + } + return false; + } + + /** + * Action to disable notification token. + */ + public static final int NOTIFICATION_ACTION_DISABLE = 0; + + /** + * Action to enable GCM notification token. + */ + public static final int NOTIFICATION_ACTION_ENABLE_GCM = 1; + + /** + * Action to enable FCM notification token. + */ + public static final int NOTIFICATION_ACTION_ENABLE_FCM = 2; + + /** + * Action to enable WNS push notification token. + */ + public static final int NOTIFICATION_ACTION_ENABLE_WNS = 3; + + /** + * Action to enable APNS notification token. + */ + public static final int NOTIFICATION_ACTION_ENABLE_APNS = 4; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + NOTIFICATION_ACTION_DISABLE, + NOTIFICATION_ACTION_ENABLE_GCM, + NOTIFICATION_ACTION_ENABLE_FCM, + NOTIFICATION_ACTION_ENABLE_WNS, + NOTIFICATION_ACTION_ENABLE_APNS, + }) + public @interface NotificationAction {} + + /** + * Check if the notification action is valid. + * + * @param notificationAction The notification action. + * @return {@code true} if valid, otherwise {@code false}. + */ + public static boolean isValidNotificationAction(@NotificationAction int notificationAction) { + switch (notificationAction) { + case NOTIFICATION_ACTION_DISABLE: + case NOTIFICATION_ACTION_ENABLE_GCM: + case NOTIFICATION_ACTION_ENABLE_FCM: + case NOTIFICATION_ACTION_ENABLE_WNS: + case NOTIFICATION_ACTION_ENABLE_APNS: + return true; + default: // fall through } return false; } /** Default entitlement version. */ public static final String DEFAULT_ENTITLEMENT_VERSION = "2.0"; -} + + private Ts43Constants() { + } +}
\ No newline at end of file diff --git a/java/com/android/libraries/entitlement/utils/Ts43XmlDoc.java b/java/com/android/libraries/entitlement/utils/Ts43XmlDoc.java index 9949994..ec6910c 100644 --- a/java/com/android/libraries/entitlement/utils/Ts43XmlDoc.java +++ b/java/com/android/libraries/entitlement/utils/Ts43XmlDoc.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.android.libraries.entitlement.utils; import android.text.TextUtils; @@ -35,6 +34,8 @@ import org.xml.sax.SAXException; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; +import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; @@ -52,7 +53,8 @@ public final class Ts43XmlDoc { /** Type names of characteristics. */ public static final class CharacteristicType { - private CharacteristicType() {} + private CharacteristicType() { + } public static final String APPLICATION = "APPLICATION"; public static final String PRIMARY_CONFIGURATION = "PrimaryConfiguration"; @@ -66,7 +68,8 @@ public final class Ts43XmlDoc { /** Names of parameters. */ public static final class Parm { - private Parm() {} + private Parm() { + } public static final String TOKEN = "token"; public static final String APP_ID = "AppID"; @@ -101,7 +104,8 @@ public final class Ts43XmlDoc { /** Parameter values of XML response content. */ public static final class ParmValues { - private ParmValues() {} + private ParmValues() { + } public static final String OPERATION_RESULT_SUCCESS = "1"; public static final String OPERATION_RESULT_ERROR_GENERAL = "100"; @@ -119,19 +123,19 @@ public final class Ts43XmlDoc { public static final String SUBSCRIPTION_RESULT_DELAYED_DOWNLOAD = "4"; public static final String SUBSCRIPTION_RESULT_DISMISS = "5"; public static final String SUBSCRIPTION_RESULT_DELETE_PROFILE_IN_USE = "6"; - public static final String CONTENTS_TYPE_XML = "xml"; public static final String CONTENTS_TYPE_JSON = "json"; - public static final String DISABLED = "0"; public static final String ENABLED = "1"; public static final String INCOMPATIBLE = "2"; } + /** * Maps characteristics to a map of parameters. Key is the characteristic type. Value is - * parameter name and value. Example: {"APPLICATION" -> {"AppId" -> "ap2009", - * "OperationResult" -> "1"}, "APPLICATION|PrimaryConfiguration" -> {"ICCID" -> "123", - * "ServiceStatus" -> "2", "PollingInterval" -> "1"} } + * parameter + * name and value. Example: {"APPLICATION" -> {"AppId" -> "ap2009", "OperationResult" -> "1"}, + * "APPLICATION|PrimaryConfiguration" -> {"ICCID" -> "123", "ServiceStatus" -> "2", + * "PollingInterval" -> "1"} } */ private final Map<String, Map<String, String>> mCharacteristicsMap = new ArrayMap<>(); @@ -150,9 +154,9 @@ public final class Ts43XmlDoc { */ @Nullable public String get(ImmutableList<String> characteristicTypes, String parameterName) { - Map<String, String> parmMap = mCharacteristicsMap.get(TextUtils.join("|", - characteristicTypes)); - return parmMap == null ? null : parmMap.get(parameterName); + Map<String, String> parmMap = mCharacteristicsMap.get( + TextUtils.join("|", characteristicTypes)); + return parmMap == null ? null : parmMap.get(parameterName.toLowerCase(Locale.ROOT)); } /** @@ -163,18 +167,15 @@ public final class Ts43XmlDoc { if (responseBody == null) { return; } - // Workaround: some server doesn't escape "&" in XML response and that will cause XML parser // failure later. // This is a quick impl of escaping w/o introducing a ton of new dependencies. responseBody = responseBody.replace("&", "&").replace("&amp;", "&"); - try { InputSource inputSource = new InputSource(new StringReader(responseBody)); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = builderFactory.newDocumentBuilder(); Document doc = docBuilder.parse(inputSource); - doc.getDocumentElement().normalize(); NodeList nodeList = doc.getDocumentElement().getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { @@ -186,20 +187,19 @@ public final class Ts43XmlDoc { } } - /** Parses characteristics and parm values into characteristicsMap. */ - private void parseNode(ArrayList<String> characteristics, Node node) { + @SuppressWarnings("AndroidJdkLibsChecker") // java.util.Map#getOrDefault + /* Parses characteristics and parm values into characteristicsMap. */ + private void parseNode(List<String> characteristics, Node node) { String nodeName = node.getNodeName(); NamedNodeMap attributes = node.getAttributes(); if (attributes == null) { return; } - if (nodeName.equals(NODE_CHARACTERISTIC)) { Node typeNode = attributes.getNamedItem("type"); if (typeNode == null) { return; } - characteristics.add(Objects.requireNonNull(typeNode.getNodeValue())); NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { @@ -212,11 +212,11 @@ public final class Ts43XmlDoc { if (parmNameNode == null || parmValueNode == null) { return; } - String characteristicKey = TextUtils.join("|", characteristics); Map<String, String> parmMap = mCharacteristicsMap.getOrDefault(characteristicKey, new ArrayMap<>()); - parmMap.put(Objects.requireNonNull(parmNameNode.getNodeValue()), + parmMap.put( + Objects.requireNonNull(parmNameNode.getNodeValue().toLowerCase(Locale.ROOT)), Objects.requireNonNull(parmValueNode.getNodeValue())); mCharacteristicsMap.put(characteristicKey, parmMap); } diff --git a/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java b/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java index b8ee406..4fc2e30 100644 --- a/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java +++ b/tests/src/com/android/libraries/entitlement/ServiceEntitlementTest.java @@ -29,7 +29,7 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; import com.android.libraries.entitlement.eapaka.EapAkaApi; -import com.android.libraries.entitlement.odsa.OdsaOperation; +import com.android.libraries.entitlement.http.HttpResponse; import com.google.common.collect.ImmutableList; @@ -58,6 +58,7 @@ public class ServiceEntitlementTest { @Rule public final MockitoRule rule = MockitoJUnit.rule(); @Mock EapAkaApi mMockEapAkaApi; + @Mock HttpResponse mMockHttpResponse; @Mock private TelephonyManager mMockTelephonyManager; @Mock private TelephonyManager mMockTelephonyManagerForSubId; @@ -101,7 +102,10 @@ public class ServiceEntitlementTest { ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); when(mMockEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOLTE), mCarrierConfig, request)) - .thenReturn(QUERY_APP_VOLTE_RESULT); + .thenAnswer(invocation -> { + when(mMockHttpResponse.body()).thenReturn(QUERY_APP_VOLTE_RESULT); + return mMockHttpResponse; + }); assertThat( mServiceEntitlement.queryEntitlementStatus(ServiceEntitlement.APP_VOLTE, request)) @@ -113,7 +117,10 @@ public class ServiceEntitlementTest { ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); when(mMockEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), mCarrierConfig, request)) - .thenReturn(QUERY_APP_VOWIFI_RESULT); + .thenAnswer(invocation -> { + when(mMockHttpResponse.body()).thenReturn(QUERY_APP_VOWIFI_RESULT); + return mMockHttpResponse; + }); assertThat( mServiceEntitlement.queryEntitlementStatus( @@ -125,10 +132,13 @@ public class ServiceEntitlementTest { @Test public void performEsimOdsa_appOdsaCompanion_returnResult() throws Exception { ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - OdsaOperation odsaOperation = OdsaOperation.builder().build(); + EsimOdsaOperation odsaOperation = EsimOdsaOperation.builder().build(); when(mMockEapAkaApi.performEsimOdsaOperation( ServiceEntitlement.APP_ODSA_COMPANION, mCarrierConfig, request, odsaOperation)) - .thenReturn(QUERY_APP_ODSA_COMPANION_RESULT); + .thenAnswer(invocation -> { + when(mMockHttpResponse.body()).thenReturn(QUERY_APP_ODSA_COMPANION_RESULT); + return mMockHttpResponse; + }); assertThat( mServiceEntitlement.performEsimOdsa( @@ -139,10 +149,13 @@ public class ServiceEntitlementTest { @Test public void performEsimOdsa_appOdsaPrimary_returnResult() throws Exception { ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - OdsaOperation odsaOperation = OdsaOperation.builder().build(); + EsimOdsaOperation odsaOperation = EsimOdsaOperation.builder().build(); when(mMockEapAkaApi.performEsimOdsaOperation( ServiceEntitlement.APP_ODSA_PRIMARY, mCarrierConfig, request, odsaOperation)) - .thenReturn(QUERY_APP_ODSA_PRIMARY_RESULT); + .thenAnswer(invocation -> { + when(mMockHttpResponse.body()).thenReturn(QUERY_APP_ODSA_PRIMARY_RESULT); + return mMockHttpResponse; + }); assertThat( mServiceEntitlement.performEsimOdsa( @@ -167,7 +180,10 @@ public class ServiceEntitlementTest { public void queryEntitlementStatusFromOidc_returnResult() throws Exception { when(mMockEapAkaApi.queryEntitlementStatusFromOidc( ServiceEntitlement.APP_ODSA_PRIMARY, mCarrierConfig, null)) - .thenReturn(QUERY_ENTITLEMENT_STATUS_FROM_OIDC); + .thenAnswer(invocation -> { + when(mMockHttpResponse.body()).thenReturn(QUERY_ENTITLEMENT_STATUS_FROM_OIDC); + return mMockHttpResponse; + }); assertThat( mServiceEntitlement.queryEntitlementStatusFromOidc( diff --git a/tests/src/com/android/libraries/entitlement/Ts43AuthenticationTest.java b/tests/src/com/android/libraries/entitlement/Ts43AuthenticationTest.java index fd60b61..f30e171 100644 --- a/tests/src/com/android/libraries/entitlement/Ts43AuthenticationTest.java +++ b/tests/src/com/android/libraries/entitlement/Ts43AuthenticationTest.java @@ -31,8 +31,11 @@ import android.testing.AndroidTestingRunner; import com.android.libraries.entitlement.Ts43Authentication.Ts43AuthToken; import com.android.libraries.entitlement.eapaka.EapAkaApi; +import com.android.libraries.entitlement.http.HttpResponse; import com.android.libraries.entitlement.utils.Ts43Constants; +import com.google.common.collect.ImmutableList; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,6 +54,8 @@ public class Ts43AuthenticationTest { private static final String TOKEN = "ASH127AHHA88SF"; private static final long VALIDITY = 86400; private static final String IMEI = "861536030196001"; + private static final ImmutableList<String> COOKIES = + ImmutableList.of("key1=value1", "key2=value2"); private static final String HTTP_RESPONSE_WITH_TOKEN = "<?xml version=\"1.0\"?>" @@ -85,16 +90,15 @@ public class Ts43AuthenticationTest { + " </characteristic>" + "</wap-provisioningdoc>"; - private CarrierConfig mCarrierConfig; - - private ServiceEntitlement mServiceEntitlement; - private Ts43Authentication mTs43Authentication; @Mock private EapAkaApi mMockEapAkaApi; @Mock + private HttpResponse mMockHttpResponse; + + @Mock private Context mContext; @Mock @@ -103,14 +107,15 @@ public class Ts43AuthenticationTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mCarrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); - mServiceEntitlement = new ServiceEntitlement(mCarrierConfig, mMockEapAkaApi); + CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); + ServiceEntitlement serviceEntitlement = new ServiceEntitlement(carrierConfig, + mMockEapAkaApi); mTs43Authentication = new Ts43Authentication(mContext, new URL(TEST_URL), ENTITLEMENT_VERSION); Field field = Ts43Authentication.class.getDeclaredField("mServiceEntitlement"); field.setAccessible(true); - field.set(mTs43Authentication, mServiceEntitlement); + field.set(mTs43Authentication, serviceEntitlement); doReturn(2).when(mTelephonyManager).getActiveModemCount(); doReturn(IMEI).when(mTelephonyManager).getImei(0); @@ -118,12 +123,14 @@ public class Ts43AuthenticationTest { doReturn(Context.TELEPHONY_SERVICE).when(mContext) .getSystemServiceName(TelephonyManager.class); doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE); + doReturn(mMockHttpResponse).when(mMockEapAkaApi) + .queryEntitlementStatus(any(), any(), any()); + doReturn(COOKIES).when(mMockHttpResponse).cookies(); } @Test public void testGetAuthToken_receivedValidToken() throws Exception { - doReturn(HTTP_RESPONSE_WITH_TOKEN).when(mMockEapAkaApi).queryEntitlementStatus( - any(), any(), any()); + doReturn(HTTP_RESPONSE_WITH_TOKEN).when(mMockHttpResponse).body(); Ts43AuthToken mToken = mTs43Authentication.getAuthToken( 0, Ts43Constants.APP_ODSA_PRIMARY, APP_NAME, APP_VERSION); assertThat(mToken.token()).isEqualTo(TOKEN); @@ -154,9 +161,8 @@ public class Ts43AuthenticationTest { } @Test - public void testGetAuthToken_tokenNotAvailable_throwException() throws Exception { - doReturn(HTTP_RESPONSE_WITHOUT_TOKEN).when(mMockEapAkaApi).queryEntitlementStatus( - any(), any(), any()); + public void testGetAuthToken_tokenNotAvailable_throwException() { + doReturn(HTTP_RESPONSE_WITHOUT_TOKEN).when(mMockHttpResponse).body(); try { mTs43Authentication.getAuthToken( @@ -170,8 +176,7 @@ public class Ts43AuthenticationTest { @Test public void testGetAuthToken_validityNotAvailable() throws Exception { - doReturn(HTTP_RESPONSE_WITHOUT_VALIDITY).when(mMockEapAkaApi).queryEntitlementStatus( - any(), any(), any()); + doReturn(HTTP_RESPONSE_WITHOUT_VALIDITY).when(mMockHttpResponse).body(); Ts43AuthToken mToken = mTs43Authentication.getAuthToken( 0, Ts43Constants.APP_ODSA_PRIMARY, APP_NAME, APP_VERSION); assertThat(mToken.token()).isEqualTo(TOKEN); diff --git a/tests/src/com/android/libraries/entitlement/Ts43OperationTest.java b/tests/src/com/android/libraries/entitlement/Ts43OperationTest.java index 2dda42c..97e2193 100644 --- a/tests/src/com/android/libraries/entitlement/Ts43OperationTest.java +++ b/tests/src/com/android/libraries/entitlement/Ts43OperationTest.java @@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; import android.content.Context; @@ -28,6 +27,7 @@ import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; import com.android.libraries.entitlement.eapaka.EapAkaApi; +import com.android.libraries.entitlement.http.HttpResponse; import com.android.libraries.entitlement.odsa.AcquireConfigurationOperation.AcquireConfigurationRequest; import com.android.libraries.entitlement.odsa.AcquireConfigurationOperation.AcquireConfigurationResponse; import com.android.libraries.entitlement.odsa.AcquireTemporaryTokenOperation.AcquireTemporaryTokenRequest; @@ -35,11 +35,12 @@ import com.android.libraries.entitlement.odsa.AcquireTemporaryTokenOperation.Acq import com.android.libraries.entitlement.odsa.CheckEligibilityOperation; import com.android.libraries.entitlement.odsa.CheckEligibilityOperation.CheckEligibilityRequest; import com.android.libraries.entitlement.odsa.CheckEligibilityOperation.CheckEligibilityResponse; +import com.android.libraries.entitlement.odsa.GetPhoneNumberOperation.GetPhoneNumberRequest; +import com.android.libraries.entitlement.odsa.GetPhoneNumberOperation.GetPhoneNumberResponse; import com.android.libraries.entitlement.odsa.ManageServiceOperation.ManageServiceRequest; import com.android.libraries.entitlement.odsa.ManageServiceOperation.ManageServiceResponse; import com.android.libraries.entitlement.odsa.ManageSubscriptionOperation.ManageSubscriptionRequest; import com.android.libraries.entitlement.odsa.ManageSubscriptionOperation.ManageSubscriptionResponse; -import com.android.libraries.entitlement.odsa.OdsaOperation; import com.android.libraries.entitlement.utils.Ts43Constants; import com.google.common.collect.ImmutableList; @@ -62,6 +63,7 @@ public class Ts43OperationTest { private static final String SUBSCRIPTION_SERVICE_URL = "http://www.MNO.org/CDSubs"; private static final String SUBSCRIPTION_SERVICE_USER_DATA = "imsi=XX"; private static final String IMEI = "861536030196001"; + private static final String TERMINAL_ID = "861536030196005"; private static final String COMPANION_TERMINAL_ID = "98112687006099944"; private static final String COMPANION_TERMINAL_EID = "JHSDHljhsdfy763hh"; private static final String ICCID = "123456789"; @@ -75,6 +77,8 @@ public class Ts43OperationTest { private static final String NOT_ENABLED_USER_DATA = "msisdn=XX"; + private static final String MSISDN = "+16502530000"; + private static final String MANAGE_SUBSCRIPTION_RESPONSE_CONTINUE_TO_WEBSHEET = "<?xml version=\"1.0\"?>" + "<wap-provisioningdoc version=\"1.1\">" @@ -202,14 +206,30 @@ public class Ts43OperationTest { + "</characteristic>\n" + "</wap-provisioningdoc>"; - private CarrierConfig mCarrierConfig; - - private ServiceEntitlement mServiceEntitlement; + public String GET_PHONE_NUMBER_RESPONSE = + "<?xml version=\"1.0\"?>\n" + + "<wap-provisioningdoc version=\"1.1\">\n" + + "<characteristic type=\"VERS\">\n" + + " <parm name=\"version\" value=\"1\"/>\n" + + " <parm name=\"validity\" value=\"172800\"/>\n" + + "</characteristic>\n" + + "<characteristic type=\"TOKEN\">\n" + + " <parm name=\"token\" value=\"ASH127AHHA88SF\"/>\n" + + "</characteristic>\n" + + "<characteristic type=\"APPLICATION\">\n" + + " <parm name=\"AppID\" value=\"ap2014\"/>\n" + + " <parm name=\"OperationResult\" value=\"1\"/>\n" + + " <parm name=\"MSISDN\" value=\"" + MSISDN + "\"/>\n" + + "</characteristic>\n" + + "</wap-provisioningdoc>"; @Mock private EapAkaApi mMockEapAkaApi; @Mock + private HttpResponse mMockHttpResponse; + + @Mock private Context mContext; @Mock @@ -220,8 +240,11 @@ public class Ts43OperationTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mCarrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); - mServiceEntitlement = new ServiceEntitlement(mCarrierConfig, mMockEapAkaApi); + CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); + ServiceEntitlement serviceEntitlement = + new ServiceEntitlement(carrierConfig, mMockEapAkaApi); + doReturn(mMockHttpResponse).when(mMockEapAkaApi) + .performEsimOdsaOperation(any(), any(), any(), any()); doReturn(2).when(mTelephonyManager).getActiveModemCount(); doReturn(IMEI).when(mTelephonyManager).getImei(0); @@ -235,48 +258,44 @@ public class Ts43OperationTest { Field field = Ts43Operation.class.getDeclaredField("mServiceEntitlement"); field.setAccessible(true); - field.set(mTs43Operation, mServiceEntitlement); + field.set(mTs43Operation, serviceEntitlement); } @Test public void testManageSubscription_continueToWebsheet() throws Exception { - doReturn(MANAGE_SUBSCRIPTION_RESPONSE_CONTINUE_TO_WEBSHEET) - .when(mMockEapAkaApi).performEsimOdsaOperation( - anyString(), any(CarrierConfig.class), - any(ServiceEntitlementRequest.class), any(OdsaOperation.class)); + doReturn(MANAGE_SUBSCRIPTION_RESPONSE_CONTINUE_TO_WEBSHEET).when(mMockHttpResponse).body(); ManageSubscriptionRequest request = ManageSubscriptionRequest.builder() .setAppId(Ts43Constants.APP_ODSA_PRIMARY) - .setOperationType(OdsaOperation.OPERATION_TYPE_SUBSCRIBE) + .setOperationType(EsimOdsaOperation.OPERATION_TYPE_SUBSCRIBE) .setCompanionTerminalId(COMPANION_TERMINAL_ID) .setCompanionTerminalEid(COMPANION_TERMINAL_EID) .build(); ManageSubscriptionResponse response = mTs43Operation.manageSubscription(request); - assertThat(response.operationResult()).isEqualTo(OdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); assertThat(response.subscriptionResult()).isEqualTo( ManageSubscriptionResponse.SUBSCRIPTION_RESULT_CONTINUE_TO_WEBSHEET); - assertThat(response.subscriptionServiceURL()).isEqualTo(new URL(SUBSCRIPTION_SERVICE_URL)); + assertThat(response.subscriptionServiceUrl()).isEqualTo(new URL(SUBSCRIPTION_SERVICE_URL)); assertThat(response.subscriptionServiceUserData()) .isEqualTo(SUBSCRIPTION_SERVICE_USER_DATA); } @Test public void testManageSubscription_downloadProfile() throws Exception { - doReturn(MANAGE_SUBSCRIPTION_RESPONSE_DOWNLOAD_PROFILE) - .when(mMockEapAkaApi).performEsimOdsaOperation( - anyString(), any(CarrierConfig.class), - any(ServiceEntitlementRequest.class), any(OdsaOperation.class)); + doReturn(MANAGE_SUBSCRIPTION_RESPONSE_DOWNLOAD_PROFILE).when(mMockHttpResponse).body(); ManageSubscriptionRequest request = ManageSubscriptionRequest.builder() .setAppId(Ts43Constants.APP_ODSA_PRIMARY) - .setOperationType(OdsaOperation.OPERATION_TYPE_SUBSCRIBE) + .setOperationType(EsimOdsaOperation.OPERATION_TYPE_SUBSCRIBE) .setCompanionTerminalId(COMPANION_TERMINAL_ID) .setCompanionTerminalEid(COMPANION_TERMINAL_EID) .build(); ManageSubscriptionResponse response = mTs43Operation.manageSubscription(request); - assertThat(response.operationResult()).isEqualTo(OdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); assertThat(response.subscriptionResult()).isEqualTo( ManageSubscriptionResponse.SUBSCRIPTION_RESULT_DOWNLOAD_PROFILE); assertThat(response.downloadInfo().profileIccid()).isEqualTo(ICCID); @@ -286,75 +305,86 @@ public class Ts43OperationTest { @Test public void testAcquireTemporaryToken() throws Exception { - doReturn(ACQUIRE_TEMPORARY_TOKEN_RESPONSE) - .when(mMockEapAkaApi).performEsimOdsaOperation( - anyString(), any(CarrierConfig.class), - any(ServiceEntitlementRequest.class), any(OdsaOperation.class)); + doReturn(ACQUIRE_TEMPORARY_TOKEN_RESPONSE).when(mMockHttpResponse).body(); AcquireTemporaryTokenRequest request = AcquireTemporaryTokenRequest.builder() .setAppId(Ts43Constants.APP_ODSA_PRIMARY) - .setOperationTargets(ImmutableList.of(OdsaOperation.OPERATION_MANAGE_SUBSCRIPTION, - OdsaOperation.OPERATION_ACQUIRE_CONFIGURATION)) + .setOperationTargets(ImmutableList.of( + EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION, + EsimOdsaOperation.OPERATION_ACQUIRE_CONFIGURATION)) .build(); AcquireTemporaryTokenResponse response = mTs43Operation.acquireTemporaryToken(request); - assertThat(response.operationResult()).isEqualTo(OdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); assertThat(response.temporaryToken()).isEqualTo(TEMPORARY_TOKEN); assertThat(response.temporaryTokenExpiry().toString()).isEqualTo(TEMPORARY_TOKEN_EXPIRY); assertThat(response.operationTargets()).isEqualTo(ImmutableList.of( - OdsaOperation.OPERATION_MANAGE_SUBSCRIPTION, - OdsaOperation.OPERATION_ACQUIRE_CONFIGURATION)); + EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION, + EsimOdsaOperation.OPERATION_ACQUIRE_CONFIGURATION)); } @Test public void testAcquireConfiguration() throws Exception { - doReturn(ACQUIRE_CONFIGURATION_RESPONSE).when(mMockEapAkaApi).performEsimOdsaOperation( - anyString(), any(CarrierConfig.class), - any(ServiceEntitlementRequest.class), any(OdsaOperation.class)); + doReturn(ACQUIRE_CONFIGURATION_RESPONSE).when(mMockHttpResponse).body(); AcquireConfigurationRequest request = AcquireConfigurationRequest.builder() .setAppId(Ts43Constants.APP_ODSA_PRIMARY) .build(); AcquireConfigurationResponse response = mTs43Operation.acquireConfiguration(request); - assertThat(response.operationResult()).isEqualTo(OdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); assertThat(response.configurations()).hasSize(1); AcquireConfigurationResponse.Configuration config = response.configurations().get(0); assertThat(config.iccid()).isEqualTo(ICCID); assertThat(config.downloadInfo().profileIccid()).isEqualTo(ICCID); assertThat(config.downloadInfo().profileSmdpAddresses()).isEqualTo( ImmutableList.of(PROFILE_SMDP_ADDRESS)); - assertThat(config.serviceStatus()).isEqualTo(OdsaOperation.SERVICE_STATUS_ACTIVATED); + assertThat(config.serviceStatus()).isEqualTo(EsimOdsaOperation.SERVICE_STATUS_ACTIVATED); } @Test public void testCheckEligibility() throws Exception { - doReturn(CHECK_ELIGIBILITY_RESPONSE).when(mMockEapAkaApi).performEsimOdsaOperation( - anyString(), any(CarrierConfig.class), - any(ServiceEntitlementRequest.class), any(OdsaOperation.class)); + doReturn(CHECK_ELIGIBILITY_RESPONSE).when(mMockHttpResponse).body(); CheckEligibilityRequest request = CheckEligibilityRequest.builder() .setAppId(Ts43Constants.APP_ODSA_PRIMARY) .build(); CheckEligibilityResponse response = mTs43Operation.checkEligibility(request); - assertThat(response.operationResult()).isEqualTo(OdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); assertThat(response.appEligibility()).isEqualTo( CheckEligibilityOperation.ELIGIBILITY_RESULT_ENABLED); assertThat(response.companionDeviceServices()).containsExactly( - OdsaOperation.COMPANION_SERVICE_SHARED_NUMBER); - assertThat(response.notEnabledURL()).isEqualTo(new URL(NOT_ENABLED_URL)); + EsimOdsaOperation.COMPANION_SERVICE_SHARED_NUMBER); + assertThat(response.notEnabledUrl()).isEqualTo(new URL(NOT_ENABLED_URL)); assertThat(response.notEnabledUserData()).isEqualTo(NOT_ENABLED_USER_DATA); } @Test public void testManageService() throws Exception { - doReturn(MANAGE_SERVICE_RESPONSE).when(mMockEapAkaApi).performEsimOdsaOperation( - anyString(), any(CarrierConfig.class), - any(ServiceEntitlementRequest.class), any(OdsaOperation.class)); + doReturn(MANAGE_SERVICE_RESPONSE).when(mMockHttpResponse).body(); ManageServiceRequest request = ManageServiceRequest.builder() .setAppId(Ts43Constants.APP_ODSA_PRIMARY) .build(); ManageServiceResponse response = mTs43Operation.manageService(request); - assertThat(response.operationResult()).isEqualTo(OdsaOperation.OPERATION_RESULT_SUCCESS); - assertThat(response.serviceStatus()).isEqualTo(OdsaOperation.SERVICE_STATUS_DEACTIVATED); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.serviceStatus()).isEqualTo( + EsimOdsaOperation.SERVICE_STATUS_DEACTIVATED); + } + + @Test + public void testGetPhoneNumber() throws Exception { + doReturn(GET_PHONE_NUMBER_RESPONSE).when(mMockHttpResponse).body(); + + GetPhoneNumberRequest request = GetPhoneNumberRequest.builder() + .setTerminalId(TERMINAL_ID) + .build(); + + GetPhoneNumberResponse response = mTs43Operation.getPhoneNumber(request); + assertThat(response.operationResult()).isEqualTo( + EsimOdsaOperation.OPERATION_RESULT_SUCCESS); + assertThat(response.msisdn()).isEqualTo(MSISDN); } } diff --git a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java index 27d9f6f..6dafef3 100644 --- a/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java +++ b/tests/src/com/android/libraries/entitlement/eapaka/EapAkaApiTest.java @@ -25,6 +25,7 @@ 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.anyString; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -32,6 +33,8 @@ import static org.mockito.Mockito.when; import static org.testng.Assert.expectThrows; import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; import android.net.Network; import android.telephony.TelephonyManager; @@ -39,6 +42,7 @@ import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; import com.android.libraries.entitlement.CarrierConfig; +import com.android.libraries.entitlement.EsimOdsaOperation; import com.android.libraries.entitlement.ServiceEntitlement; import com.android.libraries.entitlement.ServiceEntitlementException; import com.android.libraries.entitlement.ServiceEntitlementRequest; @@ -46,7 +50,6 @@ import com.android.libraries.entitlement.http.HttpClient; import com.android.libraries.entitlement.http.HttpConstants.ContentType; import com.android.libraries.entitlement.http.HttpRequest; import com.android.libraries.entitlement.http.HttpResponse; -import com.android.libraries.entitlement.odsa.OdsaOperation; import com.google.common.collect.ImmutableList; import com.google.common.net.HttpHeaders; @@ -99,9 +102,21 @@ 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"; private static final String BYPASS_EAP_AKA_RESPONSE = "abc"; + private static final String VENDOR = "VEND"; + private static final String MODEL = "MODEL"; + private static final String SW_VERSION = "SW_VERSION"; + private static final String LONG_VENDOR = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static final String LONG_MODEL = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static final String LONG_SW_VERSION = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + private static final String LONG_VENDOR_TRIMMED = "aaaa"; + private static final String LONG_MODEL_TRIMMED = "aaaaaaaaaa"; + private static final String LONG_SW_VERSION_TRIMMED = "aaaaaaaaaaaaaaaaaaaa"; + private static final String APP_VERSION = "APP_VERSION"; @Rule public final MockitoRule rule = MockitoJUnit.rule(); + @Mock private PackageManager mMockPackageManager; + @Mock private PackageInfo mMockPackageInfo; @Mock private HttpClient mMockHttpClient; @Mock private Network mMockNetwork; @Mock private TelephonyManager mMockTelephonyManager; @@ -113,8 +128,12 @@ public class EapAkaApiTest { private EapAkaApi mEapAkaApiBypassAuthentication; @Before - public void setUp() { + public void setUp() throws Exception { mContext = spy(ApplicationProvider.getApplicationContext()); + when(mContext.getPackageManager()).thenReturn(mMockPackageManager); + 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); @@ -137,11 +156,11 @@ public class EapAkaApiTest { ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().setAuthenticationToken(TOKEN).build(); - String response = + HttpResponse response = mEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); - assertThat(response).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(httpResponse); verify(mMockHttpClient).request(mHttpRequestCaptor.capture()); assertThat(mHttpRequestCaptor.getValue().timeoutInSec()) .isEqualTo(CarrierConfig.DEFAULT_TIMEOUT_IN_SEC); @@ -167,11 +186,11 @@ public class EapAkaApiTest { CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - String respopnse = + HttpResponse response = mEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); - assertThat(respopnse).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture()); // Verify that the 2nd request has cookies set by the 1st response assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties()) @@ -249,11 +268,11 @@ public class EapAkaApiTest { CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - String respopnse = + HttpResponse response = mEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); - assertThat(respopnse).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); // 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()) @@ -296,11 +315,11 @@ public class EapAkaApiTest { CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - String respopnse = + HttpResponse response = mEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); - assertThat(respopnse).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); // 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()) @@ -429,11 +448,11 @@ public class EapAkaApiTest { CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - String response = + HttpResponse response = mEapAkaApi.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); - assertThat(response).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); // Verify that the 2nd/3rd request has cookie set by the 1st/2nd response verify(mMockHttpClient, times(3)).request(mHttpRequestCaptor.capture()); assertThat(mHttpRequestCaptor.getAllValues().get(1).requestProperties()) @@ -540,11 +559,11 @@ public class EapAkaApiTest { CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - String respopnse = + HttpResponse response = mEapAkaApiBypassAuthentication.queryEntitlementStatus( ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); - assertThat(respopnse).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); // 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()) @@ -609,6 +628,156 @@ public class EapAkaApiTest { } @Test + public void queryEntitlementStatus_terminalVendorModelSWVersionTrimmed() throws Exception { + CarrierConfig carrierConfig = + CarrierConfig.builder() + .setServerUrl(TEST_URL) + .setClientTs43(CarrierConfig.CLIENT_TS_43_IMS_ENTITLEMENT) + .build(); + ServiceEntitlementRequest request = + ServiceEntitlementRequest.builder() + .setAuthenticationToken(TOKEN) + .setTerminalVendor(LONG_VENDOR) + .setTerminalModel(LONG_MODEL) + .setTerminalSoftwareVersion(LONG_SW_VERSION) + .build(); + + mEapAkaApi.queryEntitlementStatus( + ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); + + verify(mMockHttpClient).request(mHttpRequestCaptor.capture()); + String urlParams = + 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); + } + + @Test + public void queryEntitlementStatus_userAgentSet() throws Exception { + CarrierConfig carrierConfig = + CarrierConfig.builder() + .setServerUrl(TEST_URL) + .setClientTs43(CarrierConfig.CLIENT_TS_43_IMS_ENTITLEMENT) + .build(); + ServiceEntitlementRequest request = + ServiceEntitlementRequest.builder() + .setAuthenticationToken(TOKEN) + .setTerminalVendor(VENDOR) + .setTerminalModel(MODEL) + .setTerminalSoftwareVersion(SW_VERSION) + .build(); + + mEapAkaApi.queryEntitlementStatus( + ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); + + verify(mMockHttpClient).request(mHttpRequestCaptor.capture()); + String userAgent = + String.format( + "PRD-TS43 term-%s/%s %s/%s OS-Android/%s", + VENDOR, MODEL, carrierConfig.clientTs43(), APP_VERSION, SW_VERSION); + assertThat( + mHttpRequestCaptor + .getValue() + .requestProperties() + .get(HttpHeaders.USER_AGENT) + .get(0)) + .isEqualTo(userAgent); + } + + @Test + public void queryEntitlementStatus_userAgentSet_duringEapAka() 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) + .setClientTs43(CarrierConfig.CLIENT_TS_43_IMS_ENTITLEMENT) + .build(); + ServiceEntitlementRequest request = + ServiceEntitlementRequest.builder() + .setTerminalVendor(VENDOR) + .setTerminalModel(MODEL) + .setTerminalSoftwareVersion(SW_VERSION) + .build(); + + mEapAkaApi.queryEntitlementStatus( + ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); + + verify(mMockHttpClient, times(2)).request(mHttpRequestCaptor.capture()); + String userAgent = + String.format( + "PRD-TS43 term-%s/%s %s/%s OS-Android/%s", + VENDOR, MODEL, carrierConfig.clientTs43(), APP_VERSION, SW_VERSION); + assertThat( + mHttpRequestCaptor + .getAllValues().get(0) + .requestProperties() + .get(HttpHeaders.USER_AGENT) + .get(0)) + .isEqualTo(userAgent); + assertThat( + mHttpRequestCaptor + .getAllValues().get(1) + .requestProperties() + .get(HttpHeaders.USER_AGENT) + .get(0)) + .isEqualTo(userAgent); + } + + @Test + public void queryEntitlementStatus_userAgentTrimmed() throws Exception { + CarrierConfig carrierConfig = + CarrierConfig.builder() + .setServerUrl(TEST_URL) + .setClientTs43(CarrierConfig.CLIENT_TS_43_IMS_ENTITLEMENT) + .build(); + ServiceEntitlementRequest request = + ServiceEntitlementRequest.builder() + .setAuthenticationToken(TOKEN) + .setTerminalVendor(LONG_VENDOR) + .setTerminalModel(LONG_MODEL) + .setTerminalSoftwareVersion(LONG_SW_VERSION) + .build(); + + mEapAkaApi.queryEntitlementStatus( + ImmutableList.of(ServiceEntitlement.APP_VOWIFI), carrierConfig, request); + + verify(mMockHttpClient).request(mHttpRequestCaptor.capture()); + String userAgent = + String.format( + "PRD-TS43 term-%s/%s %s/%s OS-Android/%s", + LONG_VENDOR_TRIMMED, + LONG_MODEL_TRIMMED, + carrierConfig.clientTs43(), + APP_VERSION, + LONG_SW_VERSION_TRIMMED); + assertThat( + mHttpRequestCaptor + .getValue() + .requestProperties() + .get(HttpHeaders.USER_AGENT) + .get(0)) + .isEqualTo(userAgent); + } + + @Test public void performEsimOdsaOperation_noAuthenticationToken_returnsResult() throws Exception { when(mMockTelephonyManagerForSubId.getIccAuthentication( TelephonyManager.APPTYPE_USIM, @@ -626,36 +795,36 @@ public class EapAkaApiTest { .thenReturn(eapChallengeResponse).thenReturn(xmlResponse); CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - OdsaOperation operation = OdsaOperation.builder().build(); + EsimOdsaOperation operation = EsimOdsaOperation.builder().build(); - String response = + HttpResponse response = mEapAkaApi.performEsimOdsaOperation(ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request, operation); - assertThat(response).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); verify(mMockHttpClient, times(2)).request(any()); } @Test public void performEsimOdsaOperation_manageSubscription_returnsResult() throws Exception { - HttpResponse httpResponse = + HttpResponse xmlResponse = HttpResponse.builder().setContentType(ContentType.XML).setBody(RESPONSE_XML) .build(); - when(mMockHttpClient.request(any())).thenReturn(httpResponse); + when(mMockHttpClient.request(any())).thenReturn(xmlResponse); CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().setAuthenticationToken(TOKEN).build(); - OdsaOperation operation = OdsaOperation.builder() - .setOperation(OdsaOperation.OPERATION_MANAGE_SUBSCRIPTION) - .setOperationType(OdsaOperation.OPERATION_TYPE_SUBSCRIBE) + EsimOdsaOperation operation = EsimOdsaOperation.builder() + .setOperation(EsimOdsaOperation.OPERATION_MANAGE_SUBSCRIPTION) + .setOperationType(EsimOdsaOperation.OPERATION_TYPE_SUBSCRIBE) .build(); - String response = + HttpResponse response = mEapAkaApi.performEsimOdsaOperation(ServiceEntitlement.APP_ODSA_COMPANION, carrierConfig, request, operation); - assertThat(response).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); verify(mMockHttpClient, times(1)).request(any()); } @@ -682,7 +851,7 @@ public class EapAkaApiTest { .thenReturn(xmlResponse); CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - OdsaOperation operation = OdsaOperation.builder().build(); + EsimOdsaOperation operation = EsimOdsaOperation.builder().build(); ServiceEntitlementException exception = expectThrows( @@ -725,20 +894,20 @@ public class EapAkaApiTest { @Test public void queryEntitlementStatusFromOidc() throws Exception { - HttpResponse response = + HttpResponse xmlResponse = HttpResponse.builder() .setContentType(ContentType.XML) .setBody(RESPONSE_XML) .build(); - when(mMockHttpClient.request(any())) - .thenReturn(response); + when(mMockHttpClient.request(any())).thenReturn(xmlResponse); CarrierConfig carrierConfig = CarrierConfig.builder().setServerUrl(TEST_URL).build(); + ServiceEntitlementRequest request = ServiceEntitlementRequest.builder().build(); - String xmlResponse = + HttpResponse response = mEapAkaApi.queryEntitlementStatusFromOidc( - TEST_URL, carrierConfig, ServiceEntitlementRequest.ACCEPT_CONTENT_TYPE_XML); + TEST_URL, carrierConfig, request); - assertThat(xmlResponse).isEqualTo(RESPONSE_XML); + assertThat(response).isEqualTo(xmlResponse); verify(mMockHttpClient, times(1)).request(any()); } } |