summaryrefslogtreecommitdiffstats
path: root/dom/push/PushNotifier.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/push/PushNotifier.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/dom/push/PushNotifier.h b/dom/push/PushNotifier.h
new file mode 100644
index 0000000000..3718c7674e
--- /dev/null
+++ b/dom/push/PushNotifier.h
@@ -0,0 +1,193 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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_PushNotifier_h
+#define mozilla_dom_PushNotifier_h
+
+#include "nsIPushNotifier.h"
+
+#include "nsCycleCollectionParticipant.h"
+#include "nsIPrincipal.h"
+#include "nsString.h"
+
+#include "mozilla/Maybe.h"
+
+namespace mozilla::dom {
+
+class ContentChild;
+class ContentParent;
+
+/**
+ * `PushDispatcher` is a base class used to forward observer notifications and
+ * service worker events to the correct process.
+ */
+class MOZ_STACK_CLASS PushDispatcher {
+ public:
+ // Fires an XPCOM observer notification. This method may be called from both
+ // processes.
+ virtual nsresult NotifyObservers() = 0;
+
+ // Fires a service worker event. This method is called from the content
+ // process if e10s is enabled, or the parent otherwise.
+ virtual nsresult NotifyWorkers() = 0;
+
+ // A convenience method that calls `NotifyObservers` and `NotifyWorkers`.
+ nsresult NotifyObserversAndWorkers();
+
+ // Sends an IPDL message to fire an observer notification in the parent
+ // process. This method is only called from the content process, and only
+ // if e10s is enabled.
+ virtual bool SendToParent(ContentChild* aParentActor) = 0;
+
+ // Sends an IPDL message to fire an observer notification and a service worker
+ // event in the content process. This method is only called from the parent,
+ // and only if e10s is enabled.
+ virtual bool SendToChild(ContentParent* aContentActor) = 0;
+
+ // An optional method, called from the parent if e10s is enabled and there
+ // are no active content processes. The default behavior is a no-op.
+ virtual nsresult HandleNoChildProcesses();
+
+ nsIPrincipal* GetPrincipal() { return mPrincipal; }
+
+ protected:
+ PushDispatcher(const nsACString& aScope, nsIPrincipal* aPrincipal);
+
+ virtual ~PushDispatcher();
+
+ bool ShouldNotifyWorkers();
+ nsresult DoNotifyObservers(nsISupports* aSubject, const char* aTopic,
+ const nsACString& aScope);
+
+ const nsCString mScope;
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+};
+
+/**
+ * `PushNotifier` implements the `nsIPushNotifier` interface. This service
+ * broadcasts XPCOM observer notifications for incoming push messages, then
+ * forwards incoming push messages to service workers.
+ *
+ * All scriptable methods on this interface may be called from the parent or
+ * content process. Observer notifications are broadcasted to both processes.
+ */
+class PushNotifier final : public nsIPushNotifier {
+ public:
+ PushNotifier();
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushNotifier, nsIPushNotifier)
+ NS_DECL_NSIPUSHNOTIFIER
+
+ private:
+ ~PushNotifier();
+
+ nsresult Dispatch(PushDispatcher& aDispatcher);
+};
+
+/**
+ * `PushData` provides methods for retrieving push message data in different
+ * formats. This class is similar to the `PushMessageData` WebIDL interface.
+ */
+class PushData final : public nsIPushData {
+ public:
+ explicit PushData(const nsTArray<uint8_t>& aData);
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushData, nsIPushData)
+ NS_DECL_NSIPUSHDATA
+
+ private:
+ ~PushData();
+
+ nsresult EnsureDecodedText();
+
+ nsTArray<uint8_t> mData;
+ nsString mDecodedText;
+};
+
+/**
+ * `PushMessage` exposes the subscription principal and data for a push
+ * message. Each `push-message` observer receives an instance of this class
+ * as the subject.
+ */
+class PushMessage final : public nsIPushMessage {
+ public:
+ PushMessage(nsIPrincipal* aPrincipal, nsIPushData* aData);
+
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushMessage, nsIPushMessage)
+ NS_DECL_NSIPUSHMESSAGE
+
+ private:
+ ~PushMessage();
+
+ nsCOMPtr<nsIPrincipal> mPrincipal;
+ nsCOMPtr<nsIPushData> mData;
+};
+
+class PushMessageDispatcher final : public PushDispatcher {
+ public:
+ PushMessageDispatcher(const nsACString& aScope, nsIPrincipal* aPrincipal,
+ const nsAString& aMessageId,
+ const Maybe<nsTArray<uint8_t>>& aData);
+ ~PushMessageDispatcher();
+
+ nsresult NotifyObservers() override;
+ nsresult NotifyWorkers() override;
+ bool SendToParent(ContentChild* aParentActor) override;
+ bool SendToChild(ContentParent* aContentActor) override;
+
+ private:
+ const nsString mMessageId;
+ const Maybe<nsTArray<uint8_t>> mData;
+};
+
+class PushSubscriptionChangeDispatcher final : public PushDispatcher {
+ public:
+ PushSubscriptionChangeDispatcher(const nsACString& aScope,
+ nsIPrincipal* aPrincipal);
+ ~PushSubscriptionChangeDispatcher();
+
+ nsresult NotifyObservers() override;
+ nsresult NotifyWorkers() override;
+ bool SendToParent(ContentChild* aParentActor) override;
+ bool SendToChild(ContentParent* aContentActor) override;
+};
+
+class PushSubscriptionModifiedDispatcher : public PushDispatcher {
+ public:
+ PushSubscriptionModifiedDispatcher(const nsACString& aScope,
+ nsIPrincipal* aPrincipal);
+ ~PushSubscriptionModifiedDispatcher();
+
+ nsresult NotifyObservers() override;
+ nsresult NotifyWorkers() override;
+ bool SendToParent(ContentChild* aParentActor) override;
+ bool SendToChild(ContentParent* aContentActor) override;
+};
+
+class PushErrorDispatcher final : public PushDispatcher {
+ public:
+ PushErrorDispatcher(const nsACString& aScope, nsIPrincipal* aPrincipal,
+ const nsAString& aMessage, uint32_t aFlags);
+ ~PushErrorDispatcher();
+
+ nsresult NotifyObservers() override;
+ nsresult NotifyWorkers() override;
+ bool SendToParent(ContentChild* aParentActor) override;
+ bool SendToChild(ContentParent* aContentActor) override;
+
+ private:
+ nsresult HandleNoChildProcesses() override;
+
+ const nsString mMessage;
+ uint32_t mFlags;
+};
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_PushNotifier_h