Bug 1442453 - Pass objects around instead of string IDs in the child. r=baku
The existing code only passed strings around to identify PaymentRequest
objects. That meant that we were constantly having to do hashtable lookups to
find the corresponding object. This patch just uses the single map that IPDL
maintains for us and passes objects around, obviating the need for more
hashtable lookups.
MozReview-Commit-ID: 6BBonrc6q4x
--- a/dom/payments/PaymentRequest.cpp
+++ b/dom/payments/PaymentRequest.cpp
@@ -661,17 +661,17 @@ PaymentRequest::CanMakePayment(ErrorResu
return nullptr;
}
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
if (NS_WARN_IF(!manager)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
- nsresult rv = manager->CanMakePayment(mInternalId);
+ nsresult rv = manager->CanMakePayment(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_FAILURE);
return promise.forget();
}
mResultPromise = promise;
return promise.forget();
}
@@ -714,17 +714,17 @@ PaymentRequest::Show(const Optional<Owni
}
if (aDetailsPromise.WasPassed()) {
aDetailsPromise.Value().AppendNativeHandler(this);
mUpdating = true;
mDeferredShow = true;
}
- nsresult rv = manager->ShowPayment(mInternalId);
+ nsresult rv = manager->ShowPayment(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (rv == NS_ERROR_ABORT) {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
} else {
promise->MaybeReject(NS_ERROR_DOM_NOT_ALLOWED_ERR);
}
mState = eClosed;
return promise.forget();
@@ -763,17 +763,17 @@ PaymentRequest::RespondShowPayment(const
return;
}
// https://github.com/w3c/payment-request/issues/692
mShippingAddress.swap(mFullShippingAddress);
mFullShippingAddress = nullptr;
RefPtr<PaymentResponse> paymentResponse =
- new PaymentResponse(GetOwner(), mInternalId, mId, aMethodName,
+ new PaymentResponse(GetOwner(), this, mId, aMethodName,
mShippingOption, mShippingAddress, aDetails,
aPayerName, aPayerEmail, aPayerPhone);
mResponse = paymentResponse;
mAcceptPromise->MaybeResolve(paymentResponse);
mState = eClosed;
mAcceptPromise = nullptr;
}
--- a/dom/payments/PaymentRequestManager.cpp
+++ b/dom/payments/PaymentRequestManager.cpp
@@ -265,32 +265,21 @@ PaymentRequestManager::GetPaymentChild(P
NS_ENSURE_TRUE(win, nullptr);
TabChild* tabChild = TabChild::GetFrom(win->GetDocShell());
NS_ENSURE_TRUE(tabChild, nullptr);
nsAutoString requestId;
aRequest->GetInternalId(requestId);
PaymentRequestChild* paymentChild = new PaymentRequestChild(aRequest);
tabChild->SendPPaymentRequestConstructor(paymentChild);
- if (!mPaymentChildHash.Put(requestId, aRequest, mozilla::fallible) ) {
- paymentChild->MaybeDelete();
- return nullptr;
- }
return paymentChild;
}
nsresult
-PaymentRequestManager::ReleasePaymentChild(const nsAString& aId)
-{
- mPaymentChildHash.Remove(aId);
- return NS_OK;
-}
-
-nsresult
PaymentRequestManager::SendRequestPayment(PaymentRequest* aRequest,
const IPCPaymentActionRequest& aAction,
bool aResponseExpected)
{
PaymentRequestChild* requestChild = GetPaymentChild(aRequest);
nsresult rv = requestChild->RequestPayment(aAction);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -326,24 +315,16 @@ PaymentRequestManager::GetSingleton()
if (!gPaymentManager) {
gPaymentManager = new PaymentRequestManager();
ClearOnShutdown(&gPaymentManager);
}
RefPtr<PaymentRequestManager> manager = gPaymentManager;
return manager.forget();
}
-already_AddRefed<PaymentRequest>
-PaymentRequestManager::GetPaymentRequestById(const nsAString& aRequestId)
-{
- // TODO Pass PaymentRequestChild objects around instead of strings.
- RefPtr<PaymentRequest> request = mPaymentChildHash.Get(aRequestId);
- return request.forget();
-}
-
void
GetSelectedShippingOption(const PaymentDetailsBase& aDetails,
nsAString& aOption)
{
SetDOMStringToNull(aOption);
if (!aDetails.mShippingOptions.WasPassed()) {
return;
}
@@ -440,141 +421,116 @@ PaymentRequestManager::CreatePayment(JSC
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(aRequest);
return NS_OK;
}
nsresult
-PaymentRequestManager::CanMakePayment(const nsAString& aRequestId)
+PaymentRequestManager::CanMakePayment(PaymentRequest* aRequest)
{
- RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
- if (!request) {
- return NS_ERROR_FAILURE;
- }
-
- nsAutoString requestId(aRequestId);
+ nsAutoString requestId;
+ aRequest->GetInternalId(requestId);
IPCPaymentCanMakeActionRequest action(requestId);
- return SendRequestPayment(request, action);
+ return SendRequestPayment(aRequest, action);
}
nsresult
-PaymentRequestManager::ShowPayment(const nsAString& aRequestId)
+PaymentRequestManager::ShowPayment(PaymentRequest* aRequest)
{
if (mShowingRequest) {
return NS_ERROR_ABORT;
}
- RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
- if (!request) {
- return NS_ERROR_FAILURE;
+ nsresult rv = NS_OK;
+ if (!aRequest->IsUpdating()) {
+ nsAutoString requestId;
+ aRequest->GetInternalId(requestId);
+ IPCPaymentShowActionRequest action(requestId);
+ rv = SendRequestPayment(aRequest, action);
}
- nsresult rv = NS_OK;
- if (!request->IsUpdating()) {
- nsAutoString requestId(aRequestId);
- IPCPaymentShowActionRequest action(requestId);
- rv = SendRequestPayment(request, action);
- }
- mShowingRequest = request;
+ mShowingRequest = aRequest;
return rv;
}
nsresult
PaymentRequestManager::AbortPayment(PaymentRequest* aRequest, bool aDeferredShow)
{
- RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
- if (!request) {
- return NS_ERROR_FAILURE;
- }
- MOZ_ASSERT(request == mShowingRequest);
-
- nsAutoString requestId(aRequestId);
+ MOZ_ASSERT(aRequest == mShowingRequest);
+ nsAutoString requestId;
+ aRequest->GetInternalId(requestId);
IPCPaymentAbortActionRequest action(requestId);
// If aDeferredShow is true, then show was called with a promise that was
// rejected. In that case, we need to remember that we called show earlier.
return SendRequestPayment(aRequest, action, aDeferredShow);
}
nsresult
-PaymentRequestManager::CompletePayment(const nsAString& aRequestId,
+PaymentRequestManager::CompletePayment(PaymentRequest* aRequest,
const PaymentComplete& aComplete)
{
- RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
- if (!request) {
- return NS_ERROR_FAILURE;
- }
-
nsString completeStatusString(NS_LITERAL_STRING("unknown"));
uint8_t completeIndex = static_cast<uint8_t>(aComplete);
if (completeIndex < ArrayLength(PaymentCompleteValues::strings)) {
completeStatusString.AssignASCII(
PaymentCompleteValues::strings[completeIndex].value);
}
- nsAutoString requestId(aRequestId);
+ nsAutoString requestId;
+ aRequest->GetInternalId(requestId);
IPCPaymentCompleteActionRequest action(requestId, completeStatusString);
- return SendRequestPayment(request, action, false);
+ return SendRequestPayment(aRequest, action, false);
}
nsresult
PaymentRequestManager::UpdatePayment(JSContext* aCx,
- const nsAString& aRequestId,
+ PaymentRequest* aRequest,
const PaymentDetailsUpdate& aDetails,
bool aRequestShipping,
bool aDeferredShow)
{
NS_ENSURE_ARG_POINTER(aCx);
- RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
- if (!request) {
- return NS_ERROR_UNEXPECTED;
- }
IPCPaymentDetails details;
nsresult rv = ConvertDetailsUpdate(aCx, aDetails, details, aRequestShipping);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsAutoString shippingOption;
SetDOMStringToNull(shippingOption);
if (aRequestShipping) {
GetSelectedShippingOption(aDetails, shippingOption);
- request->SetShippingOption(shippingOption);
+ aRequest->SetShippingOption(shippingOption);
}
- nsAutoString requestId(aRequestId);
+ nsAutoString requestId;
+ aRequest->GetInternalId(requestId);
IPCPaymentUpdateActionRequest action(requestId, details, shippingOption);
// If aDeferredShow is true, then this call serves as the ShowUpdate call for
// this request.
return SendRequestPayment(aRequest, action, aDeferredShow);
}
nsresult
-PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
+PaymentRequestManager::RespondPayment(PaymentRequest* aRequest,
+ const IPCPaymentActionResponse& aResponse)
{
switch (aResponse.type()) {
case IPCPaymentActionResponse::TIPCPaymentCanMakeActionResponse: {
const IPCPaymentCanMakeActionResponse& response = aResponse;
- RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
- if (NS_WARN_IF(!request)) {
- return NS_ERROR_FAILURE;
- }
- request->RespondCanMakePayment(response.result());
- NotifyRequestDone(request);
+ aRequest->RespondCanMakePayment(response.result());
+ NotifyRequestDone(aRequest);
break;
}
case IPCPaymentActionResponse::TIPCPaymentShowActionResponse: {
const IPCPaymentShowActionResponse& response = aResponse;
- RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
- if (NS_WARN_IF(!request)) {
- return NS_ERROR_FAILURE;
- }
nsresult rejectedReason = NS_ERROR_DOM_ABORT_ERR;
switch (response.status()) {
case nsIPaymentActionResponse::PAYMENT_ACCEPTED: {
rejectedReason = NS_OK;
break;
}
case nsIPaymentActionResponse::PAYMENT_REJECTED: {
rejectedReason = NS_ERROR_DOM_ABORT_ERR;
@@ -584,88 +540,71 @@ PaymentRequestManager::RespondPayment(co
rejectedReason = NS_ERROR_DOM_NOT_SUPPORTED_ERR;
break;
}
default: {
rejectedReason = NS_ERROR_UNEXPECTED;
break;
}
}
- request->RespondShowPayment(response.methodName(),
- response.data(),
- response.payerName(),
- response.payerEmail(),
- response.payerPhone(),
- rejectedReason);
+ aRequest->RespondShowPayment(response.methodName(),
+ response.data(),
+ response.payerName(),
+ response.payerEmail(),
+ response.payerPhone(),
+ rejectedReason);
if (NS_FAILED(rejectedReason)) {
- MOZ_ASSERT(mShowingRequest == request);
+ MOZ_ASSERT(mShowingRequest == aRequest);
mShowingRequest = nullptr;
NotifyRequestDone(aRequest);
}
break;
}
case IPCPaymentActionResponse::TIPCPaymentAbortActionResponse: {
const IPCPaymentAbortActionResponse& response = aResponse;
- RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
- if (NS_WARN_IF(!request)) {
- return NS_ERROR_FAILURE;
- }
- request->RespondAbortPayment(response.isSucceeded());
+ aRequest->RespondAbortPayment(response.isSucceeded());
if (response.isSucceeded()) {
- MOZ_ASSERT(mShowingRequest == request);
+ MOZ_ASSERT(mShowingRequest == aRequest);
}
mShowingRequest = nullptr;
- NotifyRequestDone(request);
+ NotifyRequestDone(aRequest);
break;
}
case IPCPaymentActionResponse::TIPCPaymentCompleteActionResponse: {
- const IPCPaymentCompleteActionResponse& response = aResponse;
- RefPtr<PaymentRequest> request = GetPaymentRequestById(response.requestId());
- if (NS_WARN_IF(!request)) {
- return NS_ERROR_FAILURE;
- }
- request->RespondComplete();
- MOZ_ASSERT(mShowingRequest == request);
+ aRequest->RespondComplete();
+ MOZ_ASSERT(mShowingRequest == aRequest);
mShowingRequest = nullptr;
- NotifyRequestDone(request);
+ NotifyRequestDone(aRequest);
break;
}
default: {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
nsresult
-PaymentRequestManager::ChangeShippingAddress(const nsAString& aRequestId,
+PaymentRequestManager::ChangeShippingAddress(PaymentRequest* aRequest,
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());
+ return aRequest->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,
+PaymentRequestManager::ChangeShippingOption(PaymentRequest* aRequest,
const nsAString& aOption)
{
- RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
- if (NS_WARN_IF(!request)) {
- return NS_ERROR_FAILURE;
- }
- return request->UpdateShippingOption(aOption);
+ return aRequest->UpdateShippingOption(aOption);
}
} // end of namespace dom
} // end of namespace mozilla
--- a/dom/payments/PaymentRequestManager.h
+++ b/dom/payments/PaymentRequestManager.h
@@ -27,19 +27,16 @@ class IPCPaymentActionRequest;
*/
class PaymentRequestManager final
{
public:
NS_INLINE_DECL_REFCOUNTING(PaymentRequestManager)
static already_AddRefed<PaymentRequestManager> GetSingleton();
- already_AddRefed<PaymentRequest>
- GetPaymentRequestById(const nsAString& aRequestId);
-
/*
* This method is used to create PaymentRequest object and send corresponding
* data to chrome process for internal payment creation, such that content
* process can ask specific task by sending requestId only.
*/
nsresult
CreatePayment(JSContext* aCx,
nsPIDOMWindowInner* aWindow,
@@ -50,47 +47,43 @@ public:
PaymentRequest** aRequest);
nsresult CanMakePayment(PaymentRequest* aRequest);
nsresult ShowPayment(PaymentRequest* aRequest);
nsresult AbortPayment(PaymentRequest* aRequest, bool aDeferredShow);
nsresult CompletePayment(PaymentRequest* aRequest,
const PaymentComplete& aComplete);
nsresult UpdatePayment(JSContext* aCx,
- const nsAString& aRequestId,
+ PaymentRequest* aRequest,
const PaymentDetailsUpdate& aDetails,
bool aRequestShipping,
bool aDeferredShow);
- nsresult RespondPayment(const IPCPaymentActionResponse& aResponse);
- nsresult ChangeShippingAddress(const nsAString& aRequestId,
+ nsresult RespondPayment(PaymentRequest* aRequest,
+ const IPCPaymentActionResponse& aResponse);
+ nsresult ChangeShippingAddress(PaymentRequest* aRequest,
const IPCPaymentAddress& aAddress);
- nsresult ChangeShippingOption(const nsAString& aRequestId,
+ nsresult ChangeShippingOption(PaymentRequest* aRequest,
const nsAString& aOption);
- nsresult
- ReleasePaymentChild(const nsAString& aId);
-
private:
PaymentRequestManager() = default;
~PaymentRequestManager()
{
MOZ_ASSERT(mActivePayments.Count() == 0);
}
PaymentRequestChild* GetPaymentChild(PaymentRequest* aRequest);
nsresult SendRequestPayment(PaymentRequest* aRequest,
const IPCPaymentActionRequest& action,
bool aResponseExpected = true);
void NotifyRequestDone(PaymentRequest* aRequest);
- // The container for the created PaymentRequests
- nsDataHashtable<nsStringHashKey, PaymentRequest*> mPaymentChildHash;
// Strong pointer to requests with ongoing IPC messages to the parent.
nsDataHashtable<nsRefPtrHashKey<PaymentRequest>, uint32_t> mActivePayments;
RefPtr<PaymentRequest> mShowingRequest;
};
} // end of namespace dom
} // end of namespace mozilla
--- a/dom/payments/PaymentResponse.cpp
+++ b/dom/payments/PaymentResponse.cpp
@@ -20,28 +20,28 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(PaymentR
NS_IMPL_CYCLE_COLLECTING_RELEASE(PaymentResponse)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PaymentResponse)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
- const nsAString& aInternalId,
+ PaymentRequest* aRequest,
const nsAString& aRequestId,
const nsAString& aMethodName,
const nsAString& aShippingOption,
RefPtr<PaymentAddress> aShippingAddress,
const nsAString& aDetails,
const nsAString& aPayerName,
const nsAString& aPayerEmail,
const nsAString& aPayerPhone)
: mOwner(aWindow)
, mCompleteCalled(false)
- , mInternalId(aInternalId)
+ , mRequest(aRequest)
, mRequestId(aRequestId)
, mMethodName(aMethodName)
, mDetails(aDetails)
, mShippingOption(aShippingOption)
, mPayerName(aPayerName)
, mPayerEmail(aPayerEmail)
, mPayerPhone(aPayerPhone)
, mShippingAddress(aShippingAddress)
@@ -146,17 +146,17 @@ PaymentResponse::Complete(PaymentComplet
mCompleteCalled = true;
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
if (NS_WARN_IF(!manager)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
- nsresult rv = manager->CompletePayment(mInternalId, result);
+ nsresult rv = manager->CompletePayment(mRequest, result);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_FAILURE);
return promise.forget();
}
mPromise = promise;
return promise.forget();
}
--- a/dom/payments/PaymentResponse.h
+++ b/dom/payments/PaymentResponse.h
@@ -10,27 +10,28 @@
#include "mozilla/dom/PaymentResponseBinding.h" // PaymentComplete
#include "nsPIDOMWindow.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class PaymentAddress;
+class PaymentRequest;
class Promise;
class PaymentResponse final : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PaymentResponse)
PaymentResponse(nsPIDOMWindowInner* aWindow,
- const nsAString& aInternalId,
+ PaymentRequest* aRequest,
const nsAString& aRequestId,
const nsAString& aMethodName,
const nsAString& aShippingOption,
RefPtr<PaymentAddress> aShippingAddress,
const nsAString& aDetails,
const nsAString& aPayerName,
const nsAString& aPayerEmail,
const nsAString& aPayerPhone);
@@ -66,17 +67,17 @@ public:
void RespondComplete();
protected:
~PaymentResponse();
private:
nsCOMPtr<nsPIDOMWindowInner> mOwner;
bool mCompleteCalled;
- nsString mInternalId;
+ PaymentRequest* mRequest;
nsString mRequestId;
nsString mMethodName;
nsString mDetails;
nsString mShippingOption;
nsString mPayerName;
nsString mPayerEmail;
nsString mPayerPhone;
RefPtr<PaymentAddress> mShippingAddress;
--- a/dom/payments/ipc/PaymentRequestChild.cpp
+++ b/dom/payments/ipc/PaymentRequestChild.cpp
@@ -33,49 +33,54 @@ mozilla::ipc::IPCResult
PaymentRequestChild::RecvRespondPayment(const IPCPaymentActionResponse& aResponse)
{
if (!mRequest) {
return IPC_FAIL_NO_REASON(this);
}
const IPCPaymentActionResponse& response = aResponse;
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
- nsresult rv = manager->RespondPayment(response);
+
+ // Hold a strong reference to our request for the entire response.
+ RefPtr<PaymentRequest> request(mRequest);
+ nsresult rv = manager->RespondPayment(request, response);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
PaymentRequestChild::RecvChangeShippingAddress(const nsString& aRequestId,
const IPCPaymentAddress& aAddress)
{
if (!mRequest) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
- nsresult rv = manager->ChangeShippingAddress(aRequestId, aAddress);
+ RefPtr<PaymentRequest> request(mRequest);
+ nsresult rv = manager->ChangeShippingAddress(request, 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 (!mRequest) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
- nsresult rv = manager->ChangeShippingOption(aRequestId, aOption);
+ RefPtr<PaymentRequest> request(mRequest);
+ nsresult rv = manager->ChangeShippingOption(request, aOption);
if (NS_WARN_IF(NS_FAILED(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
void
PaymentRequestChild::ActorDestroy(ActorDestroyReason aWhy)
@@ -104,19 +109,15 @@ void
PaymentRequestChild::DetachFromRequest()
{
MOZ_ASSERT(mRequest);
nsAutoString id;
mRequest->GetInternalId(id);
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
MOZ_ASSERT(manager);
- nsresult rv = manager->ReleasePaymentChild(id);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- MOZ_ASSERT(false);
- }
mRequest->SetIPC(nullptr);
mRequest = nullptr;
}
} // end of namespace dom
} // end of namespace mozilla