Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/payments/PaymentRequestService.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/ClearOnShutdown.h"
8
#include "mozilla/dom/PaymentRequestParent.h"
9
#include "PaymentRequestService.h"
10
#include "BasicCardPayment.h"
11
#include "nsSimpleEnumerator.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
StaticRefPtr<PaymentRequestService> gPaymentService;
17
18
namespace {
19
20
class PaymentRequestEnumerator final : public nsSimpleEnumerator
21
{
22
public:
23
  NS_DECL_NSISIMPLEENUMERATOR
24
25
  PaymentRequestEnumerator()
26
    : mIndex(0)
27
0
  {}
28
29
  const nsID& DefaultInterface() override
30
0
  {
31
0
    return NS_GET_IID(nsIPaymentRequest);
32
0
  }
33
34
private:
35
  ~PaymentRequestEnumerator() override = default;
36
  uint32_t mIndex;
37
};
38
39
NS_IMETHODIMP
40
PaymentRequestEnumerator::HasMoreElements(bool* aReturn)
41
0
{
42
0
  NS_ENSURE_ARG_POINTER(aReturn);
43
0
  *aReturn = false;
44
0
  if (NS_WARN_IF(!gPaymentService)) {
45
0
    return NS_ERROR_FAILURE;
46
0
  }
47
0
  RefPtr<PaymentRequestService> service = gPaymentService;
48
0
  *aReturn = mIndex < service->NumPayments();
49
0
  return NS_OK;
50
0
}
51
52
NS_IMETHODIMP
53
PaymentRequestEnumerator::GetNext(nsISupports** aItem)
54
0
{
55
0
  NS_ENSURE_ARG_POINTER(aItem);
56
0
  if (NS_WARN_IF(!gPaymentService)) {
57
0
    return NS_ERROR_FAILURE;
58
0
  }
59
0
  RefPtr<payments::PaymentRequest> rowRequest =
60
0
    gPaymentService->GetPaymentRequestByIndex(mIndex);
61
0
  if (!rowRequest) {
62
0
    return NS_ERROR_FAILURE;
63
0
  }
64
0
  nsCOMPtr<nsIPaymentRequest> request = do_QueryInterface(rowRequest);
65
0
  mIndex++;
66
0
  request.forget(aItem);
67
0
  return NS_OK;
68
0
}
69
70
} // end of anonymous namespace
71
72
/* PaymentRequestService */
73
74
NS_IMPL_ISUPPORTS(PaymentRequestService,
75
                  nsIPaymentRequestService)
76
77
already_AddRefed<PaymentRequestService>
78
PaymentRequestService::GetSingleton()
79
0
{
80
0
  MOZ_ASSERT(NS_IsMainThread());
81
0
  if (!gPaymentService) {
82
0
    gPaymentService = new PaymentRequestService();
83
0
    ClearOnShutdown(&gPaymentService);
84
0
  }
85
0
  RefPtr<PaymentRequestService> service = gPaymentService;
86
0
  return service.forget();
87
0
}
88
89
uint32_t
90
PaymentRequestService::NumPayments() const
91
0
{
92
0
  return mRequestQueue.Length();
93
0
}
94
95
already_AddRefed<payments::PaymentRequest>
96
PaymentRequestService::GetPaymentRequestByIndex(const uint32_t aIndex)
97
0
{
98
0
  if (aIndex >= mRequestQueue.Length()) {
99
0
    return nullptr;
100
0
  }
101
0
  RefPtr<payments::PaymentRequest> request = mRequestQueue[aIndex];
102
0
  MOZ_ASSERT(request);
103
0
  return request.forget();
104
0
}
105
106
NS_IMETHODIMP
107
PaymentRequestService::GetPaymentRequestById(const nsAString& aRequestId,
108
                                             nsIPaymentRequest** aRequest)
109
0
{
110
0
  NS_ENSURE_ARG_POINTER(aRequest);
111
0
  *aRequest = nullptr;
112
0
  RefPtr<payments::PaymentRequest> rowRequest;
113
0
  nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(rowRequest));
114
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
115
0
    return rv;
116
0
  }
117
0
  nsCOMPtr<nsIPaymentRequest> request = do_QueryInterface(rowRequest);
