Line data Source code
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 file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "BackgroundChildImpl.h"
8 :
9 : #include "ActorsChild.h" // IndexedDB
10 : #include "BroadcastChannelChild.h"
11 : #include "ServiceWorkerManagerChild.h"
12 : #include "FileDescriptorSetChild.h"
13 : #ifdef MOZ_WEBRTC
14 : #include "CamerasChild.h"
15 : #endif
16 : #include "mozilla/media/MediaChild.h"
17 : #include "mozilla/Assertions.h"
18 : #include "mozilla/SchedulerGroup.h"
19 : #include "mozilla/dom/PFileSystemRequestChild.h"
20 : #include "mozilla/dom/FileSystemTaskBase.h"
21 : #include "mozilla/dom/asmjscache/AsmJSCache.h"
22 : #include "mozilla/dom/cache/ActorUtils.h"
23 : #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
24 : #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
25 : #include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
26 : #include "mozilla/dom/ipc/PendingIPCBlobChild.h"
27 : #include "mozilla/dom/quota/PQuotaChild.h"
28 : #include "mozilla/dom/GamepadEventChannelChild.h"
29 : #include "mozilla/dom/GamepadTestChannelChild.h"
30 : #include "mozilla/dom/MessagePortChild.h"
31 : #include "mozilla/ipc/IPCStreamAlloc.h"
32 : #include "mozilla/ipc/PBackgroundTestChild.h"
33 : #include "mozilla/ipc/PChildToParentStreamChild.h"
34 : #include "mozilla/ipc/PParentToChildStreamChild.h"
35 : #include "mozilla/layout/VsyncChild.h"
36 : #include "mozilla/net/HttpBackgroundChannelChild.h"
37 : #include "mozilla/net/PUDPSocketChild.h"
38 : #include "mozilla/dom/network/UDPSocketChild.h"
39 : #include "mozilla/dom/WebAuthnTransactionChild.h"
40 : #include "nsID.h"
41 : #include "nsTraceRefcnt.h"
42 :
43 : namespace {
44 :
45 : class TestChild final : public mozilla::ipc::PBackgroundTestChild
46 : {
47 : friend class mozilla::ipc::BackgroundChildImpl;
48 :
49 : nsCString mTestArg;
50 :
51 0 : explicit TestChild(const nsCString& aTestArg)
52 0 : : mTestArg(aTestArg)
53 : {
54 0 : MOZ_COUNT_CTOR(TestChild);
55 0 : }
56 :
57 : protected:
58 0 : ~TestChild() override
59 0 : {
60 0 : MOZ_COUNT_DTOR(TestChild);
61 0 : }
62 :
63 : public:
64 : mozilla::ipc::IPCResult
65 : Recv__delete__(const nsCString& aTestArg) override;
66 : };
67 :
68 : } // namespace
69 :
70 : namespace mozilla {
71 : namespace ipc {
72 :
73 : using mozilla::dom::UDPSocketChild;
74 : using mozilla::net::PUDPSocketChild;
75 :
76 : using mozilla::dom::asmjscache::PAsmJSCacheEntryChild;
77 : using mozilla::dom::cache::PCacheChild;
78 : using mozilla::dom::cache::PCacheStorageChild;
79 : using mozilla::dom::cache::PCacheStreamControlChild;
80 :
81 : using mozilla::dom::WebAuthnTransactionChild;
82 :
83 : // -----------------------------------------------------------------------------
84 : // BackgroundChildImpl::ThreadLocal
85 : // -----------------------------------------------------------------------------
86 :
87 0 : BackgroundChildImpl::
88 0 : ThreadLocal::ThreadLocal()
89 0 : : mCurrentFileHandle(nullptr)
90 : {
91 : // May happen on any thread!
92 0 : MOZ_COUNT_CTOR(mozilla::ipc::BackgroundChildImpl::ThreadLocal);
93 0 : }
94 :
95 0 : BackgroundChildImpl::
96 0 : ThreadLocal::~ThreadLocal()
97 : {
98 : // May happen on any thread!
99 0 : MOZ_COUNT_DTOR(mozilla::ipc::BackgroundChildImpl::ThreadLocal);
100 0 : }
101 :
102 : // -----------------------------------------------------------------------------
103 : // BackgroundChildImpl
104 : // -----------------------------------------------------------------------------
105 :
106 5 : BackgroundChildImpl::BackgroundChildImpl()
107 : {
108 : // May happen on any thread!
109 5 : MOZ_COUNT_CTOR(mozilla::ipc::BackgroundChildImpl);
110 5 : }
111 :
112 0 : BackgroundChildImpl::~BackgroundChildImpl()
113 : {
114 : // May happen on any thread!
115 0 : MOZ_COUNT_DTOR(mozilla::ipc::BackgroundChildImpl);
116 0 : }
117 :
118 : void
119 0 : BackgroundChildImpl::ProcessingError(Result aCode, const char* aReason)
120 : {
121 : // May happen on any thread!
122 :
123 0 : nsAutoCString abortMessage;
124 :
125 0 : switch (aCode) {
126 :
127 : #define HANDLE_CASE(_result) \
128 : case _result: \
129 : abortMessage.AssignLiteral(#_result); \
130 : break
131 :
132 0 : HANDLE_CASE(MsgDropped);
133 0 : HANDLE_CASE(MsgNotKnown);
134 0 : HANDLE_CASE(MsgNotAllowed);
135 0 : HANDLE_CASE(MsgPayloadError);
136 0 : HANDLE_CASE(MsgProcessingError);
137 0 : HANDLE_CASE(MsgRouteError);
138 0 : HANDLE_CASE(MsgValueError);
139 :
140 : #undef HANDLE_CASE
141 :
142 : default:
143 0 : MOZ_CRASH("Unknown error code!");
144 : }
145 :
146 0 : MOZ_CRASH_UNSAFE_PRINTF("%s: %s", abortMessage.get(), aReason);
147 : }
148 :
149 : void
150 0 : BackgroundChildImpl::ActorDestroy(ActorDestroyReason aWhy)
151 : {
152 : // May happen on any thread!
153 0 : }
154 :
155 : PBackgroundTestChild*
156 0 : BackgroundChildImpl::AllocPBackgroundTestChild(const nsCString& aTestArg)
157 : {
158 0 : return new TestChild(aTestArg);
159 : }
160 :
161 : bool
162 0 : BackgroundChildImpl::DeallocPBackgroundTestChild(PBackgroundTestChild* aActor)
163 : {
164 0 : MOZ_ASSERT(aActor);
165 :
166 0 : delete static_cast<TestChild*>(aActor);
167 0 : return true;
168 : }
169 :
170 : BackgroundChildImpl::PBackgroundIDBFactoryChild*
171 0 : BackgroundChildImpl::AllocPBackgroundIDBFactoryChild(
172 : const LoggingInfo& aLoggingInfo)
173 : {
174 0 : MOZ_CRASH("PBackgroundIDBFactoryChild actors should be manually "
175 : "constructed!");
176 : }
177 :
178 : bool
179 0 : BackgroundChildImpl::DeallocPBackgroundIDBFactoryChild(
180 : PBackgroundIDBFactoryChild* aActor)
181 : {
182 0 : MOZ_ASSERT(aActor);
183 :
184 0 : delete aActor;
185 0 : return true;
186 : }
187 :
188 : BackgroundChildImpl::PBackgroundIndexedDBUtilsChild*
189 0 : BackgroundChildImpl::AllocPBackgroundIndexedDBUtilsChild()
190 : {
191 0 : MOZ_CRASH("PBackgroundIndexedDBUtilsChild actors should be manually "
192 : "constructed!");
193 : }
194 :
195 : bool
196 0 : BackgroundChildImpl::DeallocPBackgroundIndexedDBUtilsChild(
197 : PBackgroundIndexedDBUtilsChild* aActor)
198 : {
199 0 : MOZ_ASSERT(aActor);
200 :
201 0 : delete aActor;
202 0 : return true;
203 : }
204 :
205 : PPendingIPCBlobChild*
206 0 : BackgroundChildImpl::AllocPPendingIPCBlobChild(const IPCBlob& aBlob)
207 : {
208 0 : return new mozilla::dom::PendingIPCBlobChild(aBlob);
209 : }
210 :
211 : bool
212 0 : BackgroundChildImpl::DeallocPPendingIPCBlobChild(PPendingIPCBlobChild* aActor)
213 : {
214 0 : delete aActor;
215 0 : return true;
216 : }
217 :
218 : PIPCBlobInputStreamChild*
219 0 : BackgroundChildImpl::AllocPIPCBlobInputStreamChild(const nsID& aID,
220 : const uint64_t& aSize)
221 : {
222 : // IPCBlobInputStreamChild is refcounted. Here it's created and in
223 : // DeallocPIPCBlobInputStreamChild is released.
224 :
225 : RefPtr<mozilla::dom::IPCBlobInputStreamChild> actor =
226 0 : new mozilla::dom::IPCBlobInputStreamChild(aID, aSize);
227 0 : return actor.forget().take();
228 : }
229 :
230 : bool
231 0 : BackgroundChildImpl::DeallocPIPCBlobInputStreamChild(PIPCBlobInputStreamChild* aActor)
232 : {
233 : RefPtr<mozilla::dom::IPCBlobInputStreamChild> actor =
234 0 : dont_AddRef(static_cast<mozilla::dom::IPCBlobInputStreamChild*>(aActor));
235 0 : return true;
236 : }
237 :
238 : PFileDescriptorSetChild*
239 0 : BackgroundChildImpl::AllocPFileDescriptorSetChild(
240 : const FileDescriptor& aFileDescriptor)
241 : {
242 0 : return new FileDescriptorSetChild(aFileDescriptor);
243 : }
244 :
245 : bool
246 0 : BackgroundChildImpl::DeallocPFileDescriptorSetChild(
247 : PFileDescriptorSetChild* aActor)
248 : {
249 0 : MOZ_ASSERT(aActor);
250 :
251 0 : delete static_cast<FileDescriptorSetChild*>(aActor);
252 0 : return true;
253 : }
254 :
255 : BackgroundChildImpl::PVsyncChild*
256 1 : BackgroundChildImpl::AllocPVsyncChild()
257 : {
258 2 : RefPtr<mozilla::layout::VsyncChild> actor = new mozilla::layout::VsyncChild();
259 : // There still has one ref-count after return, and it will be released in
260 : // DeallocPVsyncChild().
261 2 : return actor.forget().take();
262 : }
263 :
264 : bool
265 0 : BackgroundChildImpl::DeallocPVsyncChild(PVsyncChild* aActor)
266 : {
267 0 : MOZ_ASSERT(aActor);
268 :
269 : // This actor already has one ref-count. Please check AllocPVsyncChild().
270 : RefPtr<mozilla::layout::VsyncChild> actor =
271 0 : dont_AddRef(static_cast<mozilla::layout::VsyncChild*>(aActor));
272 0 : return true;
273 : }
274 :
275 : PUDPSocketChild*
276 0 : BackgroundChildImpl::AllocPUDPSocketChild(const OptionalPrincipalInfo& aPrincipalInfo,
277 : const nsCString& aFilter)
278 : {
279 0 : MOZ_CRASH("AllocPUDPSocket should not be called");
280 : return nullptr;
281 : }
282 :
283 : bool
284 0 : BackgroundChildImpl::DeallocPUDPSocketChild(PUDPSocketChild* child)
285 : {
286 :
287 0 : UDPSocketChild* p = static_cast<UDPSocketChild*>(child);
288 0 : p->ReleaseIPDLReference();
289 0 : return true;
290 : }
291 :
292 : // -----------------------------------------------------------------------------
293 : // BroadcastChannel API
294 : // -----------------------------------------------------------------------------
295 :
296 : dom::PBroadcastChannelChild*
297 0 : BackgroundChildImpl::AllocPBroadcastChannelChild(const PrincipalInfo& aPrincipalInfo,
298 : const nsCString& aOrigin,
299 : const nsString& aChannel)
300 : {
301 : RefPtr<dom::BroadcastChannelChild> agent =
302 0 : new dom::BroadcastChannelChild(aOrigin);
303 0 : return agent.forget().take();
304 : }
305 :
306 : bool
307 0 : BackgroundChildImpl::DeallocPBroadcastChannelChild(
308 : PBroadcastChannelChild* aActor)
309 : {
310 : RefPtr<dom::BroadcastChannelChild> child =
311 0 : dont_AddRef(static_cast<dom::BroadcastChannelChild*>(aActor));
312 0 : MOZ_ASSERT(child);
313 0 : return true;
314 : }
315 :
316 : camera::PCamerasChild*
317 0 : BackgroundChildImpl::AllocPCamerasChild()
318 : {
319 : #ifdef MOZ_WEBRTC
320 : RefPtr<camera::CamerasChild> agent =
321 0 : new camera::CamerasChild();
322 0 : return agent.forget().take();
323 : #else
324 : return nullptr;
325 : #endif
326 : }
327 :
328 : bool
329 0 : BackgroundChildImpl::DeallocPCamerasChild(camera::PCamerasChild *aActor)
330 : {
331 : #ifdef MOZ_WEBRTC
332 : RefPtr<camera::CamerasChild> child =
333 0 : dont_AddRef(static_cast<camera::CamerasChild*>(aActor));
334 0 : MOZ_ASSERT(aActor);
335 : #endif
336 0 : return true;
337 : }
338 :
339 : // -----------------------------------------------------------------------------
340 : // ServiceWorkerManager
341 : // -----------------------------------------------------------------------------
342 :
343 : dom::PServiceWorkerManagerChild*
344 2 : BackgroundChildImpl::AllocPServiceWorkerManagerChild()
345 : {
346 : RefPtr<dom::workers::ServiceWorkerManagerChild> agent =
347 4 : new dom::workers::ServiceWorkerManagerChild();
348 4 : return agent.forget().take();
349 : }
350 :
351 : bool
352 0 : BackgroundChildImpl::DeallocPServiceWorkerManagerChild(
353 : PServiceWorkerManagerChild* aActor)
354 : {
355 : RefPtr<dom::workers::ServiceWorkerManagerChild> child =
356 0 : dont_AddRef(static_cast<dom::workers::ServiceWorkerManagerChild*>(aActor));
357 0 : MOZ_ASSERT(child);
358 0 : return true;
359 : }
360 :
361 : // -----------------------------------------------------------------------------
362 : // Cache API
363 : // -----------------------------------------------------------------------------
364 :
365 : PCacheStorageChild*
366 0 : BackgroundChildImpl::AllocPCacheStorageChild(const Namespace& aNamespace,
367 : const PrincipalInfo& aPrincipalInfo)
368 : {
369 0 : MOZ_CRASH("CacheStorageChild actor must be provided to PBackground manager");
370 : return nullptr;
371 : }
372 :
373 : bool
374 0 : BackgroundChildImpl::DeallocPCacheStorageChild(PCacheStorageChild* aActor)
375 : {
376 0 : dom::cache::DeallocPCacheStorageChild(aActor);
377 0 : return true;
378 : }
379 :
380 : PCacheChild*
381 0 : BackgroundChildImpl::AllocPCacheChild()
382 : {
383 0 : return dom::cache::AllocPCacheChild();
384 : }
385 :
386 : bool
387 0 : BackgroundChildImpl::DeallocPCacheChild(PCacheChild* aActor)
388 : {
389 0 : dom::cache::DeallocPCacheChild(aActor);
390 0 : return true;
391 : }
392 :
393 : PCacheStreamControlChild*
394 0 : BackgroundChildImpl::AllocPCacheStreamControlChild()
395 : {
396 0 : return dom::cache::AllocPCacheStreamControlChild();
397 : }
398 :
399 : bool
400 0 : BackgroundChildImpl::DeallocPCacheStreamControlChild(PCacheStreamControlChild* aActor)
401 : {
402 0 : dom::cache::DeallocPCacheStreamControlChild(aActor);
403 0 : return true;
404 : }
405 :
406 : // -----------------------------------------------------------------------------
407 : // MessageChannel/MessagePort API
408 : // -----------------------------------------------------------------------------
409 :
410 : dom::PMessagePortChild*
411 0 : BackgroundChildImpl::AllocPMessagePortChild(const nsID& aUUID,
412 : const nsID& aDestinationUUID,
413 : const uint32_t& aSequenceID)
414 : {
415 0 : RefPtr<dom::MessagePortChild> agent = new dom::MessagePortChild();
416 0 : return agent.forget().take();
417 : }
418 :
419 : bool
420 0 : BackgroundChildImpl::DeallocPMessagePortChild(PMessagePortChild* aActor)
421 : {
422 : RefPtr<dom::MessagePortChild> child =
423 0 : dont_AddRef(static_cast<dom::MessagePortChild*>(aActor));
424 0 : MOZ_ASSERT(child);
425 0 : return true;
426 : }
427 :
428 : PChildToParentStreamChild*
429 0 : BackgroundChildImpl::AllocPChildToParentStreamChild()
430 : {
431 0 : MOZ_CRASH("PChildToParentStreamChild actors should be manually constructed!");
432 : }
433 :
434 : bool
435 0 : BackgroundChildImpl::DeallocPChildToParentStreamChild(PChildToParentStreamChild* aActor)
436 : {
437 0 : delete aActor;
438 0 : return true;
439 : }
440 :
441 : PParentToChildStreamChild*
442 0 : BackgroundChildImpl::AllocPParentToChildStreamChild()
443 : {
444 0 : return mozilla::ipc::AllocPParentToChildStreamChild();
445 : }
446 :
447 : bool
448 0 : BackgroundChildImpl::DeallocPParentToChildStreamChild(PParentToChildStreamChild* aActor)
449 : {
450 0 : delete aActor;
451 0 : return true;
452 : }
453 :
454 : PAsmJSCacheEntryChild*
455 0 : BackgroundChildImpl::AllocPAsmJSCacheEntryChild(
456 : const dom::asmjscache::OpenMode& aOpenMode,
457 : const dom::asmjscache::WriteParams& aWriteParams,
458 : const PrincipalInfo& aPrincipalInfo)
459 : {
460 0 : MOZ_CRASH("PAsmJSCacheEntryChild actors should be manually constructed!");
461 : }
462 :
463 : bool
464 0 : BackgroundChildImpl::DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild* aActor)
465 : {
466 0 : MOZ_ASSERT(aActor);
467 :
468 0 : dom::asmjscache::DeallocEntryChild(aActor);
469 0 : return true;
470 : }
471 :
472 : BackgroundChildImpl::PQuotaChild*
473 0 : BackgroundChildImpl::AllocPQuotaChild()
474 : {
475 0 : MOZ_CRASH("PQuotaChild actor should be manually constructed!");
476 : }
477 :
478 : bool
479 0 : BackgroundChildImpl::DeallocPQuotaChild(PQuotaChild* aActor)
480 : {
481 0 : MOZ_ASSERT(aActor);
482 :
483 0 : delete aActor;
484 0 : return true;
485 : }
486 :
487 : dom::PFileSystemRequestChild*
488 0 : BackgroundChildImpl::AllocPFileSystemRequestChild(const FileSystemParams& aParams)
489 : {
490 0 : MOZ_CRASH("Should never get here!");
491 : return nullptr;
492 : }
493 :
494 : bool
495 0 : BackgroundChildImpl::DeallocPFileSystemRequestChild(PFileSystemRequestChild* aActor)
496 : {
497 : // The reference is increased in FileSystemTaskBase::Start of
498 : // FileSystemTaskBase.cpp. We should decrease it after IPC.
499 : RefPtr<dom::FileSystemTaskChildBase> child =
500 0 : dont_AddRef(static_cast<dom::FileSystemTaskChildBase*>(aActor));
501 0 : return true;
502 : }
503 :
504 : // Gamepad API Background IPC
505 : dom::PGamepadEventChannelChild*
506 0 : BackgroundChildImpl::AllocPGamepadEventChannelChild()
507 : {
508 0 : MOZ_CRASH("PGamepadEventChannelChild actor should be manually constructed!");
509 : return nullptr;
510 : }
511 :
512 : bool
513 0 : BackgroundChildImpl::DeallocPGamepadEventChannelChild(PGamepadEventChannelChild* aActor)
514 : {
515 0 : MOZ_ASSERT(aActor);
516 0 : delete static_cast<dom::GamepadEventChannelChild*>(aActor);
517 0 : return true;
518 : }
519 :
520 : dom::PGamepadTestChannelChild*
521 0 : BackgroundChildImpl::AllocPGamepadTestChannelChild()
522 : {
523 0 : MOZ_CRASH("PGamepadTestChannelChild actor should be manually constructed!");
524 : return nullptr;
525 : }
526 :
527 : bool
528 0 : BackgroundChildImpl::DeallocPGamepadTestChannelChild(PGamepadTestChannelChild* aActor)
529 : {
530 0 : MOZ_ASSERT(aActor);
531 0 : delete static_cast<dom::GamepadTestChannelChild*>(aActor);
532 0 : return true;
533 : }
534 :
535 : #ifdef EARLY_BETA_OR_EARLIER
536 : void
537 75 : BackgroundChildImpl::OnChannelReceivedMessage(const Message& aMsg)
538 : {
539 75 : if (aMsg.type() == layout::PVsync::MessageType::Msg_Notify__ID) {
540 : // Not really necessary to look at the message payload, it will be
541 : // <0.5ms away from TimeStamp::Now()
542 57 : SchedulerGroup::MarkVsyncReceived();
543 : }
544 75 : }
545 : #endif
546 :
547 : dom::PWebAuthnTransactionChild*
548 0 : BackgroundChildImpl::AllocPWebAuthnTransactionChild()
549 : {
550 0 : MOZ_CRASH("PWebAuthnTransaction actor should be manually constructed!");
551 : return nullptr;
552 : }
553 :
554 : bool
555 0 : BackgroundChildImpl::DeallocPWebAuthnTransactionChild(PWebAuthnTransactionChild* aActor)
556 : {
557 0 : MOZ_ASSERT(aActor);
558 : RefPtr<dom::WebAuthnTransactionChild> child =
559 0 : dont_AddRef(static_cast<dom::WebAuthnTransactionChild*>(aActor));
560 0 : return true;
561 : }
562 :
563 : net::PHttpBackgroundChannelChild*
564 0 : BackgroundChildImpl::AllocPHttpBackgroundChannelChild(const uint64_t& aChannelId)
565 : {
566 0 : MOZ_CRASH("PHttpBackgroundChannelChild actor should be manually constructed!");
567 : return nullptr;
568 : }
569 :
570 : bool
571 3 : BackgroundChildImpl::DeallocPHttpBackgroundChannelChild(PHttpBackgroundChannelChild* aActor)
572 : {
573 : // The reference is increased in BackgroundChannelCreateCallback::ActorCreated
574 : // of HttpBackgroundChannelChild.cpp. We should decrease it after IPC
575 : // destroyed.
576 : RefPtr<net::HttpBackgroundChannelChild> child =
577 6 : dont_AddRef(static_cast<net::HttpBackgroundChannelChild*>(aActor));
578 6 : return true;
579 : }
580 :
581 : } // namespace ipc
582 : } // namespace mozilla
583 :
584 : mozilla::ipc::IPCResult
585 0 : TestChild::Recv__delete__(const nsCString& aTestArg)
586 : {
587 0 : MOZ_RELEASE_ASSERT(aTestArg == mTestArg,
588 : "BackgroundTest message was corrupted!");
589 :
590 0 : return IPC_OK();
591 : }
|