// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.browserservices.digitalgoods;
import static org.chromium.chrome.browser.browserservices.digitalgoods.DigitalGoodsConverter.checkField;
import static org.chromium.chrome.browser.browserservices.digitalgoods.DigitalGoodsConverter.convertParcelableArray;
import static org.chromium.chrome.browser.browserservices.digitalgoods.DigitalGoodsConverter.convertResponseCode;
import android.os.Bundle;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.browser.trusted.TrustedWebActivityCallback;
import org.chromium.base.Log;
import org.chromium.payments.mojom.BillingResponseCode;
import org.chromium.payments.mojom.DigitalGoods.ListPurchases_Response;
import org.chromium.payments.mojom.PurchaseReference;
/** A converter that deals with the results of ListPurchases calls. */
class ListPurchasesConverter {
private static final String TAG = "DigitalGoods";
static final String RESPONSE_COMMAND = "listPurchases.response";
static final String KEY_PURCHASES_LIST = "listPurchases.purchasesList";
static final String KEY_RESPONSE_CODE = "listPurchases.responseCode";
static final String KEY_ITEM_ID = "purchaseDetails.itemId";
static final String KEY_PURCHASE_TOKEN = "purchaseDetails.purchaseToken";
private ListPurchasesConverter() {}
/**
* Produces a {@link TrustedWebActivityCallback} that calls the given
* {@link ListPurchasesResponse}.
*/
static TrustedWebActivityCallback convertCallback(ListPurchases_Response callback) {
return new TrustedWebActivityCallback() {
@Override
public void onExtraCallback(@NonNull String callbackName, @Nullable Bundle args) {
if (!RESPONSE_COMMAND.equals(callbackName)) {
Log.w(TAG, "Wrong callback name given: " + callbackName + ".");
returnClientAppError(callback);
return;
}
if (args == null) {
Log.w(TAG, "No args provided.");
returnClientAppError(callback);
return;
}
if (!checkField(args, KEY_RESPONSE_CODE, Integer.class)
|| !checkField(args, KEY_PURCHASES_LIST, Parcelable[].class)) {
returnClientAppError(callback);
return;
}
int code = args.getInt(KEY_RESPONSE_CODE);
Parcelable[] array = args.getParcelableArray(KEY_PURCHASES_LIST);
PurchaseReference[] reference =
convertParcelableArray(
array, ListPurchasesConverter::convertPurchaseReference)
.toArray(new PurchaseReference[0]);
callback.call(convertResponseCode(code, args), reference);
}
};
}
/** Convert a Bundle into a PurchaseReference object. */
static PurchaseReference convertPurchaseReference(Bundle purchase) {
if (!checkField(purchase, KEY_ITEM_ID, String.class)) return null;
if (!checkField(purchase, KEY_PURCHASE_TOKEN, String.class)) return null;
PurchaseReference result = new PurchaseReference();
result.itemId = purchase.getString(KEY_ITEM_ID);
result.purchaseToken = purchase.getString(KEY_PURCHASE_TOKEN);
return result;
}
static void returnClientAppUnavailable(ListPurchases_Response callback) {
callback.call(BillingResponseCode.CLIENT_APP_UNAVAILABLE, new PurchaseReference[0]);
}
static void returnClientAppError(ListPurchases_Response callback) {
callback.call(BillingResponseCode.CLIENT_APP_ERROR, new PurchaseReference[0]);
}
@VisibleForTesting
static Bundle createPurchaseReferenceBundle(String itemId, String purchaseToken) {
Bundle bundle = new Bundle();
bundle.putString(KEY_ITEM_ID, itemId);
bundle.putString(KEY_PURCHASE_TOKEN, purchaseToken);
return bundle;
}
@VisibleForTesting
static Bundle createResponseBundle(int responseCode, Bundle... purchaseDetails) {
Bundle bundle = new Bundle();
bundle.putInt(KEY_RESPONSE_CODE, responseCode);
bundle.putParcelableArray(KEY_PURCHASES_LIST, purchaseDetails);
return bundle;
}
}