| Index: third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
 | 
| diff --git a/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp b/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
 | 
| index f89da6af29755ffda611632c28cc39d7abeda4b9..0b686f23f9f40d6a9c6f384fb2f3be90c265c816 100644
 | 
| --- a/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
 | 
| +++ b/third_party/WebKit/Source/modules/payments/PaymentInstruments.cpp
 | 
| @@ -4,12 +4,53 @@
 | 
|  
 | 
|  #include "modules/payments/PaymentInstruments.h"
 | 
|  
 | 
| +#include <utility>
 | 
| +
 | 
| +#include "bindings/core/v8/ExceptionState.h"
 | 
|  #include "bindings/core/v8/ScriptPromise.h"
 | 
| +#include "bindings/core/v8/ScriptPromiseResolver.h"
 | 
| +#include "bindings/core/v8/V8Binding.h"
 | 
| +#include "core/dom/DOMException.h"
 | 
|  #include "modules/payments/PaymentInstrument.h"
 | 
| +#include "modules/payments/PaymentManager.h"
 | 
| +#include "platform/wtf/Vector.h"
 | 
|  
 | 
|  namespace blink {
 | 
| +namespace {
 | 
| +
 | 
| +static const char kPaymentManagerUnavailable[] = "Payment manager unavailable";
 | 
| +
 | 
| +bool rejectError(ScriptPromiseResolver* resolver,
 | 
| +                 payments::mojom::blink::PaymentHandlerStatus status) {
 | 
| +  switch (status) {
 | 
| +    case payments::mojom::blink::PaymentHandlerStatus::SUCCESS:
 | 
| +      return false;
 | 
| +    case payments::mojom::blink::PaymentHandlerStatus::NOT_IMPLEMENTED:
 | 
| +      resolver->Reject(
 | 
| +          DOMException::Create(kNotSupportedError, "Not implemented yet"));
 | 
| +      return true;
 | 
| +    case payments::mojom::blink::PaymentHandlerStatus::NOT_FOUND:
 | 
| +      resolver->Reject(DOMException::Create(kNotFoundError,
 | 
| +                                            "There is no stored instrument"));
 | 
| +      return true;
 | 
| +    case payments::mojom::blink::PaymentHandlerStatus::NO_ACTIVE_WORKER:
 | 
| +      resolver->Reject(
 | 
| +          DOMException::Create(kInvalidStateError, "No active service worker"));
 | 
| +      return true;
 | 
| +    case payments::mojom::blink::PaymentHandlerStatus::STORAGE_OPERATION_FAILED:
 | 
| +      resolver->Reject(DOMException::Create(kInvalidStateError,
 | 
| +                                            "Storage operation is failed"));
 | 
| +      return true;
 | 
| +  }
 | 
| +  NOTREACHED();
 | 
| +  return false;
 | 
| +}
 | 
| +
 | 
| +}  // namespace
 | 
|  
 | 
| -PaymentInstruments::PaymentInstruments() {}
 | 
| +PaymentInstruments::PaymentInstruments(
 | 
| +    const payments::mojom::blink::PaymentManagerPtr& manager)
 | 
| +    : manager_(manager) {}
 | 
|  
 | 
|  ScriptPromise PaymentInstruments::deleteInstrument(
 | 
|      const String& instrument_key) {
 | 
| @@ -17,9 +58,22 @@ ScriptPromise PaymentInstruments::deleteInstrument(
 | 
|    return ScriptPromise();
 | 
|  }
 | 
|  
 | 
| -ScriptPromise PaymentInstruments::get(const String& instrument_key) {
 | 
| -  NOTIMPLEMENTED();
 | 
| -  return ScriptPromise();
 | 
| +ScriptPromise PaymentInstruments::get(ScriptState* script_state,
 | 
| +                                      const String& instrument_key) {
 | 
| +  if (!manager_.is_bound()) {
 | 
| +    return ScriptPromise::RejectWithDOMException(
 | 
| +        script_state,
 | 
| +        DOMException::Create(kInvalidStateError, kPaymentManagerUnavailable));
 | 
| +  }
 | 
| +
 | 
| +  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 | 
| +  ScriptPromise promise = resolver->Promise();
 | 
| +
 | 
| +  manager_->GetPaymentInstrument(
 | 
| +      instrument_key, ConvertToBaseCallback(WTF::Bind(
 | 
| +                          &PaymentInstruments::onGetPaymentInstrument,
 | 
| +                          WrapPersistent(this), WrapPersistent(resolver))));
 | 
| +  return promise;
 | 
|  }
 | 
|  
 | 
|  ScriptPromise PaymentInstruments::keys() {
 | 
| @@ -32,12 +86,90 @@ ScriptPromise PaymentInstruments::has(const String& instrument_key) {
 | 
|    return ScriptPromise();
 | 
|  }
 | 
|  
 | 
| -ScriptPromise PaymentInstruments::set(const String& instrument_key,
 | 
| -                                      const PaymentInstrument& details) {
 | 
| -  NOTIMPLEMENTED();
 | 
| -  return ScriptPromise();
 | 
| +ScriptPromise PaymentInstruments::set(ScriptState* script_state,
 | 
| +                                      const String& instrument_key,
 | 
| +                                      const PaymentInstrument& details,
 | 
| +                                      ExceptionState& exception_state) {
 | 
| +  if (!manager_.is_bound()) {
 | 
| +    return ScriptPromise::RejectWithDOMException(
 | 
| +        script_state,
 | 
| +        DOMException::Create(kInvalidStateError, kPaymentManagerUnavailable));
 | 
| +  }
 | 
| +
 | 
| +  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
 | 
| +  ScriptPromise promise = resolver->Promise();
 | 
| +
 | 
| +  payments::mojom::blink::PaymentInstrumentPtr instrument =
 | 
| +      payments::mojom::blink::PaymentInstrument::New();
 | 
| +  instrument->name = details.hasName() ? details.name() : WTF::g_empty_string;
 | 
| +  if (details.hasEnabledMethods()) {
 | 
| +    instrument->enabled_methods = details.enabledMethods();
 | 
| +  }
 | 
| +
 | 
| +  if (details.hasCapabilities()) {
 | 
| +    v8::Local<v8::String> value;
 | 
| +    if (!v8::JSON::Stringify(script_state->GetContext(),
 | 
| +                             details.capabilities().V8Value().As<v8::Object>())
 | 
| +             .ToLocal(&value)) {
 | 
| +      exception_state.ThrowTypeError(
 | 
| +          "Capabilities should be a JSON-serializable object");
 | 
| +      return exception_state.Reject(script_state);
 | 
| +    }
 | 
| +    instrument->stringified_capabilities = ToCoreString(value);
 | 
| +  } else {
 | 
| +    instrument->stringified_capabilities = WTF::g_empty_string;
 | 
| +  }
 | 
| +
 | 
| +  manager_->SetPaymentInstrument(
 | 
| +      instrument_key, std::move(instrument),
 | 
| +      ConvertToBaseCallback(
 | 
| +          WTF::Bind(&PaymentInstruments::onSetPaymentInstrument,
 | 
| +                    WrapPersistent(this), WrapPersistent(resolver))));
 | 
| +  return promise;
 | 
|  }
 | 
|  
 | 
|  DEFINE_TRACE(PaymentInstruments) {}
 | 
|  
 | 
| +void PaymentInstruments::onGetPaymentInstrument(
 | 
| +    ScriptPromiseResolver* resolver,
 | 
| +    payments::mojom::blink::PaymentInstrumentPtr stored_instrument,
 | 
| +    payments::mojom::blink::PaymentHandlerStatus status) {
 | 
| +  DCHECK(resolver);
 | 
| +  if (rejectError(resolver, status))
 | 
| +    return;
 | 
| +  PaymentInstrument instrument;
 | 
| +  instrument.setName(stored_instrument->name);
 | 
| +  Vector<String> enabled_methods;
 | 
| +  for (const auto& method : stored_instrument->enabled_methods) {
 | 
| +    enabled_methods.push_back(method);
 | 
| +  }
 | 
| +
 | 
| +  instrument.setEnabledMethods(enabled_methods);
 | 
| +  if (!stored_instrument->stringified_capabilities.IsEmpty()) {
 | 
| +    ScriptState::Scope scope(resolver->GetScriptState());
 | 
| +    ExceptionState exception_state(resolver->GetScriptState()->GetIsolate(),
 | 
| +                                   ExceptionState::kGetterContext,
 | 
| +                                   "PaymentInstruments", "get");
 | 
| +    instrument.setCapabilities(
 | 
| +        ScriptValue(resolver->GetScriptState(),
 | 
| +                    FromJSONString(resolver->GetScriptState()->GetIsolate(),
 | 
| +                                   stored_instrument->stringified_capabilities,
 | 
| +                                   exception_state)));
 | 
| +    if (exception_state.HadException()) {
 | 
| +      exception_state.Reject(resolver);
 | 
| +      return;
 | 
| +    }
 | 
| +  }
 | 
| +  resolver->Resolve(instrument);
 | 
| +}
 | 
| +
 | 
| +void PaymentInstruments::onSetPaymentInstrument(
 | 
| +    ScriptPromiseResolver* resolver,
 | 
| +    payments::mojom::blink::PaymentHandlerStatus status) {
 | 
| +  DCHECK(resolver);
 | 
| +  if (rejectError(resolver, status))
 | 
| +    return;
 | 
| +  resolver->Resolve();
 | 
| +}
 | 
| +
 | 
|  }  // namespace blink
 | 
| 
 |