PushNotifier.h (6212B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_PushNotifier_h 8 #define mozilla_dom_PushNotifier_h 9 10 #include "mozilla/Maybe.h" 11 #include "nsCycleCollectionParticipant.h" 12 #include "nsIPrincipal.h" 13 #include "nsIPushNotifier.h" 14 #include "nsString.h" 15 16 namespace mozilla::dom { 17 18 class ContentChild; 19 class ContentParent; 20 21 /** 22 * `PushDispatcher` is a base class used to forward observer notifications and 23 * service worker events to the correct process. 24 */ 25 class MOZ_STACK_CLASS PushDispatcher { 26 public: 27 // Fires an XPCOM observer notification. This method may be called from both 28 // processes. 29 virtual nsresult NotifyObservers() = 0; 30 31 // Fires a service worker event. This method is called from the content 32 // process if e10s is enabled, or the parent otherwise. 33 virtual nsresult NotifyWorkers() = 0; 34 35 // A convenience method that calls `NotifyObservers` and `NotifyWorkers`. 36 nsresult NotifyObserversAndWorkers(); 37 38 // Sends an IPDL message to fire an observer notification in the parent 39 // process. This method is only called from the content process, and only 40 // if e10s is enabled. 41 virtual bool SendToParent(ContentChild* aParentActor) = 0; 42 43 // Sends an IPDL message to fire an observer notification and a service worker 44 // event in the content process. This method is only called from the parent, 45 // and only if e10s is enabled. 46 virtual bool SendToChild(ContentParent* aContentActor) = 0; 47 48 // An optional method, called from the parent if e10s is enabled and there 49 // are no active content processes. The default behavior is a no-op. 50 virtual nsresult HandleNoChildProcesses(); 51 52 nsIPrincipal* GetPrincipal() { return mPrincipal; } 53 54 protected: 55 PushDispatcher(const nsACString& aScope, nsIPrincipal* aPrincipal); 56 57 virtual ~PushDispatcher(); 58 59 bool ShouldNotifyWorkers(); 60 nsresult DoNotifyObservers(nsISupports* aSubject, const char* aTopic, 61 const nsACString& aScope); 62 63 const nsCString mScope; 64 nsCOMPtr<nsIPrincipal> mPrincipal; 65 }; 66 67 /** 68 * `PushNotifier` implements the `nsIPushNotifier` interface. This service 69 * broadcasts XPCOM observer notifications for incoming push messages, then 70 * forwards incoming push messages to service workers. 71 * 72 * All scriptable methods on this interface may be called from the parent or 73 * content process. Observer notifications are broadcasted to both processes. 74 */ 75 class PushNotifier final : public nsIPushNotifier { 76 public: 77 PushNotifier(); 78 79 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 80 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushNotifier, nsIPushNotifier) 81 NS_DECL_NSIPUSHNOTIFIER 82 83 private: 84 ~PushNotifier(); 85 86 nsresult Dispatch(PushDispatcher& aDispatcher); 87 }; 88 89 /** 90 * `PushData` provides methods for retrieving push message data in different 91 * formats. This class is similar to the `PushMessageData` WebIDL interface. 92 */ 93 class PushData final : public nsIPushData { 94 public: 95 explicit PushData(const nsTArray<uint8_t>& aData); 96 97 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 98 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushData, nsIPushData) 99 NS_DECL_NSIPUSHDATA 100 101 private: 102 ~PushData(); 103 104 nsresult EnsureDecodedText(); 105 106 nsTArray<uint8_t> mData; 107 nsString mDecodedText; 108 }; 109 110 /** 111 * `PushMessage` exposes the subscription principal and data for a push 112 * message. Each `push-message` observer receives an instance of this class 113 * as the subject. 114 */ 115 class PushMessage final : public nsIPushMessage { 116 public: 117 PushMessage(nsIPrincipal* aPrincipal, nsIPushData* aData); 118 119 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 120 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PushMessage, nsIPushMessage) 121 NS_DECL_NSIPUSHMESSAGE 122 123 private: 124 ~PushMessage(); 125 126 nsCOMPtr<nsIPrincipal> mPrincipal; 127 nsCOMPtr<nsIPushData> mData; 128 }; 129 130 class PushMessageDispatcher final : public PushDispatcher { 131 public: 132 PushMessageDispatcher(const nsACString& aScope, nsIPrincipal* aPrincipal, 133 const nsAString& aMessageId, 134 const Maybe<nsTArray<uint8_t>>& aData); 135 ~PushMessageDispatcher(); 136 137 nsresult NotifyObservers() override; 138 nsresult NotifyWorkers() override; 139 bool SendToParent(ContentChild* aParentActor) override; 140 bool SendToChild(ContentParent* aContentActor) override; 141 142 private: 143 const nsString mMessageId; 144 const Maybe<nsTArray<uint8_t>> mData; 145 }; 146 147 class PushSubscriptionChangeDispatcher final : public PushDispatcher { 148 public: 149 PushSubscriptionChangeDispatcher(const nsACString& aScope, 150 nsIPrincipal* aPrincipal, 151 nsIPushSubscription* aOldSubscription); 152 ~PushSubscriptionChangeDispatcher(); 153 154 nsresult NotifyObservers() override; 155 nsresult NotifyWorkers() override; 156 bool SendToParent(ContentChild* aParentActor) override; 157 bool SendToChild(ContentParent* aContentActor) override; 158 159 private: 160 nsCOMPtr<nsIPushSubscription> mOldSubscription; 161 }; 162 163 class PushSubscriptionModifiedDispatcher : public PushDispatcher { 164 public: 165 PushSubscriptionModifiedDispatcher(const nsACString& aScope, 166 nsIPrincipal* aPrincipal); 167 ~PushSubscriptionModifiedDispatcher(); 168 169 nsresult NotifyObservers() override; 170 nsresult NotifyWorkers() override; 171 bool SendToParent(ContentChild* aParentActor) override; 172 bool SendToChild(ContentParent* aContentActor) override; 173 }; 174 175 class PushErrorDispatcher final : public PushDispatcher { 176 public: 177 PushErrorDispatcher(const nsACString& aScope, nsIPrincipal* aPrincipal, 178 const nsAString& aMessage, uint32_t aFlags); 179 ~PushErrorDispatcher(); 180 181 nsresult NotifyObservers() override; 182 nsresult NotifyWorkers() override; 183 bool SendToParent(ContentChild* aParentActor) override; 184 bool SendToChild(ContentParent* aContentActor) override; 185 186 private: 187 nsresult HandleNoChildProcesses() override; 188 189 const nsString mMessage; 190 uint32_t mFlags; 191 }; 192 193 } // namespace mozilla::dom 194 195 #endif // mozilla_dom_PushNotifier_h