/src/mozilla-central/dom/push/PushNotifier.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "PushNotifier.h" |
8 | | |
9 | | #include "nsContentUtils.h" |
10 | | #include "nsCOMPtr.h" |
11 | | #include "nsICategoryManager.h" |
12 | | #include "nsIXULRuntime.h" |
13 | | #include "nsNetUtil.h" |
14 | | #include "nsXPCOM.h" |
15 | | #include "mozilla/dom/ServiceWorkerManager.h" |
16 | | |
17 | | #include "mozilla/Services.h" |
18 | | #include "mozilla/Unused.h" |
19 | | |
20 | | #include "mozilla/dom/BodyUtil.h" |
21 | | #include "mozilla/dom/ContentChild.h" |
22 | | #include "mozilla/dom/ContentParent.h" |
23 | | |
24 | | namespace mozilla { |
25 | | namespace dom { |
26 | | |
27 | | PushNotifier::PushNotifier() |
28 | 0 | {} |
29 | | |
30 | | PushNotifier::~PushNotifier() |
31 | 0 | {} |
32 | | |
33 | | NS_IMPL_CYCLE_COLLECTION_0(PushNotifier) |
34 | | |
35 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushNotifier) |
36 | 0 | NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPushNotifier) |
37 | 0 | NS_INTERFACE_MAP_ENTRY(nsIPushNotifier) |
38 | 0 | NS_INTERFACE_MAP_END |
39 | | |
40 | | NS_IMPL_CYCLE_COLLECTING_ADDREF(PushNotifier) |
41 | | NS_IMPL_CYCLE_COLLECTING_RELEASE(PushNotifier) |
42 | | |
43 | | NS_IMETHODIMP |
44 | | PushNotifier::NotifyPushWithData(const nsACString& aScope, |
45 | | nsIPrincipal* aPrincipal, |
46 | | const nsAString& aMessageId, |
47 | | uint32_t aDataLen, uint8_t* aData) |
48 | 0 | { |
49 | 0 | NS_ENSURE_ARG(aPrincipal); |
50 | 0 | nsTArray<uint8_t> data; |
51 | 0 | if (!data.SetCapacity(aDataLen, fallible)) { |
52 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
53 | 0 | } |
54 | 0 | if (!data.InsertElementsAt(0, aData, aDataLen, fallible)) { |
55 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
56 | 0 | } |
57 | 0 | PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Some(data)); |
58 | 0 | return Dispatch(dispatcher); |
59 | 0 | } |
60 | | |
61 | | NS_IMETHODIMP |
62 | | PushNotifier::NotifyPush(const nsACString& aScope, nsIPrincipal* aPrincipal, |
63 | | const nsAString& aMessageId) |
64 | 0 | { |
65 | 0 | NS_ENSURE_ARG(aPrincipal); |
66 | 0 | PushMessageDispatcher dispatcher(aScope, aPrincipal, aMessageId, Nothing()); |
67 | 0 | return Dispatch(dispatcher); |
68 | 0 | } |
69 | | |
70 | | NS_IMETHODIMP |
71 | | PushNotifier::NotifySubscriptionChange(const nsACString& aScope, |
72 | | nsIPrincipal* aPrincipal) |
73 | 0 | { |
74 | 0 | NS_ENSURE_ARG(aPrincipal); |
75 | 0 | PushSubscriptionChangeDispatcher dispatcher(aScope, aPrincipal); |
76 | 0 | return Dispatch(dispatcher); |
77 | 0 | } |
78 | | |
79 | | NS_IMETHODIMP |
80 | | PushNotifier::NotifySubscriptionModified(const nsACString& aScope, |
81 | | nsIPrincipal* aPrincipal) |
82 | 0 | { |
83 | 0 | NS_ENSURE_ARG(aPrincipal); |
84 | 0 | PushSubscriptionModifiedDispatcher dispatcher(aScope, aPrincipal); |
85 | 0 | return Dispatch(dispatcher); |
86 | 0 | } |
87 | | |
88 | | NS_IMETHODIMP |
89 | | PushNotifier::NotifyError(const nsACString& aScope, nsIPrincipal* aPrincipal, |
90 | | const nsAString& aMessage, uint32_t aFlags) |
91 | 0 | { |
92 | 0 | NS_ENSURE_ARG(aPrincipal); |
93 | 0 | PushErrorDispatcher dispatcher(aScope, aPrincipal, aMessage, aFlags); |
94 | 0 | return Dispatch(dispatcher); |
95 | 0 | } |
96 | | |
97 | | nsresult |
98 | | PushNotifier::Dispatch(PushDispatcher& aDispatcher) |
99 | 0 | { |
100 | 0 | if (XRE_IsParentProcess()) { |
101 | 0 | // Always notify XPCOM observers in the parent process. |
102 | 0 | Unused << NS_WARN_IF(NS_FAILED(aDispatcher.NotifyObservers())); |
103 | 0 |
|
104 | 0 | nsTArray<ContentParent*> contentActors; |
105 | 0 | ContentParent::GetAll(contentActors); |
106 | 0 | if (!contentActors.IsEmpty() && !ServiceWorkerParentInterceptEnabled()) { |
107 | 0 | // At least one content process is active, so e10s must be enabled. |
108 | 0 | // Broadcast a message to notify observers and service workers. |
109 | 0 | for (uint32_t i = 0; i < contentActors.Length(); ++i) { |
110 | 0 | // We need to filter based on process type, only "web" AKA the default |
111 | 0 | // remote type is acceptable. |
112 | 0 | if (!contentActors[i]->GetRemoteType().EqualsLiteral( |
113 | 0 | DEFAULT_REMOTE_TYPE)) { |
114 | 0 | continue; |
115 | 0 | } |
116 | 0 | |
117 | 0 | // Ensure that the content actor has the permissions avaliable for the |
118 | 0 | // principal the push is being sent for before sending the push message |
119 | 0 | // down. |
120 | 0 | Unused << contentActors[i]-> |
121 | 0 | TransmitPermissionsForPrincipal(aDispatcher.GetPrincipal()); |
122 | 0 | if (aDispatcher.SendToChild(contentActors[i])) { |
123 | 0 | // Only send the push message to the first content process to avoid |
124 | 0 | // multiple SWs showing the same notification. See bug 1300112. |
125 | 0 | break; |
126 | 0 | } |
127 | 0 | } |
128 | 0 | return NS_OK; |
129 | 0 | } |
130 | 0 |
|
131 | 0 | if (BrowserTabsRemoteAutostart() && !ServiceWorkerParentInterceptEnabled()) { |
132 | 0 | // e10s is enabled, but no content processes are active. |
133 | 0 | return aDispatcher.HandleNoChildProcesses(); |
134 | 0 | } |
135 | 0 | |
136 | 0 | // e10s is disabled; notify workers in the parent. |
137 | 0 | return aDispatcher.NotifyWorkers(); |
138 | 0 | } |
139 | 0 | |
140 | 0 | // Otherwise, we're in the content process, so e10s must be enabled. Notify |
141 | 0 | // observers and workers, then send a message to notify observers in the |
142 | 0 | // parent. |
143 | 0 | MOZ_ASSERT(XRE_IsContentProcess()); |
144 | 0 |
|
145 | 0 | nsresult rv = aDispatcher.NotifyObserversAndWorkers(); |
146 | 0 |
|
147 | 0 | ContentChild* parentActor = ContentChild::GetSingleton(); |
148 | 0 | if (!NS_WARN_IF(!parentActor)) { |
149 | 0 | Unused << NS_WARN_IF(!aDispatcher.SendToParent(parentActor)); |
150 | 0 | } |
151 | 0 |
|
152 | 0 | return rv; |
153 | 0 | } |
154 | | |
155 | | PushData::PushData(const nsTArray<uint8_t>& aData) |
156 | | : mData(aData) |
157 | 0 | {} |
158 | | |
159 | | PushData::~PushData() |
160 | 0 | {} |
161 | | |
162 | | NS_IMPL_CYCLE_COLLECTION_0(PushData) |
163 | | |
164 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushData) |
165 | 0 | NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPushData) |
166 | 0 | NS_INTERFACE_MAP_ENTRY(nsIPushData) |
167 | 0 | NS_INTERFACE_MAP_END |
168 | | |
169 | | NS_IMPL_CYCLE_COLLECTING_ADDREF(PushData) |
170 | | NS_IMPL_CYCLE_COLLECTING_RELEASE(PushData) |
171 | | |
172 | | nsresult |
173 | | PushData::EnsureDecodedText() |
174 | 0 | { |
175 | 0 | if (mData.IsEmpty() || !mDecodedText.IsEmpty()) { |
176 | 0 | return NS_OK; |
177 | 0 | } |
178 | 0 | nsresult rv = BodyUtil::ConsumeText( |
179 | 0 | mData.Length(), |
180 | 0 | reinterpret_cast<uint8_t*>(mData.Elements()), |
181 | 0 | mDecodedText |
182 | 0 | ); |
183 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
184 | 0 | mDecodedText.Truncate(); |
185 | 0 | return rv; |
186 | 0 | } |
187 | 0 | return NS_OK; |
188 | 0 | } |
189 | | |
190 | | NS_IMETHODIMP |
191 | | PushData::Text(nsAString& aText) |
192 | 0 | { |
193 | 0 | nsresult rv = EnsureDecodedText(); |
194 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
195 | 0 | return rv; |
196 | 0 | } |
197 | 0 | aText = mDecodedText; |
198 | 0 | return NS_OK; |
199 | 0 | } |
200 | | |
201 | | NS_IMETHODIMP |
202 | | PushData::Json(JSContext* aCx, |
203 | | JS::MutableHandle<JS::Value> aResult) |
204 | 0 | { |
205 | 0 | nsresult rv = EnsureDecodedText(); |
206 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
207 | 0 | return rv; |
208 | 0 | } |
209 | 0 | ErrorResult error; |
210 | 0 | BodyUtil::ConsumeJson(aCx, aResult, mDecodedText, error); |
211 | 0 | return error.StealNSResult(); |
212 | 0 | } |
213 | | |
214 | | NS_IMETHODIMP |
215 | | PushData::Binary(uint32_t* aDataLen, uint8_t** aData) |
216 | 0 | { |
217 | 0 | NS_ENSURE_ARG_POINTER(aDataLen); |
218 | 0 | NS_ENSURE_ARG_POINTER(aData); |
219 | 0 |
|
220 | 0 | *aData = nullptr; |
221 | 0 | if (mData.IsEmpty()) { |
222 | 0 | *aDataLen = 0; |
223 | 0 | return NS_OK; |
224 | 0 | } |
225 | 0 | uint32_t length = mData.Length(); |
226 | 0 | uint8_t* data = static_cast<uint8_t*>(moz_xmalloc(length * sizeof(uint8_t))); |
227 | 0 | memcpy(data, mData.Elements(), length * sizeof(uint8_t)); |
228 | 0 | *aDataLen = length; |
229 | 0 | *aData = data; |
230 | 0 | return NS_OK; |
231 | 0 | } |
232 | | |
233 | | PushMessage::PushMessage(nsIPrincipal* aPrincipal, nsIPushData* aData) |
234 | | : mPrincipal(aPrincipal) |
235 | | , mData(aData) |
236 | 0 | {} |
237 | | |
238 | | PushMessage::~PushMessage() |
239 | 0 | {} |
240 | | |
241 | | NS_IMPL_CYCLE_COLLECTION(PushMessage, mPrincipal, mData) |
242 | | |
243 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushMessage) |
244 | 0 | NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPushMessage) |
245 | 0 | NS_INTERFACE_MAP_ENTRY(nsIPushMessage) |
246 | 0 | NS_INTERFACE_MAP_END |
247 | | |
248 | | NS_IMPL_CYCLE_COLLECTING_ADDREF(PushMessage) |
249 | | NS_IMPL_CYCLE_COLLECTING_RELEASE(PushMessage) |
250 | | |
251 | | NS_IMETHODIMP |
252 | | PushMessage::GetPrincipal(nsIPrincipal** aPrincipal) |
253 | 0 | { |
254 | 0 | NS_ENSURE_ARG_POINTER(aPrincipal); |
255 | 0 |
|
256 | 0 | nsCOMPtr<nsIPrincipal> principal = mPrincipal; |
257 | 0 | principal.forget(aPrincipal); |
258 | 0 | return NS_OK; |
259 | 0 | } |
260 | | |
261 | | NS_IMETHODIMP |
262 | | PushMessage::GetData(nsIPushData** aData) |
263 | 0 | { |
264 | 0 | NS_ENSURE_ARG_POINTER(aData); |
265 | 0 |
|
266 | 0 | nsCOMPtr<nsIPushData> data = mData; |
267 | 0 | data.forget(aData); |
268 | 0 | return NS_OK; |
269 | 0 | } |
270 | | |
271 | | PushDispatcher::PushDispatcher(const nsACString& aScope, |
272 | | nsIPrincipal* aPrincipal) |
273 | | : mScope(aScope) |
274 | | , mPrincipal(aPrincipal) |
275 | 0 | {} |
276 | | |
277 | | PushDispatcher::~PushDispatcher() |
278 | 0 | {} |
279 | | |
280 | | nsresult |
281 | | PushDispatcher::HandleNoChildProcesses() |
282 | 0 | { |
283 | 0 | return NS_OK; |
284 | 0 | } |
285 | | |
286 | | nsresult |
287 | | PushDispatcher::NotifyObserversAndWorkers() |
288 | 0 | { |
289 | 0 | Unused << NS_WARN_IF(NS_FAILED(NotifyObservers())); |
290 | 0 | return NotifyWorkers(); |
291 | 0 | } |
292 | | |
293 | | bool |
294 | | PushDispatcher::ShouldNotifyWorkers() |
295 | 0 | { |
296 | 0 | if (NS_WARN_IF(!mPrincipal)) { |
297 | 0 | return false; |
298 | 0 | } |
299 | 0 | // System subscriptions use observer notifications instead of service worker |
300 | 0 | // events. The `testing.notifyWorkers` pref disables worker events for |
301 | 0 | // non-system subscriptions. |
302 | 0 | return !nsContentUtils::IsSystemPrincipal(mPrincipal) && |
303 | 0 | Preferences::GetBool("dom.push.testing.notifyWorkers", true); |
304 | 0 | } |
305 | | |
306 | | nsresult |
307 | | PushDispatcher::DoNotifyObservers(nsISupports *aSubject, const char *aTopic, |
308 | | const nsACString& aScope) |
309 | 0 | { |
310 | 0 | nsCOMPtr<nsIObserverService> obsService = |
311 | 0 | mozilla::services::GetObserverService(); |
312 | 0 | if (!obsService) { |
313 | 0 | return NS_ERROR_FAILURE; |
314 | 0 | } |
315 | 0 | // If there's a service for this push category, make sure it is alive. |
316 | 0 | nsCOMPtr<nsICategoryManager> catMan = |
317 | 0 | do_GetService(NS_CATEGORYMANAGER_CONTRACTID); |
318 | 0 | if (catMan) { |
319 | 0 | nsCString contractId; |
320 | 0 | nsresult rv = catMan->GetCategoryEntry("push", mScope, contractId); |
321 | 0 | if (NS_SUCCEEDED(rv)) { |
322 | 0 | // Ensure the service is created - we don't need to do anything with |
323 | 0 | // it though - we assume the service constructor attaches a listener. |
324 | 0 | nsCOMPtr<nsISupports> service = do_GetService(contractId.get()); |
325 | 0 | } |
326 | 0 | } |
327 | 0 | return obsService->NotifyObservers(aSubject, aTopic, |
328 | 0 | NS_ConvertUTF8toUTF16(mScope).get()); |
329 | 0 | } |
330 | | |
331 | | PushMessageDispatcher::PushMessageDispatcher(const nsACString& aScope, |
332 | | nsIPrincipal* aPrincipal, |
333 | | const nsAString& aMessageId, |
334 | | const Maybe<nsTArray<uint8_t>>& aData) |
335 | | : PushDispatcher(aScope, aPrincipal) |
336 | | , mMessageId(aMessageId) |
337 | | , mData(aData) |
338 | 0 | {} |
339 | | |
340 | | PushMessageDispatcher::~PushMessageDispatcher() |
341 | 0 | {} |
342 | | |
343 | | nsresult |
344 | | PushMessageDispatcher::NotifyObservers() |
345 | 0 | { |
346 | 0 | nsCOMPtr<nsIPushData> data; |
347 | 0 | if (mData) { |
348 | 0 | data = new PushData(mData.ref()); |
349 | 0 | } |
350 | 0 | nsCOMPtr<nsIPushMessage> message = new PushMessage(mPrincipal, data); |
351 | 0 | return DoNotifyObservers(message, OBSERVER_TOPIC_PUSH, mScope); |
352 | 0 | } |
353 | | |
354 | | nsresult |
355 | | PushMessageDispatcher::NotifyWorkers() |
356 | 0 | { |
357 | 0 | if (!ShouldNotifyWorkers()) { |
358 | 0 | return NS_OK; |
359 | 0 | } |
360 | 0 | RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); |
361 | 0 | if (!swm) { |
362 | 0 | return NS_ERROR_FAILURE; |
363 | 0 | } |
364 | 0 | nsAutoCString originSuffix; |
365 | 0 | nsresult rv = mPrincipal->GetOriginSuffix(originSuffix); |
366 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
367 | 0 | return rv; |
368 | 0 | } |
369 | 0 | return swm->SendPushEvent(originSuffix, mScope, mMessageId, mData); |
370 | 0 | } |
371 | | |
372 | | bool |
373 | | PushMessageDispatcher::SendToParent(ContentChild* aParentActor) |
374 | 0 | { |
375 | 0 | if (mData) { |
376 | 0 | return aParentActor->SendNotifyPushObserversWithData(mScope, |
377 | 0 | IPC::Principal(mPrincipal), |
378 | 0 | mMessageId, |
379 | 0 | mData.ref()); |
380 | 0 | } |
381 | 0 | return aParentActor->SendNotifyPushObservers(mScope, |
382 | 0 | IPC::Principal(mPrincipal), |
383 | 0 | mMessageId); |
384 | 0 | } |
385 | | |
386 | | bool |
387 | | PushMessageDispatcher::SendToChild(ContentParent* aContentActor) |
388 | 0 | { |
389 | 0 | if (mData) { |
390 | 0 | return aContentActor->SendPushWithData(mScope, IPC::Principal(mPrincipal), |
391 | 0 | mMessageId, mData.ref()); |
392 | 0 | } |
393 | 0 | return aContentActor->SendPush(mScope, IPC::Principal(mPrincipal), |
394 | 0 | mMessageId); |
395 | 0 | } |
396 | | |
397 | | PushSubscriptionChangeDispatcher::PushSubscriptionChangeDispatcher(const nsACString& aScope, |
398 | | nsIPrincipal* aPrincipal) |
399 | | : PushDispatcher(aScope, aPrincipal) |
400 | 0 | {} |
401 | | |
402 | | PushSubscriptionChangeDispatcher::~PushSubscriptionChangeDispatcher() |
403 | | {} |
404 | | |
405 | | nsresult |
406 | | PushSubscriptionChangeDispatcher::NotifyObservers() |
407 | 0 | { |
408 | 0 | return DoNotifyObservers(mPrincipal, OBSERVER_TOPIC_SUBSCRIPTION_CHANGE, |
409 | 0 | mScope); |
410 | 0 | } |
411 | | |
412 | | nsresult |
413 | | PushSubscriptionChangeDispatcher::NotifyWorkers() |
414 | 0 | { |
415 | 0 | if (!ShouldNotifyWorkers()) { |
416 | 0 | return NS_OK; |
417 | 0 | } |
418 | 0 | RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); |
419 | 0 | if (!swm) { |
420 | 0 | return NS_ERROR_FAILURE; |
421 | 0 | } |
422 | 0 | nsAutoCString originSuffix; |
423 | 0 | nsresult rv = mPrincipal->GetOriginSuffix(originSuffix); |
424 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
425 | 0 | return rv; |
426 | 0 | } |
427 | 0 | return swm->SendPushSubscriptionChangeEvent(originSuffix, mScope); |
428 | 0 | } |
429 | | |
430 | | bool |
431 | | PushSubscriptionChangeDispatcher::SendToParent(ContentChild* aParentActor) |
432 | 0 | { |
433 | 0 | return aParentActor->SendNotifyPushSubscriptionChangeObservers(mScope, |
434 | 0 | IPC::Principal(mPrincipal)); |
435 | 0 | } |
436 | | |
437 | | bool |
438 | | PushSubscriptionChangeDispatcher::SendToChild(ContentParent* aContentActor) |
439 | 0 | { |
440 | 0 | return aContentActor->SendPushSubscriptionChange(mScope, |
441 | 0 | IPC::Principal(mPrincipal)); |
442 | 0 | } |
443 | | |
444 | | PushSubscriptionModifiedDispatcher::PushSubscriptionModifiedDispatcher(const nsACString& aScope, |
445 | | nsIPrincipal* aPrincipal) |
446 | | : PushDispatcher(aScope, aPrincipal) |
447 | 0 | {} |
448 | | |
449 | | PushSubscriptionModifiedDispatcher::~PushSubscriptionModifiedDispatcher() |
450 | | {} |
451 | | |
452 | | nsresult |
453 | | PushSubscriptionModifiedDispatcher::NotifyObservers() |
454 | 0 | { |
455 | 0 | return DoNotifyObservers(mPrincipal, OBSERVER_TOPIC_SUBSCRIPTION_MODIFIED, |
456 | 0 | mScope); |
457 | 0 | } |
458 | | |
459 | | nsresult |
460 | | PushSubscriptionModifiedDispatcher::NotifyWorkers() |
461 | 0 | { |
462 | 0 | return NS_OK; |
463 | 0 | } |
464 | | |
465 | | bool |
466 | | PushSubscriptionModifiedDispatcher::SendToParent(ContentChild* aParentActor) |
467 | 0 | { |
468 | 0 | return aParentActor->SendNotifyPushSubscriptionModifiedObservers(mScope, |
469 | 0 | IPC::Principal(mPrincipal)); |
470 | 0 | } |
471 | | |
472 | | bool |
473 | | PushSubscriptionModifiedDispatcher::SendToChild(ContentParent* aContentActor) |
474 | 0 | { |
475 | 0 | return aContentActor->SendNotifyPushSubscriptionModifiedObservers(mScope, |
476 | 0 | IPC::Principal(mPrincipal)); |
477 | 0 | } |
478 | | |
479 | | PushErrorDispatcher::PushErrorDispatcher(const nsACString& aScope, |
480 | | nsIPrincipal* aPrincipal, |
481 | | const nsAString& aMessage, |
482 | | uint32_t aFlags) |
483 | | : PushDispatcher(aScope, aPrincipal) |
484 | | , mMessage(aMessage) |
485 | | , mFlags(aFlags) |
486 | 0 | {} |
487 | | |
488 | | PushErrorDispatcher::~PushErrorDispatcher() |
489 | 0 | {} |
490 | | |
491 | | nsresult |
492 | | PushErrorDispatcher::NotifyObservers() |
493 | 0 | { |
494 | 0 | return NS_OK; |
495 | 0 | } |
496 | | |
497 | | nsresult |
498 | | PushErrorDispatcher::NotifyWorkers() |
499 | 0 | { |
500 | 0 | if (!ShouldNotifyWorkers()) { |
501 | 0 | // For system subscriptions, log the error directly to the browser console. |
502 | 0 | return nsContentUtils::ReportToConsoleNonLocalized(mMessage, |
503 | 0 | mFlags, |
504 | 0 | NS_LITERAL_CSTRING("Push"), |
505 | 0 | nullptr, /* aDocument */ |
506 | 0 | nullptr, /* aURI */ |
507 | 0 | EmptyString(), /* aLine */ |
508 | 0 | 0, /* aLineNumber */ |
509 | 0 | 0, /* aColumnNumber */ |
510 | 0 | nsContentUtils::eOMIT_LOCATION); |
511 | 0 | } |
512 | 0 | // For service worker subscriptions, report the error to all clients. |
513 | 0 | RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance(); |
514 | 0 | if (swm) { |
515 | 0 | swm->ReportToAllClients(mScope, |
516 | 0 | mMessage, |
517 | 0 | NS_ConvertUTF8toUTF16(mScope), /* aFilename */ |
518 | 0 | EmptyString(), /* aLine */ |
519 | 0 | 0, /* aLineNumber */ |
520 | 0 | 0, /* aColumnNumber */ |
521 | 0 | mFlags); |
522 | 0 | } |
523 | 0 | return NS_OK; |
524 | 0 | } |
525 | | |
526 | | bool |
527 | | PushErrorDispatcher::SendToParent(ContentChild*) |
528 | 0 | { |
529 | 0 | return true; |
530 | 0 | } |
531 | | |
532 | | bool |
533 | | PushErrorDispatcher::SendToChild(ContentParent* aContentActor) |
534 | 0 | { |
535 | 0 | return aContentActor->SendPushError(mScope, IPC::Principal(mPrincipal), |
536 | 0 | mMessage, mFlags); |
537 | 0 | } |
538 | | |
539 | | nsresult |
540 | | PushErrorDispatcher::HandleNoChildProcesses() |
541 | 0 | { |
542 | 0 | // Report to the console if no content processes are active. |
543 | 0 | nsCOMPtr<nsIURI> scopeURI; |
544 | 0 | nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), mScope); |
545 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
546 | 0 | return rv; |
547 | 0 | } |
548 | 0 | return nsContentUtils::ReportToConsoleNonLocalized(mMessage, |
549 | 0 | mFlags, |
550 | 0 | NS_LITERAL_CSTRING("Push"), |
551 | 0 | nullptr, /* aDocument */ |
552 | 0 | scopeURI, /* aURI */ |
553 | 0 | EmptyString(), /* aLine */ |
554 | 0 | 0, /* aLineNumber */ |
555 | 0 | 0, /* aColumnNumber */ |
556 | 0 | nsContentUtils::eOMIT_LOCATION); |
557 | 0 | } |
558 | | |
559 | | } // namespace dom |
560 | | } // namespace mozilla |