Bug 1318990 - PaymentRequestUpdateEvent interface and PaymentRequest API onshippingaddress/optionchange implementation. r=baku

This commit is contained in:
Eden Chuang 2017-06-23 17:15:51 +08:00
parent 06b5a3322e
commit 4282643952
28 changed files with 1076 additions and 39 deletions

View File

@ -7,6 +7,7 @@
XPIDL_SOURCES += [
'nsIPaymentActionRequest.idl',
'nsIPaymentActionResponse.idl',
'nsIPaymentAddress.idl',
'nsIPaymentRequest.idl',
'nsIPaymentRequestService.idl',
'nsIPaymentUIService.idl',

View File

@ -7,6 +7,7 @@
#include "nsIVariant.idl"
#include "nsIPaymentRequest.idl"
#include "nsIPaymentActionResponse.idl"
#include "nsIPaymentAddress.idl"
interface nsIArray;
@ -14,6 +15,8 @@ interface nsIArray;
interface nsIPaymentActionCallback : nsISupports
{
void respondPayment(in nsIPaymentActionResponse aResponse);
void changeShippingAddress(in AString aRequestId, in nsIPaymentAddress aAddress);
void changeShippingOption(in AString aRequestId, in AString aOption);
};
[builtinclass, uuid(7ddbe8be-beac-4952-96f6-619981dff7a6)]
@ -25,6 +28,7 @@ interface nsIPaymentActionRequest : nsISupports
const uint32_t SHOW_ACTION = 3;
const uint32_t ABORT_ACTION = 4;
const uint32_t COMPLETE_ACTION = 5;
const uint32_t UPDATE_ACTION = 6;
/*
* The payment request identifier.
@ -99,6 +103,21 @@ interface nsIPaymentCompleteActionRequest : nsIPaymentActionRequest
in AString aCompleteStatus);
};
[builtinclass, uuid(21f631e8-c047-4fd8-b3c6-68e26c62639a)]
interface nsIPaymentUpdateActionRequest : nsIPaymentActionRequest
{
/*
* The details information for updating the specified payment request.
*/
readonly attribute nsIPaymentDetails details;
/*
* Initialize function for this request.
*/
void initRequest(in AString aRequestId,
in nsIPaymentActionCallback aCallback,
in nsIPaymentDetails aDetails);
};
%{C++
#define NS_PAYMENT_ACTION_REQUEST_CID \
@ -116,4 +135,8 @@ interface nsIPaymentCompleteActionRequest : nsIPaymentActionRequest
#define NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID \
"@mozilla.org/dom/payments/payment-complete-action-request;1"
#define NS_PAYMENT_UPDATE_ACTION_REQUEST_CID \
{ 0x21f631e8, 0xc047, 0x4fd8, { 0xb3, 0xc6, 0x68, 0xe2, 0x6c, 0x62, 0x63, 0x9a } }
#define NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID \
"@mozilla.org/dom/payments/payment-update-action-request;1"
%}

View File

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIArray;
[builtinclass, scriptable, uuid(49a02241-7e48-477a-9345-9f246925dcb3)]
interface nsIPaymentAddress : nsISupports
{
readonly attribute AString country;
readonly attribute nsIArray addressLine;
readonly attribute AString region;
readonly attribute AString city;
readonly attribute AString dependentLocality;
readonly attribute AString postalCode;
readonly attribute AString sortingCode;
readonly attribute AString languageCode;
readonly attribute AString organization;
readonly attribute AString recipient;
readonly attribute AString phone;
void init(in AString aCountry,
in nsIArray aAddressLine,
in AString aRegion,
in AString aCity,
in AString aDependentLocality,
in AString aPostalCode,
in AString aSortingCode,
in AString aLanguageCode,
in AString aOrganization,
in AString aRecipient,
in AString aPhone);
};
%{C++
#define NS_PAYMENT_ADDRESS_CID \
{ 0x49a02241, 0x7e48, 0x477a, { 0x93, 0x45, 0x9f, 0x24, 0x69, 0x25, 0xdc, 0xb3 } }
#define NS_PAYMENT_ADDRESS_CONTRACT_ID \
"@mozilla.org/dom/payments/payment-address;1"
%}

View File

@ -8,6 +8,7 @@
#include "nsIPaymentRequest.idl"
#include "nsIPaymentActionRequest.idl"
#include "nsIPaymentActionResponse.idl"
#include "nsIPaymentAddress.idl"
#include "nsISimpleEnumerator.idl"
#include "nsIPaymentUIService.idl"
@ -40,6 +41,13 @@ interface nsIPaymentRequestService : nsISupports
* respondPayment is used for payment UI to respond the asked action result.
*/
void respondPayment(in nsIPaymentActionResponse aResponse);
/*
* These methods are used for payment UI to inform merchant the shipping
* address/option change.
*/
void changeShippingAddress(in AString requestId, in nsIPaymentAddress aAddress);
void changeShippingOption(in AString requestId, in AString option);
};
%{C++

View File

@ -13,4 +13,5 @@ interface nsIPaymentUIService : nsISupports
nsIPaymentActionResponse showPayment(in AString requestId);
nsIPaymentActionResponse abortPayment(in AString requestId);
nsIPaymentActionResponse completePayment(in AString requestId);
nsIPaymentActionResponse updatePayment(in AString requestId);
};

View File

@ -163,5 +163,36 @@ PaymentCompleteActionRequest::InitRequest(const nsAString& aRequestId,
return NS_OK;
}
/* PaymentUpdateActionRequest */
NS_IMPL_ISUPPORTS_INHERITED(PaymentUpdateActionRequest,
PaymentActionRequest,
nsIPaymentUpdateActionRequest)
NS_IMETHODIMP
PaymentUpdateActionRequest::GetDetails(nsIPaymentDetails** aDetails)
{
NS_ENSURE_ARG_POINTER(aDetails);
MOZ_ASSERT(mDetails);
nsCOMPtr<nsIPaymentDetails> details = mDetails;
details.forget(aDetails);
return NS_OK;
}
NS_IMETHODIMP
PaymentUpdateActionRequest::InitRequest(const nsAString& aRequestId,
nsIPaymentActionCallback* aCallback,
nsIPaymentDetails* aDetails)
{
NS_ENSURE_ARG_POINTER(aCallback);
NS_ENSURE_ARG_POINTER(aDetails);
nsresult rv = Init(aRequestId, nsIPaymentActionRequest::UPDATE_ACTION, aCallback);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mDetails = aDetails;
return NS_OK;
}
} // end of namespace dom
} // end of namespace mozilla