118
0
  request.forget(aRequest);
119
0
  return NS_OK;
120
0
}
121
122
nsresult
123
PaymentRequestService::GetPaymentRequestById(const nsAString& aRequestId,
124
                                             payments::PaymentRequest** aRequest)
125
0
{
126
0
  NS_ENSURE_ARG_POINTER(aRequest);
127
0
  *aRequest = nullptr;
128
0
  uint32_t numRequests = mRequestQueue.Length();
129
0
  for (uint32_t index = 0; index < numRequests; ++index) {
130
0
    RefPtr<payments::PaymentRequest> request = mRequestQueue[index];
131
0
    MOZ_ASSERT(request);
132
0
    nsAutoString requestId;
133
0
    nsresult rv = request->GetRequestId(requestId);
134
0
    NS_ENSURE_SUCCESS(rv, rv);
135
0
    if (requestId == aRequestId) {
136
0
      request.forget(aRequest);
137
0
      break;
138
0
    }
139
0
  }
140
0
  return NS_OK;
141
0
}
142
143
NS_IMETHODIMP
144
PaymentRequestService::Enumerate(nsISimpleEnumerator** aEnumerator)
145
0
{
146
0
  NS_ENSURE_ARG_POINTER(aEnumerator);
147
0
  nsCOMPtr<nsISimpleEnumerator> enumerator = new PaymentRequestEnumerator();
148
0
  enumerator.forget(aEnumerator);
149
0
  return NS_OK;
150
0
}
151
152
NS_IMETHODIMP
153
PaymentRequestService::Cleanup()
154
0
{
155
0
  mRequestQueue.Clear();
156
0
  return NS_OK;
157
0
}
158
159
NS_IMETHODIMP
160
PaymentRequestService::SetTestingUIService(nsIPaymentUIService* aUIService)
161
0
{
162
0
  // aUIService can be nullptr
163
0
  mTestingUIService = aUIService;
164
0
  return NS_OK;
165
0
}
166
167
nsresult
168
PaymentRequestService::LaunchUIAction(const nsAString& aRequestId, uint32_t aActionType)
169
0
{
170
0
  nsCOMPtr<nsIPaymentUIService> uiService;
171
0
  nsresult rv;
172
0
  if (mTestingUIService) {
173
0
    uiService = mTestingUIService;
174
0
  } else {
175
0
    uiService = do_GetService(NS_PAYMENT_UI_SERVICE_CONTRACT_ID, &rv);
176
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
177
0
      return rv;
178
0
    }
179
0
  }
180
0
  switch (aActionType) {
181
0
    case IPCPaymentActionRequest::TIPCPaymentShowActionRequest:{
182
0
      rv = uiService->ShowPayment(aRequestId);
183
0
      break;
184
0
    }
185
0
    case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
186
0
      rv = uiService->AbortPayment(aRequestId);
187
0
      break;
188
0
    }
189
0
    case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
190
0
      rv = uiService->CompletePayment(aRequestId);
191
0
      break;
192
0
    }
193
0
    case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
194
0
      rv = uiService->UpdatePayment(aRequestId);
195
0
      break;
196
0
    }
197
0
    case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
198
0
      rv = uiService->ClosePayment(aRequestId);
199
0
      break;
200
0
    }
201
0
    default : {
202
0
      return NS_ERROR_FAILURE;
203
0
    }
204
0
  }
205
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
206
0
    return rv;
207
0
  }
208
0
  return NS_OK;
209
0
}
210
211
nsresult
212
PaymentRequestService::RequestPayment(const nsAString& aRequestId,
213
                                      const IPCPaymentActionRequest& aAction,
214
                                      PaymentRequestParent* aIPC)
215
0
{
216
0
  NS_ENSURE_ARG_POINTER(aIPC);
217
0
218
0
  nsresult rv = NS_OK;
219
0
  uint32_t type = aAction.type();
220
0
221
0
  RefPtr<payments::PaymentRequest> request;
222
0
  if (type != IPCPaymentActionRequest::TIPCPaymentCreateActionRequest) {
223
0
    rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
224
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
225
0
      return rv;
226
0
    }
227
0
    if (!request && type != IPCPaymentActionRequest::TIPCPaymentCloseActionRequest) {
228
0
      return NS_ERROR_FAILURE;
229
0
    }
230
0
    if (request) {
231
0
      request->SetIPC(aIPC);
232
0
    }
233
0
  }
