summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc
blob: 2e716071750a014c9664bac48c2c728ce3b1dc89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// 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 "third_party/blink/renderer/modules/payments/goods/digital_goods_service.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_item_details.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

using payments::mojom::blink::BillingResponseCode;

namespace {

void OnGetDetailsResponse(
    ScriptPromiseResolver* resolver,
    BillingResponseCode code,
    Vector<payments::mojom::blink::ItemDetailsPtr> item_details_list) {
  if (code != BillingResponseCode::kOk) {
    resolver->Reject(mojo::ConvertTo<String>(code));
    return;
  }
  HeapVector<Member<ItemDetails>> blink_item_details_list;
  for (const auto& detail : item_details_list)
    blink_item_details_list.push_back(detail.To<blink::ItemDetails*>());

  resolver->Resolve(std::move(blink_item_details_list));
}

void OnAcknowledgeResponse(ScriptPromiseResolver* resolver,
                           BillingResponseCode code) {
  if (code != BillingResponseCode::kOk) {
    resolver->Reject(mojo::ConvertTo<String>(code));
    return;
  }
  resolver->Resolve();
}

}  // namespace

DigitalGoodsService::DigitalGoodsService(ExecutionContext* context) {
  context->GetBrowserInterfaceBroker().GetInterface(
      mojo_service_.BindNewPipeAndPassReceiver());
  DCHECK(mojo_service_);
}

DigitalGoodsService::~DigitalGoodsService() = default;

ScriptPromise DigitalGoodsService::getDetails(ScriptState* script_state,
                                              const Vector<String>& item_ids) {
  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
  ScriptPromise promise = resolver->Promise();

  if (item_ids.IsEmpty()) {
    resolver->Reject(V8ThrowException::CreateTypeError(
        script_state->GetIsolate(), "Must specify at least one item ID."));
    return promise;
  }

  mojo_service_->GetDetails(
      item_ids, WTF::Bind(&OnGetDetailsResponse, WrapPersistent(resolver)));
  return promise;
}

ScriptPromise DigitalGoodsService::acknowledge(ScriptState* script_state,
                                               const String& purchase_token,
                                               const String& purchase_type) {
  auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
  ScriptPromise promise = resolver->Promise();

  if (purchase_token.IsEmpty()) {
    resolver->Reject(V8ThrowException::CreateTypeError(
        script_state->GetIsolate(), "Must specify purchase token."));
    return promise;
  }

  bool make_available_again = false;
  if (purchase_type == "repeatable") {
    make_available_again = true;
  } else if (purchase_type == "onetime") {
    make_available_again = false;
  } else {
    // Note: don't expect this error to be thrown in practice. IDL code should
    // enforce that purchase type is valid.
    resolver->Reject(V8ThrowException::CreateTypeError(
        script_state->GetIsolate(), "Invalid purchase type."));
    return promise;
  }

  mojo_service_->Acknowledge(
      purchase_token, make_available_again,
      WTF::Bind(&OnAcknowledgeResponse, WrapPersistent(resolver)));
  return promise;
}

void DigitalGoodsService::Trace(Visitor* visitor) const {
  ScriptWrappable::Trace(visitor);
}

}  // namespace blink