Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/payments/ipc/PaymentRequestParent.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/ipc/InputStreamUtils.h"
8
#include "nsArrayUtils.h"
9
#include "nsCOMPtr.h"
10
#include "nsIPaymentRequestService.h"
11
#include "nsISupportsPrimitives.h"
12
#include "nsServiceManagerUtils.h"
13
#include "PaymentRequestData.h"
14
#include "PaymentRequestParent.h"
15
#include "PaymentRequestService.h"
16
17
namespace mozilla {
18
namespace dom {
19
20
PaymentRequestParent::PaymentRequestParent(uint64_t aTabId)
21
  : mActorAlive(true)
22
  , mTabId(aTabId)
23
  , mRequestId(EmptyString())
24
0
{
25
0
}
26
27
mozilla::ipc::IPCResult
28
PaymentRequestParent::RecvRequestPayment(const IPCPaymentActionRequest& aRequest)
29
0
{
30
0
  if (!mActorAlive) {
31
0
    return IPC_FAIL_NO_REASON(this);
32
0
  }
33
0
  switch (aRequest.type()) {
34
0
    case IPCPaymentActionRequest::TIPCPaymentCreateActionRequest:{
35
0
      const IPCPaymentCreateActionRequest& request = aRequest;
36
0
      mRequestId = request.requestId();
37
0
      break;
38
0
    }
39
0
    case IPCPaymentActionRequest::TIPCPaymentCanMakeActionRequest:{
40
0
      const IPCPaymentCanMakeActionRequest& request = aRequest;
41
0
      mRequestId = request.requestId();
42
0
      break;
43
0
    }
44
0
    case IPCPaymentActionRequest::TIPCPaymentShowActionRequest:{
45
0
      const IPCPaymentShowActionRequest& request = aRequest;
46
0
      mRequestId = request.requestId();
47
0
      break;
48
0
    }
49
0
    case IPCPaymentActionRequest::TIPCPaymentAbortActionRequest: {
50
0
      const IPCPaymentAbortActionRequest& request = aRequest;
51
0
      mRequestId = request.requestId();
52
0
      break;
53
0
    }
54
0
    case IPCPaymentActionRequest::TIPCPaymentCompleteActionRequest: {
55
0
      const IPCPaymentCompleteActionRequest& request = aRequest;
56
0
      mRequestId = request.requestId();
57
0
      break;
58
0
    }
59
0
    case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
60
0
      const IPCPaymentUpdateActionRequest& request = aRequest;
61
0
      mRequestId = request.requestId();
62
0
      break;
63
0
    }
64
0
    case IPCPaymentActionRequest::TIPCPaymentCloseActionRequest: {
65
0
      const IPCPaymentCloseActionRequest& request = aRequest;
66
0
      mRequestId = request.requestId();
67
0
      break;
68
0
    }
69
0
    case IPCPaymentActionRequest::TIPCPaymentRetryActionRequest: {
70
0
      const IPCPaymentRetryActionRequest& request = aRequest;
71
0
      mRequestId = request.requestId();
72
0
      break;
73
0
    }
74
0
    default : {
75
0
      return IPC_FAIL(this, "Unknown PaymentRequest action type");
76
0
    }
77
0
  }
78
0
  nsCOMPtr<nsIPaymentRequestService> service =
79
0
    do_GetService(NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID);
80
0
  MOZ_ASSERT(service);
81
0
  PaymentRequestService* rowService =
82
0
    static_cast<PaymentRequestService*>(service.get());
83
0
  MOZ_ASSERT(rowService);
84
0
  nsresult rv = rowService->RequestPayment(mRequestId, aRequest, this);
85
0
  if (NS_WARN_IF(NS_FAILED(rv))) {
86
0
    return IPC_FAIL(this, "nsIPaymentRequestService::RequestPayment failed");
87
0
  }
88
0
  return IPC_OK();
89
0
}
90
91
uint64_t
92
PaymentRequestParent::GetTabId()
93
0
{
94
0
  return mTabId;
95
0
}
96
97
nsresult
98
PaymentRequestParent::RespondPayment(nsIPaymentActionResponse* aResponse)
99
0
{
100
0
  if (!NS_IsMainThread()) {
101
0
    RefPtr<PaymentRequestParent> self = this;
102
0
    nsCOMPtr<nsIPaymentActionResponse> response = aResponse;
103
0
    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("PaymentRequestParent::RespondPayment",
104
0
                                                     [self, response] ()
105
0
    {
106
0
      self->RespondPayment(response);
107
0
    });
108
0
    return NS_DispatchToMainThread(r);
109
0
  }
110
0
111
0
  if (!mActorAlive) {
112
0
    return NS_ERROR_FAILURE;
113
0
  }
114
0
  uint32_t type;
115
0
  nsresult rv = aResponse->GetType(&type);
116
0
  NS_ENSURE_SUCCESS(rv, rv);
117
0
  nsAutoString requestId;
118
0
  rv = aResponse->GetRequestId(requestId);
119
0
  NS_ENSURE_SUCCESS(rv, rv);
120
0
  switch (type) {
121
0
    case nsIPaymentActionResponse::CANMAKE_ACTION: {
122
0
      nsCOMPtr<nsIPaymentCanMakeActionResponse> response = do_QueryInterface(aResponse);
123
0
      MOZ_ASSERT(response);
124
0
      bool result;
125
0
      rv = response->GetResult(&result);
126
0
      NS_ENSURE_SUCCESS(rv, rv);
127
0
      IPCPaymentCanMakeActionResponse actionResponse(requestId, result);
128
0
      if (!SendRespondPayment(actionResponse)) {
129
0
        return NS_ERROR_FAILURE;
130
0
      }
131
0
      break;
132
0
    }
133
0
    case nsIPaymentActionResponse::SHOW_ACTION: {
134
0
      nsCOMPtr<nsIPaymentShowActionResponse> response =
135
0
        do_QueryInterface(aResponse);
136
0
      MOZ_ASSERT(response);
137
0
      uint32_t acceptStatus;
138
0
      NS_ENSURE_SUCCESS(response->GetAcceptStatus(&acceptStatus), NS_ERROR_FAILURE);
139
0
      nsAutoString methodName;
140
0
      NS_ENSURE_SUCCESS(response->GetMethodName(methodName), NS_ERROR_FAILURE);
141
0
      nsAutoString data;
142
0
      NS_ENSURE_SUCCESS(response->GetData(data), NS_ERROR_FAILURE);
143
0
      nsAutoString payerName;
144
0
      NS_ENSURE_SUCCESS(response->GetPayerName(payerName), NS_ERROR_FAILURE);
145
0
      nsAutoString payerEmail;
146
0
      NS_ENSURE_SUCCESS(response->GetPayerEmail(payerEmail), NS_ERROR_FAILURE);
147
0
      nsAutoString payerPhone;
148
0
      NS_ENSURE_SUCCESS(response->GetPayerPhone(payerPhone), NS_ERROR_FAILURE);
149
0
      IPCPaymentShowActionResponse actionResponse(requestId,
150
0
                                                  acceptStatus,
151
0
                                                  methodName,
152
0
                                                  data,
153
0
                                                  payerName,
154
0
                                                  payerEmail,
155
0
                                                  payerPhone);
156
0
      if (!SendRespondPayment(actionResponse)) {
157
0
        return NS_ERROR_FAILURE;
158
0
      }
159
0
      break;
160
0
    }
161
0
    case nsIPaymentActionResponse::ABORT_ACTION: {
162
0
      nsCOMPtr<nsIPaymentAbortActionResponse> response =
163
0
        do_QueryInterface(aResponse);
164
0
      MOZ_ASSERT(response);
165
0
      bool isSucceeded;
166
0
      rv = response->IsSucceeded(&isSucceeded);
167
0
      NS_ENSURE_SUCCESS(rv, rv);
168
0
      IPCPaymentAbortActionResponse actionResponse(requestId, isSucceeded);
169
0
      if (!SendRespondPayment(actionResponse)) {
170
0
        return NS_ERROR_FAILURE;
171
0
      }
172
0
      break;
173
0
    }
174
0
    case nsIPaymentActionResponse::COMPLETE_ACTION: {
175
0
      nsCOMPtr<nsIPaymentCompleteActionResponse> response =
176
0
        do_QueryInterface(aResponse);
177
0
      MOZ_ASSERT(response);
178
0
      bool isCompleted;
179
0
      rv = response->IsCompleted(&isCompleted);
180
0
      NS_ENSURE_SUCCESS(rv, rv);
181
0
      IPCPaymentCompleteActionResponse actionResponse(requestId, isCompleted);
182
0
      if (!SendRespondPayment(actionResponse)) {
183
0
        return NS_ERROR_FAILURE;
184
0
      }
185
0
      break;
186
0
    }
187
0
    default: {
188
0
      return NS_ERROR_FAILURE;
189
0
    }
190
0
  }
191
0
  return NS_OK;
192
0
}
193
194
nsresult
195
PaymentRequestParent::ChangeShippingAddress(const nsAString& aRequestId,
196
                                            nsIPaymentAddress* aAddress)
197
0
{
198
0
  if (!NS_IsMainThread()) {
199
0
    RefPtr<PaymentRequestParent> self = this;
200
0
    nsCOMPtr<nsIPaymentAddress> address = aAddress;
201
0
    nsAutoString requestId(aRequestId);
202
0
    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("dom::PaymentRequestParent::ChangeShippingAddress",
203
0
                                                     [self, requestId, address] ()
204
0
    {
205
0
      self->ChangeShippingAddress(requestId, address);
206
0
    });
207
0
    return NS_DispatchToMainThread(r);
208
0
  }
209
0
  if (!mActorAlive) {
210
0
    return NS_ERROR_FAILURE;
211
0
  }
212
0
  nsAutoString country;
213
0
  nsresult rv = aAddress->GetCountry(country);
214
0
  NS_ENSURE_SUCCESS(rv, rv);
215
0
216
0
  nsCOMPtr<nsIArray> iaddressLine;
217
0
  rv = aAddress->GetAddressLine(getter_AddRefs(iaddressLine));
218
0
  NS_ENSURE_SUCCESS(rv, rv);
219
0
220
0
  nsAutoString region;
221
0
  rv = aAddress->GetRegion(region);
222
0
  NS_ENSURE_SUCCESS(rv, rv);
223
0
224
0
  nsAutoString city;
225
0
  rv = aAddress->GetCity(city);
226
0
  NS_ENSURE_SUCCESS(rv, rv);
227
0
228
0
  nsAutoString dependentLocality;
229
0
  rv = aAddress->GetDependentLocality(dependentLocality);
230
0
  NS_ENSURE_SUCCESS(rv, rv);
231
0
232
0
  nsAutoString postalCode;
233
0
  rv = aAddress->GetPostalCode(postalCode);
234
0
  NS_ENSURE_SUCCESS(rv, rv);
235
0
236
0
  nsAutoString sortingCode;
237
0
  rv = aAddress->GetSortingCode(sortingCode);
238
0
  NS_ENSURE_SUCCESS(rv, rv);
239
0
240
0
  nsAutoString organization;
241
0
  rv = aAddress->GetOrganization(organization);
242
0
  NS_ENSURE_SUCCESS(rv, rv);
243
0
244
0
  nsAutoString recipient;
245
0
  rv = aAddress->GetRecipient(recipient);
246
0
  NS_ENSURE_SUCCESS(rv, rv);
247
0
248
0
  nsAutoString phone;
249
0
  rv = aAddress->GetPhone(phone);
250
0
  NS_ENSURE_SUCCESS(rv, rv);
251
0
252
0
  nsTArray<nsString> addressLine;
253
0
  uint32_t length;
254
0
  rv = iaddressLine->GetLength(&length);
255
0
  NS_ENSURE_SUCCESS(rv, rv);
256
0
  for (uint32_t index = 0; index < length; ++index) {
257
0
    nsCOMPtr<nsISupportsString> iaddress = do_QueryElementAt(iaddressLine, index);
258
0
    MOZ_ASSERT(iaddress);
259
0
    nsAutoString address;
260
0
    rv = iaddress->GetData(address);
261
0
    NS_ENSURE_SUCCESS(rv, rv);
262
0
    addressLine.AppendElement(address);
263
0
  }
264
0
265
0
  IPCPaymentAddress ipcAddress(country, addressLine, region, city,
266
0
                               dependentLocality, postalCode, sortingCode,
267
0
                               organization, recipient, phone);
268
0
269
0
  nsAutoString requestId(aRequestId);
270
0
  if (!SendChangeShippingAddress(requestId, ipcAddress)) {
271
0
    return NS_ERROR_FAILURE;
272
0
  }
273
0
  return NS_OK;
274
0
}
275
276
nsresult
277
PaymentRequestParent::ChangeShippingOption(const nsAString& aRequestId,
278
                                           const nsAString& aOption)
279
0
{
280
0
  if (!NS_IsMainThread()) {
281
0
    RefPtr<PaymentRequestParent> self = this;
282
0
    nsAutoString requestId(aRequestId);
283
0
    nsAutoString option(aOption);
284
0
    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("dom::PaymentRequestParent::ChangeShippingOption",
285
0
                                                     [self, requestId, option] ()
286
0
    {
287
0
      self->ChangeShippingOption(requestId, option);
288
0
    });
289
0
    return NS_DispatchToMainThread(r);
290
0
  }
291
0
  if (!mActorAlive) {
292
0
    return NS_ERROR_FAILURE;
293
0
  }
294
0
  nsAutoString requestId(aRequestId);
295
0
  nsAutoString option(aOption);
296
0
  if (!SendChangeShippingOption(requestId, option)) {
297
0
    return NS_ERROR_FAILURE;
298
0
  }
299
0
  return NS_OK;
300
0
}
301
302
nsresult
303
PaymentRequestParent::ChangePayerDetail(const nsAString& aRequestId,
304
                                        const nsAString& aPayerName,
305
                                        const nsAString& aPayerEmail,
306
                                        const nsAString& aPayerPhone)
307
0
{
308
0
  nsAutoString requestId(aRequestId);
309
0
  nsAutoString payerName(aPayerName);
310
0
  nsAutoString payerEmail(aPayerEmail);
311
0
  nsAutoString payerPhone(aPayerPhone);
312
0
  if (!NS_IsMainThread()) {
313
0
    RefPtr<PaymentRequestParent> self = this;
314
0
    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction("dom::PaymentRequestParent::ChangePayerDetail",
315
0
                                                     [self, requestId, payerName, payerEmail, payerPhone] ()
316
0
    {
317
0
      self->ChangePayerDetail(requestId, payerName, payerEmail, payerPhone);
318
0
    });
319
0
    return NS_DispatchToMainThread(r);
320
0
  }
321
0
  if (!mActorAlive) {
322
0
    return NS_ERROR_FAILURE;
323
0
  }
324
0
  if (!SendChangePayerDetail(requestId, payerName, payerEmail, payerPhone)) {
325
0
    return NS_ERROR_FAILURE;
326
0
  }
327
0
  return NS_OK;
328
0
}
329
330
mozilla::ipc::IPCResult
331
PaymentRequestParent::Recv__delete__()
332
0
{
333
0
  mActorAlive = false;
334
0
  return IPC_OK();
335
0
}
336
337
void
338
PaymentRequestParent::ActorDestroy(ActorDestroyReason aWhy)
339
0
{
340
0
  mActorAlive = false;
341
0
  nsCOMPtr<nsIPaymentRequestService> service =
342
0
    do_GetService(NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID);
343
0
  MOZ_ASSERT(service);
344
0
  if (!mRequestId.Equals(EmptyString())) {
345
0
    nsCOMPtr<nsIPaymentRequest> request;
346
0
    nsresult rv = service->GetPaymentRequestById(mRequestId, getter_AddRefs(request));
347
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
348
0
      return;
349
0
    }
350
0
    if (!request) {
351
0
      return;
352
0
    }
353
0
    payments::PaymentRequest* rowRequest =
354
0
      static_cast<payments::PaymentRequest*>(request.get());
355
0
    MOZ_ASSERT(rowRequest);
356
0
    rowRequest->SetIPC(nullptr);
357
0
  }
358
0
}
359
} // end of namespace dom
360
} // end of namespace mozilla