View File

@ -66,6 +66,21 @@ private:
nsString mCompleteStatus;
};
class PaymentUpdateActionRequest final : public nsIPaymentUpdateActionRequest
, public PaymentActionRequest
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_NSIPAYMENTACTIONREQUEST(PaymentActionRequest::)
NS_DECL_NSIPAYMENTUPDATEACTIONREQUEST
PaymentUpdateActionRequest() = default;
private:
~PaymentUpdateActionRequest() = default;
nsCOMPtr<nsIPaymentDetails> mDetails;
};
} // end of namespace dom
} // end of namespace mozilla

View File

@ -151,6 +151,19 @@ PaymentRequest::IsValidDetailsInit(const PaymentDetailsInit& aDetails, nsAString
return IsValidDetailsBase(aDetails, aErrorMsg);
}
bool
PaymentRequest::IsValidDetailsUpdate(const PaymentDetailsUpdate& aDetails)
{
nsAutoString message;
// Check the amount.value of detail.total
if (!IsNonNegativeNumber(NS_LITERAL_STRING("details.total"),
aDetails.mTotal.mAmount.mValue, message)) {
return false;
}
return IsValidDetailsBase(aDetails, message);
}
bool
PaymentRequest::IsValidDetailsBase(const PaymentDetailsBase& aDetails, nsAString& aErrorMsg)
{
@ -262,6 +275,7 @@ PaymentRequest::PaymentRequest(nsPIDOMWindowInner* aWindow, const nsAString& aIn
, mInternalId(aInternalId)
, mShippingAddress(nullptr)
, mUpdating(false)
, mUpdateError(NS_OK)
, mState(eCreated)
{
MOZ_ASSERT(aWindow);
@ -431,6 +445,22 @@ PaymentRequest::Abort(ErrorResult& aRv)
void
PaymentRequest::RespondAbortPayment(bool aSuccess)
{
// Check whether we are aborting the update:
//
// - If |mUpdateError| is not NS_OK, we are aborting the update as
// |mUpdateError| was set in method |AbortUpdate|.
// => Reject |mAcceptPromise| and reset |mUpdateError| to complete
// the action, regardless of |aSuccess|.
//
// - Otherwise, we are handling |Abort| method call from merchant.
// => Resolve/Reject |mAbortPromise| based on |aSuccess|.
if (NS_FAILED(mUpdateError)) {
RespondShowPayment(false, EmptyString(), EmptyString(), EmptyString(),
EmptyString(), EmptyString(), mUpdateError);
mUpdateError = NS_OK;
return;
}
MOZ_ASSERT(mAbortPromise);
MOZ_ASSERT(mState == eInteractive);
@ -444,6 +474,40 @@ PaymentRequest::RespondAbortPayment(bool aSuccess)
}
}
nsresult
PaymentRequest::UpdatePayment(const PaymentDetailsUpdate& aDetails)
{
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
if (NS_WARN_IF(!manager)) {
return NS_ERROR_FAILURE;
}
nsresult rv = manager->UpdatePayment(mInternalId, aDetails);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
void
PaymentRequest::AbortUpdate(nsresult aRv)
{
MOZ_ASSERT(NS_FAILED(aRv));
// Close down any remaining user interface.
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
nsresult rv = manager->AbortPayment(mInternalId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Remember update error |aRv| and do the following steps in RespondShowPayment.
// 1. Set target.state to closed
// 2. Reject the promise target.acceptPromise with exception "aRv"
// 3. Abort the algorithm with update error
mUpdateError = aRv;
}
void
PaymentRequest::GetId(nsAString& aRetVal) const
{
@ -480,6 +544,22 @@ PaymentRequest::SetUpdating(bool aUpdating)
mUpdating = aUpdating;
}
nsresult
PaymentRequest::DispatchUpdateEvent(const nsAString& aType)
{
MOZ_ASSERT(ReadyForUpdate());
PaymentRequestUpdateEventInit init;
init.mBubbles = false;
init.mCancelable = false;
RefPtr<PaymentRequestUpdateEvent> event =
PaymentRequestUpdateEvent::Constructor(this, aType, init);
event->SetTrusted(true);
return DispatchDOMEvent(nullptr, event, nullptr, nullptr);
}
already_AddRefed<PaymentAddress>
PaymentRequest::GetShippingAddress() const
{
@ -487,12 +567,43 @@ PaymentRequest::GetShippingAddress() const
return address.forget();
}
nsresult
PaymentRequest::UpdateShippingAddress(const nsAString& aCountry,
const nsTArray<nsString>& aAddressLine,
const nsAString& aRegion,
const nsAString& aCity,
const nsAString& aDependentLocality,
const nsAString& aPostalCode,
const nsAString& aSortingCode,
const nsAString& aLanguageCode,
const nsAString& aOrganization,
const nsAString& aRecipient,
const nsAString& aPhone)
{
mShippingAddress = new PaymentAddress(GetOwner(), aCountry, aAddressLine,
aRegion, aCity, aDependentLocality,
aPostalCode, aSortingCode, aLanguageCode,
aOrganization, aRecipient, aPhone);
// Fire shippingaddresschange event
return DispatchUpdateEvent(NS_LITERAL_STRING("shippingaddresschange"));
}
void
PaymentRequest::GetShippingOption(nsAString& aRetVal) const
{
aRetVal = mShippingOption;
}
nsresult
PaymentRequest::UpdateShippingOption(const nsAString& aShippingOption)
{
mShippingOption = aShippingOption;
// Fire shippingaddresschange event
return DispatchUpdateEvent(NS_LITERAL_STRING("shippingoptionchange"));
}
Nullable<PaymentShippingType>
PaymentRequest::GetShippingType() const
{

View File

@ -12,6 +12,7 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/ErrorResult.h"
#include "nsWrapperCache.h"
#include "PaymentRequestUpdateEvent.h"
namespace mozilla {
namespace dom {
@ -50,6 +51,10 @@ public:
static bool
IsValidDetailsInit(const PaymentDetailsInit& aDetails,
nsAString& aErrorMsg);
static bool
IsValidDetailsUpdate(const PaymentDetailsUpdate& aDetails);
static bool
IsValidDetailsBase(const PaymentDetailsBase& aDetails,
nsAString& aErrorMsg);
@ -88,7 +93,24 @@ public:
void SetUpdating(bool aUpdating);
already_AddRefed<PaymentAddress> GetShippingAddress() const;
// Update mShippingAddress and fire shippingaddresschange event
nsresult UpdateShippingAddress(const nsAString& aCountry,
const nsTArray<nsString>& aAddressLine,
const nsAString& aRegion,
const nsAString& aCity,
const nsAString& aDependentLocality,
const nsAString& aPostalCode,
const nsAString& aSortingCode,
const nsAString& aLanguageCode,
const nsAString& aOrganization,
const nsAString& aRecipient,
const nsAString& aPhone);
void GetShippingOption(nsAString& aRetVal) const;
nsresult UpdateShippingOption(const nsAString& aShippingOption);
nsresult UpdatePayment(const PaymentDetailsUpdate& aDetails);
void AbortUpdate(nsresult aRv);
Nullable<PaymentShippingType> GetShippingType() const;
@ -98,6 +120,8 @@ public:
protected:
~PaymentRequest();
nsresult DispatchUpdateEvent(const nsAString& aType);
PaymentRequest(nsPIDOMWindowInner* aWindow, const nsAString& aInternalId);
// Id for internal identification
@ -123,7 +147,7 @@ protected:
// and "false" otherwise.
bool mUpdating;
// The error is set in AbortUpdate(). The value is NS_OK by default.
//nsresult mUpdateError;
nsresult mUpdateError;
enum {
eUnknown,

View File

@ -655,6 +655,116 @@ PaymentRequest::UpdatePaymentDetails(nsIPaymentDetails* aPaymentDetails)
return mPaymentDetails->Update(aPaymentDetails);
}
/* PaymentAddress */
NS_IMPL_ISUPPORTS(PaymentAddress, nsIPaymentAddress)
nsresult
PaymentAddress::Init(const nsAString& aCountry,
nsIArray* aAddressLine,
const nsAString& aRegion,
const nsAString& aCity,
const nsAString& aDependentLocality,
const nsAString& aPostalCode,
const nsAString& aSortingCode,
const nsAString& aLanguageCode,
const nsAString& aOrganization,
const nsAString& aRecipient,
const nsAString& aPhone)
{
mCountry = aCountry;
mAddressLine = aAddressLine;
mRegion = aRegion;
mCity = aCity;
mDependentLocality = aDependentLocality;
mPostalCode = aPostalCode;
mSortingCode = aSortingCode;
mLanguageCode = aLanguageCode;
mOrganization = aOrganization;
mRecipient = aRecipient;
mPhone = aPhone;
return NS_OK;
}
nsresult
PaymentAddress::GetCountry(nsAString& aCountry)
{
aCountry = mCountry;
return NS_OK;
}
nsresult
PaymentAddress::GetAddressLine(nsIArray** aAddressLine)
{
NS_ENSURE_ARG_POINTER(aAddressLine);
nsCOMPtr<nsIArray> addressLine = mAddressLine;
addressLine.forget(aAddressLine);
return NS_OK;
}
nsresult
PaymentAddress::GetRegion(nsAString& aRegion)
{
aRegion = mRegion;
return NS_OK;
}
nsresult
PaymentAddress::GetCity(nsAString& aCity)
{
aCity = mCity;
return NS_OK;
}
nsresult
PaymentAddress::GetDependentLocality(nsAString& aDependentLocality)
{
aDependentLocality = mDependentLocality;
return NS_OK;
}
nsresult
PaymentAddress::GetPostalCode(nsAString& aPostalCode)
{
aPostalCode = mPostalCode;
return NS_OK;
}
nsresult
PaymentAddress::GetSortingCode(nsAString& aSortingCode)
{
aSortingCode = mSortingCode;
return NS_OK;
}
nsresult
PaymentAddress::GetLanguageCode(nsAString& aLanguageCode)
{
aLanguageCode = mLanguageCode;
return NS_OK;
}
nsresult
PaymentAddress::GetOrganization(nsAString& aOrganization)
{
aOrganization = mOrganization;
return NS_OK;
}
nsresult
PaymentAddress::GetRecipient(nsAString& aRecipient)
{
aRecipient = mRecipient;
return NS_OK;
}
nsresult
PaymentAddress::GetPhone(nsAString& aPhone)
{
aPhone = mPhone;
return NS_OK;
}
} // end of namespace payment
} // end of namespace dom
} // end of namespace mozilla

View File

@ -7,6 +7,7 @@
#ifndef mozilla_dom_PaymentRequestData_h
#define mozilla_dom_PaymentRequestData_h
#include "nsIPaymentAddress.h"
#include "nsIPaymentRequest.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/PPaymentRequest.h"
@ -192,6 +193,30 @@ private:
nsCOMPtr<nsIPaymentOptions> mPaymentOptions;
};
class PaymentAddress final : public nsIPaymentAddress
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPAYMENTADDRESS
PaymentAddress() = default;
private:
~PaymentAddress() = default;
nsString mCountry;
nsCOMPtr<nsIArray> mAddressLine;
nsString mRegion;
nsString mCity;
nsString mDependentLocality;
nsString mPostalCode;
nsString mSortingCode;
nsString mLanguageCode;
nsString mOrganization;
nsString mRecipient;
nsString mPhone;
};
} // end of namespace payment
} // end of namespace dom
} // end of namespace mozilla

