LCOV - code coverage report
Current view: top level - dom/payments - PaymentRequestService.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 243 0.4 %
Date: 2017-07-14 16:53:18 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim:set ts=2 sw=2 sts=2 et cindent: */
       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 "PaymentRequestData.h"
       9             : #include "PaymentRequestService.h"
      10             : 
      11             : namespace mozilla {
      12             : namespace dom {
      13             : 
      14           3 : StaticRefPtr<PaymentRequestService> gPaymentService;
      15             : 
      16             : namespace {
      17             : 
      18             : class PaymentRequestEnumerator final : public nsISimpleEnumerator
      19             : {
      20             : public:
      21             :   NS_DECL_ISUPPORTS
      22             :   NS_DECL_NSISIMPLEENUMERATOR
      23             : 
      24           0 :   PaymentRequestEnumerator()
      25           0 :     : mIndex(0)
      26           0 :   {}
      27             : private:
      28             :   ~PaymentRequestEnumerator() = default;
      29             :   uint32_t mIndex;
      30             : };
      31             : 
      32           0 : NS_IMPL_ISUPPORTS(PaymentRequestEnumerator, nsISimpleEnumerator)
      33             : 
      34             : NS_IMETHODIMP
      35           0 : PaymentRequestEnumerator::HasMoreElements(bool* aReturn)
      36             : {
      37           0 :   NS_ENSURE_ARG_POINTER(aReturn);
      38           0 :   *aReturn = false;
      39           0 :   if (NS_WARN_IF(!gPaymentService)) {
      40           0 :     return NS_ERROR_FAILURE;
      41             :   }
      42           0 :   RefPtr<PaymentRequestService> service = gPaymentService;
      43           0 :   *aReturn = mIndex < service->NumPayments();
      44           0 :   return NS_OK;
      45             : }
      46             : 
      47             : NS_IMETHODIMP
      48           0 : PaymentRequestEnumerator::GetNext(nsISupports** aItem)
      49             : {
      50           0 :   NS_ENSURE_ARG_POINTER(aItem);
      51           0 :   if (NS_WARN_IF(!gPaymentService)) {
      52           0 :     return NS_ERROR_FAILURE;
      53             :   }
      54             :   nsCOMPtr<nsIPaymentRequest> request =
      55           0 :     gPaymentService->GetPaymentRequestByIndex(mIndex);
      56           0 :   if (NS_WARN_IF(!request)) {
      57           0 :     return NS_ERROR_FAILURE;
      58             :   }
      59           0 :   nsCOMPtr<nsISupports> item = do_QueryInterface(request);
      60           0 :   if (NS_WARN_IF(!item)) {
      61           0 :     return NS_ERROR_FAILURE;
      62             :   }
      63           0 :   mIndex++;
      64           0 :   item.forget(aItem);
      65           0 :   return NS_OK;
      66             : }
      67             : 
      68             : } // end of anonymous namespace
      69             : 
      70             : /* PaymentRequestService */
      71             : 
      72           0 : NS_IMPL_ISUPPORTS(PaymentRequestService,
      73             :                   nsIPaymentRequestService)
      74             : 
      75             : already_AddRefed<PaymentRequestService>
      76           0 : PaymentRequestService::GetSingleton()
      77             : {
      78           0 :   MOZ_ASSERT(NS_IsMainThread());
      79           0 :   if (!gPaymentService) {
      80           0 :     gPaymentService = new PaymentRequestService();
      81           0 :     ClearOnShutdown(&gPaymentService);
      82             :   }
      83           0 :   RefPtr<PaymentRequestService> service = gPaymentService;
      84           0 :   return service.forget();
      85             : }
      86             : 
      87             : uint32_t
      88           0 : PaymentRequestService::NumPayments() const
      89             : {
      90           0 :   return mRequestQueue.Length();
      91             : }
      92             : 
      93             : already_AddRefed<nsIPaymentRequest>
      94           0 : PaymentRequestService::GetPaymentRequestByIndex(const uint32_t aIndex)
      95             : {
      96           0 :   if (aIndex >= mRequestQueue.Length()) {
      97           0 :     return nullptr;
      98             :   }
      99           0 :   nsCOMPtr<nsIPaymentRequest> request = mRequestQueue[aIndex];
     100           0 :   MOZ_ASSERT(request);
     101           0 :   return request.forget();
     102             : }
     103             : 
     104             : NS_IMETHODIMP
     105           0 : PaymentRequestService::GetPaymentRequestById(const nsAString& aRequestId,
     106             :                                              nsIPaymentRequest** aRequest)
     107             : {
     108           0 :   NS_ENSURE_ARG_POINTER(aRequest);
     109           0 :   *aRequest = nullptr;
     110           0 :   uint32_t numRequests = mRequestQueue.Length();
     111           0 :   for (uint32_t index = 0; index < numRequests; ++index) {
     112           0 :     nsCOMPtr<nsIPaymentRequest> request = mRequestQueue[index];
     113           0 :     MOZ_ASSERT(request);
     114           0 :     nsAutoString requestId;
     115           0 :     nsresult rv = request->GetRequestId(requestId);
     116           0 :     NS_ENSURE_SUCCESS(rv, rv);
     117           0 :     if (requestId == aRequestId) {
     118           0 :       request.forget(aRequest);
     119           0 :       break;
     120             :     }
     121             :   }
     122           0 :   return NS_OK;
     123             : }
     124             : 
     125             : NS_IMETHODIMP
     126           0 : PaymentRequestService::Enumerate(nsISimpleEnumerator** aEnumerator)
     127             : {
     128           0 :   NS_ENSURE_ARG_POINTER(aEnumerator);
     129           0 :   nsCOMPtr<nsISimpleEnumerator> enumerator = new PaymentRequestEnumerator();
     130           0 :   enumerator.forget(aEnumerator);
     131           0 :   return NS_OK;
     132             : }
     133             : 
     134             : NS_IMETHODIMP
     135           0 : PaymentRequestService::Cleanup()
     136             : {
     137           0 :   mRequestQueue.Clear();
     138           0 :   return NS_OK;
     139             : }
     140             : 
     141             : NS_IMETHODIMP
     142           0 : PaymentRequestService::SetTestingUIService(nsIPaymentUIService* aUIService)
     143             : {
     144             :   // aUIService can be nullptr
     145           0 :   mTestingUIService = aUIService;
     146           0 :   return NS_OK;
     147             : }
     148             : 
     149             : nsresult
     150           0 : PaymentRequestService::CallTestingUIAction(const nsAString& aRequestId, uint32_t aActionType)
     151             : {
     152           0 :   nsCOMPtr<nsIPaymentActionResponse> response;
     153             :   nsresult rv;
     154           0 :   if (mTestingUIService) {
     155           0 :     switch (aActionType) {
     156             :       case nsIPaymentActionRequest::CANMAKE_ACTION: {
     157           0 :         rv = mTestingUIService->CanMakePayment(aRequestId, getter_AddRefs(response));
     158           0 :         break;
     159             :       }
     160             :       case nsIPaymentActionRequest::SHOW_ACTION: {
     161           0 :         rv = mTestingUIService->ShowPayment(aRequestId, getter_AddRefs(response));
     162           0 :         break;
     163             :       }
     164             :       case nsIPaymentActionRequest::ABORT_ACTION: {
     165           0 :         rv = mTestingUIService->AbortPayment(aRequestId, getter_AddRefs(response));
     166           0 :         break;
     167             :       }
     168             :       case nsIPaymentActionRequest::COMPLETE_ACTION: {
     169           0 :         rv = mTestingUIService->CompletePayment(aRequestId, getter_AddRefs(response));
     170           0 :         break;
     171             :       }
     172             :       case nsIPaymentActionRequest::UPDATE_ACTION: {
     173           0 :         rv = mTestingUIService->UpdatePayment(aRequestId, getter_AddRefs(response));
     174           0 :         break;
     175             :       }
     176             :       default : {
     177           0 :         return NS_ERROR_FAILURE;
     178             :       }
     179             :     }
     180           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     181           0 :       return rv;
     182             :     }
     183             :   } else {
     184             :     // Since there is no UI implementation and no testing UI Service is registered,
     185             :     // set false response for canMakePayment(), ABORT_SUCCEEDED for abort() and
     186             :     // COMPLETE_SUCCEEDED for complete().
     187           0 :     switch (aActionType) {
     188             :       case nsIPaymentActionRequest::CANMAKE_ACTION: {
     189             :         nsCOMPtr<nsIPaymentCanMakeActionResponse> canMakeResponse =
     190           0 :           do_CreateInstance(NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID);
     191           0 :         MOZ_ASSERT(canMakeResponse);
     192           0 :         rv = canMakeResponse->Init(aRequestId, false);
     193           0 :         NS_ENSURE_SUCCESS(rv, rv);
     194           0 :         response = do_QueryInterface(canMakeResponse);
     195           0 :         MOZ_ASSERT(response);
     196           0 :         break;
     197             :       }
     198             :       case nsIPaymentActionRequest::ABORT_ACTION: {
     199             :         nsCOMPtr<nsIPaymentAbortActionResponse> abortResponse =
     200           0 :           do_CreateInstance(NS_PAYMENT_ABORT_ACTION_RESPONSE_CONTRACT_ID);
     201           0 :         MOZ_ASSERT(abortResponse);
     202           0 :         rv = abortResponse->Init(aRequestId, nsIPaymentActionResponse::ABORT_SUCCEEDED);
     203           0 :         NS_ENSURE_SUCCESS(rv, rv);
     204           0 :         response = do_QueryInterface(abortResponse);
     205           0 :         MOZ_ASSERT(response);
     206           0 :         break;
     207             :       }
     208             :       case nsIPaymentActionRequest::COMPLETE_ACTION: {
     209             :         nsCOMPtr<nsIPaymentCompleteActionResponse> completeResponse =
     210           0 :           do_CreateInstance(NS_PAYMENT_COMPLETE_ACTION_RESPONSE_CONTRACT_ID);
     211           0 :         MOZ_ASSERT(completeResponse);
     212           0 :         rv = completeResponse->Init(aRequestId, nsIPaymentActionResponse::COMPLETE_SUCCEEDED);
     213           0 :         NS_ENSURE_SUCCESS(rv, rv);
     214           0 :         response = do_QueryInterface(completeResponse);
     215           0 :         MOZ_ASSERT(response);
     216           0 :         break;
     217             :       }
     218             :       default : {
     219           0 :         break;
     220             :       }
     221             :     }
     222             :   }
     223           0 :   if (response) {
     224           0 :     rv = RespondPayment(response);
     225           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     226           0 :       return rv;
     227             :     }
     228             :   }
     229           0 :   return NS_OK;
     230             : }
     231             : 
     232             : NS_IMETHODIMP
     233           0 : PaymentRequestService::RemoveActionCallback(nsIPaymentActionCallback* aCallback)
     234             : {
     235           0 :   NS_ENSURE_ARG_POINTER(aCallback);
     236           0 :   for (auto iter = mCallbackHashtable.Iter(); !iter.Done(); iter.Next()) {
     237           0 :     nsCOMPtr<nsIPaymentActionCallback> callback = iter.Data();
     238           0 :     MOZ_ASSERT(callback);
     239           0 :     if (callback == aCallback) {
     240           0 :       iter.Remove();
     241           0 :       return NS_OK;
     242             :     }
     243             :   }
     244           0 :   return NS_OK;
     245             : }
     246             : 
     247             : NS_IMETHODIMP
     248           0 : PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
     249             : {
     250           0 :   NS_ENSURE_ARG_POINTER(aRequest);
     251             : 
     252           0 :   nsAutoString requestId;
     253           0 :   nsresult rv = aRequest->GetRequestId(requestId);
     254           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     255           0 :     return rv;
     256             :   }
     257           0 :   nsCOMPtr<nsIPaymentActionCallback> callback;
     258           0 :   rv = aRequest->GetCallback(getter_AddRefs(callback));
     259           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     260           0 :     return rv;
     261             :   }
     262           0 :   rv = SetActionCallback(requestId, callback);
     263           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     264           0 :     return rv;
     265             :   }
     266             : 
     267             :   uint32_t type;
     268           0 :   rv = aRequest->GetType(&type);
     269           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     270           0 :     return rv;
     271             :   }
     272             : 
     273           0 :   switch (type) {
     274             :     case nsIPaymentActionRequest::CREATE_ACTION: {
     275             :       nsCOMPtr<nsIPaymentCreateActionRequest> request =
     276           0 :         do_QueryInterface(aRequest);
     277           0 :       MOZ_ASSERT(request);
     278             :       uint64_t tabId;
     279           0 :       rv = request->GetTabId(&tabId);
     280           0 :       NS_ENSURE_SUCCESS(rv, rv);
     281             : 
     282           0 :       nsCOMPtr<nsIArray> methodData;
     283           0 :       rv = request->GetMethodData(getter_AddRefs(methodData));
     284           0 :       NS_ENSURE_SUCCESS(rv, rv);
     285             : 
     286           0 :       nsCOMPtr<nsIPaymentDetails> details;
     287           0 :       rv = request->GetDetails(getter_AddRefs(details));
     288           0 :       NS_ENSURE_SUCCESS(rv, rv);
     289             : 
     290           0 :       nsCOMPtr<nsIPaymentOptions> options;
     291           0 :       rv = request->GetOptions(getter_AddRefs(options));
     292           0 :       NS_ENSURE_SUCCESS(rv, rv);
     293             : 
     294             :       nsCOMPtr<nsIPaymentRequest> payment =
     295           0 :         new payments::PaymentRequest(tabId, requestId, methodData, details, options);
     296             : 
     297           0 :       if (!mRequestQueue.AppendElement(payment, mozilla::fallible)) {
     298           0 :         return NS_ERROR_OUT_OF_MEMORY;
     299             :       }
     300           0 :       break;
     301             :     }
     302             :     /*
     303             :      *  TODO: 1. Check basic card support once the Basic Card Payment spec is
     304             :      *           implemented.
     305             :      *           https://www.w3.org/TR/payment-method-basic-card/
     306             :      *        2. Check third party payment app support by traversing all
     307             :      *           registered third party payment apps.
     308             :      */
     309             :     case nsIPaymentActionRequest::CANMAKE_ACTION:
     310             :     /*
     311             :      *  TODO: Launch/inform payment UI here once the UI module is implemented.
     312             :      */
     313             :     case nsIPaymentActionRequest::SHOW_ACTION:
     314             :     case nsIPaymentActionRequest::ABORT_ACTION:
     315             :     case nsIPaymentActionRequest::COMPLETE_ACTION: {
     316           0 :       rv = CallTestingUIAction(requestId, type);
     317           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     318           0 :         return NS_ERROR_FAILURE;
     319             :       }
     320           0 :       break;
     321             :     }
     322             :     case nsIPaymentActionRequest::UPDATE_ACTION: {
     323           0 :       nsCOMPtr<nsIPaymentUpdateActionRequest> request = do_QueryInterface(aRequest);
     324           0 :       MOZ_ASSERT(request);
     325             : 
     326           0 :       nsCOMPtr<nsIPaymentDetails> details;
     327           0 :       rv = request->GetDetails(getter_AddRefs(details));
     328           0 :       NS_ENSURE_SUCCESS(rv, rv);
     329             : 
     330           0 :       rv = request->GetRequestId(requestId);
     331           0 :       NS_ENSURE_SUCCESS(rv, rv);
     332           0 :       nsCOMPtr<nsIPaymentRequest> payment;
     333           0 :       rv = GetPaymentRequestById(requestId, getter_AddRefs(payment));
     334           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     335           0 :         return rv;
     336             :       }
     337           0 :       rv = payment->UpdatePaymentDetails(details);
     338           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     339           0 :         return rv;
     340             :       }
     341           0 :       rv = CallTestingUIAction(requestId, type);
     342           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
     343           0 :         return NS_ERROR_FAILURE;
     344             :       }
     345           0 :       break;
     346             :     }
     347             :     default: {
     348           0 :       return NS_ERROR_FAILURE;
     349             :     }
     350             :   }
     351           0 :   return NS_OK;
     352             : }
     353             : 
     354             : NS_IMETHODIMP
     355           0 : PaymentRequestService::RespondPayment(nsIPaymentActionResponse* aResponse)
     356             : {
     357           0 :   NS_ENSURE_ARG_POINTER(aResponse);
     358           0 :   nsAutoString requestId;
     359           0 :   nsresult rv = aResponse->GetRequestId(requestId);
     360           0 :   NS_ENSURE_SUCCESS(rv, rv);
     361             : 
     362           0 :   nsCOMPtr<nsIPaymentRequest> request;
     363           0 :   rv = GetPaymentRequestById(requestId, getter_AddRefs(request));
     364           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     365           0 :     return rv;
     366             :   }
     367             : 
     368           0 :   nsCOMPtr<nsIPaymentActionCallback> callback;
     369           0 :   if (!mCallbackHashtable.Get(requestId, getter_AddRefs(callback))) {
     370           0 :     return NS_ERROR_FAILURE;
     371             :   }
     372           0 :   if (NS_WARN_IF(!callback)) {
     373           0 :     return NS_ERROR_FAILURE;
     374             :   }
     375           0 :   rv = callback->RespondPayment(aResponse);
     376           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     377           0 :     return rv;
     378             :   }
     379             : 
     380             :   // Remove nsIPaymentRequest from mRequestQueue while receive succeeded abort
     381             :   // response or complete response
     382             :   uint32_t type;
     383           0 :   rv = aResponse->GetType(&type);
     384           0 :   NS_ENSURE_SUCCESS(rv, rv);
     385           0 :   switch (type) {
     386             :     case nsIPaymentActionResponse::ABORT_ACTION: {
     387             :       nsCOMPtr<nsIPaymentAbortActionResponse> response =
     388           0 :         do_QueryInterface(aResponse);
     389           0 :       MOZ_ASSERT(response);
     390             :       bool isSucceeded;
     391           0 :       rv = response->IsSucceeded(&isSucceeded);
     392           0 :       NS_ENSURE_SUCCESS(rv, rv);
     393           0 :       if (isSucceeded) {
     394           0 :         mRequestQueue.RemoveElement(request);
     395             :       }
     396           0 :       break;
     397             :     }
     398             :     case nsIPaymentActionResponse::COMPLETE_ACTION: {
     399           0 :       mRequestQueue.RemoveElement(request);
     400           0 :       break;
     401             :     }
     402             :     default: {
     403           0 :       break;
     404             :     }
     405             :   }
     406           0 :   return NS_OK;
     407             : }
     408             : 
     409             : NS_IMETHODIMP
     410           0 : PaymentRequestService::ChangeShippingAddress(const nsAString& aRequestId,
     411             :                                              nsIPaymentAddress* aAddress)
     412             : {
     413           0 :   nsCOMPtr<nsIPaymentActionCallback> callback;
     414           0 :   if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
     415           0 :     return NS_ERROR_FAILURE;
     416             :   }
     417           0 :   if (NS_WARN_IF(!callback)) {
     418           0 :     return NS_ERROR_FAILURE;
     419             :   }
     420             : 
     421           0 :   nsresult rv = callback->ChangeShippingAddress(aRequestId, aAddress);
     422           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     423           0 :     return rv;
     424             :   }
     425           0 :   return NS_OK;
     426             : }
     427             : 
     428             : NS_IMETHODIMP
     429           0 : PaymentRequestService::ChangeShippingOption(const nsAString& aRequestId,
     430             :                                             const nsAString& aOption)
     431             : {
     432           0 :   nsCOMPtr<nsIPaymentActionCallback> callback;
     433           0 :   if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
     434           0 :     return NS_ERROR_FAILURE;
     435             :   }
     436           0 :   if (NS_WARN_IF(!callback)) {
     437           0 :     return NS_ERROR_FAILURE;
     438             :   }
     439             : 
     440           0 :   nsresult rv = callback->ChangeShippingOption(aRequestId, aOption);
     441           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     442           0 :     return rv;
     443             :   }
     444             : 
     445           0 :   return NS_OK;
     446             : }
     447             : 
     448             : nsresult
     449           0 : PaymentRequestService::SetActionCallback(const nsAString& aRequestId,
     450             :                                          nsIPaymentActionCallback* aCallback)
     451             : {
     452           0 :   NS_ENSURE_ARG_POINTER(aCallback);
     453           0 :   nsCOMPtr<nsIPaymentActionCallback> callback;
     454           0 :   if (mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
     455           0 :     mCallbackHashtable.Remove(aRequestId);
     456             :   }
     457           0 :   mCallbackHashtable.Put(aRequestId, aCallback);
     458           0 :   return NS_OK;
     459             : }
     460             : 
     461             : nsresult
     462           0 : PaymentRequestService::RemoveActionCallback(const nsAString& aRequestId)
     463             : {
     464           0 :   nsCOMPtr<nsIPaymentActionCallback> callback;
     465           0 :   if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
     466           0 :     return NS_ERROR_FAILURE;
     467             :   }
     468           0 :   mCallbackHashtable.Remove(aRequestId);
     469           0 :   return NS_OK;
     470             : }
     471             : 
     472             : } // end of namespace dom
     473             : } // end of namespace mozilla

Generated by: LCOV version 1.13