234
0
235
0
  switch (type) {
236
0
    case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest: {
237
0
      MOZ_ASSERT(!request);
238
0
      const IPCPaymentCreateActionRequest& action = aAction;
239
0
      uint64_t tabId = aIPC->GetTabId();
240
0
      nsCOMPtr<nsIMutableArray> methodData = do_CreateInstance(NS_ARRAY_CONTRACTID);
241
0
      MOZ_ASSERT(methodData);
242
0
      for (IPCPaymentMethodData data : action.methodData()) {
243
0
        nsCOMPtr<nsIPaymentMethodData> method;
244
0
        rv = payments::PaymentMethodData::Create(data, getter_AddRefs(method));
245
0
        NS_ENSURE_SUCCESS(rv, rv);
246
0
        rv = methodData->AppendElement(method);
247
0
        NS_ENSURE_SUCCESS(rv, rv);
248
0
      }
249
0
      nsCOMPtr<nsIPaymentDetails> details;
250
0
      rv = payments::PaymentDetails::Create(action.details(), getter_AddRefs(details));
251
0
      NS_ENSURE_SUCCESS(rv, rv);
252
0
      nsCOMPtr<nsIPaymentOptions> options;
253
0
      rv = payments::PaymentOptions::Create(action.options(), getter_AddRefs(options));
254
0
      NS_ENSURE_SUCCESS(rv, rv);
255
0
      RefPtr<payments::PaymentRequest> request =
256
0
        new payments::PaymentRequest(tabId,
257
0
                                     aRequestId,
258
0
                                     action.topLevelPrincipal(),
259
0
                                     methodData,
260
0
                                     details,
261
0
                                     options,
262
0
                                     action.shippingOption());
263
0
264
0
      if (!mRequestQueue.AppendElement(request, mozilla::fallible)) {
265
0
        return NS_ERROR_OUT_OF_MEMORY;
266
0
      }
267
0
      break;
268
0
    }
269
0
    case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest: {
270
0
      nsCOMPtr<nsIPaymentCanMakeActionResponse> canMakeResponse =
271
0
        do_CreateInstance(NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID);
272
0
      MOZ_ASSERT(canMakeResponse);
273
0
      rv = canMakeResponse->Init(aRequestId,
274
0
                                 CanMakePayment(aRequestId));
275
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
276
0
        return rv;
277
0
      }
278
0
      rv = RespondPayment(canMakeResponse.get());
279
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
280
0
        return rv;
281
0
      }
282
0
      break;
283
0
    }
284
0
    case IPCPaymentActionRequest::TIPCPaymentShowActionRequest: {
285
0
      rv = ShowPayment(aRequestId);
286
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
287
0
        return rv;
288
0
      }
289
0
      break;
290
0
    }
291
0
    case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
292
0
      MOZ_ASSERT(request);
293
0
      request->SetState(payments::PaymentRequest::eInteractive);
294
0
      rv = LaunchUIAction(aRequestId, type);
295
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
296
0
        return rv;
297
0
      }
298
0
      break;
299
0
    }
300
0
    case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
301
0
      MOZ_ASSERT(request);
302
0
      const IPCPaymentCompleteActionRequest& action = aAction;
303
0
      request->SetCompleteStatus(action.completeStatus());
304
0
      rv = LaunchUIAction(aRequestId, type);
305
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
306
0
        return rv;
307
0
      }
308
0
      break;
309
0
    }
310
0
    case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
311
0
      const IPCPaymentUpdateActionRequest& action = aAction;
312
0
      nsCOMPtr<nsIPaymentDetails> details;
313
0
      rv = payments::PaymentDetails::Create(action.details(), getter_AddRefs(details));
314
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
315
0
        return rv;
316
0
      }
317
0
      MOZ_ASSERT(request);
318
0
      rv = request->UpdatePaymentDetails(details, action.shippingOption());
