Commit 58413e78 authored by Peter E Conn's avatar Peter E Conn Committed by Commit Bot

💸 Make Chrome take DGAPI result codes in mojo format.

This is a follow up from questions left in:
  https://chromium-review.googlesource.com/c/chromium/src/+/2510271

Chrome previously expected the TWA shell to provide it with appropriate
values for the SKU value (a string with the currency sign removed) and
the purchase time (in microseconds, not milliseconds). With this CL
we standardise on this, expecting that the response code is in the mojo
format instead of a Play Billing one.

This is because the TWA shell may not get that information from Play
Billing (it coule be using a different store), so it doesn't make
sense for other stores to have to convert their codes to Play Billing
codes first.

Change-Id: I0d11eefdacc085b629373ba3bc7dc2568583577a
Bug: 1139795
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521819
Commit-Queue: Peter Conn <peconn@chromium.org>
Reviewed-by: default avatarMichael van Ouwerkerk <mvanouwerkerk@chromium.org>
Reviewed-by: default avatarGlen Robertson <glenrob@chromium.org>
Reviewed-by: default avatarJeevan Shikaram <jshikaram@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825863}
parent e4323c45
......@@ -60,7 +60,7 @@ class AcknowledgeConverter {
}
int code = args.getInt(RESPONSE_ACKNOWLEDGE_RESPONSE_CODE);
callback.call(convertResponseCode(code));
callback.call(convertResponseCode(code, args));
}
};
}
......
......@@ -26,6 +26,8 @@ import java.util.List;
public class DigitalGoodsConverter {
private static final String TAG = "DigitalGoods";
static final String KEY_VERSION = "digitalgoods.version";
// These values are copied from the Play Billing library since Chrome cannot depend on it.
// https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode
static final int PLAY_BILLING_OK = 0;
......@@ -35,7 +37,35 @@ public class DigitalGoodsConverter {
private DigitalGoodsConverter() {}
static int convertResponseCode(int responseCode) {
/** Converts the given response code to one suitable for mojo. */
static int convertResponseCode(int responseCode, Bundle bundle) {
// In the initial development, the TWA shell provided a Play Billing response code, so it
// needs to be converted to a Mojo one. Later on (but still before the feature was publicly
// launched), we decided that the TWA shell should provide data to Chrome already converted
// to a Mojo format. This is because the TWA shell may not be using Play Billing, so it
// doesn't make sense to standardise on that.
// We kept support for the older version just to make testing and development easier. It may
// be removed once the feature has launched.
int version = bundle.getInt(KEY_VERSION);
if (version == 0) {
return playBillingToMojoResponseCode(responseCode);
}
if (BillingResponseCode.isKnownValue(responseCode)) {
return responseCode;
}
Log.w(TAG, "Unexpected response code: " + responseCode);
return BillingResponseCode.ERROR;
}
/** Convenience method for legacy callers. */
static int convertResponseCodeV0(int responseCode) {
return convertResponseCode(responseCode, new Bundle());
}
private static int playBillingToMojoResponseCode(int responseCode) {
switch (responseCode) {
case PLAY_BILLING_OK:
return BillingResponseCode.OK;
......
......@@ -89,7 +89,7 @@ public class GetDetailsConverter {
ItemDetails[] details =
convertParcelableArray(array, GetDetailsConverter::convertItemDetails)
.toArray(new ItemDetails[0]);
callback.call(convertResponseCode(code), details);
callback.call(convertResponseCode(code, args), details);
}
};
}
......
......@@ -78,7 +78,7 @@ class ListPurchasesConverter {
PurchaseDetails[] details = convertParcelableArray(
array, ListPurchasesConverter::convertPurchaseDetails)
.toArray(new PurchaseDetails[0]);
callback.call(convertResponseCode(code), details);
callback.call(convertResponseCode(code, args), details);
}
};
}
......
......@@ -19,5 +19,19 @@ Android APIs are the source of truth for information such as price.
* `TrustedWebActivityClient` is the class that talks to Trusted Web Activities.
* `DigitalGoodsAdapter` sits between `DigitalGoodsImpl` and
`TrustedWebActivityClient`, transforming between appropriate data types.
* `DigitalGoodsConverter`, `GetDetailsConverter` and `AcknowledgeConverter` contain the lower level
transformations that `DigitalGoodsAdapter` uses.
* `DigitalGoodsConverter`, `GetDetailsConverter` and `AcknowledgeConverter`
contain the lower level transformations that `DigitalGoodsAdapter` uses.
## Interface versions
The bundles passed from the TWA shell to Chromium may contain a version code
(see `DigitalGoodsConverter#KEY_VERSION`). If the version code is missing, it
is assumed to be `0`.
Naturally, version `0` was the first version of the interface, but it was
never used by stable Chromium or Android Browser Helper.
Version changes:
- Version `1` changed the format of response code. Previously the response code
had been given in the Play Billing format. With version `1` Chromium expects
the TWA client to convert the response code to a Chromium format.
......@@ -116,7 +116,7 @@ public class DigitalGoodsConverterTest {
convertedCallback.onExtraCallback(GetDetailsConverter.RESPONSE_COMMAND, args);
assertEquals(convertResponseCode(responseCode), state.responseCode);
assertEquals(DigitalGoodsConverter.convertResponseCodeV0(responseCode), state.responseCode);
assertItemDetails(state.results[0], "1", "t1", "d1", "c1", "v1");
assertSubsItemDetails(state.results[0], null, null, null, null, null);
assertItemDetails(state.results[1], "2", "t2", "d2", "c2", "v2");
......@@ -269,24 +269,42 @@ public class DigitalGoodsConverterTest {
convertedCallback.onExtraCallback(ListPurchasesConverter.RESPONSE_COMMAND, args);
assertEquals(convertResponseCode(responseCode), state.responseCode);
assertEquals(DigitalGoodsConverter.convertResponseCodeV0(responseCode), state.responseCode);
assertPurchaseDetails(state.results[0], "1", "t1", true, 1, 1L, true);
assertPurchaseDetails(state.results[1], "2", "t2", false, 2, 2L, false);
}
@Test
public void convertResponseCodes() {
assertEquals(BillingResponseCode.OK, convertResponseCode(PLAY_BILLING_OK));
assertEquals(BillingResponseCode.OK,
DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_OK));
assertEquals(BillingResponseCode.ITEM_ALREADY_OWNED,
convertResponseCode(PLAY_BILLING_ITEM_ALREADY_OWNED));
DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_ITEM_ALREADY_OWNED));
assertEquals(BillingResponseCode.ITEM_NOT_OWNED,
convertResponseCode(PLAY_BILLING_ITEM_NOT_OWNED));
DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_ITEM_NOT_OWNED));
assertEquals(BillingResponseCode.ITEM_UNAVAILABLE,
convertResponseCode(PLAY_BILLING_ITEM_UNAVAILABLE));
DigitalGoodsConverter.convertResponseCodeV0(PLAY_BILLING_ITEM_UNAVAILABLE));
// Check that other numbers get set to ERROR.
assertEquals(BillingResponseCode.ERROR, convertResponseCode(2));
assertEquals(BillingResponseCode.ERROR, convertResponseCode(-1));
assertEquals(BillingResponseCode.ERROR, convertResponseCode(10));
assertEquals(BillingResponseCode.ERROR, DigitalGoodsConverter.convertResponseCodeV0(2));
assertEquals(BillingResponseCode.ERROR, DigitalGoodsConverter.convertResponseCodeV0(-1));
assertEquals(BillingResponseCode.ERROR, DigitalGoodsConverter.convertResponseCodeV0(10));
}
@Test
public void convertResponseCodes_v2() {
Bundle args = new Bundle();
args.putInt(DigitalGoodsConverter.KEY_VERSION, 1);
assertEquals(BillingResponseCode.OK, convertResponseCode(BillingResponseCode.OK, args));
assertEquals(BillingResponseCode.ITEM_ALREADY_OWNED,
convertResponseCode(BillingResponseCode.ITEM_ALREADY_OWNED, args));
assertEquals(BillingResponseCode.ITEM_NOT_OWNED,
convertResponseCode(BillingResponseCode.ITEM_NOT_OWNED, args));
assertEquals(BillingResponseCode.ITEM_UNAVAILABLE,
convertResponseCode(BillingResponseCode.ITEM_UNAVAILABLE, args));
assertEquals(BillingResponseCode.ERROR, convertResponseCode(123, args));
assertEquals(BillingResponseCode.ERROR, convertResponseCode(-12, args));
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment