--- a/dom/interfaces/push/moz.build
+++ b/dom/interfaces/push/moz.build
@@ -1,12 +1,13 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPIDL_SOURCES += [
+ 'nsIPushErrorReporter.idl',
'nsIPushNotifier.idl',
'nsIPushService.idl',
]
XPIDL_MODULE = 'dom_push'
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/push/nsIPushErrorReporter.idl
@@ -0,0 +1,46 @@
+/* -*- 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/. */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(b58249f9-1a04-48cc-bc20-2c992d64c73e)]
+interface nsIPushErrorReporter : nsISupports
+{
+ /**
+ * Ack status codes, reported when the Push service acknowledges an incoming
+ * message.
+ *
+ * Acks are sent before the message is dispatched to the service worker,
+ * since the server delays new messages until all outstanding ones have been
+ * acked. |reportDeliveryError| will be called if an error occurs in the
+ * worker's `push` event handler after acking the message.
+ */
+ const uint16_t ACK_DELIVERED = 0;
+ const uint16_t ACK_DECRYPTION_ERROR = 1;
+ const uint16_t ACK_NOT_DELIVERED = 2;
+
+ /**
+ * Unsubscribe reasons, reported when the service drops a subscription.
+ */
+ const uint16_t UNSUBSCRIBE_MANUAL = 3;
+ const uint16_t UNSUBSCRIBE_QUOTA_EXCEEDED = 4;
+ const uint16_t UNSUBSCRIBE_PERMISSION_REVOKED = 5;
+
+ /**
+ * Delivery error reasons, reported when a service worker fails to handle
+ * an incoming push message in its `push` event handler.
+ */
+ const uint16_t DELIVERY_UNCAUGHT_EXCEPTION = 6;
+ const uint16_t DELIVERY_UNHANDLED_REJECTION = 7;
+ const uint16_t DELIVERY_INTERNAL_ERROR = 8;
+
+ /**
+ * Reports a `push` event handler error to the Push service. |messageId| is
+ * an opaque string passed to `nsIPushNotifier.notifyPush{WithData}`.
+ * |status| is a delivery error reason.
+ */
+ void reportDeliveryError(in DOMString messageId,
+ [optional] in uint16_t reason);
+};
--- a/dom/interfaces/push/nsIPushNotifier.idl
+++ b/dom/interfaces/push/nsIPushNotifier.idl
@@ -1,37 +1,44 @@
+/* -*- 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/. */
+
#include "nsISupports.idl"
interface nsIPrincipal;
/**
* Fires service worker events for push messages sent to content subscriptions,
* and XPCOM observer notifications for system subscriptions. This service
* can only be used from the parent process.
*/
-[scriptable, uuid(b00dfdeb-14e5-425b-adc7-b531442e3216)]
+[scriptable, builtinclass, uuid(b00dfdeb-14e5-425b-adc7-b531442e3216)]
interface nsIPushNotifier : nsISupports
{
- void notifyPush(in ACString scope, in nsIPrincipal principal);
+ void notifyPush(in ACString scope, in nsIPrincipal principal,
+ in DOMString messageId);
void notifyPushWithData(in ACString scope, in nsIPrincipal principal,
+ in DOMString messageId,
[optional] in uint32_t dataLen,
[array, size_is(dataLen)] in uint8_t data);
void notifySubscriptionChange(in ACString scope, in nsIPrincipal principal);
};
/**
* A push message sent to a system subscription, used as the subject of a
* `push-message` observer notification. System subscriptions are created by
* the system principal, and do not use worker events.
*
* This interface resembles the `PushMessageData` WebIDL interface.
*/
-[scriptable, uuid(136dc8fd-8c56-4176-9170-eaa86b6ba99e)]
+[scriptable, builtinclass, uuid(136dc8fd-8c56-4176-9170-eaa86b6ba99e)]
interface nsIPushMessage : nsISupports
{
/** Extracts the data as a UTF-8 text string. */
DOMString text();
/** Extracts the data as a JSON value. */
[implicit_jscontext] jsval json();
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -3260,47 +3260,50 @@ ContentChild::RecvTestGraphicsDeviceRese
#if defined(XP_WIN)
gfxPlatform::GetPlatform()->TestDeviceReset(DeviceResetReason(aResetReason));
#endif
return true;
}
bool
ContentChild::RecvPush(const nsCString& aScope,
- const IPC::Principal& aPrincipal)
+ const IPC::Principal& aPrincipal,
+ const nsString& aMessageId)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
- nsresult rv = pushNotifier->NotifyPushWorkers(aScope, aPrincipal, Nothing());
+ nsresult rv = pushNotifier->NotifyPushWorkers(aScope, aPrincipal,
+ aMessageId, Nothing());
Unused << NS_WARN_IF(NS_FAILED(rv));
#endif
return true;
}
bool
ContentChild::RecvPushWithData(const nsCString& aScope,
const IPC::Principal& aPrincipal,
+ const nsString& aMessageId,
InfallibleTArray<uint8_t>&& aData)
{
#ifndef MOZ_SIMPLEPUSH
nsCOMPtr<nsIPushNotifier> pushNotifierIface =
do_GetService("@mozilla.org/push/Notifier;1");
if (NS_WARN_IF(!pushNotifierIface)) {
return true;
}
PushNotifier* pushNotifier =
static_cast<PushNotifier*>(pushNotifierIface.get());
nsresult rv = pushNotifier->NotifyPushWorkers(aScope, aPrincipal,
- Some(aData));
+ aMessageId, Some(aData));
Unused << NS_WARN_IF(NS_FAILED(rv));
#endif
return true;
}
bool
ContentChild::RecvPushSubscriptionChange(const nsCString& aScope,
const IPC::Principal& aPrincipal)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -528,21 +528,23 @@ public:
RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
const uint32_t& aAction) override;
virtual bool RecvEndDragSession(const bool& aDoneDrag,
const bool& aUserCancelled) override;
virtual bool
RecvPush(const nsCString& aScope,
- const IPC::Principal& aPrincipal) override;
+ const IPC::Principal& aPrincipal,
+ const nsString& aMessageId) override;
virtual bool
RecvPushWithData(const nsCString& aScope,
const IPC::Principal& aPrincipal,
+ const nsString& aMessageId,
InfallibleTArray<uint8_t>&& aData) override;
virtual bool
RecvPushSubscriptionChange(const nsCString& aScope,
const IPC::Principal& aPrincipal) override;
#ifdef ANDROID
gfx::IntSize GetScreenSize() { return mScreenSize; }
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -731,22 +731,23 @@ child:
/**
* Notify the child that the Gecko Media Plugins installed changed.
*/
async NotifyGMPsChanged();
/**
* Send a `push` event without data to a service worker in the child.
*/
- async Push(nsCString scope, Principal principal);
+ async Push(nsCString scope, Principal principal, nsString messageId);
/**
* Send a `push` event with data to a service worker in the child.
*/
- async PushWithData(nsCString scope, Principal principal, uint8_t[] data);
+ async PushWithData(nsCString scope, Principal principal,
+ nsString messageId, uint8_t[] data);
/**
* Send a `pushsubscriptionchange` event to a service worker in the child.
*/
async PushSubscriptionChange(nsCString scope, Principal principal);
parent:
/**
--- a/dom/push/PushNotifier.cpp
+++ b/dom/push/PushNotifier.cpp
@@ -35,32 +35,34 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(PushNotifier)
NS_IMPL_CYCLE_COLLECTING_RELEASE(PushNotifier)
NS_IMETHODIMP
PushNotifier::NotifyPushWithData(const nsACString& aScope,
nsIPrincipal* aPrincipal,
+ const nsAString& aMessageId,
uint32_t aDataLen, uint8_t* aData)
{
nsTArray<uint8_t> data;
if (!data.SetCapacity(aDataLen, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (!data.InsertElementsAt(0, aData, aDataLen, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
- return NotifyPush(aScope, aPrincipal, Some(data));
+ return NotifyPush(aScope, aPrincipal, aMessageId, Some(data));
}
NS_IMETHODIMP
-PushNotifier::NotifyPush(const nsACString& aScope, nsIPrincipal* aPrincipal)
+PushNotifier::NotifyPush(const nsACString& aScope, nsIPrincipal* aPrincipal,
+ const nsAString& aMessageId)
{
- return NotifyPush(aScope, aPrincipal, Nothing());
+ return NotifyPush(aScope, aPrincipal, aMessageId, Nothing());
}
NS_IMETHODIMP
PushNotifier::NotifySubscriptionChange(const nsACString& aScope,
nsIPrincipal* aPrincipal)
{
if (XRE_IsContentProcess()) {
return NS_ERROR_NOT_IMPLEMENTED;
@@ -78,41 +80,43 @@ PushNotifier::NotifySubscriptionChange(c
return rv;
}
}
return NS_OK;
}
nsresult
PushNotifier::NotifyPush(const nsACString& aScope, nsIPrincipal* aPrincipal,
- Maybe<nsTArray<uint8_t>> aData)
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData)
{
if (XRE_IsContentProcess()) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult rv;
if (ShouldNotifyObservers(aPrincipal)) {
rv = NotifyPushObservers(aScope, aData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (ShouldNotifyWorkers(aPrincipal)) {
- rv = NotifyPushWorkers(aScope, aPrincipal, aData);
+ rv = NotifyPushWorkers(aScope, aPrincipal, aMessageId, aData);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
nsresult
PushNotifier::NotifyPushWorkers(const nsACString& aScope,
nsIPrincipal* aPrincipal,
- Maybe<nsTArray<uint8_t>> aData)
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData)
{
if (!aPrincipal) {
return NS_ERROR_INVALID_ARG;
}
if (XRE_IsContentProcess() || !BrowserTabsRemoteAutostart()) {
// Notify the worker from the current process. Either we're running in
// the content process and received a message from the parent, or e10s
@@ -121,31 +125,31 @@ PushNotifier::NotifyPushWorkers(const ns
if (!swm) {
return NS_ERROR_FAILURE;
}
nsAutoCString originSuffix;
nsresult rv = aPrincipal->GetOriginSuffix(originSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- return swm->SendPushEvent(originSuffix, aScope, aData);
+ return swm->SendPushEvent(originSuffix, aScope, aMessageId, aData);
}
// Otherwise, we're in the parent and e10s is enabled. Broadcast the event
// to all content processes.
bool ok = true;
nsTArray<ContentParent*> contentActors;
ContentParent::GetAll(contentActors);
for (uint32_t i = 0; i < contentActors.Length(); ++i) {
if (aData) {
ok &= contentActors[i]->SendPushWithData(PromiseFlatCString(aScope),
- IPC::Principal(aPrincipal), aData.ref());
+ IPC::Principal(aPrincipal), PromiseFlatString(aMessageId), aData.ref());
} else {
ok &= contentActors[i]->SendPush(PromiseFlatCString(aScope),
- IPC::Principal(aPrincipal));
+ IPC::Principal(aPrincipal), PromiseFlatString(aMessageId));
}
}
return ok ? NS_OK : NS_ERROR_FAILURE;
}
nsresult
PushNotifier::NotifySubscriptionChangeWorkers(const nsACString& aScope,
nsIPrincipal* aPrincipal)
@@ -176,17 +180,17 @@ PushNotifier::NotifySubscriptionChangeWo
ok &= contentActors[i]->SendPushSubscriptionChange(
PromiseFlatCString(aScope), IPC::Principal(aPrincipal));
}
return ok ? NS_OK : NS_ERROR_FAILURE;
}
nsresult
PushNotifier::NotifyPushObservers(const nsACString& aScope,
- Maybe<nsTArray<uint8_t>> aData)
+ const Maybe<nsTArray<uint8_t>>& aData)
{
nsCOMPtr<nsIObserverService> obsService =
mozilla::services::GetObserverService();
if (!obsService) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIPushMessage> message = nullptr;
if (aData) {
--- a/dom/push/PushNotifier.h
+++ b/dom/push/PushNotifier.h
@@ -34,29 +34,31 @@ class PushNotifier final : public nsIPus
public:
PushNotifier();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushNotifier, nsIPushNotifier)
NS_DECL_NSIPUSHNOTIFIER
nsresult NotifyPush(const nsACString& aScope, nsIPrincipal* aPrincipal,
- Maybe<nsTArray<uint8_t>> aData);
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData);
nsresult NotifyPushWorkers(const nsACString& aScope,
nsIPrincipal* aPrincipal,
- Maybe<nsTArray<uint8_t>> aData);
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData);
nsresult NotifySubscriptionChangeWorkers(const nsACString& aScope,
nsIPrincipal* aPrincipal);
protected:
virtual ~PushNotifier();
private:
nsresult NotifyPushObservers(const nsACString& aScope,
- Maybe<nsTArray<uint8_t>> aData);
+ const Maybe<nsTArray<uint8_t>>& aData);
nsresult NotifySubscriptionChangeObservers(const nsACString& aScope);
bool ShouldNotifyObservers(nsIPrincipal* aPrincipal);
bool ShouldNotifyWorkers(nsIPrincipal* aPrincipal);
};
/**
* `PushMessage` implements the `nsIPushMessage` interface, similar to
* the `PushMessageData` WebIDL interface. Instances of this class are
--- a/dom/workers/ServiceWorkerManager.cpp
+++ b/dom/workers/ServiceWorkerManager.cpp
@@ -2208,26 +2208,27 @@ ServiceWorkerManager::SendPushEvent(cons
uint8_t* aDataBytes,
uint8_t optional_argc)
{
if (optional_argc == 2) {
nsTArray<uint8_t> data;
if (!data.InsertElementsAt(0, aDataBytes, aDataLength, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
- return SendPushEvent(aOriginAttributes, aScope, Some(data));
+ return SendPushEvent(aOriginAttributes, aScope, EmptyString(), Some(data));
}
MOZ_ASSERT(optional_argc == 0);
- return SendPushEvent(aOriginAttributes, aScope, Nothing());
+ return SendPushEvent(aOriginAttributes, aScope, EmptyString(), Nothing());
}
nsresult
ServiceWorkerManager::SendPushEvent(const nsACString& aOriginAttributes,
const nsACString& aScope,
- Maybe<nsTArray<uint8_t>> aData)
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData)
{
#ifdef MOZ_SIMPLEPUSH
return NS_ERROR_NOT_AVAILABLE;
#else
PrincipalOriginAttributes attrs;
if (!attrs.PopulateFromSuffix(aOriginAttributes)) {
return NS_ERROR_INVALID_ARG;
}
@@ -2235,17 +2236,18 @@ ServiceWorkerManager::SendPushEvent(cons
ServiceWorkerInfo* serviceWorker = GetActiveWorkerInfoForScope(attrs, aScope);
if (NS_WARN_IF(!serviceWorker)) {
return NS_ERROR_FAILURE;
}
RefPtr<ServiceWorkerRegistrationInfo> registration =
GetRegistration(serviceWorker->GetPrincipal(), aScope);
- return serviceWorker->WorkerPrivate()->SendPushEvent(aData, registration);
+ return serviceWorker->WorkerPrivate()->SendPushEvent(aMessageId, aData,
+ registration);
#endif // MOZ_SIMPLEPUSH
}
NS_IMETHODIMP
ServiceWorkerManager::SendPushSubscriptionChangeEvent(const nsACString& aOriginAttributes,
const nsACString& aScope)
{
#ifdef MOZ_SIMPLEPUSH
--- a/dom/workers/ServiceWorkerManager.h
+++ b/dom/workers/ServiceWorkerManager.h
@@ -495,17 +495,18 @@ public:
ServiceWorkerRegistrationListener* aListener);
void
MaybeCheckNavigationUpdate(nsIDocument* aDoc);
nsresult
SendPushEvent(const nsACString& aOriginAttributes,
const nsACString& aScope,
- Maybe<nsTArray<uint8_t>> aData);
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData);
nsresult
NotifyUnregister(nsIPrincipal* aPrincipal, const nsAString& aScope);
private:
ServiceWorkerManager();
~ServiceWorkerManager();
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -5,16 +5,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ServiceWorkerPrivate.h"
#include "ServiceWorkerManager.h"
#include "nsStreamUtils.h"
#include "nsStringStream.h"
#include "mozilla/dom/FetchUtil.h"
#include "mozilla/dom/IndexedDatabaseManager.h"
+#include "mozilla/unused.h"
+
+#ifndef MOZ_SIMPLEPUSH
+#include "nsIPushErrorReporter.h"
+#endif
using namespace mozilla;
using namespace mozilla::dom;
BEGIN_WORKERS_NAMESPACE
NS_IMPL_CYCLE_COLLECTING_ADDREF(ServiceWorkerPrivate)
NS_IMPL_CYCLE_COLLECTING_RELEASE(ServiceWorkerPrivate)
@@ -551,63 +556,138 @@ ServiceWorkerPrivate::SendLifeCycleEvent
}
return NS_OK;
}
#ifndef MOZ_SIMPLEPUSH
namespace {
+class PushErrorReporter final : public PromiseNativeHandler
+{
+ WorkerPrivate* mWorkerPrivate;
+ nsString mMessageId;
+
+ ~PushErrorReporter()
+ {
+ }
+
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+
+ PushErrorReporter(WorkerPrivate* aWorkerPrivate,
+ const nsAString& aMessageId)
+ : mWorkerPrivate(aWorkerPrivate)
+ , mMessageId(aMessageId)
+ {
+ mWorkerPrivate->AssertIsOnWorkerThread();
+ }
+
+ void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
+ {
+ mWorkerPrivate->AssertIsOnWorkerThread();
+ // Do nothing, we are only here to report errors to the Push service.
+ }
+
+ void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
+ {
+ mWorkerPrivate->AssertIsOnWorkerThread();
+ Report(nsIPushErrorReporter::DELIVERY_UNHANDLED_REJECTION);
+ }
+
+ void Report(uint16_t aReason = nsIPushErrorReporter::DELIVERY_INTERNAL_ERROR)
+ {
+ mWorkerPrivate->AssertIsOnWorkerThread();
+
+ if (NS_WARN_IF(aReason > nsIPushErrorReporter::DELIVERY_INTERNAL_ERROR) ||
+ mMessageId.IsEmpty()) {
+ return;
+ }
+ nsCOMPtr<nsIRunnable> runnable =
+ NS_NewRunnableMethodWithArg<uint16_t>(this,
+ &PushErrorReporter::ReportOnMainThread, aReason);
+ MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+ NS_DispatchToMainThread(runnable.forget())));
+ }
+
+ void ReportOnMainThread(uint16_t aReason)
+ {
+ AssertIsOnMainThread();
+ nsCOMPtr<nsIPushErrorReporter> reporter =
+ do_GetService("@mozilla.org/push/Service;1");
+ if (reporter) {
+ nsresult rv = reporter->ReportDeliveryError(mMessageId, aReason);
+ Unused << NS_WARN_IF(NS_FAILED(rv));
+ }
+ }
+};
+
+NS_IMPL_ISUPPORTS0(PushErrorReporter)
+
class SendPushEventRunnable final : public ExtendableFunctionalEventWorkerRunnable
{
+ nsString mMessageId;
Maybe<nsTArray<uint8_t>> mData;
public:
SendPushEventRunnable(WorkerPrivate* aWorkerPrivate,
KeepAliveToken* aKeepAliveToken,
+ const nsAString& aMessageId,
const Maybe<nsTArray<uint8_t>>& aData,
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> aRegistration)
: ExtendableFunctionalEventWorkerRunnable(
aWorkerPrivate, aKeepAliveToken, aRegistration)
+ , mMessageId(aMessageId)
, mData(aData)
{
AssertIsOnMainThread();
MOZ_ASSERT(aWorkerPrivate);
MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
MOZ_ASSERT(aWorkerPrivate);
GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
+ RefPtr<PushErrorReporter> errorReporter =
+ new PushErrorReporter(aWorkerPrivate, mMessageId);
+
PushEventInit pei;
if (mData) {
const nsTArray<uint8_t>& bytes = mData.ref();
JSObject* data = Uint8Array::Create(aCx, bytes.Length(), bytes.Elements());
if (!data) {
+ errorReporter->Report();
return false;
}
pei.mData.Construct().SetAsArrayBufferView().Init(data);
}
pei.mBubbles = false;
pei.mCancelable = false;
ErrorResult result;
RefPtr<PushEvent> event =
PushEvent::Constructor(globalObj, NS_LITERAL_STRING("push"), pei, result);
if (NS_WARN_IF(result.Failed())) {
result.SuppressException();
+ errorReporter->Report();
return false;
}
event->SetTrusted(true);
+ RefPtr<Promise> waitUntil;
DispatchExtendableEventOnWorkerScope(aCx, aWorkerPrivate->GlobalScope(),
- event, nullptr);
+ event, getter_AddRefs(waitUntil));
+ if (waitUntil) {
+ waitUntil->AppendNativeHandler(errorReporter);
+ } else {
+ errorReporter->Report(nsIPushErrorReporter::DELIVERY_UNCAUGHT_EXCEPTION);
+ }
return true;
}
};
class SendPushSubscriptionChangeEventRunnable final : public ExtendableEventWorkerRunnable
{
@@ -645,34 +725,36 @@ public:
return true;
}
};
} // anonymous namespace
#endif // !MOZ_SIMPLEPUSH
nsresult
-ServiceWorkerPrivate::SendPushEvent(const Maybe<nsTArray<uint8_t>>& aData,
+ServiceWorkerPrivate::SendPushEvent(const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData,
ServiceWorkerRegistrationInfo* aRegistration)
{
#ifdef MOZ_SIMPLEPUSH
return NS_ERROR_NOT_AVAILABLE;
#else
nsresult rv = SpawnWorkerIfNeeded(PushEvent, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(mKeepAliveToken);
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> regInfo(
new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(aRegistration, false));
RefPtr<WorkerRunnable> r = new SendPushEventRunnable(mWorkerPrivate,
- mKeepAliveToken,
- aData,
- regInfo);
+ mKeepAliveToken,
+ aMessageId,
+ aData,
+ regInfo);
if (mInfo->State() == ServiceWorkerState::Activating) {
mPendingFunctionalEvents.AppendElement(r.forget());
return NS_OK;
}
MOZ_ASSERT(mInfo->State() == ServiceWorkerState::Activated);
--- a/dom/workers/ServiceWorkerPrivate.h
+++ b/dom/workers/ServiceWorkerPrivate.h
@@ -77,17 +77,18 @@ public:
CheckScriptEvaluation(LifeCycleEventCallback* aCallback);
nsresult
SendLifeCycleEvent(const nsAString& aEventType,
LifeCycleEventCallback* aCallback,
nsIRunnable* aLoadFailure);
nsresult
- SendPushEvent(const Maybe<nsTArray<uint8_t>>& aData,
+ SendPushEvent(const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData,
ServiceWorkerRegistrationInfo* aRegistration);
nsresult
SendPushSubscriptionChangeEvent();
nsresult
SendNotificationClickEvent(const nsAString& aID,
const nsAString& aTitle,