319
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
320
0
        return rv;
321
0
      }
322
0
323
0
      // mShowingRequest exists and it equals to the updated PaymentRequest
324
0
      // Call UI::UpdatePayment
325
0
      if (mShowingRequest && mShowingRequest == request) {
326
0
        rv = LaunchUIAction(aRequestId, type);
327
0
        if (NS_WARN_IF(NS_FAILED(rv))) {
328
0
          return rv;
329
0
        }
330
0
      } else {
331
0
        // mShowingRequest does not equal to the updated PaymentRequest, try to
332
0
        // show the updated one.
333
0
        rv = ShowPayment(aRequestId);
334
0
        if (NS_WARN_IF(NS_FAILED(rv))) {
335
0
          return rv;
336
0
        }
337
0
      }
338
0
      break;
339
0
    }
340
0
    case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
341
0
      rv = LaunchUIAction(aRequestId, type);
342
0
      if (NS_WARN_IF(NS_FAILED(rv))) {
343
0
        return rv;
344
0
      }
345
0
      if (mShowingRequest == request) {
346
0
        mShowingRequest = nullptr;
347
0
      }
348
0
      mRequestQueue.RemoveElement(request);
349
0
      break;
350
0
    }
351
0
    case IPCPaymentActionRequest::TIPCPaymentRetryActionRequest: {
352
0
      const IPCPaymentRetryActionRequest& action = aAction;
353
0
      MOZ_ASSERT(request);
354
0
      request->UpdateErrors(action.error(),
355
0
                            action.payerErrors(),
356
0
                            action.paymentMethodErrors(),
357
0
                            action.shippingAddressErrors());
358
0
      request->SetState(payments::PaymentRequest::eInteractive);
359
0
      MOZ_ASSERT(mShowingRequest == request);
360
0
      rv = LaunchUIAction(aRequestId,
361
0
                          IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest);
362
0
      break;
363
0
    }
364
0
    default: {
365
0
      return NS_ERROR_FAILURE;
366
0
    }
367
0
  }
368
0
  return NS_OK;
369
0
}
370
371
NS_IMETHODIMP
372
PaymentRequestService::RespondPayment(nsIPaymentActionResponse* aResponse)
373
0
{
374
0
  NS_ENSURE_ARG_POINTER(aResponse);
375
0
  nsAutoString requestId;
376
0
  nsresult rv = aResponse->GetRequestId(requestId);
377
0
  NS_ENSURE_SUCCESS(rv, rv);
378
0
379
0
  RefPtr<payments::PaymentRequest> request;
380
0
  rv = GetPaymentRequestById(requestId, getter_AddRefs(request));
381
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
382
0
    return rv;
383
0
  }
384
0
  if (!request) {
385
0
    return NS_ERROR_FAILURE;
386
0
  }
387
0
  uint32_t type;
388
0
  rv = aResponse->GetType(&type);
389
0
  NS_ENSURE_SUCCESS(rv, rv);
390
0
391
0
  // PaymentRequest can only be responded when
392
0
  // 1. the state is eInteractive
393
0
  // 2. the state is eClosed and response type is COMPLETE_ACTION
394
0
  // 3. the state is eCreated and response type is CANMAKE_ACTION
395
0
  payments::PaymentRequest::eState state = request->GetState();
396
0
  bool canBeResponded =
397
0
    (state == payments::PaymentRequest::eInteractive) ||
398
0
    (state == payments::PaymentRequest::eClosed &&
399
0
      type == nsIPaymentActionResponse::COMPLETE_ACTION) ||
400
0
    (state == payments::PaymentRequest::eCreated &&
401
0
      type == nsIPaymentActionResponse::CANMAKE_ACTION);
402
0
  if (!canBeResponded) {
403
0
    return NS_ERROR_FAILURE;
404
0
  }
405
0
406
0
  if (!request->GetIPC()) {
407
0
    return NS_ERROR_FAILURE;
408
0
  }
409
0
  rv = request->GetIPC()->RespondPayment(aResponse);
410
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
411
0
    return rv;
412
0
  }
413
0
414
0
  // Remove PaymentRequest from mRequestQueue while receive succeeded abort