View File

@ -5,12 +5,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "PaymentRequestManager.h"
#include "PaymentRequestUtils.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/PaymentRequestChild.h"
#include "nsContentUtils.h"
#include "nsIJSON.h"
#include "nsString.h"
namespace mozilla {
@ -21,16 +21,6 @@ namespace {
* Following Convert* functions are used for convert PaymentRequest structs
* to transferable structs for IPC.
*/
nsresult
SerializeFromJSObject(JSContext* aCx, JS::HandleObject aObject, nsAString& aSerializedObject){
nsCOMPtr<nsIJSON> serializer = do_CreateInstance("@mozilla.org/dom/json;1");
if (NS_WARN_IF(!serializer)) {
return NS_ERROR_FAILURE;
}
JS::RootedValue value(aCx, JS::ObjectValue(*aObject));
return serializer->EncodeFromJSVal(value.address(), aCx, aSerializedObject);
}
nsresult
ConvertMethodData(const PaymentMethodData& aMethodData,
IPCPaymentMethodData& aIPCMethodData)
@ -189,6 +179,41 @@ ConvertDetailsInit(const PaymentDetailsInit& aDetails,
return NS_OK;
}
nsresult
ConvertDetailsUpdate(const PaymentDetailsUpdate& aDetails,
IPCPaymentDetails& aIPCDetails)
{
// Convert PaymentDetailsBase members
nsTArray<IPCPaymentItem> displayItems;
nsTArray<IPCPaymentShippingOption> shippingOptions;
nsTArray<IPCPaymentDetailsModifier> modifiers;
nsresult rv = ConvertDetailsBase(aDetails, displayItems, shippingOptions, modifiers);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Convert required |total|
IPCPaymentItem total;
ConvertItem(aDetails.mTotal, total);
// Convert |error|
nsString error(EmptyString());
if (aDetails.mError.WasPassed()) {
error = aDetails.mError.Value();
}
aIPCDetails = IPCPaymentDetails(EmptyString(), // id
total,
displayItems,
shippingOptions,
modifiers,
error,
aDetails.mDisplayItems.WasPassed(),
aDetails.mShippingOptions.WasPassed(),
aDetails.mModifiers.WasPassed());
return NS_OK;
}
void
ConvertOptions(const PaymentOptions& aOptions,
IPCPaymentOptions& aIPCOption)
@ -467,12 +492,32 @@ PaymentRequestManager::CompletePayment(const nsAString& aRequestId,
return SendRequestPayment(request, action);
}
nsresult
PaymentRequestManager::UpdatePayment(const nsAString& aRequestId,
const PaymentDetailsUpdate& aDetails)
{
RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
if (!request) {
return NS_ERROR_UNEXPECTED;
}
IPCPaymentDetails details;
nsresult rv = ConvertDetailsUpdate(aDetails, details);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsAutoString requestId(aRequestId);
IPCPaymentUpdateActionRequest action(requestId, details);
return SendRequestPayment(request, action);
}
nsresult
PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
{
switch (aResponse.type()) {
case IPCPaymentActionResponse::TIPCPaymentCanMakeActionResponse: {
IPCPaymentCanMakeActionResponse response = aResponse;
const IPCPaymentCanMakeActionResponse& response = aResponse;
RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
if (NS_WARN_IF(!request)) {
return NS_ERROR_FAILURE;
@ -485,7 +530,7 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
break;
}
case IPCPaymentActionResponse::TIPCPaymentShowActionResponse: {
IPCPaymentShowActionResponse response = aResponse;
const IPCPaymentShowActionResponse& response = aResponse;
RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
if (NS_WARN_IF(!request)) {
return NS_ERROR_FAILURE;
@ -496,10 +541,17 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
response.payerName(),
response.payerEmail(),
response.payerPhone());
if (!response.isAccepted()) {
mRequestQueue.RemoveElement(request);
nsresult rv = ReleasePaymentChild(request);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
break;
}
case IPCPaymentActionResponse::TIPCPaymentAbortActionResponse: {
IPCPaymentAbortActionResponse response = aResponse;
const IPCPaymentAbortActionResponse& response = aResponse;
RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
if (NS_WARN_IF(!request)) {
return NS_ERROR_FAILURE;
@ -515,7 +567,7 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
break;
}
case IPCPaymentActionResponse::TIPCPaymentCompleteActionResponse: {
IPCPaymentCompleteActionResponse response = aResponse;
const IPCPaymentCompleteActionResponse& response = aResponse;
RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
if (NS_WARN_IF(!request)) {
return NS_ERROR_FAILURE;
@ -535,5 +587,37 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
return NS_OK;
}
nsresult
PaymentRequestManager::ChangeShippingAddress(const nsAString& aRequestId,
const IPCPaymentAddress& aAddress)
{
RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
if (NS_WARN_IF(!request)) {
return NS_ERROR_FAILURE;
}
return request->UpdateShippingAddress(aAddress.country(),
aAddress.addressLine(),
aAddress.region(),
aAddress.city(),
aAddress.dependentLocality(),
aAddress.postalCode(),
aAddress.sortingCode(),
aAddress.languageCode(),
aAddress.organization(),
aAddress.recipient(),
aAddress.phone());
}
nsresult
PaymentRequestManager::ChangeShippingOption(const nsAString& aRequestId,
const nsAString& aOption)
{
RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
if (NS_WARN_IF(!request)) {
return NS_ERROR_FAILURE;
}
return request->UpdateShippingOption(aOption);
}
} // end of namespace dom
} // end of namespace mozilla

View File

@ -10,6 +10,7 @@
#include "nsISupports.h"
#include "PaymentRequest.h"
#include "mozilla/dom/PaymentRequestBinding.h"
#include "mozilla/dom/PaymentRequestUpdateEventBinding.h"
#include "mozilla/dom/PaymentResponseBinding.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
@ -51,8 +52,14 @@ public:
nsresult AbortPayment(const nsAString& aRequestId);
nsresult CompletePayment(const nsAString& aRequestId,
const PaymentComplete& aComplete);
nsresult UpdatePayment(const nsAString& aRequestId,
const PaymentDetailsUpdate& aDetails);
nsresult RespondPayment(const IPCPaymentActionResponse& aResponse);
nsresult ChangeShippingAddress(const nsAString& aRequestId,
const IPCPaymentAddress& aAddress);
nsresult ChangeShippingOption(const nsAString& aRequestId,
const nsAString& aOption);
nsresult
ReleasePaymentChild(PaymentRequestChild* aPaymentChild);

View File

@ -7,44 +7,53 @@
#include "mozilla/ModuleUtils.h"
#include "PaymentActionRequest.h"
#include "PaymentActionResponse.h"
#include "PaymentRequestData.h"
#include "PaymentRequestService.h"
using mozilla::dom::PaymentActionRequest;
using mozilla::dom::PaymentCreateActionRequest;
using mozilla::dom::PaymentCompleteActionRequest;
using mozilla::dom::PaymentUpdateActionRequest;
using mozilla::dom::PaymentCanMakeActionResponse;
using mozilla::dom::PaymentAbortActionResponse;
using mozilla::dom::PaymentShowActionResponse;
using mozilla::dom::PaymentCompleteActionResponse;
using mozilla::dom::payments::PaymentAddress;
using mozilla::dom::PaymentRequestService;
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentActionRequest)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCreateActionRequest)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCompleteActionRequest)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentUpdateActionRequest)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCanMakeActionResponse)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentAbortActionResponse)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentShowActionResponse)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentCompleteActionResponse)
NS_GENERIC_FACTORY_CONSTRUCTOR(PaymentAddress)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(PaymentRequestService,
PaymentRequestService::GetSingleton)
NS_DEFINE_NAMED_CID(NS_PAYMENT_ACTION_REQUEST_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_CREATE_ACTION_REQUEST_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_COMPLETE_ACTION_REQUEST_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_UPDATE_ACTION_REQUEST_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_ABORT_ACTION_RESPONSE_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_SHOW_ACTION_RESPONSE_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_COMPLETE_ACTION_RESPONSE_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_ADDRESS_CID);
NS_DEFINE_NAMED_CID(NS_PAYMENT_REQUEST_SERVICE_CID);
static const mozilla::Module::CIDEntry kPaymentRequestCIDs[] = {
{ &kNS_PAYMENT_ACTION_REQUEST_CID, false, nullptr, PaymentActionRequestConstructor},
{ &kNS_PAYMENT_CREATE_ACTION_REQUEST_CID, false, nullptr, PaymentCreateActionRequestConstructor},
{ &kNS_PAYMENT_COMPLETE_ACTION_REQUEST_CID, false, nullptr, PaymentCompleteActionRequestConstructor},
{ &kNS_PAYMENT_UPDATE_ACTION_REQUEST_CID, false, nullptr, PaymentUpdateActionRequestConstructor},
{ &kNS_PAYMENT_CANMAKE_ACTION_RESPONSE_CID, false, nullptr, PaymentCanMakeActionResponseConstructor},
{ &kNS_PAYMENT_ABORT_ACTION_RESPONSE_CID, false, nullptr, PaymentAbortActionResponseConstructor},
{ &kNS_PAYMENT_SHOW_ACTION_RESPONSE_CID, false, nullptr, PaymentShowActionResponseConstructor},
{ &kNS_PAYMENT_COMPLETE_ACTION_RESPONSE_CID, false, nullptr, PaymentCompleteActionResponseConstructor},
{ &kNS_PAYMENT_ADDRESS_CID, false, nullptr, PaymentAddressConstructor},
{ &kNS_PAYMENT_REQUEST_SERVICE_CID, true, nullptr, PaymentRequestServiceConstructor },
{ nullptr }
};
@ -53,10 +62,12 @@ static const mozilla::Module::ContractIDEntry kPaymentRequestContracts[] = {
{ NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_ACTION_REQUEST_CID },
{ NS_PAYMENT_CREATE_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_CREATE_ACTION_REQUEST_CID },
{ NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_COMPLETE_ACTION_REQUEST_CID },
{ NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID, &kNS_PAYMENT_UPDATE_ACTION_REQUEST_CID },
{ NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_CANMAKE_ACTION_RESPONSE_CID },
{ NS_PAYMENT_ABORT_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_ABORT_ACTION_RESPONSE_CID },
{ NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_SHOW_ACTION_RESPONSE_CID },
{ NS_PAYMENT_COMPLETE_ACTION_RESPONSE_CONTRACT_ID, &kNS_PAYMENT_COMPLETE_ACTION_RESPONSE_CID },
{ NS_PAYMENT_ADDRESS_CONTRACT_ID, &kNS_PAYMENT_ADDRESS_CID },
{ NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID, &kNS_PAYMENT_REQUEST_SERVICE_CID },
{ nullptr }
};
@ -65,10 +76,12 @@ static const mozilla::Module::CategoryEntry kPaymentRequestCategories[] = {
{ "payment-request", "PaymentActionRequest", NS_PAYMENT_ACTION_REQUEST_CONTRACT_ID },
{ "payment-request", "PaymentCreateActionRequest", NS_PAYMENT_CREATE_ACTION_REQUEST_CONTRACT_ID },
{ "payment-request", "PaymentCompleteActionRequest", NS_PAYMENT_COMPLETE_ACTION_REQUEST_CONTRACT_ID },
{ "payment-request", "PaymentUpdateActionRequest", NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID },
{ "payment-request", "PaymentCanMakeActionResponse", NS_PAYMENT_CANMAKE_ACTION_RESPONSE_CONTRACT_ID },
{ "payment-request", "PaymentAbortActionResponse", NS_PAYMENT_ABORT_ACTION_RESPONSE_CONTRACT_ID },
{ "payment-request", "PaymentShowActionResponse", NS_PAYMENT_SHOW_ACTION_RESPONSE_CONTRACT_ID },
{ "payment-request", "PaymentCompleteActionResponse", NS_PAYMENT_COMPLETE_ACTION_RESPONSE_CONTRACT_ID },
{ "payment-request", "PaymentAddress", NS_PAYMENT_ADDRESS_CONTRACT_ID },
{ "payment-request", "PaymentRequestService", NS_PAYMENT_REQUEST_SERVICE_CONTRACT_ID },
{ nullptr }
};

