зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1442453 - Create a single IPC actor per PaymentRequest. r=baku
There isn't any need to create an actor per call to the parent. This patch lines up PaymentRequest with PPaymentRequestChild objects and links them together. It also simplifies the maps and arrays we use to keep track of these objects. There's one tricky bit to note in this patch: in the case that a promise is passed to paymentRequest.show(), we don't notify the parent process until the promise resolves (when we call either UpdatePayment or AbortUpdate). In that case, I needed to distinguish between an "update" because of the promise resolving or a call to updateWith on an shippingaddresschange event in order to get the bookkeeping right with the mActivePayments hashtable. In that case, the PaymentRequest is kept alive by mShowingRequest alone. In all other cases, mActivePayments keeps the PaymentRequest alive until we resolve or reject the correct promise. MozReview-Commit-ID: HoHjn8eqC4T --HG-- extra : rebase_source : 4da1d65d1f791f4a5c18871ab3a3dcf94e833b90
This commit is contained in:
Родитель
40ee64ba85
Коммит
49d7053a3e
|
@ -3439,6 +3439,7 @@ TabChild::AllocPPaymentRequestChild()
|
|||
bool
|
||||
TabChild::DeallocPPaymentRequestChild(PPaymentRequestChild* actor)
|
||||
{
|
||||
delete actor;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "BasicCardPayment.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/PaymentRequest.h"
|
||||
#include "mozilla/dom/PaymentRequestChild.h"
|
||||
#include "mozilla/dom/PaymentResponse.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -631,8 +632,10 @@ PaymentRequest::PaymentRequest(nsPIDOMWindowInner* aWindow, const nsAString& aIn
|
|||
, mShippingAddress(nullptr)
|
||||
, mUpdating(false)
|
||||
, mRequestShipping(false)
|
||||
, mDeferredShow(false)
|
||||
, mUpdateError(NS_OK)
|
||||
, mState(eCreated)
|
||||
, mIPC(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
}
|
||||
|
@ -713,6 +716,7 @@ PaymentRequest::Show(const Optional<OwningNonNull<Promise>>& aDetailsPromise,
|
|||
if (aDetailsPromise.WasPassed()) {
|
||||
aDetailsPromise.Value().AppendNativeHandler(this);
|
||||
mUpdating = true;
|
||||
mDeferredShow = true;
|
||||
}
|
||||
|
||||
nsresult rv = manager->ShowPayment(mInternalId);
|
||||
|
@ -807,7 +811,10 @@ PaymentRequest::Abort(ErrorResult& aRv)
|
|||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
nsresult rv = manager->AbortPayment(mInternalId);
|
||||
|
||||
// It's possible for to call this between show and its promise resolving.
|
||||
nsresult rv = manager->AbortPayment(this, mDeferredShow);
|
||||
mDeferredShow = false;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
|
@ -852,14 +859,16 @@ PaymentRequest::RespondAbortPayment(bool aSuccess)
|
|||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequest::UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetails)
|
||||
PaymentRequest::UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetails,
|
||||
bool aDeferredShow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCx);
|
||||
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
|
||||
if (NS_WARN_IF(!manager)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = manager->UpdatePayment(aCx, mInternalId, aDetails, mRequestShipping);
|
||||
nsresult rv = manager->UpdatePayment(aCx, this, aDetails, mRequestShipping,
|
||||
aDeferredShow);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -867,14 +876,14 @@ PaymentRequest::UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetai
|
|||
}
|
||||
|
||||
void
|
||||
PaymentRequest::AbortUpdate(nsresult aRv)
|
||||
PaymentRequest::AbortUpdate(nsresult aRv, bool aDeferredShow)
|
||||
{
|
||||
MOZ_ASSERT(NS_FAILED(aRv));
|
||||
|
||||
// Close down any remaining user interface.
|
||||
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
|
||||
MOZ_ASSERT(manager);
|
||||
nsresult rv = manager->AbortPayment(mInternalId);
|
||||
nsresult rv = manager->AbortPayment(this, aDeferredShow);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
@ -1019,33 +1028,40 @@ PaymentRequest::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
|||
// Converting value to a PaymentDetailsUpdate dictionary
|
||||
PaymentDetailsUpdate details;
|
||||
if (!details.Init(aCx, aValue)) {
|
||||
AbortUpdate(NS_ERROR_DOM_TYPE_ERR);
|
||||
AbortUpdate(NS_ERROR_DOM_TYPE_ERR, mDeferredShow);
|
||||
JS_ClearPendingException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = IsValidDetailsUpdate(details, mRequestShipping);
|
||||
if (NS_FAILED(rv)) {
|
||||
AbortUpdate(rv);
|
||||
AbortUpdate(rv, mDeferredShow);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the PaymentRequest with the new details
|
||||
if (NS_FAILED(UpdatePayment(aCx, details))) {
|
||||
AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
|
||||
if (NS_FAILED(UpdatePayment(aCx, details, mDeferredShow))) {
|
||||
AbortUpdate(NS_ERROR_DOM_ABORT_ERR, mDeferredShow);
|
||||
return;
|
||||
}
|
||||
|
||||
mDeferredShow = false;
|
||||
}
|
||||
|
||||
void
|
||||
PaymentRequest::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
MOZ_ASSERT(mDeferredShow);
|
||||
mUpdating = false;
|
||||
AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
|
||||
AbortUpdate(NS_ERROR_DOM_ABORT_ERR, mDeferredShow);
|
||||
mDeferredShow = false;
|
||||
}
|
||||
|
||||
PaymentRequest::~PaymentRequest()
|
||||
{
|
||||
if (mIPC) {
|
||||
mIPC->MaybeDelete();
|
||||
}
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace dom {
|
|||
|
||||
class EventHandlerNonNull;
|
||||
class PaymentAddress;
|
||||
class PaymentRequestChild;
|
||||
class PaymentResponse;
|
||||
|
||||
class PaymentRequest final : public DOMEventTargetHelper
|
||||
|
@ -135,8 +136,9 @@ public:
|
|||
void GetShippingOption(nsAString& aRetVal) const;
|
||||
nsresult UpdateShippingOption(const nsAString& aShippingOption);
|
||||
|
||||
nsresult UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetails);
|
||||
void AbortUpdate(nsresult aRv);
|
||||
nsresult UpdatePayment(JSContext* aCx, const PaymentDetailsUpdate& aDetails,
|
||||
bool aDeferredShow);
|
||||
void AbortUpdate(nsresult aRv, bool aDeferredShow);
|
||||
|
||||
void SetShippingType(const Nullable<PaymentShippingType>& aShippingType);
|
||||
Nullable<PaymentShippingType> GetShippingType() const;
|
||||
|
@ -154,6 +156,16 @@ public:
|
|||
IMPL_EVENT_HANDLER(shippingaddresschange);
|
||||
IMPL_EVENT_HANDLER(shippingoptionchange);
|
||||
|
||||
void SetIPC(PaymentRequestChild* aChild)
|
||||
{
|
||||
mIPC = aChild;
|
||||
}
|
||||
|
||||
PaymentRequestChild* GetIPC()
|
||||
{
|
||||
return mIPC;
|
||||
}
|
||||
|
||||
protected:
|
||||
~PaymentRequest();
|
||||
|
||||
|
@ -191,6 +203,11 @@ protected:
|
|||
// Whether shipping was requested. This models [[options]].requestShipping,
|
||||
// but we don't actually store the full [[options]] internal slot.
|
||||
bool mRequestShipping;
|
||||
|
||||
// True if the user passed a promise to show, causing us to defer telling the
|
||||
// front end about it.
|
||||
bool mDeferredShow;
|
||||
|
||||
// The error is set in AbortUpdate(). The value is NS_OK by default.
|
||||
nsresult mUpdateError;
|
||||
|
||||
|
@ -200,6 +217,8 @@ protected:
|
|||
eInteractive,
|
||||
eClosed
|
||||
} mState;
|
||||
|
||||
PaymentRequestChild* mIPC;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -252,94 +252,74 @@ ConvertOptions(const PaymentOptions& aOptions,
|
|||
|
||||
StaticRefPtr<PaymentRequestManager> gPaymentManager;
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::GetPaymentChild(PaymentRequest* aRequest,
|
||||
PaymentRequestChild** aChild)
|
||||
PaymentRequestChild*
|
||||
PaymentRequestManager::GetPaymentChild(PaymentRequest* aRequest)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequest);
|
||||
NS_ENSURE_ARG_POINTER(aChild);
|
||||
*aChild = nullptr;
|
||||
MOZ_ASSERT(aRequest);
|
||||
|
||||
RefPtr<PaymentRequestChild> paymentChild;
|
||||
if (mPaymentChildHash.Get(aRequest, getter_AddRefs(paymentChild))) {
|
||||
paymentChild.forget(aChild);
|
||||
return NS_OK;
|
||||
if (PaymentRequestChild* child = aRequest->GetIPC()) {
|
||||
return child;
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* win = aRequest->GetOwner();
|
||||
NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(win, nullptr);
|
||||
TabChild* tabChild = TabChild::GetFrom(win->GetDocShell());
|
||||
NS_ENSURE_TRUE(tabChild, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(tabChild, nullptr);
|
||||
nsAutoString requestId;
|
||||
aRequest->GetInternalId(requestId);
|
||||
|
||||
paymentChild = new PaymentRequestChild();
|
||||
PaymentRequestChild* paymentChild = new PaymentRequestChild(aRequest);
|
||||
tabChild->SendPPaymentRequestConstructor(paymentChild);
|
||||
if (!mPaymentChildHash.Put(aRequest, paymentChild, mozilla::fallible) ) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!mPaymentChildHash.Put(requestId, aRequest, mozilla::fallible) ) {
|
||||
paymentChild->MaybeDelete();
|
||||
return nullptr;
|
||||
}
|
||||
paymentChild.forget(aChild);
|
||||
return NS_OK;
|
||||
|
||||
return paymentChild;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::ReleasePaymentChild(PaymentRequestChild* aPaymentChild)
|
||||
PaymentRequestManager::ReleasePaymentChild(const nsAString& aId)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPaymentChild);
|
||||
for (auto iter = mPaymentChildHash.Iter(); !iter.Done(); iter.Next()) {
|
||||
RefPtr<PaymentRequestChild> child = iter.Data();
|
||||
if (NS_WARN_IF(!child)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (child == aPaymentChild) {
|
||||
iter.Remove();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::ReleasePaymentChild(PaymentRequest* aRequest)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequest);
|
||||
|
||||
RefPtr<PaymentRequestChild> paymentChild;
|
||||
if(!mPaymentChildHash.Remove(aRequest, getter_AddRefs(paymentChild))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (NS_WARN_IF(!paymentChild)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
paymentChild->MaybeDelete();
|
||||
mPaymentChildHash.Remove(aId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::SendRequestPayment(PaymentRequest* aRequest,
|
||||
const IPCPaymentActionRequest& aAction,
|
||||
bool aReleaseAfterSend)
|
||||
bool aResponseExpected)
|
||||
{
|
||||
RefPtr<PaymentRequestChild> requestChild;
|
||||
nsresult rv = GetPaymentChild(aRequest, getter_AddRefs(requestChild));
|
||||
PaymentRequestChild* requestChild = GetPaymentChild(aRequest);
|
||||
nsresult rv = requestChild->RequestPayment(aAction);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = requestChild->RequestPayment(aAction);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aReleaseAfterSend) {
|
||||
rv = ReleasePaymentChild(aRequest);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
if (aResponseExpected) {
|
||||
auto count = mActivePayments.LookupForAdd(aRequest);
|
||||
if (count) {
|
||||
count.Data()++;
|
||||
} else {
|
||||
count.OrInsert([]() { return 1; });
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PaymentRequestManager::NotifyRequestDone(PaymentRequest* aRequest)
|
||||
{
|
||||
auto entry = mActivePayments.Lookup(aRequest);
|
||||
MOZ_ASSERT(entry);
|
||||
MOZ_ASSERT(entry.Data() > 0);
|
||||
|
||||
uint32_t count = --entry.Data();
|
||||
if (count == 0) {
|
||||
entry.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<PaymentRequestManager>
|
||||
PaymentRequestManager::GetSingleton()
|
||||
{
|
||||
|
@ -354,13 +334,9 @@ PaymentRequestManager::GetSingleton()
|
|||
already_AddRefed<PaymentRequest>
|
||||
PaymentRequestManager::GetPaymentRequestById(const nsAString& aRequestId)
|
||||
{
|
||||
for (const RefPtr<PaymentRequest>& request : mRequestQueue) {
|
||||
if (request->Equals(aRequestId)) {
|
||||
RefPtr<PaymentRequest> paymentRequest = request;
|
||||
return paymentRequest.forget();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
// TODO Pass PaymentRequestChild objects around instead of strings.
|
||||
RefPtr<PaymentRequest> request = mPaymentChildHash.Get(aRequestId);
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -460,11 +436,10 @@ PaymentRequestManager::CreatePayment(JSContext* aCx,
|
|||
options,
|
||||
shippingOption);
|
||||
|
||||
rv = SendRequestPayment(request, action, true);
|
||||
rv = SendRequestPayment(request, action, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mRequestQueue.AppendElement(request);
|
||||
request.forget(aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -504,17 +479,20 @@ PaymentRequestManager::ShowPayment(const nsAString& aRequestId)
|
|||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::AbortPayment(const nsAString& aRequestId)
|
||||
PaymentRequestManager::AbortPayment(PaymentRequest* aRequest, bool aDeferredShow)
|
||||
{
|
||||
RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
|
||||
if (!request) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_ASSERT(request == mShowingRequest);
|
||||
|
||||
nsAutoString requestId(aRequestId);
|
||||
IPCPaymentAbortActionRequest action(requestId);
|
||||
|
||||
return SendRequestPayment(request, action);
|
||||
// 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
|
||||
|
@ -536,14 +514,15 @@ PaymentRequestManager::CompletePayment(const nsAString& aRequestId,
|
|||
nsAutoString requestId(aRequestId);
|
||||
IPCPaymentCompleteActionRequest action(requestId, completeStatusString);
|
||||
|
||||
return SendRequestPayment(request, action);
|
||||
return SendRequestPayment(request, action, false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestManager::UpdatePayment(JSContext* aCx,
|
||||
const nsAString& aRequestId,
|
||||
const PaymentDetailsUpdate& aDetails,
|
||||
bool aRequestShipping)
|
||||
bool aRequestShipping,
|
||||
bool aDeferredShow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCx);
|
||||
RefPtr<PaymentRequest> request = GetPaymentRequestById(aRequestId);
|
||||
|
@ -565,7 +544,10 @@ PaymentRequestManager::UpdatePayment(JSContext* aCx,
|
|||
|
||||
nsAutoString requestId(aRequestId);
|
||||
IPCPaymentUpdateActionRequest action(requestId, details, shippingOption);
|
||||
return SendRequestPayment(request, action);
|
||||
|
||||
// If aDeferredShow is true, then this call serves as the ShowUpdate call for
|
||||
// this request.
|
||||
return SendRequestPayment(aRequest, action, aDeferredShow);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -579,10 +561,7 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
request->RespondCanMakePayment(response.result());
|
||||
nsresult rv = ReleasePaymentChild(request);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
NotifyRequestDone(request);
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionResponse::TIPCPaymentShowActionResponse: {
|
||||
|
@ -619,11 +598,7 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
|
|||
if (NS_FAILED(rejectedReason)) {
|
||||
MOZ_ASSERT(mShowingRequest == request);
|
||||
mShowingRequest = nullptr;
|
||||
mRequestQueue.RemoveElement(request);
|
||||
nsresult rv = ReleasePaymentChild(request);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
NotifyRequestDone(aRequest);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -636,13 +611,9 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
|
|||
request->RespondAbortPayment(response.isSucceeded());
|
||||
if (response.isSucceeded()) {
|
||||
MOZ_ASSERT(mShowingRequest == request);
|
||||
mRequestQueue.RemoveElement(request);
|
||||
}
|
||||
mShowingRequest = nullptr;
|
||||
nsresult rv = ReleasePaymentChild(request);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
NotifyRequestDone(request);
|
||||
break;
|
||||
}
|
||||
case IPCPaymentActionResponse::TIPCPaymentCompleteActionResponse: {
|
||||
|
@ -654,11 +625,7 @@ PaymentRequestManager::RespondPayment(const IPCPaymentActionResponse& aResponse)
|
|||
request->RespondComplete();
|
||||
MOZ_ASSERT(mShowingRequest == request);
|
||||
mShowingRequest = nullptr;
|
||||
mRequestQueue.RemoveElement(request);
|
||||
nsresult rv = ReleasePaymentChild(request);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
NotifyRequestDone(request);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -49,15 +49,16 @@ public:
|
|||
const PaymentOptions& aOptions,
|
||||
PaymentRequest** aRequest);
|
||||
|
||||
nsresult CanMakePayment(const nsAString& aRequestId);
|
||||
nsresult ShowPayment(const nsAString& aRequestId);
|
||||
nsresult AbortPayment(const nsAString& aRequestId);
|
||||
nsresult CompletePayment(const nsAString& aRequestId,
|
||||
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,
|
||||
const PaymentDetailsUpdate& aDetails,
|
||||
bool aRequestShipping);
|
||||
bool aRequestShipping,
|
||||
bool aDeferredShow);
|
||||
|
||||
nsresult RespondPayment(const IPCPaymentActionResponse& aResponse);
|
||||
nsresult ChangeShippingAddress(const nsAString& aRequestId,
|
||||
|
@ -66,23 +67,27 @@ public:
|
|||
const nsAString& aOption);
|
||||
|
||||
nsresult
|
||||
ReleasePaymentChild(PaymentRequestChild* aPaymentChild);
|
||||
ReleasePaymentChild(const nsAString& aId);
|
||||
|
||||
private:
|
||||
PaymentRequestManager() = default;
|
||||
~PaymentRequestManager() = default;
|
||||
~PaymentRequestManager()
|
||||
{
|
||||
MOZ_ASSERT(mActivePayments.Count() == 0);
|
||||
}
|
||||
|
||||
nsresult GetPaymentChild(PaymentRequest* aRequest,
|
||||
PaymentRequestChild** aPaymentChild);
|
||||
nsresult ReleasePaymentChild(PaymentRequest* aRequest);
|
||||
PaymentRequestChild* GetPaymentChild(PaymentRequest* aRequest);
|
||||
|
||||
nsresult SendRequestPayment(PaymentRequest* aRequest,
|
||||
const IPCPaymentActionRequest& action,
|
||||
bool aReleaseAfterSend = false);
|
||||
bool aResponseExpected = true);
|
||||
|
||||
void NotifyRequestDone(PaymentRequest* aRequest);
|
||||
|
||||
// The container for the created PaymentRequests
|
||||
nsTArray<RefPtr<PaymentRequest>> mRequestQueue;
|
||||
nsRefPtrHashtable<nsRefPtrHashKey<PaymentRequest>, PaymentRequestChild> mPaymentChildHash;
|
||||
nsDataHashtable<nsStringHashKey, PaymentRequest*> mPaymentChildHash;
|
||||
// Strong pointer to requests with ongoing IPC messages to the parent.
|
||||
nsDataHashtable<nsRefPtrHashKey<PaymentRequest>, uint32_t> mActivePayments;
|
||||
RefPtr<PaymentRequest> mShowingRequest;
|
||||
};
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ PaymentRequestUpdateEvent::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value
|
|||
// Converting value to a PaymentDetailsUpdate dictionary
|
||||
PaymentDetailsUpdate details;
|
||||
if (!details.Init(aCx, aValue)) {
|
||||
mRequest->AbortUpdate(NS_ERROR_TYPE_ERR);
|
||||
mRequest->AbortUpdate(NS_ERROR_TYPE_ERR, false);
|
||||
JS_ClearPendingException(aCx);
|
||||
return;
|
||||
}
|
||||
|
@ -76,13 +76,13 @@ PaymentRequestUpdateEvent::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value
|
|||
// PaymentRequest.
|
||||
nsresult rv = mRequest->IsValidDetailsUpdate(details, true/*aRequestShipping*/);
|
||||
if (NS_FAILED(rv)) {
|
||||
mRequest->AbortUpdate(rv);
|
||||
mRequest->AbortUpdate(rv, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the PaymentRequest with the new details
|
||||
if (NS_FAILED(mRequest->UpdatePayment(aCx, details))) {
|
||||
mRequest->AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
|
||||
if (NS_FAILED(mRequest->UpdatePayment(aCx, details, false))) {
|
||||
mRequest->AbortUpdate(NS_ERROR_DOM_ABORT_ERR, false);
|
||||
return;
|
||||
}
|
||||
mWaitForUpdate = false;
|
||||
|
@ -94,7 +94,7 @@ PaymentRequestUpdateEvent::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value
|
|||
{
|
||||
MOZ_ASSERT(mRequest);
|
||||
|
||||
mRequest->AbortUpdate(NS_ERROR_DOM_ABORT_ERR);
|
||||
mRequest->AbortUpdate(NS_ERROR_DOM_ABORT_ERR, false);
|
||||
mWaitForUpdate = false;
|
||||
mRequest->SetUpdating(false);
|
||||
}
|
||||
|
|
|
@ -5,20 +5,22 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PaymentRequestChild.h"
|
||||
#include "mozilla/dom/PaymentRequest.h"
|
||||
#include "mozilla/dom/PaymentRequestManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
PaymentRequestChild::PaymentRequestChild()
|
||||
: mActorAlive(true)
|
||||
PaymentRequestChild::PaymentRequestChild(PaymentRequest* aRequest)
|
||||
: mRequest(aRequest)
|
||||
{
|
||||
mRequest->SetIPC(this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PaymentRequestChild::RequestPayment(const IPCPaymentActionRequest& aAction)
|
||||
{
|
||||
if (!mActorAlive) {
|
||||
if (!mRequest) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!SendRequestPayment(aAction)) {
|
||||
|
@ -30,7 +32,7 @@ PaymentRequestChild::RequestPayment(const IPCPaymentActionRequest& aAction)
|
|||
mozilla::ipc::IPCResult
|
||||
PaymentRequestChild::RecvRespondPayment(const IPCPaymentActionResponse& aResponse)
|
||||
{
|
||||
if (!mActorAlive) {
|
||||
if (!mRequest) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
const IPCPaymentActionResponse& response = aResponse;
|
||||
|
@ -47,7 +49,7 @@ mozilla::ipc::IPCResult
|
|||
PaymentRequestChild::RecvChangeShippingAddress(const nsString& aRequestId,
|
||||
const IPCPaymentAddress& aAddress)
|
||||
{
|
||||
if (!mActorAlive) {
|
||||
if (!mRequest) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
|
||||
|
@ -63,7 +65,7 @@ mozilla::ipc::IPCResult
|
|||
PaymentRequestChild::RecvChangeShippingOption(const nsString& aRequestId,
|
||||
const nsString& aOption)
|
||||
{
|
||||
if (!mActorAlive) {
|
||||
if (!mRequest) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
|
||||
|
@ -78,20 +80,16 @@ PaymentRequestChild::RecvChangeShippingOption(const nsString& aRequestId,
|
|||
void
|
||||
PaymentRequestChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mActorAlive = false;
|
||||
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
|
||||
MOZ_ASSERT(manager);
|
||||
nsresult rv = manager->ReleasePaymentChild(this);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_ASSERT(false);
|
||||
if (mRequest) {
|
||||
DetachFromRequest();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PaymentRequestChild::MaybeDelete()
|
||||
{
|
||||
if (mActorAlive) {
|
||||
mActorAlive = false;
|
||||
if (mRequest) {
|
||||
DetachFromRequest();
|
||||
Send__delete__(this);
|
||||
}
|
||||
}
|
||||
|
@ -102,5 +100,23 @@ PaymentRequestChild::SendRequestPayment(const IPCPaymentActionRequest& aAction)
|
|||
return PPaymentRequestChild::SendRequestPayment(aAction);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -12,11 +12,12 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class PaymentRequest;
|
||||
|
||||
class PaymentRequestChild final : public PPaymentRequestChild
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PaymentRequestChild);
|
||||
public:
|
||||
PaymentRequestChild();
|
||||
explicit PaymentRequestChild(PaymentRequest* aRequest);
|
||||
|
||||
void MaybeDelete();
|
||||
|
||||
|
@ -40,8 +41,8 @@ private:
|
|||
~PaymentRequestChild() = default;
|
||||
|
||||
bool SendRequestPayment(const IPCPaymentActionRequest& aAction);
|
||||
|
||||
bool mActorAlive;
|
||||
void DetachFromRequest();
|
||||
PaymentRequest* MOZ_NON_OWNING_REF mRequest;
|
||||
};
|
||||
|
||||
} // end of namespace dom
|
||||
|
|
Загрузка…
Ссылка в новой задаче