1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/modules/payments/payment_manager.h"
6 
7 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
8 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
9 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
10 #include "third_party/blink/renderer/core/dom/dom_exception.h"
11 #include "third_party/blink/renderer/modules/payments/payment_instruments.h"
12 #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h"
13 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
14 #include "third_party/blink/renderer/platform/bindings/script_state.h"
15 #include "third_party/blink/renderer/platform/wtf/functional.h"
16 
17 namespace blink {
18 
instruments()19 PaymentInstruments* PaymentManager::instruments() {
20   if (!instruments_)
21     instruments_ = MakeGarbageCollected<PaymentInstruments>(manager_);
22   return instruments_;
23 }
24 
userHint()25 const String& PaymentManager::userHint() {
26   return user_hint_;
27 }
28 
setUserHint(const String & user_hint)29 void PaymentManager::setUserHint(const String& user_hint) {
30   user_hint_ = user_hint;
31   manager_->SetUserHint(user_hint_);
32 }
33 
enableDelegations(ScriptState * script_state,const Vector<String> & stringified_delegations,ExceptionState & exception_state)34 ScriptPromise PaymentManager::enableDelegations(
35     ScriptState* script_state,
36     const Vector<String>& stringified_delegations,
37     ExceptionState& exception_state) {
38   if (!script_state->ContextIsValid()) {
39     exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
40                                       "Cannot enable payment delegations");
41     return ScriptPromise();
42   }
43 
44   if (enable_delegations_resolver_) {
45     exception_state.ThrowDOMException(
46         DOMExceptionCode::kInvalidStateError,
47         "Cannot call enableDelegations() again until the previous "
48         "enableDelegations() is finished");
49     return ScriptPromise();
50   }
51 
52   Vector<payments::mojom::blink::PaymentDelegation> delegations;
53   for (auto delegation : stringified_delegations) {
54     if (delegation == "shippingAddress") {
55       delegations.emplace_back(
56           payments::mojom::blink::PaymentDelegation::SHIPPING_ADDRESS);
57     } else if (delegation == "payerName") {
58       delegations.emplace_back(
59           payments::mojom::blink::PaymentDelegation::PAYER_NAME);
60     } else if (delegation == "payerPhone") {
61       delegations.emplace_back(
62           payments::mojom::blink::PaymentDelegation::PAYER_PHONE);
63     } else {
64       DCHECK_EQ("payerEmail", delegation);
65       delegations.emplace_back(
66           payments::mojom::blink::PaymentDelegation::PAYER_EMAIL);
67     }
68   }
69 
70   manager_->EnableDelegations(
71       std::move(delegations),
72       WTF::Bind(&PaymentManager::OnEnableDelegationsResponse,
73                 WrapPersistent(this)));
74   enable_delegations_resolver_ =
75       MakeGarbageCollected<ScriptPromiseResolver>(script_state);
76   return enable_delegations_resolver_->Promise();
77 }
78 
Trace(Visitor * visitor)79 void PaymentManager::Trace(Visitor* visitor) {
80   visitor->Trace(registration_);
81   visitor->Trace(instruments_);
82   visitor->Trace(enable_delegations_resolver_);
83   ScriptWrappable::Trace(visitor);
84 }
85 
PaymentManager(ServiceWorkerRegistration * registration)86 PaymentManager::PaymentManager(ServiceWorkerRegistration* registration)
87     : registration_(registration), instruments_(nullptr) {
88   DCHECK(registration);
89 
90   if (ExecutionContext* context = registration->GetExecutionContext()) {
91     context->GetBrowserInterfaceBroker().GetInterface(
92         manager_.BindNewPipeAndPassReceiver(
93             context->GetTaskRunner(TaskType::kUserInteraction)));
94   }
95 
96   manager_.set_disconnect_handler(WTF::Bind(
97       &PaymentManager::OnServiceConnectionError, WrapWeakPersistent(this)));
98   manager_->Init(registration_->GetExecutionContext()->Url(),
99                  registration_->scope());
100 }
101 
OnEnableDelegationsResponse(payments::mojom::blink::PaymentHandlerStatus status)102 void PaymentManager::OnEnableDelegationsResponse(
103     payments::mojom::blink::PaymentHandlerStatus status) {
104   DCHECK(enable_delegations_resolver_);
105   enable_delegations_resolver_->Resolve(
106       status == payments::mojom::blink::PaymentHandlerStatus::SUCCESS);
107   enable_delegations_resolver_.Clear();
108 }
109 
OnServiceConnectionError()110 void PaymentManager::OnServiceConnectionError() {
111   if (enable_delegations_resolver_)
112     enable_delegations_resolver_.Clear();
113 
114   manager_.reset();
115 }
116 
117 }  // namespace blink
118