blob: 4a487718bdae5d962f4a0a6c810aff041231e84a [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/payments/respond_with_callback.h"
#include "content/browser/payments/payment_app_provider_impl.h"
#include "content/browser/payments/payment_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;
} // namespace
mojo::PendingRemote<PaymentHandlerResponseCallback>
RespondWithCallback::BindNewPipeAndPassRemote() {
return receiver_.BindNewPipeAndPassRemote();
}
RespondWithCallback::RespondWithCallback(
ServiceWorkerMetrics::EventType event_type,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<PaymentEventDispatcher> event_dispatcher)
: 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_, /*was_handled=*/false);
}
void RespondWithCallback::ClearRespondWithCallbackAndCloseWindow() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!event_dispatcher_)
return;
if (base::WeakPtr<PaymentAppProviderImpl> provider =
event_dispatcher_->payment_app_provider())
provider->CloseOpenedWindow();
event_dispatcher_->ResetRespondWithCallback();
}
CanMakePaymentRespondWithCallback::CanMakePaymentRespondWithCallback(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<PaymentEventDispatcher> event_dispatcher,
PaymentAppProvider::CanMakePaymentCallback callback)
: RespondWithCallback(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(BrowserThread::UI);
FinishServiceWorkerRequest();
std::move(callback_).Run(std::move(response));
delete this;
}
void CanMakePaymentRespondWithCallback::OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
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;
}
std::move(callback_).Run(
content::PaymentAppProviderUtil::CreateBlankCanMakePaymentResponse(
response_type));
delete this;
}
InvokeRespondWithCallback::InvokeRespondWithCallback(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<PaymentEventDispatcher> event_dispatcher,
PaymentAppProvider::InvokePaymentAppCallback callback)
: RespondWithCallback(ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
service_worker_version,
event_dispatcher),
callback_(std::move(callback)) {}
void InvokeRespondWithCallback::AbortPaymentSinceOpennedWindowClosing(
PaymentEventResponseType reason) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
FinishServiceWorkerRequest();
RespondToPaymentRequestWithErrorAndDeleteSelf(reason);
}
InvokeRespondWithCallback::~InvokeRespondWithCallback() = default;
void InvokeRespondWithCallback::OnResponseForPaymentRequest(
PaymentHandlerResponsePtr response) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
FinishServiceWorkerRequest();
std::move(callback_).Run(std::move(response));
ClearRespondWithCallbackAndCloseWindow();
}
void InvokeRespondWithCallback::OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
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(BrowserThread::UI);
std::move(callback_).Run(
content::PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
response_type));
ClearRespondWithCallbackAndCloseWindow();
}
AbortRespondWithCallback::AbortRespondWithCallback(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
base::WeakPtr<PaymentEventDispatcher> event_dispatcher,
PaymentAppProvider::AbortCallback callback)
: RespondWithCallback(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(BrowserThread::UI);
FinishServiceWorkerRequest();
std::move(callback_).Run(payment_aborted);
if (payment_aborted)
ClearRespondWithCallbackAndCloseWindow();
delete this;
}
void AbortRespondWithCallback::OnServiceWorkerError(
blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
std::move(callback_).Run(/*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