415
0
  // response or complete response
416
0
  switch (type) {
417
0
    case nsIPaymentActionResponse::ABORT_ACTION: {
418
0
      nsCOMPtr<nsIPaymentAbortActionResponse> response =
419
0
        do_QueryInterface(aResponse);
420
0
      MOZ_ASSERT(response);
421
0
      bool isSucceeded;
422
0
      rv = response->IsSucceeded(&isSucceeded);
423
0
      NS_ENSURE_SUCCESS(rv, rv);
424
0
      mShowingRequest = nullptr;
425
0
      if (isSucceeded) {
426
0
        mRequestQueue.RemoveElement(request);
427
0
        request->SetState(payments::PaymentRequest::eClosed);
428
0
      }
429
0
      break;
430
0
    }
431
0
    case nsIPaymentActionResponse::SHOW_ACTION: {
432
0
      request->SetState(payments::PaymentRequest::eClosed);
433
0
      nsCOMPtr<nsIPaymentShowActionResponse> response =
434
0
        do_QueryInterface(aResponse);
435
0
      MOZ_ASSERT(response);
436
0
      uint32_t acceptStatus;
437
0
      rv = response->GetAcceptStatus(&acceptStatus);
438
0
      NS_ENSURE_SUCCESS(rv, rv);
439
0
      if (acceptStatus != nsIPaymentActionResponse::PAYMENT_ACCEPTED) {
440
0
        // Check if rejecting the showing PaymentRequest.
441
0
        // If yes, set mShowingRequest as nullptr.
442
0
        if (mShowingRequest == request) {
443
0
          mShowingRequest = nullptr;
444
0
        }
445
0
        mRequestQueue.RemoveElement(request);
446
0
      }
447
0
      break;
448
0
    }
449
0
    case nsIPaymentActionResponse::COMPLETE_ACTION: {
450
0
      mShowingRequest = nullptr;
451
0
      mRequestQueue.RemoveElement(request);
452
0
      break;
453
0
    }
454
0
    default: {
455
0
      break;
456
0
    }
457
0
  }
458
0
  return NS_OK;
459
0
}
460
461
NS_IMETHODIMP
462
PaymentRequestService::ChangeShippingAddress(const nsAString& aRequestId,
463
                                             nsIPaymentAddress* aAddress)
464
0
{
465
0
  RefPtr<payments::PaymentRequest> request;
466
0
  nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
467
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
468
0
    return rv;
469
0
  }
470
0
  if (!request) {
471
0
    return NS_ERROR_FAILURE;
472
0
  }
473
0
  if (request->GetState() != payments::PaymentRequest::eInteractive) {
474
0
    return NS_ERROR_FAILURE;
475
0
  }
476
0
  if (!request->GetIPC()) {
477
0
    return NS_ERROR_FAILURE;
478
0
  }
479
0
  rv = request->GetIPC()->ChangeShippingAddress(aRequestId, aAddress);
480
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
481
0
    return rv;
482
0
  }
483
0
  return NS_OK;
484
0
}
485
486
NS_IMETHODIMP
487
PaymentRequestService::ChangeShippingOption(const nsAString& aRequestId,
488
                                            const nsAString& aOption)
489
0
{
490
0
  RefPtr<payments::PaymentRequest> request;
491
0
  nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
492
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
493
0
    return rv;
494
0
  }
495
0
  if (!request) {
496
0
    return NS_ERROR_FAILURE;
497
0
  }
498
0
  if (request->GetState() != payments::PaymentRequest::eInteractive) {
499
0
    return NS_ERROR_FAILURE;
500
0
  }
501
0
  if (!request->GetIPC()) {
502
0
    return NS_ERROR_FAILURE;
503
0
  }
504
0
  rv = request->GetIPC()->ChangeShippingOption(aRequestId, aOption);
505
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
506
0
    return rv;
507
0
  }
508
0
  return NS_OK;