View File

@ -169,6 +169,10 @@ PaymentRequestService::CallTestingUIAction(const nsAString& aRequestId, uint32_t
rv = mTestingUIService->CompletePayment(aRequestId, getter_AddRefs(response));
break;
}
case nsIPaymentActionRequest::UPDATE_ACTION: {
rv = mTestingUIService->UpdatePayment(aRequestId, getter_AddRefs(response));
break;
}
default : {
return NS_ERROR_FAILURE;
}
@ -178,7 +182,8 @@ PaymentRequestService::CallTestingUIAction(const nsAString& aRequestId, uint32_t
}
} else {
// Since there is no UI implementation and no testing UI Service is registered,
// set false response for canMakePayment() and ABORT_SUCCEEDED for abort()
// set false response for canMakePayment(), ABORT_SUCCEEDED for abort() and
// COMPLETE_SUCCEEDED for complete().
switch (aActionType) {
case nsIPaymentActionRequest::CANMAKE_ACTION: {
nsCOMPtr<nsIPaymentCanMakeActionResponse> canMakeResponse =
@ -200,6 +205,16 @@ PaymentRequestService::CallTestingUIAction(const nsAString& aRequestId, uint32_t
MOZ_ASSERT(response);
break;
}
case nsIPaymentActionRequest::COMPLETE_ACTION: {
nsCOMPtr<nsIPaymentCompleteActionResponse> completeResponse =
do_CreateInstance(NS_PAYMENT_COMPLETE_ACTION_RESPONSE_CONTRACT_ID);
MOZ_ASSERT(completeResponse);
rv = completeResponse->Init(aRequestId, nsIPaymentActionResponse::COMPLETE_SUCCEEDED);
NS_ENSURE_SUCCESS(rv, rv);
response = do_QueryInterface(completeResponse);
MOZ_ASSERT(response);
break;
}
default : {
break;
}
@ -262,27 +277,19 @@ PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
MOZ_ASSERT(request);
uint64_t tabId;
rv = request->GetTabId(&tabId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIArray> methodData;
rv = request->GetMethodData(getter_AddRefs(methodData));
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPaymentDetails> details;
rv = request->GetDetails(getter_AddRefs(details));
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPaymentOptions> options;
rv = request->GetOptions(getter_AddRefs(options));
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPaymentRequest> payment =
new payments::PaymentRequest(tabId, requestId, methodData, details, options);
@ -312,6 +319,31 @@ PaymentRequestService::RequestPayment(nsIPaymentActionRequest* aRequest)
}
break;
}
case nsIPaymentActionRequest::UPDATE_ACTION: {
nsCOMPtr<nsIPaymentUpdateActionRequest> request = do_QueryInterface(aRequest);
MOZ_ASSERT(request);
nsCOMPtr<nsIPaymentDetails> details;
rv = request->GetDetails(getter_AddRefs(details));
NS_ENSURE_SUCCESS(rv, rv);
rv = request->GetRequestId(requestId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPaymentRequest> payment;
rv = GetPaymentRequestById(requestId, getter_AddRefs(payment));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = payment->UpdatePaymentDetails(details);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = CallTestingUIAction(requestId, type);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
break;
}
default: {
return NS_ERROR_FAILURE;
}
@ -374,6 +406,45 @@ PaymentRequestService::RespondPayment(nsIPaymentActionResponse* aResponse)
return NS_OK;
}
NS_IMETHODIMP
PaymentRequestService::ChangeShippingAddress(const nsAString& aRequestId,
nsIPaymentAddress* aAddress)
{
nsCOMPtr<nsIPaymentActionCallback> callback;
if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
return NS_ERROR_FAILURE;
}
if (NS_WARN_IF(!callback)) {
return NS_ERROR_FAILURE;
}
nsresult rv = callback->ChangeShippingAddress(aRequestId, aAddress);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
NS_IMETHODIMP
PaymentRequestService::ChangeShippingOption(const nsAString& aRequestId,
const nsAString& aOption)
{
nsCOMPtr<nsIPaymentActionCallback> callback;
if (!mCallbackHashtable.Get(aRequestId, getter_AddRefs(callback))) {
return NS_ERROR_FAILURE;
}
if (NS_WARN_IF(!callback)) {
return NS_ERROR_FAILURE;
}
nsresult rv = callback->ChangeShippingOption(aRequestId, aOption);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
PaymentRequestService::SetActionCallback(const nsAString& aRequestId,
nsIPaymentActionCallback* aCallback)

View File

@ -0,0 +1,139 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/PaymentRequestUpdateEvent.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_INHERITED(PaymentRequestUpdateEvent, Event, mRequest)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PaymentRequestUpdateEvent, Event)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PaymentRequestUpdateEvent)
NS_INTERFACE_MAP_END_INHERITING(Event)
NS_IMPL_ADDREF_INHERITED(PaymentRequestUpdateEvent, Event)
NS_IMPL_RELEASE_INHERITED(PaymentRequestUpdateEvent, Event)
already_AddRefed<PaymentRequestUpdateEvent>
PaymentRequestUpdateEvent::Constructor(mozilla::dom::EventTarget* aOwner,
const nsAString& aType,
const PaymentRequestUpdateEventInit& aEventInitDict)
{
RefPtr<PaymentRequestUpdateEvent> e = new PaymentRequestUpdateEvent(aOwner);
bool trusted = e->Init(aOwner);
e->InitEvent(aType, aEventInitDict.mBubbles, aEventInitDict.mCancelable);
e->SetTrusted(trusted);
e->SetComposed(aEventInitDict.mComposed);
return e.forget();
}
already_AddRefed<PaymentRequestUpdateEvent>
PaymentRequestUpdateEvent::Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const PaymentRequestUpdateEventInit& aEventInitDict,
ErrorResult& aRv)
{
nsCOMPtr<mozilla::dom::EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
return Constructor(owner, aType, aEventInitDict);
}
PaymentRequestUpdateEvent::PaymentRequestUpdateEvent(EventTarget* aOwner)
: Event(aOwner, nullptr, nullptr)
, mWaitForUpdate(false)
{
MOZ_ASSERT(aOwner);
// event's target should be a PaymentRequest object
mRequest = static_cast<PaymentRequest *>(aOwner);
}
void
PaymentRequestUpdateEvent::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
MOZ_ASSERT(mRequest);
if (NS_WARN_IF(!aValue.isObject()) || !mWaitForUpdate) {
return;
}
// Converting value to a PaymentDetailsUpdate dictionary
PaymentDetailsUpdate details;
if (!details.Init(aCx, aValue)) {
return;
}
// Validate and canonicalize the details
if (!mRequest->IsValidDetailsUpdate(details)) {
mRequest->AbortUpdate(NS_ERROR_TYPE_ERR);
return;
}
// [TODO]
// If the data member of modifier is present,
// let serializedData be the result of JSON-serializing modifier.data into a string.
// null if it is not.
// Update the PaymentRequest with the new details
if (NS_FAILED(mRequest->UpdatePayment(details))) {
mRequest->AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
return;
}
mWaitForUpdate = false;
mRequest->SetUpdating(false);
}
void
PaymentRequestUpdateEvent::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
MOZ_ASSERT(mRequest);
mRequest->AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
mWaitForUpdate = false;
mRequest->SetUpdating(false);
}
void
PaymentRequestUpdateEvent::UpdateWith(Promise& aPromise, ErrorResult& aRv)
{
MOZ_ASSERT(mRequest);
if (mWaitForUpdate || !mRequest->ReadyForUpdate() ||
!mEvent->mFlags.mIsBeingDispatched) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
aPromise.AppendNativeHandler(this);
StopPropagation();
StopImmediatePropagation();
mWaitForUpdate = true;
mRequest->SetUpdating(true);
}
bool
PaymentRequestUpdateEvent::IsTrusted() const
{
return true;
}
PaymentRequestUpdateEvent::~PaymentRequestUpdateEvent()
{
}
JSObject*
PaymentRequestUpdateEvent::WrapObjectInternal(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return PaymentRequestUpdateEventBinding::Wrap(aCx, this, aGivenProto);
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PaymentRequestUpdateEvent_h
#define mozilla_dom_PaymentRequestUpdateEvent_h
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/PaymentRequestUpdateEventBinding.h"
#include "mozilla/dom/PromiseNativeHandler.h"
namespace mozilla {
namespace dom {
class Promise;
class PaymentRequestUpdateEvent final : public Event
, public PromiseNativeHandler
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PaymentRequestUpdateEvent, Event)
explicit PaymentRequestUpdateEvent(EventTarget* aOwner);
virtual JSObject*
WrapObjectInternal(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
virtual void
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
virtual void
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
static already_AddRefed<PaymentRequestUpdateEvent>
Constructor(EventTarget* aOwner,
const nsAString& aType,
const PaymentRequestUpdateEventInit& aEventInitDict);
static already_AddRefed<PaymentRequestUpdateEvent>
Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const PaymentRequestUpdateEventInit& aEventInitDict,
ErrorResult& aRv);
void UpdateWith(Promise& aPromise, ErrorResult& aRv);
bool IsTrusted() const;
protected:
~PaymentRequestUpdateEvent();
private:
// Indicating whether an updateWith()-initiated update is currently in progress.
bool mWaitForUpdate;
RefPtr<PaymentRequest> mRequest;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PaymentRequestUpdateEvent_h

View File

@ -8,10 +8,41 @@
#include "PaymentRequestUtils.h"
#include "nsIMutableArray.h"
#include "nsISupportsPrimitives.h"
#include "nsIJSON.h"
namespace mozilla {
namespace dom {
nsresult
SerializeFromJSObject(JSContext* aCx, JS::HandleObject aObject, nsAString& aSerializedObject) {
nsCOMPtr<nsIJSON> serializer = do_CreateInstance("@mozilla.org/dom/json;1");
if (NS_WARN_IF(!serializer)) {
return NS_ERROR_FAILURE;
}
JS::RootedValue value(aCx, JS::ObjectValue(*aObject));
return serializer->EncodeFromJSVal(value.address(), aCx, aSerializedObject);
}
nsresult
DeserializeToJSObject(const nsAString& aSerializedObject, JSContext* aCx, JS::MutableHandleObject aObject) {
nsCOMPtr<nsIJSON> deserializer = do_CreateInstance("@mozilla.org/dom/json;1");
if (NS_WARN_IF(!deserializer)) {
return NS_ERROR_FAILURE;
}
JS::RootedValue value(aCx);
JS::MutableHandleValue handleVal(&value);
nsresult rv = deserializer->DecodeToJSVal(aSerializedObject, aCx, handleVal);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (value.isObject()) {
aObject.set(&value.toObject());
} else {
aObject.set(nullptr);
}
return NS_OK;
}
nsresult
ConvertStringstoISupportsStrings(const nsTArray<nsString>& aStrings,
nsIArray** aIStrings)

View File

@ -13,6 +13,16 @@
namespace mozilla {
namespace dom {
nsresult
SerializeFromJSObject(JSContext* aCx,
JS::HandleObject aObject,
nsAString& aSerializedObject);
nsresult
DeserializeToJSObject(const nsAString& aSerializedObject,
JSContext* aCx,
JS::MutableHandleObject aObject);
nsresult
ConvertStringstoISupportsStrings(const nsTArray<nsString>& aStrings,
nsIArray** aIStrings);

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/PaymentResponse.h"
#include "PaymentRequestUtils.h"
namespace mozilla {
namespace dom {
@ -35,6 +36,7 @@ PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
, mInternalId(aInternalId)
, mRequestId(aRequestId)
, mMethodName(aMethodName)
, mDetails(aDetails)
, mShippingOption(aShippingOption)
, mPayerName(aPayerName)
, mPayerEmail(aPayerEmail)
@ -44,9 +46,6 @@ PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
// TODO: from https://github.com/w3c/browser-payment-api/issues/480
// Add payerGivenName + payerFamilyName to PaymentAddress
// TODO : need to figure how to deserialize aDetails to JSObject
}
PaymentResponse::~PaymentResponse()
@ -72,9 +71,9 @@ PaymentResponse::GetMethodName(nsString& aRetVal) const
}
void
PaymentResponse::GetDetails(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal) const
PaymentResponse::GetDetails(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal) const
{
// TODO : need to save aDetails as JSObject
DeserializeToJSObject(mDetails, aCx, aRetVal);
}
void

View File

@ -74,6 +74,7 @@ private:
nsString mInternalId;
nsString mRequestId;
nsString mMethodName;
nsString mDetails;
nsString mShippingOption;
nsString mPayerName;
nsString mPayerEmail;

View File

@ -96,6 +96,12 @@ struct IPCPaymentCompleteActionRequest
nsString completeStatus;
};
struct IPCPaymentUpdateActionRequest
{
nsString requestId;
IPCPaymentDetails details;
};
union IPCPaymentActionRequest
{
IPCPaymentCreateActionRequest;
@ -103,6 +109,7 @@ union IPCPaymentActionRequest
IPCPaymentShowActionRequest;
IPCPaymentAbortActionRequest;
IPCPaymentCompleteActionRequest;
IPCPaymentUpdateActionRequest;
};
struct IPCPaymentCanMakeActionResponse
@ -142,6 +149,21 @@ union IPCPaymentActionResponse
IPCPaymentCompleteActionResponse;
};
struct IPCPaymentAddress
{
nsString country;
nsString[] addressLine;
nsString region;
nsString city;
nsString dependentLocality;
nsString postalCode;
nsString sortingCode;
nsString languageCode;
nsString organization;
nsString recipient;
nsString phone;
};
sync protocol PPaymentRequest
{
manager PBrowser;
@ -153,6 +175,10 @@ parent:
child:
async RespondPayment(IPCPaymentActionResponse aResponse);
async ChangeShippingAddress(nsString aRequestId,
IPCPaymentAddress aAddress);
async ChangeShippingOption(nsString aRequestId,
nsString aOption);
};
} // end of namespace dom

View File

@ -43,6 +43,38 @@ PaymentRequestChild::RecvRespondPayment(const IPCPaymentActionResponse& aRespons
return IPC_OK();
}
mozilla::ipc::IPCResult
PaymentRequestChild::RecvChangeShippingAddress(const nsString& aRequestId,
const IPCPaymentAddress& aAddress)
{
if (!mActorAlive) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
nsresult rv = manager->ChangeShippingAddress(aRequestId, aAddress);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
PaymentRequestChild::RecvChangeShippingOption(const nsString& aRequestId,
const nsString& aOption)
{
if (!mActorAlive) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
nsresult rv = manager->ChangeShippingOption(aRequestId, aOption);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
void
PaymentRequestChild::ActorDestroy(ActorDestroyReason aWhy)
{

View File

@ -18,14 +18,24 @@ class PaymentRequestChild final : public PPaymentRequestChild
public:
PaymentRequestChild();
virtual mozilla::ipc::IPCResult
RecvRespondPayment(const IPCPaymentActionResponse& aResponse) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
void MaybeDelete();
nsresult RequestPayment(const IPCPaymentActionRequest& aAction);
protected:
mozilla::ipc::IPCResult
RecvRespondPayment(const IPCPaymentActionResponse& aResponse) override;
mozilla::ipc::IPCResult
RecvChangeShippingAddress(const nsString& aRequestId,
const IPCPaymentAddress& aAddress) override;
mozilla::ipc::IPCResult
RecvChangeShippingOption(const nsString& aRequestId,
const nsString& aOption) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
private:
~PaymentRequestChild() = default;

View File

@ -128,6 +128,24 @@ PaymentRequestParent::RecvRequestPayment(const IPCPaymentActionRequest& aRequest
MOZ_ASSERT(action);
break;
}
case IPCPaymentActionRequest::TIPCPaymentUpdateActionRequest: {
const IPCPaymentUpdateActionRequest& request = aRequest;
nsCOMPtr<nsIPaymentDetails> details;
rv = payments::PaymentDetails::Create(request.details(), getter_AddRefs(details));
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}
nsCOMPtr<nsIPaymentUpdateActionRequest> updateAction =
do_CreateInstance(NS_PAYMENT_UPDATE_ACTION_REQUEST_CONTRACT_ID);
rv = updateAction->InitRequest(request.requestId(),
callback,
details);
action = do_QueryInterface(updateAction);
MOZ_ASSERT(action);
break;
}
default: {
return IPC_FAIL(this, "Unexpected request type");
}
@ -239,6 +257,116 @@ PaymentRequestParent::RespondPayment(nsIPaymentActionResponse* aResponse)
return NS_OK;
}
NS_IMETHODIMP
PaymentRequestParent::ChangeShippingAddress(const nsAString& aRequestId,
nsIPaymentAddress* aAddress)
{
if (!NS_IsMainThread()) {
nsCOMPtr<nsIPaymentActionCallback> self = this;
nsCOMPtr<nsIPaymentAddress> address = aAddress;
nsAutoString requestId(aRequestId);
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, requestId, address] ()
{
self->ChangeShippingAddress(requestId, address);
});
return NS_DispatchToMainThread(r);
}
if (!mActorAlived) {
return NS_ERROR_FAILURE;
}
nsAutoString country;
nsresult rv = aAddress->GetCountry(country);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIArray> iaddressLine;
rv = aAddress->GetAddressLine(getter_AddRefs(iaddressLine));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString region;
rv = aAddress->GetRegion(region);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString city;
rv = aAddress->GetCity(city);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString dependentLocality;
rv = aAddress->GetDependentLocality(dependentLocality);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString postalCode;
rv = aAddress->GetPostalCode(postalCode);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString sortingCode;
rv = aAddress->GetSortingCode(sortingCode);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString languageCode;
rv = aAddress->GetLanguageCode(languageCode);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString organization;
rv = aAddress->GetOrganization(organization);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString recipient;
rv = aAddress->GetRecipient(recipient);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString phone;
rv = aAddress->GetPhone(phone);
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsString> addressLine;
uint32_t length;
rv = iaddressLine->GetLength(&length);
NS_ENSURE_SUCCESS(rv, rv);
for (uint32_t index = 0; index < length; ++index) {
nsCOMPtr<nsISupportsString> iaddress = do_QueryElementAt(iaddressLine, index);
MOZ_ASSERT(iaddress);
nsAutoString address;
rv = iaddress->GetData(address);
NS_ENSURE_SUCCESS(rv, rv);
addressLine.AppendElement(address);
}
IPCPaymentAddress ipcAddress(country, addressLine, region, city,
dependentLocality, postalCode, sortingCode,
languageCode, organization, recipient, phone);
nsAutoString requestId(aRequestId);
if (!SendChangeShippingAddress(requestId, ipcAddress)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
PaymentRequestParent::ChangeShippingOption(const nsAString& aRequestId,
const nsAString& aOption)
{
if (!NS_IsMainThread()) {
nsCOMPtr<nsIPaymentActionCallback> self = this;
nsAutoString requestId(aRequestId);
nsAutoString option(aOption);
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self, requestId, option] ()
{
self->ChangeShippingOption(requestId, option);
});
return NS_DispatchToMainThread(r);
}
if (!mActorAlived) {
return NS_ERROR_FAILURE;
}
nsAutoString requestId(aRequestId);
nsAutoString option(aOption);
if (!SendChangeShippingOption(requestId, option)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
mozilla::ipc::IPCResult
PaymentRequestParent::Recv__delete__()
{

View File

@ -17,6 +17,7 @@ EXPORTS.mozilla.dom += [
'PaymentAddress.h',
'PaymentRequest.h',
'PaymentRequestManager.h',
'PaymentRequestUpdateEvent.h',
'PaymentResponse.h',
]
@ -29,6 +30,7 @@ UNIFIED_SOURCES += [
'PaymentRequestManager.cpp',
'PaymentRequestModule.cpp',
'PaymentRequestService.cpp',
'PaymentRequestUpdateEvent.cpp',
'PaymentRequestUtils.cpp',
'PaymentResponse.cpp',
]

View File

@ -0,0 +1,25 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this WebIDL file is
* https://www.w3.org/TR/payment-request/#paymentrequestupdateevent-interface
*/
dictionary PaymentDetailsUpdate : PaymentDetailsBase {
DOMString error;
PaymentItem total;
};
[Constructor(DOMString type,
optional PaymentRequestUpdateEventInit eventInitDict),
SecureContext,
Func="mozilla::dom::PaymentRequest::PrefEnabled"]
interface PaymentRequestUpdateEvent : Event {
[Throws]
void updateWith(Promise<PaymentDetailsUpdate> detailsPromise);
};
dictionary PaymentRequestUpdateEventInit : EventInit {
};

View File

@ -726,6 +726,7 @@ WEBIDL_FILES = [
'ParentNode.webidl',
'PaymentAddress.webidl',
'PaymentRequest.webidl',
'PaymentRequestUpdateEvent.webidl',
'PaymentResponse.webidl',
'Performance.webidl',
'PerformanceEntry.webidl',