Bug 1447773 - Time out PaymentResponse after 5 seconds. r=mrbkap

MozReview-Commit-ID: JnoKgLC6yL6

--HG--
extra : rebase_source : 8fb0f553409b1ecf142568146f3f4cc7ad33ac4f
This commit is contained in:
Henri Sivonen 2018-05-29 12:31:22 +03:00
Родитель 330ef8028e
Коммит 77eaf92c58
5 изменённых файлов: 71 добавлений и 20 удалений

Просмотреть файл

@ -478,13 +478,18 @@ PaymentRequestManager::AbortPayment(PaymentRequest* aRequest, bool aDeferredShow
nsresult
PaymentRequestManager::CompletePayment(PaymentRequest* aRequest,
const PaymentComplete& aComplete)
const PaymentComplete& aComplete,
bool aTimedOut)
{
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);
if (aTimedOut) {
completeStatusString.AssignLiteral("timeout");
} else {
uint8_t completeIndex = static_cast<uint8_t>(aComplete);
if (completeIndex < ArrayLength(PaymentCompleteValues::strings)) {
completeStatusString.AssignASCII(
PaymentCompleteValues::strings[completeIndex].value);
}
}
nsAutoString requestId;

Просмотреть файл

@ -50,7 +50,8 @@ public:
nsresult ShowPayment(PaymentRequest* aRequest);
nsresult AbortPayment(PaymentRequest* aRequest, bool aDeferredShow);
nsresult CompletePayment(PaymentRequest* aRequest,
const PaymentComplete& aComplete);
const PaymentComplete& aComplete,
bool aTimedOut = false);
nsresult UpdatePayment(JSContext* aCx,
PaymentRequest* aRequest,
const PaymentDetailsUpdate& aDetails,

Просмотреть файл

@ -4,6 +4,7 @@
* 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/StaticPrefs.h"
#include "mozilla/dom/PaymentResponse.h"
#include "mozilla/dom/BasicCardPaymentBinding.h"
#include "BasicCardPayment.h"
@ -22,6 +23,7 @@ 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_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_END
PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
@ -49,6 +51,11 @@ PaymentResponse::PaymentResponse(nsPIDOMWindowInner* aWindow,
// TODO: from https://github.com/w3c/browser-payment-api/issues/480
// Add payerGivenName + payerFamilyName to PaymentAddress
NS_NewTimerWithCallback(getter_AddRefs(mTimer),
this,
StaticPrefs::dom_payments_response_timeout(),
nsITimer::TYPE_ONE_SHOT,
aWindow->EventTargetFor(TaskCategory::Other));
}
PaymentResponse::~PaymentResponse()
@ -136,16 +143,13 @@ PaymentResponse::Complete(PaymentComplete result, ErrorResult& aRv)
return nullptr;
}
nsIGlobalObject* global = mOwner->AsGlobal();
ErrorResult errResult;
RefPtr<Promise> promise = Promise::Create(global, errResult);
if (errResult.Failed()) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
mCompleteCalled = true;
if (mTimer) {
mTimer->Cancel();
mTimer = nullptr;
}
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
if (NS_WARN_IF(!manager)) {
aRv.Throw(NS_ERROR_FAILURE);
@ -153,8 +157,16 @@ PaymentResponse::Complete(PaymentComplete result, ErrorResult& aRv)
}
nsresult rv = manager->CompletePayment(mRequest, result);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_FAILURE);
return promise.forget();
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsIGlobalObject* global = mOwner->AsGlobal();
ErrorResult errResult;
RefPtr<Promise> promise = Promise::Create(global, errResult);
if (errResult.Failed()) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
mPromise = promise;
@ -164,10 +176,29 @@ PaymentResponse::Complete(PaymentComplete result, ErrorResult& aRv)
void
PaymentResponse::RespondComplete()
{
MOZ_ASSERT(mPromise);
// mPromise may be null when timing out
if (mPromise) {
mPromise->MaybeResolve(JS::UndefinedHandleValue);
mPromise = nullptr;
}
}
mPromise->MaybeResolve(JS::UndefinedHandleValue);
mPromise = nullptr;
NS_IMETHODIMP
PaymentResponse::Notify(nsITimer *timer)
{
mTimer = nullptr;
if (mCompleteCalled) {
return NS_OK;
}
mCompleteCalled = true;
RefPtr<PaymentRequestManager> manager = PaymentRequestManager::GetSingleton();
if (NS_WARN_IF(!manager)) {
return NS_ERROR_FAILURE;
}
return manager->CompletePayment(mRequest, PaymentComplete::Unknown, true);
}
} // namespace dom

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/dom/PaymentResponseBinding.h" // PaymentComplete
#include "nsPIDOMWindow.h"
#include "nsWrapperCache.h"
#include "nsITimer.h"
namespace mozilla {
namespace dom {
@ -18,13 +19,15 @@ class PaymentAddress;
class PaymentRequest;
class Promise;
class PaymentResponse final : public nsISupports,
class PaymentResponse final : public nsITimerCallback,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(PaymentResponse)
NS_IMETHOD Notify(nsITimer* aTimer) override;
PaymentResponse(nsPIDOMWindowInner* aWindow,
PaymentRequest* aRequest,
const nsAString& aRequestId,
@ -83,6 +86,9 @@ private:
RefPtr<PaymentAddress> mShippingAddress;
// Promise for "PaymentResponse::Complete"
RefPtr<Promise> mPromise;
// Timer for timing out if the page doesn't call
// complete()
nsCOMPtr<nsITimer> mTimer;
};
} // namespace dom

Просмотреть файл

@ -116,6 +116,14 @@ VARCACHE_PREF(
// Note, this is not currently safe to use for normal browsing yet.
PREF("dom.serviceWorkers.parent_intercept", bool, false)
// Time in milliseconds for PaymentResponse to wait for
// the Web page to call complete().
VARCACHE_PREF(
"dom.payments.response.timeout",
dom_payments_response_timeout,
uint32_t, 5000
)
//---------------------------------------------------------------------------
// Clear-Site-Data prefs
//---------------------------------------------------------------------------