Commit cdd6f59c authored by DongJun Kim's avatar DongJun Kim Committed by Commit Bot

Refactoring RespondWithCallback class

This patch is for refactoring RespondWithCallback class
and include below changes.

- Expose RespondWithCallback from PaymentAppProviderImpl.

- Adds helper class like as "ServiceWorkerCoreThreadEventDispatcher"
it appears that all of the functions that access WebContents on the
service worker core thread are for dispatching some type of event.

- Remove InvokeRespondWithcallbacksRepository then
ServiceWorkerCoreThreadEventDispatcher owns an instance of
InvokeRespondWithCallback instead and manage its lifetime.

Bug: 1075687
Change-Id: I34ee154600a137ef47a03f797f15da689d205a79
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368660
Commit-Queue: DongJun Kim <djmix.kim@samsung.com>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809926}
parent 5ca77216
...@@ -1286,6 +1286,10 @@ source_set("browser") { ...@@ -1286,6 +1286,10 @@ source_set("browser") {
"payments/payment_instrument_icon_fetcher.h", "payments/payment_instrument_icon_fetcher.h",
"payments/payment_manager.cc", "payments/payment_manager.cc",
"payments/payment_manager.h", "payments/payment_manager.h",
"payments/respond_with_callback.cc",
"payments/respond_with_callback.h",
"payments/service_worker_core_thread_event_dispatcher.cc",
"payments/service_worker_core_thread_event_dispatcher.h",
"permissions/permission_controller_impl.cc", "permissions/permission_controller_impl.cc",
"permissions/permission_controller_impl.h", "permissions/permission_controller_impl.h",
"permissions/permission_service_context.cc", "permissions/permission_service_context.cc",
......
...@@ -13,12 +13,9 @@ ...@@ -13,12 +13,9 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/token.h" #include "base/token.h"
#include "components/payments/core/native_error_strings.h"
#include "components/payments/core/payments_validators.h"
#include "content/browser/devtools/devtools_background_services_context_impl.h" #include "content/browser/devtools/devtools_background_services_context_impl.h"
#include "content/browser/payments/payment_app_context_impl.h" #include "content/browser/payments/payment_app_context_impl.h"
#include "content/browser/payments/payment_app_installer.h" #include "content/browser/payments/payment_app_installer.h"
...@@ -44,349 +41,15 @@ namespace content { ...@@ -44,349 +41,15 @@ namespace content {
namespace { namespace {
using payments::mojom::CanMakePaymentEventDataPtr; using payments::mojom::CanMakePaymentEventDataPtr;
using payments::mojom::CanMakePaymentEventResponseType;
using payments::mojom::CanMakePaymentResponse;
using payments::mojom::CanMakePaymentResponsePtr;
using payments::mojom::PaymentDetailsModifierPtr; using payments::mojom::PaymentDetailsModifierPtr;
using payments::mojom::PaymentEventResponseType; using payments::mojom::PaymentEventResponseType;
using payments::mojom::PaymentHandlerResponse; using payments::mojom::PaymentHandlerStatus;
using payments::mojom::PaymentHandlerResponseCallback;
using payments::mojom::PaymentHandlerResponsePtr;
using payments::mojom::PaymentMethodDataPtr; using payments::mojom::PaymentMethodDataPtr;
using payments::mojom::PaymentRequestEventDataPtr;
CanMakePaymentResponsePtr CreateBlankCanMakePaymentResponse(
CanMakePaymentEventResponseType response_type) {
return CanMakePaymentResponse::New(response_type, /*can_make_payment=*/false,
/*ready_for_minimal_ui=*/false,
/*account_balance=*/base::nullopt);
}
PaymentHandlerResponsePtr CreateBlankPaymentHandlerResponse(
PaymentEventResponseType response_type) {
return PaymentHandlerResponse::New(
"" /*=method_name*/, "" /*=stringified_details*/, response_type,
base::nullopt /*=payer_name*/, base::nullopt /*=payer_email*/,
base::nullopt /*=payer_phone*/, nullptr /*=shipping_address*/,
base::nullopt /*=shipping_option*/);
}
class InvokeRespondWithCallback;
// A repository to store invoking payment app callback. It is used to abort
// payment when the opened payment handler window is closed before payment
// response is received or timeout.
// Note that there is only one opened payment handler window per browser
// context.
class InvokePaymentAppCallbackRepository {
public:
static InvokePaymentAppCallbackRepository* GetInstance() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
return base::Singleton<InvokePaymentAppCallbackRepository>::get();
}
// Disallow copy and assign.
InvokePaymentAppCallbackRepository(
const InvokePaymentAppCallbackRepository& other) = delete;
InvokePaymentAppCallbackRepository& operator=(
const InvokePaymentAppCallbackRepository& other) = delete;
InvokeRespondWithCallback* GetCallback(BrowserContext* browser_context) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
auto it = invoke_callbacks_.find(browser_context);
if (it != invoke_callbacks_.end()) {
return it->second;
}
return nullptr;
}
void SetCallback(BrowserContext* browser_context,
InvokeRespondWithCallback* callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
invoke_callbacks_[browser_context] = callback;
}
void RemoveCallback(BrowserContext* browser_context) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
invoke_callbacks_.erase(browser_context);
}
private:
InvokePaymentAppCallbackRepository() = default;
~InvokePaymentAppCallbackRepository() = default;
friend struct base::DefaultSingletonTraits<
InvokePaymentAppCallbackRepository>;
std::map<BrowserContext*, InvokeRespondWithCallback*> invoke_callbacks_;
};
// Abstract base class for event callbacks that are invoked when the payment
// handler resolves the promise passed in to TheEvent.respondWith() method.
class RespondWithCallback : public PaymentHandlerResponseCallback,
public WebContentsObserver {
public:
// Disallow copy and assign.
RespondWithCallback(const RespondWithCallback& other) = delete;
RespondWithCallback& operator=(const RespondWithCallback& other) = delete;
mojo::PendingRemote<PaymentHandlerResponseCallback>
BindNewPipeAndPassRemote() {
return receiver_.BindNewPipeAndPassRemote();
}
protected:
RespondWithCallback(
WebContents* web_contents,
ServiceWorkerMetrics::EventType event_type,
scoped_refptr<ServiceWorkerVersion> service_worker_version)
: WebContentsObserver(web_contents),
service_worker_version_(service_worker_version) {
request_id_ = service_worker_version->StartRequest(
event_type, base::BindOnce(&RespondWithCallback::OnServiceWorkerError,
weak_ptr_factory_.GetWeakPtr()));
}
~RespondWithCallback() override = default;
// PaymentHandlerResponseCallback implementation.
void OnResponseForCanMakePayment(
CanMakePaymentResponsePtr response) override {}
// PaymentHandlerResponseCallback implementation.
void OnResponseForPaymentRequest(
PaymentHandlerResponsePtr response) override {}
// PaymentHandlerResponseCallback implementation.
void OnResponseForAbortPayment(bool payment_aborted) override {}
virtual void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) = 0;
void FinishServiceWorkerRequest() {
service_worker_version_->FinishRequest(request_id_, false);
}
void MaybeRecordTimeoutMetric(blink::ServiceWorkerStatusCode status) {
if (status == blink::ServiceWorkerStatusCode::kErrorTimeout) {
UMA_HISTOGRAM_BOOLEAN("PaymentRequest.ServiceWorkerStatusCodeTimeout",
true);
}
}
void ClearCallbackRepositoryAndCloseWindow() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (!web_contents())
return;
InvokePaymentAppCallbackRepository::GetInstance()->RemoveCallback(
web_contents()->GetBrowserContext());
}
private:
int request_id_;
scoped_refptr<ServiceWorkerVersion> service_worker_version_;
mojo::Receiver<PaymentHandlerResponseCallback> receiver_{this};
base::WeakPtrFactory<RespondWithCallback> weak_ptr_factory_{this};
};
// Self-deleting callback for "canmakepayment" event. Invoked when the payment
// handler resolves the promise passed into CanMakePaymentEvent.respondWith()
// method.
class CanMakePaymentRespondWithCallback : public RespondWithCallback {
public:
CanMakePaymentRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
PaymentAppProvider::CanMakePaymentCallback callback)
: RespondWithCallback(web_contents,
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
service_worker_version),
callback_(std::move(callback)) {}
// Disallow copy and assign.
CanMakePaymentRespondWithCallback(
const CanMakePaymentRespondWithCallback& other) = delete;
CanMakePaymentRespondWithCallback& operator=(
const CanMakePaymentRespondWithCallback& other) = delete;
private:
~CanMakePaymentRespondWithCallback() override = default;
// PaymentHandlerResponseCallback implementation.
void OnResponseForCanMakePayment(
CanMakePaymentResponsePtr response) override {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), std::move(response)));
delete this;
}
// RespondWithCallback implementation.
void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) override {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
MaybeRecordTimeoutMetric(service_worker_status);
CanMakePaymentEventResponseType response_type =
CanMakePaymentEventResponseType::BROWSER_ERROR;
if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected) {
response_type = CanMakePaymentEventResponseType::REJECT;
} else if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorTimeout) {
response_type = CanMakePaymentEventResponseType::TIMEOUT;
}
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_),
CreateBlankCanMakePaymentResponse(response_type)));
delete this;
}
PaymentAppProvider::CanMakePaymentCallback callback_;
};
// Self-deleting callback for "paymentrequest" event. Invoked when the payment
// handler resolves the promise passed into PaymentRequestEvent.respondWith()
// method.
class InvokeRespondWithCallback : public RespondWithCallback {
public:
InvokeRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
PaymentAppProvider::InvokePaymentAppCallback callback)
: RespondWithCallback(web_contents,
ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
service_worker_version),
callback_(std::move(callback)) {
InvokePaymentAppCallbackRepository::GetInstance()->SetCallback(
web_contents->GetBrowserContext(), this);
}
// Disallow copy and assign.
InvokeRespondWithCallback(const InvokeRespondWithCallback& other) = delete;
InvokeRespondWithCallback& operator=(const InvokeRespondWithCallback& other) =
delete;
// Called only for "paymentrequest" event.
void AbortPaymentSinceOpennedWindowClosing(PaymentEventResponseType reason) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RespondToPaymentRequestWithErrorAndDeleteSelf(reason);
}
private:
~InvokeRespondWithCallback() override = default;
// PaymentHandlerResponseCallback implementation.
void OnResponseForPaymentRequest(
PaymentHandlerResponsePtr response) override {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), std::move(response)));
ClearCallbackRepositoryAndCloseWindow();
delete this;
}
// RespondWithCallback implementation.
void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) override {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
MaybeRecordTimeoutMetric(service_worker_status);
PaymentEventResponseType response_type =
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR;
if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected) {
response_type = PaymentEventResponseType::PAYMENT_EVENT_REJECT;
} else if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorTimeout) {
response_type = PaymentEventResponseType::PAYMENT_EVENT_TIMEOUT;
}
RespondToPaymentRequestWithErrorAndDeleteSelf(response_type);
}
void RespondToPaymentRequestWithErrorAndDeleteSelf(
PaymentEventResponseType response_type) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_),
CreateBlankPaymentHandlerResponse(response_type)));
ClearCallbackRepositoryAndCloseWindow();
delete this;
}
PaymentAppProvider::InvokePaymentAppCallback callback_;
};
// Self-deleting callback for "abortpayment" event. Invoked when the payment
// handler resolves the promise passed into AbortPayment.respondWith() method.
class AbortRespondWithCallback : public RespondWithCallback {
public:
AbortRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
PaymentAppProvider::AbortCallback callback)
: RespondWithCallback(web_contents,
ServiceWorkerMetrics::EventType::ABORT_PAYMENT,
service_worker_version),
callback_(std::move(callback)) {}
// Disallow copy and assign.
AbortRespondWithCallback(const AbortRespondWithCallback& other) = delete;
AbortRespondWithCallback& operator=(const AbortRespondWithCallback& other) =
delete;
private:
~AbortRespondWithCallback() override = default;
// PaymentHandlerResponseCallback implementation.
void OnResponseForAbortPayment(bool payment_aborted) override {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), payment_aborted));
if (payment_aborted)
ClearCallbackRepositoryAndCloseWindow();
delete this;
}
// RespondWithCallback implementation.
void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) override {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
MaybeRecordTimeoutMetric(service_worker_status);
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), /*payment_aborted=*/false));
// Do not call ClearCallbackRepositoryAndCloseWindow() here, because payment
// has not been aborted. The service worker either rejected, timed out, or
// threw a JavaScript exception in the "abortpayment" event, but that does
// not affect the ongoing "paymentrequest" event.
delete this;
}
PaymentAppProvider::AbortCallback callback_;
};
void DidUpdatePaymentAppIconOnCoreThread( void DidUpdatePaymentAppIconOnCoreThread(
PaymentAppProvider::UpdatePaymentAppIconCallback callback, PaymentAppProvider::UpdatePaymentAppIconCallback callback,
payments::mojom::PaymentHandlerStatus status) { PaymentHandlerStatus status) {
GetUIThreadTaskRunner({})->PostTask( GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), status)); FROM_HERE, base::BindOnce(std::move(callback), status));
} }
...@@ -400,7 +63,7 @@ void UpdatePaymentAppIconOnCoreThread( ...@@ -400,7 +63,7 @@ void UpdatePaymentAppIconOnCoreThread(
const std::string& method_name, const std::string& method_name,
const SupportedDelegations& supported_delegations, const SupportedDelegations& supported_delegations,
PaymentAppProvider::UpdatePaymentAppIconCallback callback) { PaymentAppProvider::UpdatePaymentAppIconCallback callback) {
DCHECK_CURRENTLY_ON(content::ServiceWorkerContext::GetCoreThreadId()); DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
payment_app_context->payment_app_database() payment_app_context->payment_app_database()
->SetPaymentAppInfoForRegisteredServiceWorker( ->SetPaymentAppInfoForRegisteredServiceWorker(
registration_id, instrument_key, name, string_encoded_icon, registration_id, instrument_key, name, string_encoded_icon,
...@@ -409,144 +72,6 @@ void UpdatePaymentAppIconOnCoreThread( ...@@ -409,144 +72,6 @@ void UpdatePaymentAppIconOnCoreThread(
std::move(callback))); std::move(callback)));
} }
void DispatchAbortPaymentEvent(
WebContents* web_contents,
PaymentAppProvider::AbortCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), false));
return;
}
DCHECK(active_version);
int event_finish_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT, base::DoNothing());
// This object self-deletes after either success or error callback is
// invoked.
RespondWithCallback* respond_with_callback = new AbortRespondWithCallback(
web_contents, active_version, std::move(callback));
active_version->endpoint()->DispatchAbortPaymentEvent(
respond_with_callback->BindNewPipeAndPassRemote(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void DispatchCanMakePaymentEvent(
WebContents* web_contents,
CanMakePaymentEventDataPtr event_data,
PaymentAppProvider::CanMakePaymentCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback),
CreateBlankCanMakePaymentResponse(
CanMakePaymentEventResponseType::BROWSER_ERROR)));
return;
}
DCHECK(active_version);
int event_finish_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT, base::DoNothing());
// This object self-deletes after either success or error callback is
// invoked.
RespondWithCallback* respond_with_callback =
new CanMakePaymentRespondWithCallback(web_contents, active_version,
std::move(callback));
active_version->endpoint()->DispatchCanMakePaymentEvent(
std::move(event_data), respond_with_callback->BindNewPipeAndPassRemote(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void DispatchPaymentRequestEvent(
WebContents* web_contents,
PaymentRequestEventDataPtr event_data,
PaymentAppProvider::InvokePaymentAppCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
std::move(callback),
CreateBlankPaymentHandlerResponse(
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR)));
return;
}
DCHECK(active_version);
int event_finish_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::PAYMENT_REQUEST, base::DoNothing());
// This object self-deletes after either success or error callback is
// invoked.
RespondWithCallback* respond_with_callback = new InvokeRespondWithCallback(
web_contents, active_version, std::move(callback));
active_version->endpoint()->DispatchPaymentRequestEvent(
std::move(event_data), respond_with_callback->BindNewPipeAndPassRemote(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void DidFindRegistrationOnCoreThread(
ServiceWorkerStartCallback callback,
blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(nullptr, service_worker_status);
return;
}
ServiceWorkerVersion* active_version =
service_worker_registration->active_version();
DCHECK(active_version);
active_version->RunAfterStartWorker(
ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
base::BindOnce(std::move(callback),
base::WrapRefCounted(active_version)));
}
void FindRegistrationOnCoreThread(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
int64_t registration_id,
ServiceWorkerStartCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
service_worker_context->FindReadyRegistrationForIdOnly(
registration_id,
base::BindOnce(&DidFindRegistrationOnCoreThread, std::move(callback)));
}
void AbortInvokePaymentApp(WebContents* web_contents,
PaymentEventResponseType reason) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (!web_contents)
return;
InvokeRespondWithCallback* callback =
InvokePaymentAppCallbackRepository::GetInstance()->GetCallback(
web_contents->GetBrowserContext());
if (callback)
callback->AbortPaymentSinceOpennedWindowClosing(reason);
}
void AddMethodDataToMap(const std::vector<PaymentMethodDataPtr>& method_data, void AddMethodDataToMap(const std::vector<PaymentMethodDataPtr>& method_data,
std::map<std::string, std::string>* out) { std::map<std::string, std::string>* out) {
for (size_t i = 0; i < method_data.size(); ++i) { for (size_t i = 0; i < method_data.size(); ++i) {
...@@ -575,84 +100,6 @@ void AddModifiersToMap(const std::vector<PaymentDetailsModifierPtr>& modifiers, ...@@ -575,84 +100,6 @@ void AddModifiersToMap(const std::vector<PaymentDetailsModifierPtr>& modifiers,
} }
} }
void OnResponseForCanMakePaymentOnUiThread(
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
PaymentAppProvider::CanMakePaymentCallback callback,
CanMakePaymentResponsePtr response) {
std::string error_message;
if (response->account_balance && !response->account_balance->empty() &&
!payments::PaymentsValidators::IsValidAmountFormat(
*response->account_balance, &error_message)) {
mojo::ReportBadMessage(
payments::errors::kCanMakePaymentEventInvalidAccountBalanceValue);
response = CreateBlankCanMakePaymentResponse(
CanMakePaymentEventResponseType::INVALID_ACCOUNT_BALANCE_VALUE);
}
if (dev_tools) {
std::stringstream response_type;
response_type << response->response_type;
std::map<std::string, std::string> data = {
{"Type", response_type.str()},
{"Can Make Payment", response->can_make_payment ? "true" : "false"}};
if (base::FeatureList::IsEnabled(features::kWebPaymentsMinimalUI)) {
data["Ready for Minimal UI"] =
response->ready_for_minimal_ui ? "true" : "false";
data["Account Balance"] =
response->account_balance ? *response->account_balance : "";
}
dev_tools->LogBackgroundServiceEvent(
registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler,
"Can make payment response",
/*instance_id=*/payment_request_id, data);
}
std::move(callback).Run(std::move(response));
}
void OnResponseForAbortPaymentOnUiThread(
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
PaymentAppProvider::AbortCallback callback,
bool payment_aborted) {
if (dev_tools) {
dev_tools->LogBackgroundServiceEvent(
registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler,
"Abort payment response",
/*instance_id=*/payment_request_id,
{{"Payment Aborted", payment_aborted ? "true" : "false"}});
}
std::move(callback).Run(payment_aborted);
}
void OnResponseForPaymentRequestOnUiThread(
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
PaymentAppProvider::InvokePaymentAppCallback callback,
PaymentHandlerResponsePtr response) {
if (dev_tools) {
std::stringstream response_type;
response_type << response->response_type;
dev_tools->LogBackgroundServiceEvent(
registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler,
"Payment response",
/*instance_id=*/payment_request_id,
{{"Method Name", response->method_name},
{"Details", response->stringified_details},
{"Type", response_type.str()}});
}
std::move(callback).Run(std::move(response));
}
} // namespace } // namespace
// static // static
...@@ -699,13 +146,19 @@ void PaymentAppProviderImpl::InvokePaymentApp( ...@@ -699,13 +146,19 @@ void PaymentAppProviderImpl::InvokePaymentApp(
/*instance_id=*/event_data->payment_request_id, data); /*instance_id=*/event_data->payment_request_id, data);
} }
StartServiceWorkerForDispatch( StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
registration_id, BrowserContext::GetDefaultStoragePartition(
web_contents_->GetBrowserContext()));
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
partition->GetServiceWorkerContext();
RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce( base::BindOnce(
&DispatchPaymentRequestEvent, web_contents_, std::move(event_data), &ServiceWorkerCoreThreadEventDispatcher::InvokePaymentOnCoreThread,
base::BindOnce(&OnResponseForPaymentRequestOnUiThread, dev_tools, event_dispatcher_->GetWeakPtr(), registration_id, sw_origin,
registration_id, sw_origin, std::move(dev_tools), std::move(service_worker_context),
event_data->payment_request_id, std::move(callback)))); std::move(event_data), std::move(callback)));
} }
void PaymentAppProviderImpl::InstallAndInvokePaymentApp( void PaymentAppProviderImpl::InstallAndInvokePaymentApp(
...@@ -727,7 +180,7 @@ void PaymentAppProviderImpl::InstallAndInvokePaymentApp( ...@@ -727,7 +180,7 @@ void PaymentAppProviderImpl::InstallAndInvokePaymentApp(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(
std::move(callback), std::move(callback),
CreateBlankPaymentHandlerResponse( PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR))); PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR)));
return; return;
} }
...@@ -766,7 +219,7 @@ void PaymentAppProviderImpl::UpdatePaymentAppIcon( ...@@ -766,7 +219,7 @@ void PaymentAppProviderImpl::UpdatePaymentAppIcon(
partition->GetPaymentAppContext(); partition->GetPaymentAppContext();
RunOrPostTaskOnThread( RunOrPostTaskOnThread(
FROM_HERE, content::ServiceWorkerContext::GetCoreThreadId(), FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(&UpdatePaymentAppIconOnCoreThread, payment_app_context, base::BindOnce(&UpdatePaymentAppIconOnCoreThread, payment_app_context,
registration_id, instrument_key, name, string_encoded_icon, registration_id, instrument_key, name, string_encoded_icon,
method_name, supported_delegations, std::move(callback))); method_name, supported_delegations, std::move(callback)));
...@@ -800,13 +253,20 @@ void PaymentAppProviderImpl::CanMakePayment( ...@@ -800,13 +253,20 @@ void PaymentAppProviderImpl::CanMakePayment(
/*instance_id=*/payment_request_id, data); /*instance_id=*/payment_request_id, data);
} }
StartServiceWorkerForDispatch( StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
registration_id, BrowserContext::GetDefaultStoragePartition(
base::BindOnce(&DispatchCanMakePaymentEvent, web_contents_, web_contents_->GetBrowserContext()));
std::move(event_data), scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
base::BindOnce(&OnResponseForCanMakePaymentOnUiThread, partition->GetServiceWorkerContext();
dev_tools, registration_id, sw_origin,
payment_request_id, std::move(callback)))); RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(
&ServiceWorkerCoreThreadEventDispatcher::CanMakePaymentOnCoreThread,
event_dispatcher_->GetWeakPtr(), registration_id, sw_origin,
payment_request_id, std::move(dev_tools),
std::move(service_worker_context), std::move(event_data),
std::move(callback)));
} }
void PaymentAppProviderImpl::AbortPayment(int64_t registration_id, void PaymentAppProviderImpl::AbortPayment(int64_t registration_id,
...@@ -825,12 +285,19 @@ void PaymentAppProviderImpl::AbortPayment(int64_t registration_id, ...@@ -825,12 +285,19 @@ void PaymentAppProviderImpl::AbortPayment(int64_t registration_id,
/*instance_id=*/payment_request_id, {}); /*instance_id=*/payment_request_id, {});
} }
StartServiceWorkerForDispatch( StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
registration_id, BrowserContext::GetDefaultStoragePartition(
base::BindOnce(&DispatchAbortPaymentEvent, web_contents_, web_contents_->GetBrowserContext()));
base::BindOnce(&OnResponseForAbortPaymentOnUiThread, scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
dev_tools, registration_id, sw_origin, partition->GetServiceWorkerContext();
payment_request_id, std::move(callback))));
RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(
&ServiceWorkerCoreThreadEventDispatcher::AbortPaymentOnCoreThread,
event_dispatcher_->GetWeakPtr(), registration_id, sw_origin,
payment_request_id, std::move(dev_tools),
std::move(service_worker_context), std::move(callback)));
} }
void PaymentAppProviderImpl::SetOpenedWindow() { void PaymentAppProviderImpl::SetOpenedWindow() {
...@@ -860,11 +327,12 @@ void PaymentAppProviderImpl::CloseOpenedWindow() { ...@@ -860,11 +327,12 @@ void PaymentAppProviderImpl::CloseOpenedWindow() {
void PaymentAppProviderImpl::OnClosingOpenedWindow( void PaymentAppProviderImpl::OnClosingOpenedWindow(
PaymentEventResponseType reason) { PaymentEventResponseType reason) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(web_contents_);
RunOrPostTaskOnThread( RunOrPostTaskOnThread(
FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(&AbortInvokePaymentApp, web_contents_, reason)); base::BindOnce(&ServiceWorkerCoreThreadEventDispatcher::
OnClosingOpenedWindowOnCoreThread,
event_dispatcher_->GetWeakPtr(), reason));
} }
scoped_refptr<DevToolsBackgroundServicesContextImpl> scoped_refptr<DevToolsBackgroundServicesContextImpl>
...@@ -888,7 +356,8 @@ PaymentAppProviderImpl::GetDevTools(const url::Origin& sw_origin) { ...@@ -888,7 +356,8 @@ PaymentAppProviderImpl::GetDevTools(const url::Origin& sw_origin) {
void PaymentAppProviderImpl::StartServiceWorkerForDispatch( void PaymentAppProviderImpl::StartServiceWorkerForDispatch(
int64_t registration_id, int64_t registration_id,
ServiceWorkerStartCallback callback) { ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerStartCallback
callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
...@@ -897,10 +366,12 @@ void PaymentAppProviderImpl::StartServiceWorkerForDispatch( ...@@ -897,10 +366,12 @@ void PaymentAppProviderImpl::StartServiceWorkerForDispatch(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context = scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
partition->GetServiceWorkerContext(); partition->GetServiceWorkerContext();
RunOrPostTaskOnThread(FROM_HERE, ServiceWorkerContext::GetCoreThreadId(), RunOrPostTaskOnThread(
base::BindOnce(&FindRegistrationOnCoreThread, FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
std::move(service_worker_context), base::BindOnce(
registration_id, std::move(callback))); &ServiceWorkerCoreThreadEventDispatcher::FindRegistrationOnCoreThread,
event_dispatcher_->GetWeakPtr(), std::move(service_worker_context),
registration_id, std::move(callback)));
} }
void PaymentAppProviderImpl::OnInstallPaymentApp( void PaymentAppProviderImpl::OnInstallPaymentApp(
...@@ -917,15 +388,24 @@ void PaymentAppProviderImpl::OnInstallPaymentApp( ...@@ -917,15 +388,24 @@ void PaymentAppProviderImpl::OnInstallPaymentApp(
InvokePaymentApp(registration_id, sw_origin, std::move(event_data), InvokePaymentApp(registration_id, sw_origin, std::move(event_data),
std::move(callback)); std::move(callback));
} else { } else {
std::move(callback).Run(CreateBlankPaymentHandlerResponse( std::move(callback).Run(
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR)); PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR));
} }
} }
PaymentAppProviderImpl::PaymentAppProviderImpl(WebContents* web_contents) PaymentAppProviderImpl::PaymentAppProviderImpl(WebContents* web_contents)
: web_contents_(web_contents) {} : web_contents_(web_contents),
event_dispatcher_(
std::make_unique<ServiceWorkerCoreThreadEventDispatcher>(
web_contents_)) {
event_dispatcher_->set_payment_app_provider(weak_ptr_factory_.GetWeakPtr());
}
PaymentAppProviderImpl::~PaymentAppProviderImpl() = default; PaymentAppProviderImpl::~PaymentAppProviderImpl() {
BrowserThread::DeleteSoon(ServiceWorkerContext::GetCoreThreadId(), FROM_HERE,
std::move(event_dispatcher_));
}
PaymentAppProviderImpl::PaymentHandlerWindowObserver:: PaymentAppProviderImpl::PaymentHandlerWindowObserver::
PaymentHandlerWindowObserver(WebContents* web_contents) PaymentHandlerWindowObserver(WebContents* web_contents)
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_PROVIDER_IMPL_H_ #ifndef CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_PROVIDER_IMPL_H_
#define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_PROVIDER_IMPL_H_ #define CONTENT_BROWSER_PAYMENTS_PAYMENT_APP_PROVIDER_IMPL_H_
#include "content/browser/devtools/devtools_background_services_context_impl.h"
#include "content/browser/payments/payment_app_context_impl.h" #include "content/browser/payments/payment_app_context_impl.h"
#include "content/browser/payments/service_worker_core_thread_event_dispatcher.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/public/browser/payment_app_provider.h" #include "content/public/browser/payment_app_provider.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
...@@ -14,11 +14,6 @@ ...@@ -14,11 +14,6 @@
namespace content { namespace content {
using payments::mojom::PaymentRequestEventDataPtr;
using ServiceWorkerStartCallback =
base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion>,
blink::ServiceWorkerStatusCode)>;
class CONTENT_EXPORT PaymentAppProviderImpl class CONTENT_EXPORT PaymentAppProviderImpl
: public PaymentAppProvider, : public PaymentAppProvider,
public WebContentsUserData<PaymentAppProviderImpl> { public WebContentsUserData<PaymentAppProviderImpl> {
...@@ -77,13 +72,16 @@ class CONTENT_EXPORT PaymentAppProviderImpl ...@@ -77,13 +72,16 @@ class CONTENT_EXPORT PaymentAppProviderImpl
scoped_refptr<DevToolsBackgroundServicesContextImpl> GetDevTools( scoped_refptr<DevToolsBackgroundServicesContextImpl> GetDevTools(
const url::Origin& sw_origin); const url::Origin& sw_origin);
void StartServiceWorkerForDispatch(int64_t registration_id, void StartServiceWorkerForDispatch(
ServiceWorkerStartCallback callback); int64_t registration_id,
void OnInstallPaymentApp(const url::Origin& sw_origin, ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerStartCallback
PaymentRequestEventDataPtr event_data, callback);
RegistrationIdCallback registration_id_callback, void OnInstallPaymentApp(
InvokePaymentAppCallback callback, const url::Origin& sw_origin,
int64_t registration_id); payments::mojom::PaymentRequestEventDataPtr event_data,
RegistrationIdCallback registration_id_callback,
InvokePaymentAppCallback callback,
int64_t registration_id);
// Note that constructor of WebContentsObserver is protected. // Note that constructor of WebContentsObserver is protected.
class PaymentHandlerWindowObserver : public WebContentsObserver { class PaymentHandlerWindowObserver : public WebContentsObserver {
...@@ -97,6 +95,9 @@ class CONTENT_EXPORT PaymentAppProviderImpl ...@@ -97,6 +95,9 @@ class CONTENT_EXPORT PaymentAppProviderImpl
// Owns this object. // Owns this object.
WebContents* web_contents_; WebContents* web_contents_;
// It should be accessed only on the service worker core thread.
std::unique_ptr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher_;
base::WeakPtrFactory<PaymentAppProviderImpl> weak_ptr_factory_{this}; base::WeakPtrFactory<PaymentAppProviderImpl> weak_ptr_factory_{this};
}; };
......
...@@ -47,4 +47,25 @@ bool PaymentAppProviderUtil::IsValidInstallablePaymentApp( ...@@ -47,4 +47,25 @@ bool PaymentAppProviderUtil::IsValidInstallablePaymentApp(
return true; return true;
} }
// static
payments::mojom::CanMakePaymentResponsePtr
PaymentAppProviderUtil::CreateBlankCanMakePaymentResponse(
payments::mojom::CanMakePaymentEventResponseType response_type) {
return payments::mojom::CanMakePaymentResponse::New(
response_type, /*can_make_payment=*/false,
/*ready_for_minimal_ui=*/false,
/*account_balance=*/base::nullopt);
}
// static
payments::mojom::PaymentHandlerResponsePtr
PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
payments::mojom::PaymentEventResponseType response_type) {
return payments::mojom::PaymentHandlerResponse::New(
/*method_name=*/"", /*stringified_details=*/"", response_type,
/*payer_name=*/base::nullopt, /*payer_email=*/base::nullopt,
/*payer_phone=*/base::nullopt, /*shipping_address=*/nullptr,
/*shipping_option=*/base::nullopt);
}
} // namespace content } // namespace content
// 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 "content/browser/payments/respond_with_callback.h"
#include "content/browser/payments/payment_app_provider_impl.h"
#include "content/browser/payments/service_worker_core_thread_event_dispatcher.h"
namespace content {
namespace {
using payments::mojom::CanMakePaymentEventResponseType;
using payments::mojom::CanMakePaymentResponsePtr;
using payments::mojom::PaymentEventResponseType;
using payments::mojom::PaymentHandlerResponseCallback;
using payments::mojom::PaymentHandlerResponsePtr;
void CloseOpenedWindowUiThread(
base::WeakPtr<PaymentAppProviderImpl> payment_app_provider) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (payment_app_provider)
payment_app_provider->CloseOpenedWindow();
}
} // namespace
mojo::PendingRemote<PaymentHandlerResponseCallback>
RespondWithCallback::BindNewPipeAndPassRemote() {
return receiver_.BindNewPipeAndPassRemote();
}
RespondWithCallback::RespondWithCallback(
WebContents* web_contents,
ServiceWorkerMetrics::EventType event_type,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher)
: WebContentsObserver(web_contents),
service_worker_version_(service_worker_version),
event_dispatcher_(event_dispatcher) {
request_id_ = service_worker_version->StartRequest(
event_type, base::BindOnce(&RespondWithCallback::OnServiceWorkerError,
weak_ptr_factory_.GetWeakPtr()));
}
RespondWithCallback::~RespondWithCallback() = default;
void RespondWithCallback::FinishServiceWorkerRequest() {
service_worker_version_->FinishRequest(request_id_, false);
}
void RespondWithCallback::MaybeRecordTimeoutMetric(
blink::ServiceWorkerStatusCode status) {
if (status == blink::ServiceWorkerStatusCode::kErrorTimeout) {
UMA_HISTOGRAM_BOOLEAN("PaymentRequest.ServiceWorkerStatusCodeTimeout",
true);
}
}
void RespondWithCallback::ClearRespondWithCallbackAndCloseWindow() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (!web_contents())
return;
if (!event_dispatcher_)
return;
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(&CloseOpenedWindowUiThread,
event_dispatcher_->payment_app_provider()));
event_dispatcher_->ResetRespondWithCallback();
}
CanMakePaymentRespondWithCallback::CanMakePaymentRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
PaymentAppProvider::CanMakePaymentCallback callback)
: RespondWithCallback(web_contents,
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
service_worker_version,
event_dispatcher),
callback_(std::move(callback)) {}
CanMakePaymentRespondWithCallback::~CanMakePaymentRespondWithCallback() =
default;
void CanMakePaymentRespondWithCallback::OnResponseForCanMakePayment(
CanMakePaymentResponsePtr response) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), std::move(response)));
delete this;
}
void CanMakePaymentRespondWithCallback::OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
MaybeRecordTimeoutMetric(service_worker_status);
CanMakePaymentEventResponseType response_type =
CanMakePaymentEventResponseType::BROWSER_ERROR;
if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected) {
response_type = CanMakePaymentEventResponseType::REJECT;
} else if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorTimeout) {
response_type = CanMakePaymentEventResponseType::TIMEOUT;
}
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(
std::move(callback_),
content::PaymentAppProviderUtil::CreateBlankCanMakePaymentResponse(
response_type)));
delete this;
}
InvokeRespondWithCallback::InvokeRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
PaymentAppProvider::InvokePaymentAppCallback callback)
: RespondWithCallback(web_contents,
ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
service_worker_version,
event_dispatcher),
callback_(std::move(callback)) {}
void InvokeRespondWithCallback::AbortPaymentSinceOpennedWindowClosing(
PaymentEventResponseType reason) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RespondToPaymentRequestWithErrorAndDeleteSelf(reason);
}
InvokeRespondWithCallback::~InvokeRespondWithCallback() = default;
void InvokeRespondWithCallback::OnResponseForPaymentRequest(
PaymentHandlerResponsePtr response) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), std::move(response)));
ClearRespondWithCallbackAndCloseWindow();
}
void InvokeRespondWithCallback::OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
MaybeRecordTimeoutMetric(service_worker_status);
PaymentEventResponseType response_type =
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR;
if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected) {
response_type = PaymentEventResponseType::PAYMENT_EVENT_REJECT;
} else if (service_worker_status ==
blink::ServiceWorkerStatusCode::kErrorTimeout) {
response_type = PaymentEventResponseType::PAYMENT_EVENT_TIMEOUT;
}
RespondToPaymentRequestWithErrorAndDeleteSelf(response_type);
}
void InvokeRespondWithCallback::RespondToPaymentRequestWithErrorAndDeleteSelf(
PaymentEventResponseType response_type) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(
std::move(callback_),
content::PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
response_type)));
ClearRespondWithCallbackAndCloseWindow();
}
AbortRespondWithCallback::AbortRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
PaymentAppProvider::AbortCallback callback)
: RespondWithCallback(web_contents,
ServiceWorkerMetrics::EventType::ABORT_PAYMENT,
service_worker_version,
event_dispatcher),
callback_(std::move(callback)) {}
AbortRespondWithCallback::~AbortRespondWithCallback() = default;
// PaymentHandlerResponseCallback implementation.
void AbortRespondWithCallback::OnResponseForAbortPayment(bool payment_aborted) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
FinishServiceWorkerRequest();
RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), payment_aborted));
if (payment_aborted)
ClearRespondWithCallbackAndCloseWindow();
delete this;
}
void AbortRespondWithCallback::OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
MaybeRecordTimeoutMetric(service_worker_status);
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(std::move(callback_), /*payment_aborted=*/false));
// Do not call ClearRespondWithCallbackAndCloseWindow() here, because payment
// has not been aborted. The service worker either rejected, timed out, or
// threw a JavaScript exception in the "abortpayment" event, but that does
// not affect the ongoing "paymentrequest" event.
delete this;
}
} // namespace content.
// 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 CONTENT_BROWSER_PAYMENTS_RESPOND_WITH_CALLBACK_H_
#define CONTENT_BROWSER_PAYMENTS_RESPOND_WITH_CALLBACK_H_
#include "base/callback_forward.h"
#include "base/memory/singleton.h"
#include "base/metrics/histogram_macros.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/payment_app_provider.h"
#include "content/public/browser/payment_app_provider_util.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/blink/public/mojom/payments/payment_app.mojom.h"
namespace content {
class ServiceWorkerCoreThreadEventDispatcher;
enum class RespondWithCallbackType { kInvoke, kAbort, kCanMakePayment };
// Abstract base class for event callbacks that are invoked when the payment
// handler resolves the promise passed in to TheEvent.respondWith() method.
class RespondWithCallback
: public payments::mojom::PaymentHandlerResponseCallback,
public WebContentsObserver {
public:
// Disallow copy and assign.
RespondWithCallback(const RespondWithCallback& other) = delete;
RespondWithCallback& operator=(const RespondWithCallback& other) = delete;
mojo::PendingRemote<payments::mojom::PaymentHandlerResponseCallback>
BindNewPipeAndPassRemote();
protected:
RespondWithCallback(
WebContents* web_contents,
ServiceWorkerMetrics::EventType event_type,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher);
~RespondWithCallback() override;
// payments::mojom::PaymentHandlerResponseCallback implementation.
void OnResponseForCanMakePayment(
payments::mojom::CanMakePaymentResponsePtr response) override {}
// payments::mojom::PaymentHandlerResponseCallback implementation.
void OnResponseForPaymentRequest(
payments::mojom::PaymentHandlerResponsePtr response) override {}
// payments::mojom::PaymentHandlerResponseCallback implementation.
void OnResponseForAbortPayment(bool payment_aborted) override {}
virtual void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) = 0;
void FinishServiceWorkerRequest();
void MaybeRecordTimeoutMetric(blink::ServiceWorkerStatusCode status);
void ClearRespondWithCallbackAndCloseWindow();
private:
int request_id_;
scoped_refptr<ServiceWorkerVersion> service_worker_version_;
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher_;
mojo::Receiver<payments::mojom::PaymentHandlerResponseCallback> receiver_{
this};
base::WeakPtrFactory<RespondWithCallback> weak_ptr_factory_{this};
};
// Self-deleting callback for "canmakepayment" event. Invoked when the payment
// handler resolves the promise passed into CanMakePaymentEvent.respondWith()
// method.
class CanMakePaymentRespondWithCallback : public RespondWithCallback {
public:
CanMakePaymentRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
PaymentAppProvider::CanMakePaymentCallback callback);
~CanMakePaymentRespondWithCallback() override;
// Disallow copy and assign.
CanMakePaymentRespondWithCallback(
const CanMakePaymentRespondWithCallback& other) = delete;
CanMakePaymentRespondWithCallback& operator=(
const CanMakePaymentRespondWithCallback& other) = delete;
private:
// payments::mojom::PaymentHandlerResponseCallback implementation.
void OnResponseForCanMakePayment(
payments::mojom::CanMakePaymentResponsePtr response) override;
// RespondWithCallback implementation.
void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) override;
PaymentAppProvider::CanMakePaymentCallback callback_;
};
// Self-deleting callback for "paymentrequest" event. Invoked when the payment
// handler resolves the promise passed into PaymentRequestEvent.respondWith()
// method.
class InvokeRespondWithCallback : public RespondWithCallback {
public:
InvokeRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
PaymentAppProvider::InvokePaymentAppCallback callback);
~InvokeRespondWithCallback() override;
// Disallow copy and assign.
InvokeRespondWithCallback(const InvokeRespondWithCallback& other) = delete;
InvokeRespondWithCallback& operator=(const InvokeRespondWithCallback& other) =
delete;
// Called only for "paymentrequest" event.
void AbortPaymentSinceOpennedWindowClosing(
payments::mojom::PaymentEventResponseType reason);
private:
// payments::mojom::PaymentHandlerResponseCallback implementation.
void OnResponseForPaymentRequest(
payments::mojom::PaymentHandlerResponsePtr response) override;
// RespondWithCallback implementation.
void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) override;
void RespondToPaymentRequestWithErrorAndDeleteSelf(
payments::mojom::PaymentEventResponseType response_type);
PaymentAppProvider::InvokePaymentAppCallback callback_;
};
// Self-deleting callback for "abortpayment" event. Invoked when the payment
// handler resolves the promise passed into AbortPayment.respondWith() method.
class AbortRespondWithCallback : public RespondWithCallback {
public:
AbortRespondWithCallback(
WebContents* web_contents,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> event_dispatcher,
PaymentAppProvider::AbortCallback callback);
~AbortRespondWithCallback() override;
// Disallow copy and assign.
AbortRespondWithCallback(const AbortRespondWithCallback& other) = delete;
AbortRespondWithCallback& operator=(const AbortRespondWithCallback& other) =
delete;
private:
// payments::mojom::PaymentHandlerResponseCallback implementation.
void OnResponseForAbortPayment(bool payment_aborted) override;
// RespondWithCallback implementation.
void OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) override;
PaymentAppProvider::AbortCallback callback_;
};
} // namespace content.
#endif // CONTENT_BROWSER_PAYMENTS_RESPOND_WITH_CALLBACK_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 "content/browser/payments/service_worker_core_thread_event_dispatcher.h"
#include "base/bind.h"
#include "base/feature_list.h"
#include "components/payments/core/native_error_strings.h"
#include "components/payments/core/payments_validators.h"
#include "content/browser/payments/payment_app_provider_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
namespace content {
namespace {
using payments::mojom::CanMakePaymentEventDataPtr;
using payments::mojom::CanMakePaymentEventResponseType;
using payments::mojom::CanMakePaymentResponsePtr;
using payments::mojom::PaymentEventResponseType;
using payments::mojom::PaymentHandlerResponsePtr;
using payments::mojom::PaymentRequestEventDataPtr;
} // namespace
namespace {
void DidFindRegistrationOnCoreThread(
ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerStartCallback callback,
blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(nullptr, service_worker_status);
return;
}
ServiceWorkerVersion* active_version =
service_worker_registration->active_version();
DCHECK(active_version);
active_version->RunAfterStartWorker(
ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
base::BindOnce(std::move(callback),
base::WrapRefCounted(active_version)));
}
void OnResponseForPaymentRequestOnUiThread(
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
PaymentAppProvider::InvokePaymentAppCallback callback,
PaymentHandlerResponsePtr response) {
if (dev_tools) {
std::stringstream response_type;
response_type << response->response_type;
dev_tools->LogBackgroundServiceEvent(
registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler,
"Payment response",
/*instance_id=*/payment_request_id,
{{"Method Name", response->method_name},
{"Details", response->stringified_details},
{"Type", response_type.str()}});
}
std::move(callback).Run(std::move(response));
}
void OnResponseForCanMakePaymentOnUiThread(
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
PaymentAppProvider::CanMakePaymentCallback callback,
CanMakePaymentResponsePtr response) {
std::string error_message;
if (response->account_balance && !response->account_balance->empty() &&
!payments::PaymentsValidators::IsValidAmountFormat(
*response->account_balance, &error_message)) {
mojo::ReportBadMessage(
payments::errors::kCanMakePaymentEventInvalidAccountBalanceValue);
response =
content::PaymentAppProviderUtil::CreateBlankCanMakePaymentResponse(
CanMakePaymentEventResponseType::INVALID_ACCOUNT_BALANCE_VALUE);
}
if (dev_tools) {
std::stringstream response_type;
response_type << response->response_type;
std::map<std::string, std::string> data = {
{"Type", response_type.str()},
{"Can Make Payment", response->can_make_payment ? "true" : "false"}};
if (base::FeatureList::IsEnabled(features::kWebPaymentsMinimalUI)) {
data["Ready for Minimal UI"] =
response->ready_for_minimal_ui ? "true" : "false";
data["Account Balance"] =
response->account_balance ? *response->account_balance : "";
}
dev_tools->LogBackgroundServiceEvent(
registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler,
"Can make payment response",
/*instance_id=*/payment_request_id, data);
}
std::move(callback).Run(std::move(response));
}
void OnResponseForAbortPaymentOnUiThread(
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
PaymentAppProvider::AbortCallback callback,
bool payment_aborted) {
if (dev_tools) {
dev_tools->LogBackgroundServiceEvent(
registration_id, sw_origin, DevToolsBackgroundService::kPaymentHandler,
"Abort payment response",
/*instance_id=*/payment_request_id,
{{"Payment Aborted", payment_aborted ? "true" : "false"}});
}
std::move(callback).Run(payment_aborted);
}
} // namespace
ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerCoreThreadEventDispatcher(
WebContents* web_contents)
: WebContentsObserver(web_contents) {}
ServiceWorkerCoreThreadEventDispatcher::
~ServiceWorkerCoreThreadEventDispatcher() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
}
void ServiceWorkerCoreThreadEventDispatcher::DispatchAbortPaymentEvent(
PaymentAppProvider::AbortCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (!web_contents())
return;
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), false));
return;
}
DCHECK(active_version);
int event_finish_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT, base::DoNothing());
// This object self-deletes after either success or error callback is
// invoked.
RespondWithCallback* respond_with_callback = new AbortRespondWithCallback(
web_contents(), active_version, weak_ptr_factory_.GetWeakPtr(),
std::move(callback));
active_version->endpoint()->DispatchAbortPaymentEvent(
respond_with_callback->BindNewPipeAndPassRemote(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void ServiceWorkerCoreThreadEventDispatcher::AbortPaymentOnCoreThread(
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
PaymentAppProvider::AbortCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
service_worker_context->FindReadyRegistrationForIdOnly(
registration_id,
base::BindOnce(
&DidFindRegistrationOnCoreThread,
base::BindOnce(
&ServiceWorkerCoreThreadEventDispatcher::
DispatchAbortPaymentEvent,
weak_ptr_factory_.GetWeakPtr(),
base::BindOnce(&OnResponseForAbortPaymentOnUiThread, dev_tools,
registration_id, sw_origin, payment_request_id,
std::move(callback)))));
}
void ServiceWorkerCoreThreadEventDispatcher::DispatchCanMakePaymentEvent(
CanMakePaymentEventDataPtr event_data,
PaymentAppProvider::CanMakePaymentCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (!web_contents())
return;
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
std::move(callback),
PaymentAppProviderUtil::CreateBlankCanMakePaymentResponse(
CanMakePaymentEventResponseType::BROWSER_ERROR)));
return;
}
DCHECK(active_version);
int event_finish_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT, base::DoNothing());
// This object self-deletes after either success or error callback is
// invoked.
RespondWithCallback* respond_with_callback =
new CanMakePaymentRespondWithCallback(web_contents(), active_version,
weak_ptr_factory_.GetWeakPtr(),
std::move(callback));
active_version->endpoint()->DispatchCanMakePaymentEvent(
std::move(event_data), respond_with_callback->BindNewPipeAndPassRemote(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void ServiceWorkerCoreThreadEventDispatcher::CanMakePaymentOnCoreThread(
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
CanMakePaymentEventDataPtr event_data,
PaymentAppProvider::CanMakePaymentCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
service_worker_context->FindReadyRegistrationForIdOnly(
registration_id,
base::BindOnce(
&DidFindRegistrationOnCoreThread,
base::BindOnce(
&ServiceWorkerCoreThreadEventDispatcher::
DispatchCanMakePaymentEvent,
weak_ptr_factory_.GetWeakPtr(), std::move(event_data),
base::BindOnce(&OnResponseForCanMakePaymentOnUiThread, dev_tools,
registration_id, sw_origin, payment_request_id,
std::move(callback)))));
}
void ServiceWorkerCoreThreadEventDispatcher::DispatchPaymentRequestEvent(
PaymentRequestEventDataPtr event_data,
PaymentAppProvider::InvokePaymentAppCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (!web_contents())
return;
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
std::move(callback),
content::PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR)));
return;
}
DCHECK(active_version);
int event_finish_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::PAYMENT_REQUEST, base::DoNothing());
invoke_respond_with_callback_ = std::make_unique<InvokeRespondWithCallback>(
web_contents(), active_version, weak_ptr_factory_.GetWeakPtr(),
std::move(callback));
active_version->endpoint()->DispatchPaymentRequestEvent(
std::move(event_data),
invoke_respond_with_callback_->BindNewPipeAndPassRemote(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void ServiceWorkerCoreThreadEventDispatcher::InvokePaymentOnCoreThread(
int64_t registration_id,
const url::Origin& sw_origin,
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
PaymentRequestEventDataPtr event_data,
PaymentAppProvider::InvokePaymentAppCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
service_worker_context->FindReadyRegistrationForIdOnly(
registration_id,
base::BindOnce(
&DidFindRegistrationOnCoreThread,
base::BindOnce(&ServiceWorkerCoreThreadEventDispatcher::
DispatchPaymentRequestEvent,
weak_ptr_factory_.GetWeakPtr(), std::move(event_data),
base::BindOnce(&OnResponseForPaymentRequestOnUiThread,
dev_tools, registration_id, sw_origin,
event_data->payment_request_id,
std::move(callback)))));
}
void ServiceWorkerCoreThreadEventDispatcher::FindRegistrationOnCoreThread(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
int64_t registration_id,
ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerStartCallback
callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
service_worker_context->FindReadyRegistrationForIdOnly(
registration_id,
base::BindOnce(&DidFindRegistrationOnCoreThread, std::move(callback)));
}
void ServiceWorkerCoreThreadEventDispatcher::OnClosingOpenedWindowOnCoreThread(
PaymentEventResponseType reason) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
InvokeRespondWithCallback* callback = invoke_respond_with_callback_.get();
if (callback)
callback->AbortPaymentSinceOpennedWindowClosing(reason);
}
void ServiceWorkerCoreThreadEventDispatcher::ResetRespondWithCallback() {
RunOrPostTaskOnThread(FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
base::BindOnce(&ServiceWorkerCoreThreadEventDispatcher::
ResetRespondWithCallbackCoreThread,
weak_ptr_factory_.GetWeakPtr()));
}
void ServiceWorkerCoreThreadEventDispatcher::
ResetRespondWithCallbackCoreThread() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
invoke_respond_with_callback_.reset();
}
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher>
ServiceWorkerCoreThreadEventDispatcher::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
} // namespace content.
// 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 CONTENT_BROWSER_PAYMENTS_SERVICE_WORKER_CORE_THREAD_EVENT_DISPATCHER_H_
#define CONTENT_BROWSER_PAYMENTS_SERVICE_WORKER_CORE_THREAD_EVENT_DISPATCHER_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/devtools_background_services_context_impl.h"
#include "content/browser/payments/respond_with_callback.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/public/browser/web_contents_observer.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
class WebContents;
class PaymentAppProviderImpl;
// All of the methods and the destructor should be running on the
// service worker core thread.
class ServiceWorkerCoreThreadEventDispatcher : public WebContentsObserver {
public:
explicit ServiceWorkerCoreThreadEventDispatcher(WebContents* web_contents);
~ServiceWorkerCoreThreadEventDispatcher() override;
using ServiceWorkerStartCallback =
base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion>,
blink::ServiceWorkerStatusCode)>;
void set_payment_app_provider(
base::WeakPtr<PaymentAppProviderImpl> payment_app_provider) {
payment_app_provider_ = payment_app_provider;
}
base::WeakPtr<PaymentAppProviderImpl> payment_app_provider() const {
return payment_app_provider_;
}
void AbortPaymentOnCoreThread(
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
PaymentAppProvider::AbortCallback callback);
void CanMakePaymentOnCoreThread(
int64_t registration_id,
const url::Origin& sw_origin,
const std::string& payment_request_id,
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
payments::mojom::CanMakePaymentEventDataPtr event_data,
PaymentAppProvider::CanMakePaymentCallback callback);
void InvokePaymentOnCoreThread(
int64_t registration_id,
const url::Origin& sw_origin,
scoped_refptr<DevToolsBackgroundServicesContextImpl> dev_tools,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
payments::mojom::PaymentRequestEventDataPtr event_data,
PaymentAppProvider::InvokePaymentAppCallback callback);
void FindRegistrationOnCoreThread(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
int64_t registration_id,
ServiceWorkerCoreThreadEventDispatcher::ServiceWorkerStartCallback
callback);
void OnClosingOpenedWindowOnCoreThread(
payments::mojom::PaymentEventResponseType reason);
void ResetRespondWithCallback();
base::WeakPtr<ServiceWorkerCoreThreadEventDispatcher> GetWeakPtr();
private:
// AbortCallback require to be run on the UI thread.
void DispatchAbortPaymentEvent(
PaymentAppProvider::AbortCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status);
// CanMakePaymentCallback require to be run on the UI thread.
void DispatchCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr event_data,
PaymentAppProvider::CanMakePaymentCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status);
// InvokePaymentAppCallback require to be run on the UI thread.
void DispatchPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr event_data,
PaymentAppProvider::InvokePaymentAppCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
blink::ServiceWorkerStatusCode service_worker_status);
void ResetRespondWithCallbackCoreThread();
std::unique_ptr<InvokeRespondWithCallback> invoke_respond_with_callback_;
// payment_app_provider_ require to be run on the UI thread.
base::WeakPtr<PaymentAppProviderImpl> payment_app_provider_;
base::WeakPtrFactory<ServiceWorkerCoreThreadEventDispatcher>
weak_ptr_factory_{this};
};
} // namespace content.
#endif // CONTENT_BROWSER_PAYMENTS_SERVICE_WORKER_CORE_THREAD_EVENT_DISPATCHER_H_
...@@ -23,6 +23,16 @@ class CONTENT_EXPORT PaymentAppProviderUtil { ...@@ -23,6 +23,16 @@ class CONTENT_EXPORT PaymentAppProviderUtil {
const GURL& sw_js_url, const GURL& sw_js_url,
const GURL& sw_scope, const GURL& sw_scope,
std::string* error_message); std::string* error_message);
// Create blank struct for response to "can make payment".
static payments::mojom::CanMakePaymentResponsePtr
CreateBlankCanMakePaymentResponse(
payments::mojom::CanMakePaymentEventResponseType response_type);
// Create blank struct for receipt payment app response from render side.
static payments::mojom::PaymentHandlerResponsePtr
CreateBlankPaymentHandlerResponse(
payments::mojom::PaymentEventResponseType response_type);
}; };
} // namespace content } // namespace content
......
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