509
0
}
510
511
bool
512
PaymentRequestService::CanMakePayment(const nsAString& aRequestId)
513
0
{
514
0
  /*
515
0
   *  TODO: Check third party payment app support by traversing all
516
0
   *        registered third party payment apps.
517
0
   */
518
0
  return IsBasicCardPayment(aRequestId);
519
0
}
520
521
nsresult
522
PaymentRequestService::ShowPayment(const nsAString& aRequestId)
523
0
{
524
0
  nsresult rv;
525
0
  RefPtr<payments::PaymentRequest> request;
526
0
  rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
527
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
528
0
    return rv;
529
0
  }
530
0
  MOZ_ASSERT(request);
531
0
  request->SetState(payments::PaymentRequest::eInteractive);
532
0
533
0
  if (mShowingRequest || !CanMakePayment(aRequestId)) {
534
0
    uint32_t responseStatus;
535
0
    if (mShowingRequest) {
536
0
      responseStatus = nsIPaymentActionResponse::PAYMENT_REJECTED;
537
0
    } else {
538
0
      responseStatus = nsIPaymentActionResponse::PAYMENT_NOTSUPPORTED;
539
0
    }
540
0
    nsCOMPtr<nsIPaymentShowActionResponse> showResponse =
541
0
      do_CreateInstance(NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID);
542
0
    MOZ_ASSERT(showResponse);
543
0
    rv = showResponse->Init(aRequestId,
544
0
                            responseStatus,
545
0
                            EmptyString(),
546
0
                            nullptr,
547
0
                            EmptyString(),
548
0
                            EmptyString(),
549
0
                            EmptyString());
550
0
    rv = RespondPayment(showResponse.get());
551
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
552
0
        return rv;
553
0
    }
554
0
  } else {
555
0
    mShowingRequest = request;
556
0
    rv = LaunchUIAction(aRequestId,
557
0
                        IPCPaymentActionRequest::TIPCPaymentShowActionRequest);
558
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
559
0
      return rv;
560
0
    }
561
0
  }
562
0
  return NS_OK;
563
0
}
564
565
bool
566
PaymentRequestService::IsBasicCardPayment(const nsAString& aRequestId)
567
0
{
568
0
  RefPtr<payments::PaymentRequest> request;
569
0
  nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
570
0
  NS_ENSURE_SUCCESS(rv, false);
571
0
  nsCOMPtr<nsIArray> methods;
572
0
  rv = request->GetPaymentMethods(getter_AddRefs(methods));
573
0
  NS_ENSURE_SUCCESS(rv, false);
574
0
  uint32_t length;
575
0
  rv = methods->GetLength(&length);
576
0
  NS_ENSURE_SUCCESS(rv, false);
577
0
  RefPtr<BasicCardService> service = BasicCardService::GetService();
578
0
  MOZ_ASSERT(service);
579
0
  for (uint32_t index = 0; index < length; ++index) {
580
0
    nsCOMPtr<nsIPaymentMethodData> method = do_QueryElementAt(methods, index);
581
0
    MOZ_ASSERT(method);
582
0
    nsAutoString supportedMethods;
583
0
    rv = method->GetSupportedMethods(supportedMethods);
584
0
    NS_ENSURE_SUCCESS(rv, false);
585
0
    if (service->IsBasicCardPayment(supportedMethods)) {
586
0
      return true;
587
0
    }
588
0
  }
589
0
  return false;
590
0
}
591
592
NS_IMETHODIMP
593
PaymentRequestService::ChangePayerDetail(const nsAString& aRequestId,
594
                                         const nsAString& aPayerName,
595
                                         const nsAString& aPayerEmail,
596
                                         const nsAString& aPayerPhone)
597
0
{
598
0
  RefPtr<payments::PaymentRequest> request;
599
0
  nsresult rv = GetPaymentRequestById(aRequestId, getter_AddRefs(request));
600
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
601
0
    return rv;
602
0
  }
603
0
  MOZ_ASSERT(request);
604
0
  if (!request->GetIPC()) {
605
0
    return NS_ERROR_FAILURE;
606
0
  }
607
0
  rv = request->GetIPC()->ChangePayerDetail(
608
0
    aRequestId, aPayerName, aPayerEmail, aPayerPhone);
609
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
610
0
    return rv;
611
0
  }
612
0
  return NS_OK;
613
0
}
614
615
} // end of namespace dom
616
} // end of namespace mozilla