Commit 1ba631a1 authored by Jeevan Shikaram's avatar Jeevan Shikaram Committed by Commit Bot

[Play Billing] Implement Digital Goods on Chrome OS.

This CL implements the browser side of the DigitalGoods and
DigitalGoodsFactory Mojom instances in Blink. The DigitalGoods requests
are forwarded on to ARC++ to be comepleted.

Note that this CL introduces a dependency on third_party/blink/public
/mojom for components/arc/mojom.

Bug: 1137688, 1110494
Change-Id: I7dc5bc22f3190021e12a4c8a53b430c7117c224e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2467302
Commit-Queue: Jeevan Shikaram <jshikaram@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarGlen Robertson <glenrob@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825163}
parent 87a96753
...@@ -2297,6 +2297,12 @@ static_library("browser") { ...@@ -2297,6 +2297,12 @@ static_library("browser") {
"//ui/webui/resources/cr_components/customize_themes:mojom", "//ui/webui/resources/cr_components/customize_themes:mojom",
] ]
if (is_chromeos) { if (is_chromeos) {
sources += [
"apps/digital_goods/digital_goods_factory_impl.cc",
"apps/digital_goods/digital_goods_factory_impl.h",
"apps/digital_goods/digital_goods_impl.cc",
"apps/digital_goods/digital_goods_impl.h",
]
deps += [ deps += [
"//chrome/app/theme:chrome_unscaled_resources_grit", "//chrome/app/theme:chrome_unscaled_resources_grit",
"//chrome/browser/nearby_sharing/common", "//chrome/browser/nearby_sharing/common",
...@@ -2335,6 +2341,7 @@ static_library("browser") { ...@@ -2335,6 +2341,7 @@ static_library("browser") {
"//chromeos/system", "//chromeos/system",
"//chromeos/timezone", "//chromeos/timezone",
"//chromeos/tpm", "//chromeos/tpm",
"//components/arc/mojom",
"//components/drive", "//components/drive",
"//components/quirks", "//components/quirks",
"//components/session_manager/core", "//components/session_manager/core",
......
dominickn@chromium.org
jshikaram@chromium.org
# COMPONENT: Platform>Apps>Foundation
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/apps/digital_goods/digital_goods_factory_impl.h"
#include <utility>
#include "base/feature_list.h"
#include "chrome/browser/apps/digital_goods/digital_goods_impl.h"
#include "components/payments/core/features.h"
#include "components/payments/core/payments_experimental_features.h"
namespace apps {
// Public methods:
DigitalGoodsFactoryImpl::~DigitalGoodsFactoryImpl() = default;
// static
void DigitalGoodsFactoryImpl::BindDigitalGoodsFactory(
content::RenderFrameHost* render_frame_host,
mojo::PendingReceiver<payments::mojom::DigitalGoodsFactory> receiver) {
DigitalGoodsFactoryImpl::GetOrCreateForCurrentDocument(render_frame_host)
->BindRequest(std::move(receiver));
}
// Creates a DigitalGoodsImpl instance.
void DigitalGoodsFactoryImpl::CreateDigitalGoods(
const std::string& payment_method,
CreateDigitalGoodsCallback callback) {
// Check feature flag.
if (!payments::PaymentsExperimentalFeatures::IsEnabled(
payments::features::kAppStoreBilling)) {
std::move(callback).Run(
payments::mojom::CreateDigitalGoodsResponseCode::kUnsupportedContext,
/* digital_goods = */ mojo::NullRemote());
return;
}
// TODO(jshikaram): Check that it's a valid TWA (check the host was installed
// via the play store using ApkWebApp Service)
// TODO(jshikaram): check with Android if there is a payment_method available.
std::move(callback).Run(payments::mojom::CreateDigitalGoodsResponseCode::kOk,
DigitalGoodsImpl::CreateAndBind(render_frame_host_));
}
// Private methods:
DigitalGoodsFactoryImpl::DigitalGoodsFactoryImpl(
content::RenderFrameHost* render_frame_host)
: render_frame_host_(render_frame_host), receiver_(this) {}
void DigitalGoodsFactoryImpl::BindRequest(
mojo::PendingReceiver<payments::mojom::DigitalGoodsFactory> receiver) {
receiver_.Bind(std::move(receiver));
}
RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(DigitalGoodsFactoryImpl)
} // namespace apps
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_APPS_DIGITAL_GOODS_DIGITAL_GOODS_FACTORY_IMPL_H_
#define CHROME_BROWSER_APPS_DIGITAL_GOODS_DIGITAL_GOODS_FACTORY_IMPL_H_
#include <string>
#include "content/public/browser/render_document_host_user_data.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom.h"
namespace apps {
class DigitalGoodsFactoryImpl
: public content::RenderDocumentHostUserData<DigitalGoodsFactoryImpl>,
public payments::mojom::DigitalGoodsFactory {
public:
~DigitalGoodsFactoryImpl() override;
static void BindDigitalGoodsFactory(
content::RenderFrameHost* render_frame_host,
mojo::PendingReceiver<payments::mojom::DigitalGoodsFactory> receiver);
// payments::mojom::DigitalGoodsFactory overrides.
void CreateDigitalGoods(const std::string& payment_method,
CreateDigitalGoodsCallback callback) override;
private:
explicit DigitalGoodsFactoryImpl(content::RenderFrameHost* render_frame_host);
friend class content::RenderDocumentHostUserData<DigitalGoodsFactoryImpl>;
RENDER_DOCUMENT_HOST_USER_DATA_KEY_DECL();
void BindRequest(
mojo::PendingReceiver<payments::mojom::DigitalGoodsFactory> receiver);
content::RenderFrameHost* render_frame_host_;
mojo::Receiver<payments::mojom::DigitalGoodsFactory> receiver_;
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_DIGITAL_GOODS_DIGITAL_GOODS_FACTORY_IMPL_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/apps/digital_goods/digital_goods_impl.h"
#include "base/optional.h"
#include "chrome/browser/chromeos/apps/apk_web_app_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/components/app_registrar.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
namespace {
void LogErrorState(const std::string& package_name, const std::string& scope) {
DVLOG(1) << "DGAPI call failed because package name or scope was empty.";
DVLOG(1) << "Package Name: " << package_name;
DVLOG(1) << "Scope: " << scope;
}
} // namespace
namespace apps {
// Public methods:
DigitalGoodsImpl::~DigitalGoodsImpl() = default;
// static
mojo::PendingRemote<payments::mojom::DigitalGoods>
DigitalGoodsImpl::CreateAndBind(content::RenderFrameHost* render_frame_host) {
return DigitalGoodsImpl::GetOrCreateForCurrentDocument(render_frame_host)
->BindRequest();
}
mojo::PendingRemote<payments::mojom::DigitalGoods>
DigitalGoodsImpl::BindRequest() {
return receiver_.BindNewPipeAndPassRemote();
}
void DigitalGoodsImpl::GetDetails(const std::vector<std::string>& item_ids,
GetDetailsCallback callback) {
auto* digital_goods_service = GetArcDigitalGoodsBridge();
if (!digital_goods_service) {
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable,
/*item_detail_list=*/{});
return;
}
const std::string package_name = GetTwaPackageName();
const std::string scope = GetScope();
if (package_name.empty() || scope.empty()) {
LogErrorState(package_name, scope);
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable,
/*item_detail_list=*/{});
return;
}
digital_goods_service->GetDetails(package_name, scope, item_ids,
std::move(callback));
}
void DigitalGoodsImpl::Acknowledge(const std::string& purchase_token,
bool make_available_again,
AcknowledgeCallback callback) {
auto* digital_goods_service = GetArcDigitalGoodsBridge();
if (!digital_goods_service) {
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable);
return;
}
const std::string package_name = GetTwaPackageName();
const std::string scope = GetScope();
if (package_name.empty() || scope.empty()) {
LogErrorState(package_name, scope);
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable);
return;
}
digital_goods_service->Acknowledge(package_name, scope, purchase_token,
make_available_again, std::move(callback));
}
void DigitalGoodsImpl::ListPurchases(ListPurchasesCallback callback) {
auto* digital_goods_service = GetArcDigitalGoodsBridge();
if (!digital_goods_service) {
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable,
/* purchase_details_list = */ {});
return;
}
const std::string package_name = GetTwaPackageName();
const std::string scope = GetScope();
if (package_name.empty() || scope.empty()) {
LogErrorState(package_name, scope);
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable,
/* purchase_details_list = */ {});
return;
}
digital_goods_service->ListPurchases(package_name, scope,
std::move(callback));
}
// Private methods:
DigitalGoodsImpl::DigitalGoodsImpl(content::RenderFrameHost* render_frame_host)
: render_frame_host_(render_frame_host), receiver_(this) {}
arc::ArcDigitalGoodsBridge* DigitalGoodsImpl::GetArcDigitalGoodsBridge() {
return arc::ArcDigitalGoodsBridge::GetForBrowserContext(
render_frame_host_->GetBrowserContext());
}
std::string DigitalGoodsImpl::GetTwaPackageName() {
auto* apk_web_app_service = chromeos::ApkWebAppService::Get(
Profile::FromBrowserContext(render_frame_host_->GetBrowserContext()));
if (!apk_web_app_service) {
return "";
}
base::Optional<std::string> twa_package_name =
apk_web_app_service->GetPackageNameForWebApp(
content::WebContents::FromRenderFrameHost(render_frame_host_)
->GetLastCommittedURL());
return twa_package_name.value_or("");
}
std::string DigitalGoodsImpl::GetScope() {
web_app::AppRegistrar& registrar =
web_app::WebAppProvider::Get(
Profile::FromBrowserContext(render_frame_host_->GetBrowserContext()))
->registrar();
base::Optional<web_app::AppId> app_id = registrar.FindAppWithUrlInScope(
content::WebContents::FromRenderFrameHost(render_frame_host_)
->GetLastCommittedURL());
if (!app_id) {
return "";
}
GURL scope = registrar.GetAppScope(app_id.value());
if (!scope.is_valid()) {
return "";
}
return scope.spec();
}
RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(DigitalGoodsImpl)
} // namespace apps
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_APPS_DIGITAL_GOODS_DIGITAL_GOODS_IMPL_H_
#define CHROME_BROWSER_APPS_DIGITAL_GOODS_DIGITAL_GOODS_IMPL_H_
#include <string>
#include <vector>
#include "components/arc/pay/arc_digital_goods_bridge.h"
#include "content/public/browser/render_document_host_user_data.h"
#include "content/public/browser/render_widget_host.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom.h"
namespace apps {
class DigitalGoodsImpl
: public content::RenderDocumentHostUserData<DigitalGoodsImpl>,
public payments::mojom::DigitalGoods {
public:
~DigitalGoodsImpl() override;
static mojo::PendingRemote<payments::mojom::DigitalGoods> CreateAndBind(
content::RenderFrameHost* render_frame_host);
mojo::PendingRemote<payments::mojom::DigitalGoods> BindRequest();
// payments::mojom::DigitalGoods overrides.
void GetDetails(const std::vector<std::string>& item_ids,
GetDetailsCallback callback) override;
void Acknowledge(const std::string& purchase_token,
bool make_available_again,
AcknowledgeCallback callback) override;
void ListPurchases(ListPurchasesCallback callback) override;
private:
explicit DigitalGoodsImpl(content::RenderFrameHost* render_frame_host);
friend class content::RenderDocumentHostUserData<DigitalGoodsImpl>;
RENDER_DOCUMENT_HOST_USER_DATA_KEY_DECL();
arc::ArcDigitalGoodsBridge* GetArcDigitalGoodsBridge();
std::string GetTwaPackageName();
std::string GetScope();
content::RenderFrameHost* render_frame_host_;
mojo::Receiver<payments::mojom::DigitalGoods> receiver_;
};
} // namespace apps
#endif // CHROME_BROWSER_APPS_DIGITAL_GOODS_DIGITAL_GOODS_IMPL_H_
...@@ -149,6 +149,7 @@ ...@@ -149,6 +149,7 @@
#endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/apps/digital_goods/digital_goods_factory_impl.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_features.h" #include "chrome/browser/nearby_sharing/common/nearby_share_features.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h" #include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
#include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom.h" #include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom.h"
...@@ -194,6 +195,7 @@ ...@@ -194,6 +195,7 @@
#include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h" #include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h"
#include "chromeos/services/network_health/public/mojom/network_health.mojom.h" #include "chromeos/services/network_health/public/mojom/network_health.mojom.h"
#include "media/capture/video/chromeos/mojom/camera_app.mojom.h" #include "media/capture/video/chromeos/mojom/camera_app.mojom.h"
#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom.h"
#endif #endif
#if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #if defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
...@@ -561,6 +563,11 @@ void PopulateChromeFrameBinders( ...@@ -561,6 +563,11 @@ void PopulateChromeFrameBinders(
base::BindRepeating(&payments::CreatePaymentCredential)); base::BindRepeating(&payments::CreatePaymentCredential));
#endif #endif
#if defined(OS_CHROMEOS)
map->Add<payments::mojom::DigitalGoodsFactory>(base::BindRepeating(
&apps::DigitalGoodsFactoryImpl::BindDigitalGoodsFactory));
#endif
#if defined(OS_WIN) || defined(OS_CHROMEOS) #if defined(OS_WIN) || defined(OS_CHROMEOS)
if (base::FeatureList::IsEnabled(features::kWebShare)) { if (base::FeatureList::IsEnabled(features::kWebShare)) {
map->Add<blink::mojom::ShareService>( map->Add<blink::mojom::ShareService>(
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
#include "components/arc/midis/arc_midis_bridge.h" #include "components/arc/midis/arc_midis_bridge.h"
#include "components/arc/net/arc_net_host_impl.h" #include "components/arc/net/arc_net_host_impl.h"
#include "components/arc/obb_mounter/arc_obb_mounter_bridge.h" #include "components/arc/obb_mounter/arc_obb_mounter_bridge.h"
#include "components/arc/pay/arc_digital_goods_bridge.h"
#include "components/arc/pay/arc_payment_app_bridge.h" #include "components/arc/pay/arc_payment_app_bridge.h"
#include "components/arc/power/arc_power_bridge.h" #include "components/arc/power/arc_power_bridge.h"
#include "components/arc/property/arc_property_bridge.h" #include "components/arc/property/arc_property_bridge.h"
...@@ -186,6 +187,7 @@ void ArcServiceLauncher::OnPrimaryUserProfilePrepared(Profile* profile) { ...@@ -186,6 +187,7 @@ void ArcServiceLauncher::OnPrimaryUserProfilePrepared(Profile* profile) {
ArcCertStoreBridge::GetForBrowserContext(profile); ArcCertStoreBridge::GetForBrowserContext(profile);
ArcClipboardBridge::GetForBrowserContext(profile); ArcClipboardBridge::GetForBrowserContext(profile);
ArcCrashCollectorBridge::GetForBrowserContext(profile); ArcCrashCollectorBridge::GetForBrowserContext(profile);
ArcDigitalGoodsBridge::GetForBrowserContext(profile);
ArcDiskQuotaBridge::GetForBrowserContext(profile); ArcDiskQuotaBridge::GetForBrowserContext(profile);
ArcEnterpriseReportingService::GetForBrowserContext(profile); ArcEnterpriseReportingService::GetForBrowserContext(profile);
ArcFileSystemBridge::GetForBrowserContext(profile); ArcFileSystemBridge::GetForBrowserContext(profile);
......
...@@ -67,6 +67,8 @@ static_library("arc") { ...@@ -67,6 +67,8 @@ static_library("arc") {
"net/arc_net_host_impl.h", "net/arc_net_host_impl.h",
"obb_mounter/arc_obb_mounter_bridge.cc", "obb_mounter/arc_obb_mounter_bridge.cc",
"obb_mounter/arc_obb_mounter_bridge.h", "obb_mounter/arc_obb_mounter_bridge.h",
"pay/arc_digital_goods_bridge.cc",
"pay/arc_digital_goods_bridge.h",
"pay/arc_payment_app_bridge.cc", "pay/arc_payment_app_bridge.cc",
"pay/arc_payment_app_bridge.h", "pay/arc_payment_app_bridge.h",
"power/arc_power_bridge.cc", "power/arc_power_bridge.cc",
......
...@@ -24,6 +24,7 @@ include_rules = [ ...@@ -24,6 +24,7 @@ include_rules = [
"+storage/browser/file_system", "+storage/browser/file_system",
"+third_party/re2", "+third_party/re2",
"+third_party/skia", "+third_party/skia",
"+third_party/blink/public/mojom",
"+ui/base", "+ui/base",
"+ui/display", "+ui/display",
"+ui/events", "+ui/events",
......
...@@ -26,6 +26,7 @@ if (is_chromeos) { ...@@ -26,6 +26,7 @@ if (is_chromeos) {
"cert_store.mojom", "cert_store.mojom",
"clipboard.mojom", "clipboard.mojom",
"crash_collector.mojom", "crash_collector.mojom",
"digital_goods.mojom",
"disk_quota.mojom", "disk_quota.mojom",
"enterprise_reporting.mojom", "enterprise_reporting.mojom",
"file_system.mojom", "file_system.mojom",
...@@ -71,12 +72,14 @@ if (is_chromeos) { ...@@ -71,12 +72,14 @@ if (is_chromeos) {
":media", ":media",
":notifications", ":notifications",
":oemcrypto", ":oemcrypto",
"//components/payments/mojom:mojom",
"//media/capture/video/chromeos/mojom:cros_camera", "//media/capture/video/chromeos/mojom:cros_camera",
"//mojo/public/mojom/base", "//mojo/public/mojom/base",
"//printing/mojom", "//printing/mojom",
"//services/device/public/mojom:usb", "//services/device/public/mojom:usb",
"//services/media_session/public/mojom", "//services/media_session/public/mojom",
"//services/resource_coordinator/public/mojom", "//services/resource_coordinator/public/mojom",
"//third_party/blink/public/mojom:android_mojo_bindings",
"//ui/accessibility/mojom", "//ui/accessibility/mojom",
"//ui/gfx/geometry/mojom", "//ui/gfx/geometry/mojom",
"//url/mojom:url_mojom_gurl", "//url/mojom:url_mojom_gurl",
......
...@@ -18,6 +18,7 @@ import "components/arc/mojom/cast_receiver.mojom"; ...@@ -18,6 +18,7 @@ import "components/arc/mojom/cast_receiver.mojom";
import "components/arc/mojom/cert_store.mojom"; import "components/arc/mojom/cert_store.mojom";
import "components/arc/mojom/clipboard.mojom"; import "components/arc/mojom/clipboard.mojom";
import "components/arc/mojom/crash_collector.mojom"; import "components/arc/mojom/crash_collector.mojom";
import "components/arc/mojom/digital_goods.mojom";
import "components/arc/mojom/disk_quota.mojom"; import "components/arc/mojom/disk_quota.mojom";
import "components/arc/mojom/enterprise_reporting.mojom"; import "components/arc/mojom/enterprise_reporting.mojom";
import "components/arc/mojom/file_system.mojom"; import "components/arc/mojom/file_system.mojom";
...@@ -56,9 +57,9 @@ import "components/arc/mojom/volume_mounter.mojom"; ...@@ -56,9 +57,9 @@ import "components/arc/mojom/volume_mounter.mojom";
import "components/arc/mojom/wake_lock.mojom"; import "components/arc/mojom/wake_lock.mojom";
import "components/arc/mojom/wallpaper.mojom"; import "components/arc/mojom/wallpaper.mojom";
// Next MinVersion: 51 // Next MinVersion: 52
// Deprecated method IDs: 101, 105, 121 // Deprecated method IDs: 101, 105, 121
// Next method ID: 156 // Next method ID: 157
interface ArcBridgeHost { interface ArcBridgeHost {
// Keep the entries alphabetical. In order to do so without breaking // Keep the entries alphabetical. In order to do so without breaking
// compatibility with the ARC instance, explicitly assign each interface a // compatibility with the ARC instance, explicitly assign each interface a
...@@ -119,6 +120,10 @@ interface ArcBridgeHost { ...@@ -119,6 +120,10 @@ interface ArcBridgeHost {
[MinVersion=7] OnCrashCollectorInstanceReady@112( [MinVersion=7] OnCrashCollectorInstanceReady@112(
pending_remote<CrashCollectorInstance> instance_remote); pending_remote<CrashCollectorInstance> instance_remote);
// Notifies Chrome that the DigitalGoodsInstance interface is ready.
[MinVersion=51] OnDigitalGoodsInstanceReady@156(
pending_remote<DigitalGoodsInstance> instance_remote);
// Notifies Chrome that the DiskQuotaInstance interface is ready. // Notifies Chrome that the DiskQuotaInstance interface is ready.
[MinVersion=39] OnDiskQuotaInstanceReady@144( [MinVersion=39] OnDiskQuotaInstanceReady@144(
pending_remote<DiskQuotaInstance> instance_remote); pending_remote<DiskQuotaInstance> instance_remote);
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Next MinVersion: 1
module arc.mojom;
import "third_party/blink/public/mojom/digital_goods/digital_goods.mojom";
// Allows the browser process to forward calls for the Digital Goods API to
// ARC++
// Next method ID: 3
interface DigitalGoodsInstance {
// Queries a specific package for SKU details by item IDs.
[MinVersion=0] GetDetails@0(string package_name,
string scope,
array<string> item_ids)
=> (payments.mojom.BillingResponseCode code,
array<payments.mojom.ItemDetails> item_details_list);
// Informs a package that the purchase identified by |purchase_token| was
// successfully acknowledged. If |make_available_again| is true, indicates
// that the purchase is repeatable (e.g. a consumable item). If it is false,
// indicates that the purchase is one-off (e.g. a permanent upgrade).
[MinVersion=0] Acknowledge@1(string package_name,
string scope,
string purchase_token,
bool make_available_again)
=> (payments.mojom.BillingResponseCode code);
// Queries a package for information on all items that are currently owned by
// the user.
[MinVersion=0] ListPurchases@2(string package_name,
string scope)
=> (payments.mojom.BillingResponseCode code,
array<payments.mojom.PurchaseDetails> purchase_details_list);
};
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/pay/arc_digital_goods_bridge.h"
#include <utility>
#include "base/no_destructor.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "components/arc/session/arc_bridge_service.h"
namespace arc {
namespace {
class ArcDigitalGoodsBridgeFactory
: public internal::ArcBrowserContextKeyedServiceFactoryBase<
ArcDigitalGoodsBridge,
ArcDigitalGoodsBridgeFactory> {
public:
// Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
static constexpr const char* kName = "ArcDigitalGoodsBridgeFactory";
static ArcDigitalGoodsBridgeFactory* GetInstance() {
static base::NoDestructor<ArcDigitalGoodsBridgeFactory> factory;
return factory.get();
}
ArcDigitalGoodsBridgeFactory() = default;
~ArcDigitalGoodsBridgeFactory() override = default;
};
} // namespace
// static
ArcDigitalGoodsBridge* ArcDigitalGoodsBridge::GetForBrowserContext(
content::BrowserContext* context) {
return ArcDigitalGoodsBridgeFactory::GetForBrowserContext(context);
}
// static
ArcDigitalGoodsBridge* ArcDigitalGoodsBridge::GetForBrowserContextForTesting(
content::BrowserContext* context) {
return ArcDigitalGoodsBridgeFactory::GetForBrowserContextForTesting(context);
}
ArcDigitalGoodsBridge::ArcDigitalGoodsBridge(
content::BrowserContext* browser_context,
ArcBridgeService* bridge_service)
: arc_bridge_service_(bridge_service) {}
ArcDigitalGoodsBridge::~ArcDigitalGoodsBridge() = default;
void ArcDigitalGoodsBridge::GetDetails(const std::string& package_name,
const std::string& scope,
const std::vector<std::string>& item_ids,
GetDetailsCallback callback) {
mojom::DigitalGoodsInstance* digital_goods = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->digital_goods(), GetDetails);
if (!digital_goods) {
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable,
/* item_detail_list = */ {});
return;
}
digital_goods->GetDetails(package_name, scope, item_ids, std::move(callback));
}
void ArcDigitalGoodsBridge::Acknowledge(const std::string& package_name,
const std::string& scope,
const std::string& purchase_token,
bool make_available_again,
AcknowledgeCallback callback) {
mojom::DigitalGoodsInstance* digital_goods = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->digital_goods(), Acknowledge);
if (!digital_goods) {
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable);
return;
}
digital_goods->Acknowledge(package_name, scope, purchase_token,
make_available_again, std::move(callback));
}
void ArcDigitalGoodsBridge::ListPurchases(const std::string& package_name,
const std::string& scope,
ListPurchasesCallback callback) {
mojom::DigitalGoodsInstance* digital_goods = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->digital_goods(), ListPurchases);
if (!digital_goods) {
std::move(callback).Run(
payments::mojom::BillingResponseCode::kClientAppUnavailable,
/* purchase_details_list = */ {});
return;
}
digital_goods->ListPurchases(package_name, scope, std::move(callback));
}
} // namespace arc
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_ARC_PAY_ARC_DIGITAL_GOODS_BRIDGE_H_
#define COMPONENTS_ARC_PAY_ARC_DIGITAL_GOODS_BRIDGE_H_
#include <string>
#include <vector>
#include "components/arc/mojom/digital_goods.mojom.h"
#include "components/keyed_service/core/keyed_service.h"
namespace content {
class BrowserContext;
} // namespace content
namespace arc {
class ArcBridgeService;
// Queries a TWA's digital goods service.
class ArcDigitalGoodsBridge : public KeyedService {
public:
using GetDetailsCallback =
base::OnceCallback<void(payments::mojom::BillingResponseCode,
std::vector<payments::mojom::ItemDetailsPtr>)>;
using AcknowledgeCallback =
base::OnceCallback<void(payments::mojom::BillingResponseCode)>;
using ListPurchasesCallback = base::OnceCallback<void(
payments::mojom::BillingResponseCode,
std::vector<payments::mojom::PurchaseDetailsPtr>)>;
// Returns the instance owned by the given BrowserContext, or nullptr if the
// browser |context| is not allowed to use ARC.
static ArcDigitalGoodsBridge* GetForBrowserContext(
content::BrowserContext* context);
// Used only in testing with a TestBrowserContext.
static ArcDigitalGoodsBridge* GetForBrowserContextForTesting(
content::BrowserContext* context);
ArcDigitalGoodsBridge(content::BrowserContext* browser_context,
ArcBridgeService* bridge_service);
~ArcDigitalGoodsBridge() override;
// Disallow copy and assign.
ArcDigitalGoodsBridge(const ArcDigitalGoodsBridge& other) = delete;
ArcDigitalGoodsBridge& operator=(const ArcDigitalGoodsBridge& other) = delete;
// Queries a specific package for SKU details by item IDs.
void GetDetails(const std::string& package_name,
const std::string& scope,
const std::vector<std::string>& item_ids,
GetDetailsCallback callback);
// Informs a package that the purchase identified by |purchase_token| was
// successfully acknowledged.
void Acknowledge(const std::string& package_name,
const std::string& scope,
const std::string& purchase_token,
bool make_available_again,
AcknowledgeCallback callback);
// Queries a package for information on all items that are currently owned by
// the user.
void ListPurchases(const std::string& package_name,
const std::string& scope,
ListPurchasesCallback callback);
private:
ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
};
} // namespace arc
#endif // COMPONENTS_ARC_PAY_ARC_DIGITAL_GOODS_BRIDGE_H_
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "components/arc/mojom/cert_store.mojom.h" #include "components/arc/mojom/cert_store.mojom.h"
#include "components/arc/mojom/clipboard.mojom.h" #include "components/arc/mojom/clipboard.mojom.h"
#include "components/arc/mojom/crash_collector.mojom.h" #include "components/arc/mojom/crash_collector.mojom.h"
#include "components/arc/mojom/digital_goods.mojom.h"
#include "components/arc/mojom/disk_quota.mojom.h" #include "components/arc/mojom/disk_quota.mojom.h"
#include "components/arc/mojom/enterprise_reporting.mojom.h" #include "components/arc/mojom/enterprise_reporting.mojom.h"
#include "components/arc/mojom/file_system.mojom.h" #include "components/arc/mojom/file_system.mojom.h"
...@@ -163,6 +164,12 @@ void ArcBridgeHostImpl::OnCrashCollectorInstanceReady( ...@@ -163,6 +164,12 @@ void ArcBridgeHostImpl::OnCrashCollectorInstanceReady(
std::move(crash_collector_remote)); std::move(crash_collector_remote));
} }
void ArcBridgeHostImpl::OnDigitalGoodsInstanceReady(
mojo::PendingRemote<mojom::DigitalGoodsInstance> digital_goods_remote) {
OnInstanceReady(arc_bridge_service_->digital_goods(),
std::move(digital_goods_remote));
}
void ArcBridgeHostImpl::OnDiskQuotaInstanceReady( void ArcBridgeHostImpl::OnDiskQuotaInstanceReady(
mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) { mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) {
OnInstanceReady(arc_bridge_service_->disk_quota(), OnInstanceReady(arc_bridge_service_->disk_quota(),
......
...@@ -72,6 +72,9 @@ class ArcBridgeHostImpl : public mojom::ArcBridgeHost { ...@@ -72,6 +72,9 @@ class ArcBridgeHostImpl : public mojom::ArcBridgeHost {
void OnCrashCollectorInstanceReady( void OnCrashCollectorInstanceReady(
mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote) mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote)
override; override;
void OnDigitalGoodsInstanceReady(
mojo::PendingRemote<mojom::DigitalGoodsInstance> digital_goods_remote)
override;
void OnDiskQuotaInstanceReady( void OnDiskQuotaInstanceReady(
mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) override; mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) override;
void OnEnterpriseReportingInstanceReady( void OnEnterpriseReportingInstanceReady(
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "components/arc/mojom/cert_store.mojom.h" #include "components/arc/mojom/cert_store.mojom.h"
#include "components/arc/mojom/clipboard.mojom.h" #include "components/arc/mojom/clipboard.mojom.h"
#include "components/arc/mojom/crash_collector.mojom.h" #include "components/arc/mojom/crash_collector.mojom.h"
#include "components/arc/mojom/digital_goods.mojom.h"
#include "components/arc/mojom/disk_quota.mojom.h" #include "components/arc/mojom/disk_quota.mojom.h"
#include "components/arc/mojom/enterprise_reporting.mojom.h" #include "components/arc/mojom/enterprise_reporting.mojom.h"
#include "components/arc/mojom/file_system.mojom.h" #include "components/arc/mojom/file_system.mojom.h"
......
...@@ -40,6 +40,7 @@ class ClipboardHost; ...@@ -40,6 +40,7 @@ class ClipboardHost;
class ClipboardInstance; class ClipboardInstance;
class CrashCollectorHost; class CrashCollectorHost;
class CrashCollectorInstance; class CrashCollectorInstance;
class DigitalGoodsInstance;
class DiskQuotaHost; class DiskQuotaHost;
class DiskQuotaInstance; class DiskQuotaInstance;
class EnterpriseReportingHost; class EnterpriseReportingHost;
...@@ -181,6 +182,9 @@ class ArcBridgeService { ...@@ -181,6 +182,9 @@ class ArcBridgeService {
crash_collector() { crash_collector() {
return &crash_collector_; return &crash_collector_;
} }
ConnectionHolder<mojom::DigitalGoodsInstance>* digital_goods() {
return &digital_goods_;
}
ConnectionHolder<mojom::DiskQuotaInstance, mojom::DiskQuotaHost>* ConnectionHolder<mojom::DiskQuotaInstance, mojom::DiskQuotaHost>*
disk_quota() { disk_quota() {
return &disk_quota_; return &disk_quota_;
...@@ -311,6 +315,7 @@ class ArcBridgeService { ...@@ -311,6 +315,7 @@ class ArcBridgeService {
ConnectionHolder<mojom::ClipboardInstance, mojom::ClipboardHost> clipboard_; ConnectionHolder<mojom::ClipboardInstance, mojom::ClipboardHost> clipboard_;
ConnectionHolder<mojom::CrashCollectorInstance, mojom::CrashCollectorHost> ConnectionHolder<mojom::CrashCollectorInstance, mojom::CrashCollectorHost>
crash_collector_; crash_collector_;
ConnectionHolder<mojom::DigitalGoodsInstance> digital_goods_;
ConnectionHolder<mojom::DiskQuotaInstance, mojom::DiskQuotaHost> disk_quota_; ConnectionHolder<mojom::DiskQuotaInstance, mojom::DiskQuotaHost> disk_quota_;
ConnectionHolder<mojom::EnterpriseReportingInstance, ConnectionHolder<mojom::EnterpriseReportingInstance,
mojom::EnterpriseReportingHost> mojom::EnterpriseReportingHost>
......
...@@ -109,6 +109,9 @@ void FakeArcBridgeHost::OnCrashCollectorInstanceReady( ...@@ -109,6 +109,9 @@ void FakeArcBridgeHost::OnCrashCollectorInstanceReady(
mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote) { mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote) {
} }
void FakeArcBridgeHost::OnDigitalGoodsInstanceReady(
mojo::PendingRemote<mojom::DigitalGoodsInstance> digital_goods_remote) {}
void FakeArcBridgeHost::OnDiskQuotaInstanceReady( void FakeArcBridgeHost::OnDiskQuotaInstanceReady(
mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) {} mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) {}
......
...@@ -51,6 +51,9 @@ class FakeArcBridgeHost : public mojom::ArcBridgeHost { ...@@ -51,6 +51,9 @@ class FakeArcBridgeHost : public mojom::ArcBridgeHost {
void OnCrashCollectorInstanceReady( void OnCrashCollectorInstanceReady(
mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote) mojo::PendingRemote<mojom::CrashCollectorInstance> crash_collector_remote)
override; override;
void OnDigitalGoodsInstanceReady(
mojo::PendingRemote<mojom::DigitalGoodsInstance> digital_goods_remote)
override;
void OnDiskQuotaInstanceReady( void OnDiskQuotaInstanceReady(
mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) override; mojo::PendingRemote<mojom::DiskQuotaInstance> disk_quota_remote) override;
void OnEnterpriseReportingInstanceReady( void OnEnterpriseReportingInstanceReady(
......
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