BackgroundParentImpl.cpp (50158B)
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 "BackgroundParentImpl.h" 8 9 #include "BroadcastChannelParent.h" 10 #ifdef MOZ_WEBRTC 11 # include "CamerasParent.h" 12 #endif 13 #include "mozilla/Assertions.h" 14 #include "mozilla/RDDProcessManager.h" 15 #include "mozilla/ipc/UtilityProcessManager.h" 16 #include "mozilla/RemoteDecodeUtils.h" 17 #include "mozilla/RefPtr.h" 18 #include "mozilla/dom/BackgroundSessionStorageServiceParent.h" 19 #include "mozilla/dom/ClientManagerActors.h" 20 #include "mozilla/dom/ContentParent.h" 21 #include "mozilla/dom/CookieStoreParent.h" 22 #include "mozilla/dom/DOMTypes.h" 23 #include "mozilla/dom/EndpointForReportParent.h" 24 #include "mozilla/dom/FetchParent.h" 25 #include "mozilla/dom/FileCreatorParent.h" 26 #include "mozilla/dom/FileSystemManagerParentFactory.h" 27 #include "mozilla/dom/FileSystemRequestParent.h" 28 #include "mozilla/dom/GamepadEventChannelParent.h" 29 #include "mozilla/dom/GamepadTestChannelParent.h" 30 #include "mozilla/dom/MIDIManagerParent.h" 31 #include "mozilla/dom/MIDIPlatformService.h" 32 #include "mozilla/dom/MIDIPortParent.h" 33 #include "mozilla/dom/MLSTransactionParent.h" 34 #include "mozilla/dom/MessagePortParent.h" 35 #include "mozilla/dom/PGamepadEventChannelParent.h" 36 #include "mozilla/dom/PGamepadTestChannelParent.h" 37 #include "mozilla/dom/RemoteWorkerControllerParent.h" 38 #include "mozilla/dom/RemoteWorkerServiceParent.h" 39 #include "mozilla/dom/ReportingHeader.h" 40 #include "mozilla/dom/ServiceWorkerActors.h" 41 #include "mozilla/dom/ServiceWorkerContainerParent.h" 42 #include "mozilla/dom/ServiceWorkerManagerParent.h" 43 #include "mozilla/dom/ServiceWorkerParent.h" 44 #include "mozilla/dom/ServiceWorkerRegistrar.h" 45 #include "mozilla/dom/ServiceWorkerRegistrationParent.h" 46 #include "mozilla/dom/SessionStorageManager.h" 47 #include "mozilla/dom/SharedWorkerParent.h" 48 #include "mozilla/dom/StorageActivityService.h" 49 #include "mozilla/dom/StorageIPC.h" 50 #include "mozilla/dom/TemporaryIPCBlobParent.h" 51 #include "mozilla/dom/WebTransportParent.h" 52 #include "mozilla/dom/cache/ActorUtils.h" 53 #include "mozilla/dom/indexedDB/ActorsParent.h" 54 #include "mozilla/dom/locks/LockManagerParent.h" 55 #include "mozilla/dom/localstorage/ActorsParent.h" 56 #include "mozilla/dom/network/UDPSocketParent.h" 57 #include "mozilla/dom/notification/NotificationParent.h" 58 #include "mozilla/dom/quota/ActorsParent.h" 59 #include "mozilla/dom/quota/QuotaParent.h" 60 #include "mozilla/dom/simpledb/ActorsParent.h" 61 #include "mozilla/dom/cache/BoundStorageKeyParent.h" 62 #include "mozilla/dom/VsyncParent.h" 63 #include "mozilla/ipc/BackgroundParent.h" 64 #include "mozilla/ipc/BackgroundUtils.h" 65 #include "mozilla/ipc/Endpoint.h" 66 #include "mozilla/ipc/IdleSchedulerParent.h" 67 #include "mozilla/ipc/PBackgroundSharedTypes.h" 68 #include "mozilla/ipc/PBackgroundTestParent.h" 69 #include "mozilla/net/BackgroundDataBridgeParent.h" 70 #include "mozilla/net/HttpBackgroundChannelParent.h" 71 #include "nsIHttpChannelInternal.h" 72 #include "nsIPrincipal.h" 73 #include "nsProxyRelease.h" 74 #include "nsThreadUtils.h" 75 #include "nsXULAppAPI.h" 76 77 using mozilla::AssertIsOnMainThread; 78 using mozilla::dom::FileSystemRequestParent; 79 using mozilla::dom::MessagePortParent; 80 using mozilla::dom::MIDIManagerParent; 81 using mozilla::dom::MIDIPlatformService; 82 using mozilla::dom::MIDIPortParent; 83 using mozilla::dom::PMessagePortParent; 84 using mozilla::dom::PMIDIManagerParent; 85 using mozilla::dom::PMIDIPortParent; 86 using mozilla::dom::PMLSTransactionParent; 87 using mozilla::dom::PServiceWorkerContainerParent; 88 using mozilla::dom::PServiceWorkerParent; 89 using mozilla::dom::PServiceWorkerRegistrationParent; 90 using mozilla::dom::ServiceWorkerParent; 91 using mozilla::dom::UDPSocketParent; 92 using mozilla::dom::cache::PCacheParent; 93 using mozilla::dom::cache::PCacheStorageParent; 94 using mozilla::dom::cache::PCacheStreamControlParent; 95 using mozilla::ipc::AssertIsOnBackgroundThread; 96 97 namespace { 98 99 class TestParent final : public mozilla::ipc::PBackgroundTestParent { 100 friend class mozilla::ipc::BackgroundParentImpl; 101 102 MOZ_COUNTED_DEFAULT_CTOR(TestParent) 103 104 protected: 105 ~TestParent() override { MOZ_COUNT_DTOR(TestParent); } 106 107 public: 108 void ActorDestroy(ActorDestroyReason aWhy) override; 109 }; 110 111 } // namespace 112 113 namespace mozilla::ipc { 114 115 using mozilla::dom::BroadcastChannelParent; 116 using mozilla::dom::ContentParent; 117 using mozilla::dom::ThreadsafeContentParentHandle; 118 119 BackgroundParentImpl::BackgroundParentImpl() { 120 AssertIsInMainProcess(); 121 122 MOZ_COUNT_CTOR(mozilla::ipc::BackgroundParentImpl); 123 } 124 125 BackgroundParentImpl::~BackgroundParentImpl() { 126 AssertIsInMainProcess(); 127 AssertIsOnMainThread(); 128 129 MOZ_COUNT_DTOR(mozilla::ipc::BackgroundParentImpl); 130 } 131 132 void BackgroundParentImpl::ProcessingError(Result aCode, const char* aReason) { 133 if (MsgDropped == aCode) { 134 return; 135 } 136 137 // XXX Remove this cut-out once bug 1858621 is fixed. Some parent actors 138 // currently return nullptr in actor allocation methods for non fatal errors. 139 // We don't want to crash the parent process or child processes in that case. 140 if (MsgValueError == aCode) { 141 return; 142 } 143 144 // Other errors are big deals. 145 nsDependentCString reason(aReason); 146 if (BackgroundParent::IsOtherProcessActor(this)) { 147 #ifndef FUZZING 148 BackgroundParent::KillHardAsync(this, reason); 149 #endif 150 if (CanSend()) { 151 GetIPCChannel()->InduceConnectionError(); 152 } 153 } else { 154 CrashReporter::RecordAnnotationCString( 155 CrashReporter::Annotation::ipc_channel_error, aReason); 156 157 MOZ_CRASH("in-process BackgroundParent abort due to IPC error"); 158 } 159 } 160 161 void BackgroundParentImpl::ActorDestroy(ActorDestroyReason aWhy) { 162 AssertIsInMainProcess(); 163 AssertIsOnBackgroundThread(); 164 } 165 166 BackgroundParentImpl::PBackgroundTestParent* 167 BackgroundParentImpl::AllocPBackgroundTestParent(const nsACString& aTestArg) { 168 AssertIsInMainProcess(); 169 AssertIsOnBackgroundThread(); 170 171 return new TestParent(); 172 } 173 174 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPBackgroundTestConstructor( 175 PBackgroundTestParent* aActor, const nsACString& aTestArg) { 176 AssertIsInMainProcess(); 177 AssertIsOnBackgroundThread(); 178 MOZ_ASSERT(aActor); 179 180 if (!PBackgroundTestParent::Send__delete__(aActor, aTestArg)) { 181 return IPC_FAIL_NO_REASON(this); 182 } 183 return IPC_OK(); 184 } 185 186 bool BackgroundParentImpl::DeallocPBackgroundTestParent( 187 PBackgroundTestParent* aActor) { 188 AssertIsInMainProcess(); 189 AssertIsOnBackgroundThread(); 190 MOZ_ASSERT(aActor); 191 192 delete static_cast<TestParent*>(aActor); 193 return true; 194 } 195 196 auto BackgroundParentImpl::AllocPBackgroundIDBFactoryParent( 197 const LoggingInfo& aLoggingInfo, const nsACString& aSystemLocale) 198 -> already_AddRefed<PBackgroundIDBFactoryParent> { 199 using mozilla::dom::indexedDB::AllocPBackgroundIDBFactoryParent; 200 201 AssertIsInMainProcess(); 202 AssertIsOnBackgroundThread(); 203 204 return AllocPBackgroundIDBFactoryParent(aLoggingInfo, aSystemLocale); 205 } 206 207 mozilla::ipc::IPCResult 208 BackgroundParentImpl::RecvPBackgroundIDBFactoryConstructor( 209 PBackgroundIDBFactoryParent* aActor, const LoggingInfo& aLoggingInfo, 210 const nsACString& aSystemLocale) { 211 using mozilla::dom::indexedDB::RecvPBackgroundIDBFactoryConstructor; 212 213 AssertIsInMainProcess(); 214 AssertIsOnBackgroundThread(); 215 MOZ_ASSERT(aActor); 216 217 if (!RecvPBackgroundIDBFactoryConstructor(aActor, aLoggingInfo, 218 aSystemLocale)) { 219 return IPC_FAIL_NO_REASON(this); 220 } 221 return IPC_OK(); 222 } 223 224 auto BackgroundParentImpl::AllocPBackgroundIndexedDBUtilsParent() 225 -> PBackgroundIndexedDBUtilsParent* { 226 AssertIsInMainProcess(); 227 AssertIsOnBackgroundThread(); 228 229 return mozilla::dom::indexedDB::AllocPBackgroundIndexedDBUtilsParent(); 230 } 231 232 bool BackgroundParentImpl::DeallocPBackgroundIndexedDBUtilsParent( 233 PBackgroundIndexedDBUtilsParent* aActor) { 234 AssertIsInMainProcess(); 235 AssertIsOnBackgroundThread(); 236 MOZ_ASSERT(aActor); 237 238 return mozilla::dom::indexedDB::DeallocPBackgroundIndexedDBUtilsParent( 239 aActor); 240 } 241 242 mozilla::ipc::IPCResult BackgroundParentImpl::RecvFlushPendingFileDeletions() { 243 AssertIsInMainProcess(); 244 AssertIsOnBackgroundThread(); 245 246 if (!mozilla::dom::indexedDB::RecvFlushPendingFileDeletions()) { 247 return IPC_FAIL_NO_REASON(this); 248 } 249 return IPC_OK(); 250 } 251 252 already_AddRefed<BackgroundParentImpl::PBackgroundSDBConnectionParent> 253 BackgroundParentImpl::AllocPBackgroundSDBConnectionParent( 254 const PersistenceType& aPersistenceType, 255 const PrincipalInfo& aPrincipalInfo) { 256 AssertIsInMainProcess(); 257 AssertIsOnBackgroundThread(); 258 259 return mozilla::dom::AllocPBackgroundSDBConnectionParent(aPersistenceType, 260 aPrincipalInfo); 261 } 262 263 mozilla::ipc::IPCResult 264 BackgroundParentImpl::RecvPBackgroundSDBConnectionConstructor( 265 PBackgroundSDBConnectionParent* aActor, 266 const PersistenceType& aPersistenceType, 267 const PrincipalInfo& aPrincipalInfo) { 268 AssertIsInMainProcess(); 269 AssertIsOnBackgroundThread(); 270 MOZ_ASSERT(aActor); 271 272 if (!mozilla::dom::RecvPBackgroundSDBConnectionConstructor( 273 aActor, aPersistenceType, aPrincipalInfo)) { 274 return IPC_FAIL_NO_REASON(this); 275 } 276 return IPC_OK(); 277 } 278 279 BackgroundParentImpl::PBackgroundLSObserverParent* 280 BackgroundParentImpl::AllocPBackgroundLSObserverParent( 281 const uint64_t& aObserverId) { 282 AssertIsInMainProcess(); 283 AssertIsOnBackgroundThread(); 284 285 return mozilla::dom::AllocPBackgroundLSObserverParent(aObserverId); 286 } 287 288 mozilla::ipc::IPCResult 289 BackgroundParentImpl::RecvPBackgroundLSObserverConstructor( 290 PBackgroundLSObserverParent* aActor, const uint64_t& aObserverId) { 291 AssertIsInMainProcess(); 292 AssertIsOnBackgroundThread(); 293 MOZ_ASSERT(aActor); 294 295 if (!mozilla::dom::RecvPBackgroundLSObserverConstructor(aActor, 296 aObserverId)) { 297 return IPC_FAIL_NO_REASON(this); 298 } 299 return IPC_OK(); 300 } 301 302 bool BackgroundParentImpl::DeallocPBackgroundLSObserverParent( 303 PBackgroundLSObserverParent* aActor) { 304 AssertIsInMainProcess(); 305 AssertIsOnBackgroundThread(); 306 MOZ_ASSERT(aActor); 307 308 return mozilla::dom::DeallocPBackgroundLSObserverParent(aActor); 309 } 310 311 BackgroundParentImpl::PBackgroundLSRequestParent* 312 BackgroundParentImpl::AllocPBackgroundLSRequestParent( 313 const LSRequestParams& aParams) { 314 AssertIsInMainProcess(); 315 AssertIsOnBackgroundThread(); 316 317 return mozilla::dom::AllocPBackgroundLSRequestParent(this, aParams); 318 } 319 320 mozilla::ipc::IPCResult 321 BackgroundParentImpl::RecvPBackgroundLSRequestConstructor( 322 PBackgroundLSRequestParent* aActor, const LSRequestParams& aParams) { 323 AssertIsInMainProcess(); 324 AssertIsOnBackgroundThread(); 325 MOZ_ASSERT(aActor); 326 327 if (!mozilla::dom::RecvPBackgroundLSRequestConstructor(aActor, aParams)) { 328 return IPC_FAIL_NO_REASON(this); 329 } 330 return IPC_OK(); 331 } 332 333 bool BackgroundParentImpl::DeallocPBackgroundLSRequestParent( 334 PBackgroundLSRequestParent* aActor) { 335 AssertIsInMainProcess(); 336 AssertIsOnBackgroundThread(); 337 MOZ_ASSERT(aActor); 338 339 return mozilla::dom::DeallocPBackgroundLSRequestParent(aActor); 340 } 341 342 BackgroundParentImpl::PBackgroundLSSimpleRequestParent* 343 BackgroundParentImpl::AllocPBackgroundLSSimpleRequestParent( 344 const LSSimpleRequestParams& aParams) { 345 AssertIsInMainProcess(); 346 AssertIsOnBackgroundThread(); 347 348 return mozilla::dom::AllocPBackgroundLSSimpleRequestParent(this, aParams); 349 } 350 351 mozilla::ipc::IPCResult 352 BackgroundParentImpl::RecvPBackgroundLSSimpleRequestConstructor( 353 PBackgroundLSSimpleRequestParent* aActor, 354 const LSSimpleRequestParams& aParams) { 355 AssertIsInMainProcess(); 356 AssertIsOnBackgroundThread(); 357 MOZ_ASSERT(aActor); 358 359 if (!mozilla::dom::RecvPBackgroundLSSimpleRequestConstructor(aActor, 360 aParams)) { 361 return IPC_FAIL_NO_REASON(this); 362 } 363 return IPC_OK(); 364 } 365 366 bool BackgroundParentImpl::DeallocPBackgroundLSSimpleRequestParent( 367 PBackgroundLSSimpleRequestParent* aActor) { 368 AssertIsInMainProcess(); 369 AssertIsOnBackgroundThread(); 370 MOZ_ASSERT(aActor); 371 372 return mozilla::dom::DeallocPBackgroundLSSimpleRequestParent(aActor); 373 } 374 375 BackgroundParentImpl::PBackgroundLocalStorageCacheParent* 376 BackgroundParentImpl::AllocPBackgroundLocalStorageCacheParent( 377 const PrincipalInfo& aPrincipalInfo, const nsACString& aOriginKey, 378 const uint32_t& aPrivateBrowsingId) { 379 AssertIsInMainProcess(); 380 AssertIsOnBackgroundThread(); 381 382 return mozilla::dom::AllocPBackgroundLocalStorageCacheParent( 383 aPrincipalInfo, aOriginKey, aPrivateBrowsingId); 384 } 385 386 mozilla::ipc::IPCResult 387 BackgroundParentImpl::RecvPBackgroundLocalStorageCacheConstructor( 388 PBackgroundLocalStorageCacheParent* aActor, 389 const PrincipalInfo& aPrincipalInfo, const nsACString& aOriginKey, 390 const uint32_t& aPrivateBrowsingId) { 391 AssertIsInMainProcess(); 392 AssertIsOnBackgroundThread(); 393 MOZ_ASSERT(aActor); 394 395 return mozilla::dom::RecvPBackgroundLocalStorageCacheConstructor( 396 this, aActor, aPrincipalInfo, aOriginKey, aPrivateBrowsingId); 397 } 398 399 bool BackgroundParentImpl::DeallocPBackgroundLocalStorageCacheParent( 400 PBackgroundLocalStorageCacheParent* aActor) { 401 AssertIsInMainProcess(); 402 AssertIsOnBackgroundThread(); 403 MOZ_ASSERT(aActor); 404 405 return mozilla::dom::DeallocPBackgroundLocalStorageCacheParent(aActor); 406 } 407 408 auto BackgroundParentImpl::AllocPBackgroundStorageParent( 409 const nsAString& aProfilePath, const uint32_t& aPrivateBrowsingId) 410 -> PBackgroundStorageParent* { 411 AssertIsInMainProcess(); 412 AssertIsOnBackgroundThread(); 413 414 return mozilla::dom::AllocPBackgroundStorageParent(aProfilePath, 415 aPrivateBrowsingId); 416 } 417 418 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPBackgroundStorageConstructor( 419 PBackgroundStorageParent* aActor, const nsAString& aProfilePath, 420 const uint32_t& aPrivateBrowsingId) { 421 AssertIsInMainProcess(); 422 AssertIsOnBackgroundThread(); 423 MOZ_ASSERT(aActor); 424 425 return mozilla::dom::RecvPBackgroundStorageConstructor(aActor, aProfilePath, 426 aPrivateBrowsingId); 427 } 428 429 bool BackgroundParentImpl::DeallocPBackgroundStorageParent( 430 PBackgroundStorageParent* aActor) { 431 AssertIsInMainProcess(); 432 AssertIsOnBackgroundThread(); 433 MOZ_ASSERT(aActor); 434 435 return mozilla::dom::DeallocPBackgroundStorageParent(aActor); 436 } 437 438 already_AddRefed<BackgroundParentImpl::PBackgroundSessionStorageManagerParent> 439 BackgroundParentImpl::AllocPBackgroundSessionStorageManagerParent( 440 const uint64_t& aTopContextId) { 441 AssertIsInMainProcess(); 442 AssertIsOnBackgroundThread(); 443 444 return dom::AllocPBackgroundSessionStorageManagerParent(aTopContextId); 445 } 446 447 already_AddRefed<mozilla::dom::PBackgroundSessionStorageServiceParent> 448 BackgroundParentImpl::AllocPBackgroundSessionStorageServiceParent() { 449 AssertIsInMainProcess(); 450 AssertIsOnBackgroundThread(); 451 452 return MakeAndAddRef<mozilla::dom::BackgroundSessionStorageServiceParent>(); 453 } 454 455 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateFileSystemManagerParent( 456 const PrincipalInfo& aPrincipalInfo, 457 Endpoint<PFileSystemManagerParent>&& aParentEndpoint, 458 CreateFileSystemManagerParentResolver&& aResolver) { 459 AssertIsInMainProcess(); 460 AssertIsOnBackgroundThread(); 461 462 return mozilla::dom::CreateFileSystemManagerParent( 463 this, aPrincipalInfo, std::move(aParentEndpoint), std::move(aResolver)); 464 } 465 466 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateWebTransportParent( 467 const nsAString& aURL, nsIPrincipal* aPrincipal, 468 const uint64_t& aBrowsingContextID, 469 const mozilla::Maybe<IPCClientInfo>& aClientInfo, const bool& aDedicated, 470 const bool& aRequireUnreliable, const uint32_t& aCongestionControl, 471 nsTArray<WebTransportHash>&& aServerCertHashes, 472 Endpoint<PWebTransportParent>&& aParentEndpoint, 473 CreateWebTransportParentResolver&& aResolver) { 474 AssertIsInMainProcess(); 475 AssertIsOnBackgroundThread(); 476 477 RefPtr<mozilla::dom::WebTransportParent> webt = 478 new mozilla::dom::WebTransportParent(); 479 webt->Create(aURL, aPrincipal, aBrowsingContextID, aClientInfo, aDedicated, 480 aRequireUnreliable, aCongestionControl, 481 std::move(aServerCertHashes), std::move(aParentEndpoint), 482 std::move(aResolver)); 483 return IPC_OK(); 484 } 485 486 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateNotificationParent( 487 Endpoint<dom::notification::PNotificationParent>&& aParentEndpoint, 488 NotNull<nsIPrincipal*> aPrincipal, 489 NotNull<nsIPrincipal*> aEffectiveStoragePrincipal, 490 const bool& aIsSecureContext, const nsAString& aScope, 491 const IPCNotification& aNotification, 492 CreateNotificationParentResolver&& aResolver) { 493 AssertIsInMainProcess(); 494 AssertIsOnBackgroundThread(); 495 496 dom::notification::NotificationParentArgs args{ 497 aPrincipal, aEffectiveStoragePrincipal, aIsSecureContext, 498 nsString(aScope), aNotification}; 499 nsresult rv = dom::notification::NotificationParent::CreateOnMainThread( 500 std::move(args), std::move(aParentEndpoint), std::move(aResolver)); 501 if (NS_FAILED(rv)) { 502 return IPC_FAIL(this, "Invalid NotificationParent constructor arguments"); 503 } 504 return IPC_OK(); 505 } 506 507 already_AddRefed<PIdleSchedulerParent> 508 BackgroundParentImpl::AllocPIdleSchedulerParent() { 509 AssertIsOnBackgroundThread(); 510 RefPtr<IdleSchedulerParent> actor = new IdleSchedulerParent(); 511 return actor.forget(); 512 } 513 514 already_AddRefed<dom::PRemoteWorkerControllerParent> 515 BackgroundParentImpl::AllocPRemoteWorkerControllerParent( 516 const dom::RemoteWorkerData& aRemoteWorkerData) { 517 RefPtr<dom::RemoteWorkerControllerParent> actor = 518 new dom::RemoteWorkerControllerParent(aRemoteWorkerData); 519 return actor.forget(); 520 } 521 522 IPCResult BackgroundParentImpl::RecvPRemoteWorkerControllerConstructor( 523 dom::PRemoteWorkerControllerParent* aActor, 524 const dom::RemoteWorkerData& aRemoteWorkerData) { 525 MOZ_ASSERT(aActor); 526 527 return IPC_OK(); 528 } 529 530 mozilla::dom::PSharedWorkerParent* 531 BackgroundParentImpl::AllocPSharedWorkerParent( 532 const mozilla::dom::RemoteWorkerData& aData, const uint64_t& aWindowID, 533 const mozilla::dom::MessagePortIdentifier& aPortIdentifier) { 534 RefPtr<dom::SharedWorkerParent> agent = 535 new mozilla::dom::SharedWorkerParent(); 536 return agent.forget().take(); 537 } 538 539 IPCResult BackgroundParentImpl::RecvPSharedWorkerConstructor( 540 PSharedWorkerParent* aActor, const mozilla::dom::RemoteWorkerData& aData, 541 const uint64_t& aWindowID, 542 const mozilla::dom::MessagePortIdentifier& aPortIdentifier) { 543 mozilla::dom::SharedWorkerParent* actor = 544 static_cast<mozilla::dom::SharedWorkerParent*>(aActor); 545 actor->Initialize(aData, aWindowID, aPortIdentifier); 546 return IPC_OK(); 547 } 548 549 bool BackgroundParentImpl::DeallocPSharedWorkerParent( 550 mozilla::dom::PSharedWorkerParent* aActor) { 551 RefPtr<mozilla::dom::SharedWorkerParent> actor = 552 dont_AddRef(static_cast<mozilla::dom::SharedWorkerParent*>(aActor)); 553 return true; 554 } 555 556 dom::PFileCreatorParent* BackgroundParentImpl::AllocPFileCreatorParent( 557 const nsAString& aFullPath, const nsAString& aType, const nsAString& aName, 558 const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck, 559 const bool& aIsFromNsIFile) { 560 RefPtr<dom::FileCreatorParent> actor = new dom::FileCreatorParent(); 561 return actor.forget().take(); 562 } 563 564 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPFileCreatorConstructor( 565 dom::PFileCreatorParent* aActor, const nsAString& aFullPath, 566 const nsAString& aType, const nsAString& aName, 567 const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck, 568 const bool& aIsFromNsIFile) { 569 bool isFileRemoteType = false; 570 571 // If the ContentParentHandle is null we are dealing with a same-process 572 // actor. 573 RefPtr<ThreadsafeContentParentHandle> parent = 574 BackgroundParent::GetContentParentHandle(this); 575 if (!parent) { 576 isFileRemoteType = true; 577 } else { 578 isFileRemoteType = parent->GetRemoteType() == FILE_REMOTE_TYPE; 579 } 580 581 dom::FileCreatorParent* actor = static_cast<dom::FileCreatorParent*>(aActor); 582 583 // We allow the creation of File via this IPC call only for the 'file' process 584 // or for testing. 585 if (!isFileRemoteType && !StaticPrefs::dom_file_createInChild()) { 586 (void)dom::FileCreatorParent::Send__delete__( 587 actor, dom::FileCreationErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR)); 588 return IPC_OK(); 589 } 590 591 return actor->CreateAndShareFile(aFullPath, aType, aName, aLastModified, 592 aExistenceCheck, aIsFromNsIFile); 593 } 594 595 bool BackgroundParentImpl::DeallocPFileCreatorParent( 596 dom::PFileCreatorParent* aActor) { 597 RefPtr<dom::FileCreatorParent> actor = 598 dont_AddRef(static_cast<dom::FileCreatorParent*>(aActor)); 599 return true; 600 } 601 602 dom::PTemporaryIPCBlobParent* 603 BackgroundParentImpl::AllocPTemporaryIPCBlobParent() { 604 return new dom::TemporaryIPCBlobParent(); 605 } 606 607 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPTemporaryIPCBlobConstructor( 608 dom::PTemporaryIPCBlobParent* aActor) { 609 dom::TemporaryIPCBlobParent* actor = 610 static_cast<dom::TemporaryIPCBlobParent*>(aActor); 611 return actor->CreateAndShareFile(); 612 } 613 614 bool BackgroundParentImpl::DeallocPTemporaryIPCBlobParent( 615 dom::PTemporaryIPCBlobParent* aActor) { 616 delete aActor; 617 return true; 618 } 619 620 already_AddRefed<BackgroundParentImpl::PVsyncParent> 621 BackgroundParentImpl::AllocPVsyncParent() { 622 AssertIsInMainProcess(); 623 AssertIsOnBackgroundThread(); 624 625 RefPtr<mozilla::dom::VsyncParent> actor = new mozilla::dom::VsyncParent(); 626 627 RefPtr<mozilla::VsyncDispatcher> vsyncDispatcher = 628 gfxPlatform::GetPlatform()->GetGlobalVsyncDispatcher(); 629 actor->UpdateVsyncDispatcher(vsyncDispatcher); 630 return actor.forget(); 631 } 632 633 camera::PCamerasParent* BackgroundParentImpl::AllocPCamerasParent() { 634 AssertIsInMainProcess(); 635 AssertIsOnBackgroundThread(); 636 637 #ifdef MOZ_WEBRTC 638 RefPtr<mozilla::camera::CamerasParent> actor = 639 mozilla::camera::CamerasParent::Create(); 640 return actor.forget().take(); 641 #else 642 return nullptr; 643 #endif 644 } 645 646 #ifdef MOZ_WEBRTC 647 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPCamerasConstructor( 648 camera::PCamerasParent* aActor) { 649 AssertIsInMainProcess(); 650 AssertIsOnBackgroundThread(); 651 MOZ_ASSERT(aActor); 652 return static_cast<camera::CamerasParent*>(aActor)->RecvPCamerasConstructor(); 653 } 654 #endif 655 656 bool BackgroundParentImpl::DeallocPCamerasParent( 657 camera::PCamerasParent* aActor) { 658 AssertIsInMainProcess(); 659 AssertIsOnBackgroundThread(); 660 MOZ_ASSERT(aActor); 661 662 #ifdef MOZ_WEBRTC 663 RefPtr<mozilla::camera::CamerasParent> actor = 664 dont_AddRef(static_cast<mozilla::camera::CamerasParent*>(aActor)); 665 #endif 666 return true; 667 } 668 669 auto BackgroundParentImpl::AllocPUDPSocketParent( 670 const Maybe<PrincipalInfo>& /* unused */, const nsACString& /* unused */) 671 -> PUDPSocketParent* { 672 RefPtr<UDPSocketParent> p = new UDPSocketParent(this); 673 674 return p.forget().take(); 675 } 676 677 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPUDPSocketConstructor( 678 PUDPSocketParent* aActor, const Maybe<PrincipalInfo>& aOptionalPrincipal, 679 const nsACString& aFilter) { 680 AssertIsInMainProcess(); 681 AssertIsOnBackgroundThread(); 682 683 if (aOptionalPrincipal.isSome()) { 684 // Support for checking principals (for non-mtransport use) will be handled 685 // in bug 1167039 686 return IPC_FAIL_NO_REASON(this); 687 } 688 // No principal - This must be from mtransport (WebRTC/ICE) - We'd want 689 // to DispatchToMainThread() here, but if we do we must block RecvBind() 690 // until Init() gets run. Since we don't have a principal, and we verify 691 // we have a filter, we can safely skip the Dispatch and just invoke Init() 692 // to install the filter. 693 694 // For mtransport, this will always be "stun", which doesn't allow outbound 695 // packets if they aren't STUN packets until a STUN response is seen. 696 if (!aFilter.EqualsASCII(NS_NETWORK_SOCKET_FILTER_HANDLER_STUN_SUFFIX)) { 697 return IPC_FAIL_NO_REASON(this); 698 } 699 700 if (!static_cast<UDPSocketParent*>(aActor)->Init(nullptr, aFilter)) { 701 MOZ_CRASH("UDPSocketCallback - failed init"); 702 } 703 704 return IPC_OK(); 705 } 706 707 bool BackgroundParentImpl::DeallocPUDPSocketParent(PUDPSocketParent* actor) { 708 UDPSocketParent* p = static_cast<UDPSocketParent*>(actor); 709 p->Release(); 710 return true; 711 } 712 713 mozilla::dom::PBroadcastChannelParent* 714 BackgroundParentImpl::AllocPBroadcastChannelParent( 715 const PrincipalInfo& aPrincipalInfo, const nsACString& aOrigin, 716 const nsAString& aChannel) { 717 AssertIsInMainProcess(); 718 AssertIsOnBackgroundThread(); 719 720 nsString originChannelKey; 721 722 // The format of originChannelKey is: 723 // <channelName>|<origin+OriginAttributes> 724 725 originChannelKey.Assign(aChannel); 726 727 originChannelKey.AppendLiteral("|"); 728 729 originChannelKey.Append(NS_ConvertUTF8toUTF16(aOrigin)); 730 731 return new BroadcastChannelParent(originChannelKey); 732 } 733 734 namespace { 735 736 class CheckPrincipalRunnable final : public Runnable { 737 public: 738 CheckPrincipalRunnable( 739 already_AddRefed<ThreadsafeContentParentHandle> aParent, 740 const PrincipalInfo& aPrincipalInfo, const nsACString& aOrigin) 741 : Runnable("ipc::CheckPrincipalRunnable"), 742 mContentParent(aParent), 743 mPrincipalInfo(aPrincipalInfo), 744 mOrigin(aOrigin) { 745 AssertIsInMainProcess(); 746 AssertIsOnBackgroundThread(); 747 748 MOZ_ASSERT(mContentParent); 749 } 750 751 NS_IMETHOD Run() override { 752 AssertIsOnMainThread(); 753 RefPtr<ContentParent> contentParent = mContentParent->GetContentParent(); 754 if (!contentParent) { 755 return NS_OK; 756 } 757 758 auto principalOrErr = PrincipalInfoToPrincipal(mPrincipalInfo); 759 if (NS_WARN_IF(principalOrErr.isErr())) { 760 contentParent->KillHard( 761 "BroadcastChannel killed: PrincipalInfoToPrincipal failed."); 762 return NS_OK; 763 } 764 765 nsAutoCString origin; 766 nsresult rv = principalOrErr.unwrap()->GetOrigin(origin); 767 if (NS_FAILED(rv)) { 768 contentParent->KillHard( 769 "BroadcastChannel killed: principal::GetOrigin failed."); 770 return NS_OK; 771 } 772 773 if (NS_WARN_IF(!mOrigin.Equals(origin))) { 774 contentParent->KillHard("BroadcastChannel killed: origins do not match."); 775 return NS_OK; 776 } 777 778 return NS_OK; 779 } 780 781 private: 782 RefPtr<ThreadsafeContentParentHandle> mContentParent; 783 PrincipalInfo mPrincipalInfo; 784 nsCString mOrigin; 785 }; 786 787 } // namespace 788 789 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPBroadcastChannelConstructor( 790 PBroadcastChannelParent* actor, const PrincipalInfo& aPrincipalInfo, 791 const nsACString& aOrigin, const nsAString& aChannel) { 792 AssertIsInMainProcess(); 793 AssertIsOnBackgroundThread(); 794 795 RefPtr<ThreadsafeContentParentHandle> parent = 796 BackgroundParent::GetContentParentHandle(this); 797 798 // If the ContentParent is null we are dealing with a same-process actor. 799 if (!parent) { 800 return IPC_OK(); 801 } 802 803 // XXX The principal can be checked right here on the PBackground thread 804 // since BackgroundParentImpl now overrides the ProcessingError method and 805 // kills invalid child processes (IPC_FAIL triggers a processing error). 806 807 RefPtr<CheckPrincipalRunnable> runnable = 808 new CheckPrincipalRunnable(parent.forget(), aPrincipalInfo, aOrigin); 809 MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable)); 810 811 return IPC_OK(); 812 } 813 814 bool BackgroundParentImpl::DeallocPBroadcastChannelParent( 815 PBroadcastChannelParent* aActor) { 816 AssertIsInMainProcess(); 817 AssertIsOnBackgroundThread(); 818 MOZ_ASSERT(aActor); 819 820 delete static_cast<BroadcastChannelParent*>(aActor); 821 return true; 822 } 823 824 mozilla::dom::PCookieStoreParent* 825 BackgroundParentImpl::AllocPCookieStoreParent() { 826 AssertIsInMainProcess(); 827 AssertIsOnBackgroundThread(); 828 829 RefPtr<mozilla::dom::CookieStoreParent> actor = 830 new mozilla::dom::CookieStoreParent(); 831 return actor.forget().take(); 832 } 833 834 bool BackgroundParentImpl::DeallocPCookieStoreParent( 835 PCookieStoreParent* aActor) { 836 AssertIsInMainProcess(); 837 AssertIsOnBackgroundThread(); 838 MOZ_ASSERT(aActor); 839 840 RefPtr<mozilla::dom::CookieStoreParent> actor = 841 dont_AddRef(static_cast<mozilla::dom::CookieStoreParent*>(aActor)); 842 return true; 843 } 844 845 mozilla::dom::PServiceWorkerManagerParent* 846 BackgroundParentImpl::AllocPServiceWorkerManagerParent() { 847 AssertIsInMainProcess(); 848 AssertIsOnBackgroundThread(); 849 850 RefPtr<dom::ServiceWorkerManagerParent> agent = 851 new dom::ServiceWorkerManagerParent(); 852 return agent.forget().take(); 853 } 854 855 bool BackgroundParentImpl::DeallocPServiceWorkerManagerParent( 856 PServiceWorkerManagerParent* aActor) { 857 AssertIsInMainProcess(); 858 AssertIsOnBackgroundThread(); 859 MOZ_ASSERT(aActor); 860 861 RefPtr<dom::ServiceWorkerManagerParent> parent = 862 dont_AddRef(static_cast<dom::ServiceWorkerManagerParent*>(aActor)); 863 MOZ_ASSERT(parent); 864 return true; 865 } 866 867 mozilla::ipc::IPCResult 868 BackgroundParentImpl::RecvShutdownServiceWorkerRegistrar() { 869 AssertIsInMainProcess(); 870 AssertIsOnBackgroundThread(); 871 872 if (BackgroundParent::IsOtherProcessActor(this)) { 873 return IPC_FAIL_NO_REASON(this); 874 } 875 876 RefPtr<dom::ServiceWorkerRegistrar> service = 877 dom::ServiceWorkerRegistrar::Get(); 878 MOZ_ASSERT(service); 879 880 service->Shutdown(); 881 return IPC_OK(); 882 } 883 884 already_AddRefed<PCacheStorageParent> 885 BackgroundParentImpl::AllocPCacheStorageParent( 886 const Namespace& aNamespace, const PrincipalInfo& aPrincipalInfo) { 887 return dom::cache::AllocPCacheStorageParent(this, nullptr, aNamespace, 888 aPrincipalInfo); 889 } 890 891 PMessagePortParent* BackgroundParentImpl::AllocPMessagePortParent( 892 const nsID& aUUID, const nsID& aDestinationUUID, 893 const uint32_t& aSequenceID) { 894 AssertIsInMainProcess(); 895 AssertIsOnBackgroundThread(); 896 897 return new MessagePortParent(aUUID); 898 } 899 900 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPMessagePortConstructor( 901 PMessagePortParent* aActor, const nsID& aUUID, const nsID& aDestinationUUID, 902 const uint32_t& aSequenceID) { 903 AssertIsInMainProcess(); 904 AssertIsOnBackgroundThread(); 905 906 MessagePortParent* mp = static_cast<MessagePortParent*>(aActor); 907 if (!mp->Entangle(aDestinationUUID, aSequenceID)) { 908 return IPC_FAIL_NO_REASON(this); 909 } 910 return IPC_OK(); 911 } 912 913 bool BackgroundParentImpl::DeallocPMessagePortParent( 914 PMessagePortParent* aActor) { 915 AssertIsInMainProcess(); 916 AssertIsOnBackgroundThread(); 917 MOZ_ASSERT(aActor); 918 919 delete static_cast<MessagePortParent*>(aActor); 920 return true; 921 } 922 923 mozilla::ipc::IPCResult BackgroundParentImpl::RecvMessagePortForceClose( 924 const nsID& aUUID, const nsID& aDestinationUUID, 925 const uint32_t& aSequenceID) { 926 AssertIsInMainProcess(); 927 AssertIsOnBackgroundThread(); 928 929 if (!MessagePortParent::ForceClose(aUUID, aDestinationUUID, aSequenceID)) { 930 return IPC_FAIL(this, "MessagePortParent::ForceClose failed."); 931 } 932 933 return IPC_OK(); 934 } 935 936 already_AddRefed<BackgroundParentImpl::PQuotaParent> 937 BackgroundParentImpl::AllocPQuotaParent() { 938 AssertIsInMainProcess(); 939 AssertIsOnBackgroundThread(); 940 941 return mozilla::dom::quota::AllocPQuotaParent(); 942 } 943 944 mozilla::ipc::IPCResult BackgroundParentImpl::RecvShutdownQuotaManager() { 945 AssertIsInMainProcess(); 946 AssertIsOnBackgroundThread(); 947 948 if (BackgroundParent::IsOtherProcessActor(this)) { 949 return IPC_FAIL_NO_REASON(this); 950 } 951 952 if (!mozilla::dom::quota::RecvShutdownQuotaManager()) { 953 return IPC_FAIL_NO_REASON(this); 954 } 955 return IPC_OK(); 956 } 957 958 mozilla::ipc::IPCResult 959 BackgroundParentImpl::RecvShutdownBackgroundSessionStorageManagers() { 960 AssertIsInMainProcess(); 961 AssertIsOnBackgroundThread(); 962 963 if (BackgroundParent::IsOtherProcessActor(this)) { 964 return IPC_FAIL_NO_REASON(this); 965 } 966 967 if (!mozilla::dom::RecvShutdownBackgroundSessionStorageManagers()) { 968 return IPC_FAIL_NO_REASON(this); 969 } 970 return IPC_OK(); 971 } 972 973 mozilla::ipc::IPCResult 974 BackgroundParentImpl::RecvPropagateBackgroundSessionStorageManager( 975 const uint64_t& aCurrentTopContextId, const uint64_t& aTargetTopContextId) { 976 AssertIsInMainProcess(); 977 AssertIsOnBackgroundThread(); 978 979 if (BackgroundParent::IsOtherProcessActor(this)) { 980 return IPC_FAIL(this, "Wrong actor"); 981 } 982 983 mozilla::dom::RecvPropagateBackgroundSessionStorageManager( 984 aCurrentTopContextId, aTargetTopContextId); 985 986 return IPC_OK(); 987 } 988 989 mozilla::ipc::IPCResult 990 BackgroundParentImpl::RecvRemoveBackgroundSessionStorageManager( 991 const uint64_t& aTopContextId) { 992 AssertIsInMainProcess(); 993 AssertIsOnBackgroundThread(); 994 995 if (BackgroundParent::IsOtherProcessActor(this)) { 996 return IPC_FAIL_NO_REASON(this); 997 } 998 999 if (!mozilla::dom::RecvRemoveBackgroundSessionStorageManager(aTopContextId)) { 1000 return IPC_FAIL_NO_REASON(this); 1001 } 1002 return IPC_OK(); 1003 } 1004 1005 mozilla::ipc::IPCResult BackgroundParentImpl::RecvGetSessionStorageManagerData( 1006 const uint64_t& aTopContextId, const uint32_t& aSizeLimit, 1007 const bool& aCancelSessionStoreTimer, 1008 GetSessionStorageManagerDataResolver&& aResolver) { 1009 AssertIsInMainProcess(); 1010 AssertIsOnBackgroundThread(); 1011 1012 if (BackgroundParent::IsOtherProcessActor(this)) { 1013 return IPC_FAIL(this, "Wrong actor"); 1014 } 1015 1016 if (!mozilla::dom::RecvGetSessionStorageData(aTopContextId, aSizeLimit, 1017 aCancelSessionStoreTimer, 1018 std::move(aResolver))) { 1019 return IPC_FAIL(this, "Couldn't get session storage data"); 1020 } 1021 1022 return IPC_OK(); 1023 } 1024 1025 mozilla::ipc::IPCResult BackgroundParentImpl::RecvLoadSessionStorageManagerData( 1026 const uint64_t& aTopContextId, 1027 nsTArray<mozilla::dom::SSCacheCopy>&& aOriginCacheCopy) { 1028 AssertIsInMainProcess(); 1029 AssertIsOnBackgroundThread(); 1030 1031 if (BackgroundParent::IsOtherProcessActor(this)) { 1032 return IPC_FAIL(this, "Wrong actor"); 1033 } 1034 1035 if (!mozilla::dom::RecvLoadSessionStorageData(aTopContextId, 1036 std::move(aOriginCacheCopy))) { 1037 return IPC_FAIL_NO_REASON(this); 1038 } 1039 1040 return IPC_OK(); 1041 } 1042 1043 already_AddRefed<dom::PFileSystemRequestParent> 1044 BackgroundParentImpl::AllocPFileSystemRequestParent( 1045 const FileSystemParams& aParams) { 1046 AssertIsInMainProcess(); 1047 AssertIsOnBackgroundThread(); 1048 1049 RefPtr<FileSystemRequestParent> result = new FileSystemRequestParent(); 1050 1051 if (NS_WARN_IF(!result->Initialize(aParams))) { 1052 return nullptr; 1053 } 1054 1055 return result.forget(); 1056 } 1057 1058 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPFileSystemRequestConstructor( 1059 PFileSystemRequestParent* aActor, const FileSystemParams& params) { 1060 static_cast<FileSystemRequestParent*>(aActor)->Start(); 1061 return IPC_OK(); 1062 } 1063 1064 // Gamepad API Background IPC 1065 already_AddRefed<dom::PGamepadEventChannelParent> 1066 BackgroundParentImpl::AllocPGamepadEventChannelParent() { 1067 return dom::GamepadEventChannelParent::Create(); 1068 } 1069 1070 already_AddRefed<dom::PGamepadTestChannelParent> 1071 BackgroundParentImpl::AllocPGamepadTestChannelParent() { 1072 return dom::GamepadTestChannelParent::Create(); 1073 } 1074 1075 already_AddRefed<net::PHttpBackgroundChannelParent> 1076 BackgroundParentImpl::AllocPHttpBackgroundChannelParent( 1077 const uint64_t& aChannelId) { 1078 AssertIsInMainProcess(); 1079 AssertIsOnBackgroundThread(); 1080 1081 RefPtr<net::HttpBackgroundChannelParent> actor = 1082 new net::HttpBackgroundChannelParent(); 1083 return actor.forget(); 1084 } 1085 1086 mozilla::ipc::IPCResult 1087 BackgroundParentImpl::RecvPHttpBackgroundChannelConstructor( 1088 net::PHttpBackgroundChannelParent* aActor, const uint64_t& aChannelId) { 1089 MOZ_ASSERT(aActor); 1090 AssertIsInMainProcess(); 1091 AssertIsOnBackgroundThread(); 1092 1093 net::HttpBackgroundChannelParent* aParent = 1094 static_cast<net::HttpBackgroundChannelParent*>(aActor); 1095 1096 if (NS_WARN_IF(NS_FAILED(aParent->Init(aChannelId)))) { 1097 return IPC_FAIL_NO_REASON(this); 1098 } 1099 1100 return IPC_OK(); 1101 } 1102 1103 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateBoundStorageKeyParent( 1104 Endpoint<::mozilla::dom::cache::PBoundStorageKeyParent>&& aEndpoint, 1105 const Namespace& aNamespace, const PrincipalInfo& aPrincipalInfo) { 1106 AssertIsInMainProcess(); 1107 AssertIsOnBackgroundThread(); 1108 1109 if (!aEndpoint.IsValid()) { 1110 return IPC_FAIL(this, "Invalid endpoint for BoundStorageKeyParent"); 1111 } 1112 1113 auto* pActor = new dom::cache::BoundStorageKeyParent(this); 1114 if (!aEndpoint.Bind(pActor)) { 1115 return IPC_FAIL(this, 1116 "Failed to bind endpoint for BoundStorageKeyParent actor"); 1117 } 1118 1119 return IPC_OK(); 1120 } 1121 1122 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateMIDIPort( 1123 Endpoint<PMIDIPortParent>&& aEndpoint, const MIDIPortInfo& aPortInfo, 1124 const bool& aSysexEnabled) { 1125 AssertIsInMainProcess(); 1126 AssertIsOnBackgroundThread(); 1127 1128 if (!aEndpoint.IsValid()) { 1129 return IPC_FAIL(this, "invalid endpoint for MIDIPort"); 1130 } 1131 1132 MIDIPlatformService::OwnerThread()->Dispatch(NS_NewRunnableFunction( 1133 "CreateMIDIPortRunnable", [=, endpoint = std::move(aEndpoint)]() mutable { 1134 RefPtr<MIDIPortParent> result = 1135 new MIDIPortParent(aPortInfo, aSysexEnabled); 1136 endpoint.Bind(result); 1137 })); 1138 1139 return IPC_OK(); 1140 } 1141 1142 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateMIDIManager( 1143 Endpoint<PMIDIManagerParent>&& aEndpoint) { 1144 AssertIsInMainProcess(); 1145 AssertIsOnBackgroundThread(); 1146 1147 if (!aEndpoint.IsValid()) { 1148 return IPC_FAIL(this, "invalid endpoint for MIDIManager"); 1149 } 1150 1151 MIDIPlatformService::OwnerThread()->Dispatch(NS_NewRunnableFunction( 1152 "CreateMIDIManagerRunnable", 1153 [=, endpoint = std::move(aEndpoint)]() mutable { 1154 RefPtr<MIDIManagerParent> result = new MIDIManagerParent(); 1155 endpoint.Bind(result); 1156 MIDIPlatformService::Get()->AddManager(result); 1157 })); 1158 1159 return IPC_OK(); 1160 } 1161 1162 mozilla::ipc::IPCResult BackgroundParentImpl::RecvHasMIDIDevice( 1163 HasMIDIDeviceResolver&& aResolver) { 1164 AssertIsInMainProcess(); 1165 AssertIsOnBackgroundThread(); 1166 1167 InvokeAsync(MIDIPlatformService::OwnerThread(), __func__, 1168 []() { 1169 bool hasDevice = MIDIPlatformService::Get()->HasDevice(); 1170 return BoolPromise::CreateAndResolve(hasDevice, __func__); 1171 }) 1172 ->Then(GetCurrentSerialEventTarget(), __func__, 1173 [resolver = std::move(aResolver)]( 1174 const BoolPromise::ResolveOrRejectValue& r) { 1175 resolver(r.IsResolve() && r.ResolveValue()); 1176 }); 1177 1178 return IPC_OK(); 1179 } 1180 1181 // NOTE: Only accessed on the background thread. 1182 static StaticRefPtr<nsISerialEventTarget> sMLSTaskQueue; 1183 1184 class MLSTaskQueueShutdownTask final : public nsITargetShutdownTask { 1185 public: 1186 NS_DECL_THREADSAFE_ISUPPORTS 1187 1188 void TargetShutdown() override { sMLSTaskQueue = nullptr; } 1189 1190 private: 1191 ~MLSTaskQueueShutdownTask() = default; 1192 }; 1193 1194 NS_IMPL_ISUPPORTS(MLSTaskQueueShutdownTask, nsITargetShutdownTask) 1195 1196 mozilla::ipc::IPCResult BackgroundParentImpl::RecvCreateMLSTransaction( 1197 Endpoint<PMLSTransactionParent>&& aEndpoint, 1198 NotNull<nsIPrincipal*> aPrincipal) { 1199 AssertIsInMainProcess(); 1200 AssertIsOnBackgroundThread(); 1201 1202 if (!aEndpoint.IsValid()) { 1203 return IPC_FAIL(this, "invalid endpoint for MLSTransaction"); 1204 } 1205 1206 if (!sMLSTaskQueue) { 1207 nsCOMPtr<nsISerialEventTarget> taskQueue; 1208 MOZ_ALWAYS_SUCCEEDS(NS_CreateBackgroundTaskQueue( 1209 "MLSTaskQueue", getter_AddRefs(taskQueue))); 1210 sMLSTaskQueue = taskQueue.forget(); 1211 1212 // Clean up the sMLSTaskQueue static when the PBackground thread shuts down. 1213 nsCOMPtr<nsITargetShutdownTask> shutdownTask = 1214 new MLSTaskQueueShutdownTask(); 1215 MOZ_ALWAYS_SUCCEEDS( 1216 GetCurrentSerialEventTarget()->RegisterShutdownTask(shutdownTask)); 1217 } 1218 1219 // Construct the database's prefix path 1220 nsCOMPtr<nsIFile> file; 1221 nsresult rv = 1222 mozilla::dom::MLSTransactionParent::ConstructDatabasePrefixPath(file); 1223 if (NS_WARN_IF(NS_FAILED(rv))) { 1224 // The enpoint's destructor will close the actor 1225 return IPC_OK(); 1226 } 1227 1228 // Dispatch the task to the MLS task queue 1229 sMLSTaskQueue->Dispatch(NS_NewRunnableFunction( 1230 "CreateMLSTransactionRunnable", 1231 [endpoint = std::move(aEndpoint), file, 1232 principal = RefPtr{aPrincipal.get()}]() mutable { 1233 // Create the mls directory if it doesn't exist 1234 nsresult rv = 1235 mozilla::dom::MLSTransactionParent::CreateDirectoryIfNotExists( 1236 file); 1237 if (NS_WARN_IF(NS_FAILED(rv))) { 1238 return; 1239 } 1240 1241 // Construct the database's full path 1242 nsAutoCString databasePath; 1243 rv = mozilla::dom::MLSTransactionParent::ConstructDatabaseFullPath( 1244 file, principal, databasePath); 1245 if (NS_WARN_IF(NS_FAILED(rv))) { 1246 return; 1247 } 1248 1249 // Create the MLS transaction parent and bind it to the endpoint 1250 RefPtr<PMLSTransactionParent> result = 1251 new mozilla::dom::MLSTransactionParent(databasePath); 1252 endpoint.Bind(result); 1253 })); 1254 return IPC_OK(); 1255 } 1256 1257 already_AddRefed<mozilla::dom::PClientManagerParent> 1258 BackgroundParentImpl::AllocPClientManagerParent() { 1259 return mozilla::dom::AllocClientManagerParent(); 1260 } 1261 1262 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPClientManagerConstructor( 1263 mozilla::dom::PClientManagerParent* aActor) { 1264 mozilla::dom::InitClientManagerParent(aActor); 1265 return IPC_OK(); 1266 } 1267 1268 IPCResult BackgroundParentImpl::RecvStorageActivity( 1269 const PrincipalInfo& aPrincipalInfo) { 1270 dom::StorageActivityService::SendActivity(aPrincipalInfo); 1271 return IPC_OK(); 1272 } 1273 1274 IPCResult BackgroundParentImpl::RecvPServiceWorkerManagerConstructor( 1275 PServiceWorkerManagerParent* const aActor) { 1276 // Only the parent process is allowed to construct this actor. 1277 if (BackgroundParent::IsOtherProcessActor(this)) { 1278 return IPC_FAIL_NO_REASON(aActor); 1279 } 1280 return IPC_OK(); 1281 } 1282 1283 already_AddRefed<PServiceWorkerParent> 1284 BackgroundParentImpl::AllocPServiceWorkerParent( 1285 const IPCServiceWorkerDescriptor&) { 1286 return MakeAndAddRef<ServiceWorkerParent>(); 1287 } 1288 1289 IPCResult BackgroundParentImpl::RecvPServiceWorkerConstructor( 1290 PServiceWorkerParent* aActor, 1291 const IPCServiceWorkerDescriptor& aDescriptor) { 1292 dom::InitServiceWorkerParent(aActor, aDescriptor); 1293 return IPC_OK(); 1294 } 1295 1296 already_AddRefed<PServiceWorkerContainerParent> 1297 BackgroundParentImpl::AllocPServiceWorkerContainerParent() { 1298 return MakeAndAddRef<mozilla::dom::ServiceWorkerContainerParent>(); 1299 } 1300 1301 mozilla::ipc::IPCResult 1302 BackgroundParentImpl::RecvPServiceWorkerContainerConstructor( 1303 PServiceWorkerContainerParent* aActor) { 1304 dom::InitServiceWorkerContainerParent(aActor); 1305 return IPC_OK(); 1306 } 1307 1308 already_AddRefed<PServiceWorkerRegistrationParent> 1309 BackgroundParentImpl::AllocPServiceWorkerRegistrationParent( 1310 const IPCServiceWorkerRegistrationDescriptor&, const IPCClientInfo&) { 1311 return MakeAndAddRef<mozilla::dom::ServiceWorkerRegistrationParent>(); 1312 } 1313 1314 mozilla::ipc::IPCResult 1315 BackgroundParentImpl::RecvPServiceWorkerRegistrationConstructor( 1316 PServiceWorkerRegistrationParent* aActor, 1317 const IPCServiceWorkerRegistrationDescriptor& aDescriptor, 1318 const IPCClientInfo& aForClient) { 1319 dom::InitServiceWorkerRegistrationParent(aActor, aDescriptor, aForClient); 1320 return IPC_OK(); 1321 } 1322 1323 dom::PEndpointForReportParent* 1324 BackgroundParentImpl::AllocPEndpointForReportParent( 1325 const nsAString& aGroupName, const PrincipalInfo& aPrincipalInfo) { 1326 RefPtr<dom::EndpointForReportParent> actor = 1327 new dom::EndpointForReportParent(); 1328 return actor.forget().take(); 1329 } 1330 1331 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPEndpointForReportConstructor( 1332 PEndpointForReportParent* aActor, const nsAString& aGroupName, 1333 const PrincipalInfo& aPrincipalInfo) { 1334 static_cast<dom::EndpointForReportParent*>(aActor)->Run(aGroupName, 1335 aPrincipalInfo); 1336 return IPC_OK(); 1337 } 1338 1339 mozilla::ipc::IPCResult 1340 BackgroundParentImpl::RecvEnsureRDDProcessAndCreateBridge( 1341 EnsureRDDProcessAndCreateBridgeResolver&& aResolver) { 1342 using Type = std::tuple<const nsresult&, 1343 Endpoint<mozilla::PRemoteMediaManagerChild>&&>; 1344 1345 RefPtr<ThreadsafeContentParentHandle> parent = 1346 BackgroundParent::GetContentParentHandle(this); 1347 if (NS_WARN_IF(!parent)) { 1348 aResolver( 1349 Type(NS_ERROR_NOT_AVAILABLE, Endpoint<PRemoteMediaManagerChild>())); 1350 return IPC_OK(); 1351 } 1352 1353 RDDProcessManager* rdd = RDDProcessManager::Get(); 1354 if (!rdd) { 1355 aResolver( 1356 Type(NS_ERROR_NOT_AVAILABLE, Endpoint<PRemoteMediaManagerChild>())); 1357 return IPC_OK(); 1358 } 1359 1360 rdd->EnsureRDDProcessAndCreateBridge(OtherEndpointProcInfo(), 1361 parent->ChildID()) 1362 ->Then(GetCurrentSerialEventTarget(), __func__, 1363 [resolver = std::move(aResolver)]( 1364 mozilla::RDDProcessManager::EnsureRDDPromise:: 1365 ResolveOrRejectValue&& aValue) mutable { 1366 if (aValue.IsReject()) { 1367 resolver(Type(aValue.RejectValue(), 1368 Endpoint<PRemoteMediaManagerChild>())); 1369 return; 1370 } 1371 resolver(Type(NS_OK, std::move(aValue.ResolveValue()))); 1372 }); 1373 return IPC_OK(); 1374 } 1375 1376 mozilla::ipc::IPCResult 1377 BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge( 1378 const RemoteMediaIn& aLocation, 1379 EnsureUtilityProcessAndCreateBridgeResolver&& aResolver) { 1380 EndpointProcInfo otherProcInfo = OtherEndpointProcInfo(); 1381 RefPtr<ThreadsafeContentParentHandle> parent = 1382 BackgroundParent::GetContentParentHandle(this); 1383 if (NS_WARN_IF(!parent)) { 1384 return IPC_FAIL_NO_REASON(this); 1385 } 1386 dom::ContentParentId childId = parent->ChildID(); 1387 nsCOMPtr<nsISerialEventTarget> managerThread = GetCurrentSerialEventTarget(); 1388 if (!managerThread) { 1389 return IPC_FAIL_NO_REASON(this); 1390 } 1391 NS_DispatchToMainThread(NS_NewRunnableFunction( 1392 "BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge()", 1393 [aResolver, managerThread, otherProcInfo, childId, aLocation]() { 1394 RefPtr<UtilityProcessManager> upm = 1395 UtilityProcessManager::GetSingleton(); 1396 using Type = std::tuple<const nsresult&, 1397 Endpoint<mozilla::PRemoteMediaManagerChild>&&>; 1398 if (!upm) { 1399 managerThread->Dispatch(NS_NewRunnableFunction( 1400 "BackgroundParentImpl::RecvEnsureUtilityProcessAndCreateBridge::" 1401 "Failure", 1402 [aResolver]() { 1403 aResolver(Type(NS_ERROR_NOT_AVAILABLE, 1404 Endpoint<PRemoteMediaManagerChild>())); 1405 })); 1406 } else { 1407 SandboxingKind sbKind = GetSandboxingKindFromLocation(aLocation); 1408 upm->StartProcessForRemoteMediaDecoding(otherProcInfo, childId, 1409 sbKind) 1410 ->Then(managerThread, __func__, 1411 [resolver = aResolver]( 1412 mozilla::ipc::UtilityProcessManager:: 1413 StartRemoteDecodingUtilityPromise:: 1414 ResolveOrRejectValue&& aValue) mutable { 1415 if (aValue.IsReject()) { 1416 // the RejectValue() has something that might be an 1417 // nsresult, but our sole caller discards it anyway 1418 resolver(Type(NS_ERROR_FAILURE, 1419 Endpoint<PRemoteMediaManagerChild>())); 1420 return; 1421 } 1422 resolver(Type(NS_OK, std::move(aValue.ResolveValue()))); 1423 }); 1424 } 1425 })); 1426 return IPC_OK(); 1427 } 1428 1429 mozilla::ipc::IPCResult BackgroundParentImpl::RecvRequestCameraAccess( 1430 const bool& aAllowPermissionRequest, 1431 RequestCameraAccessResolver&& aResolver) { 1432 #ifdef MOZ_WEBRTC 1433 mozilla::camera::CamerasParent::RequestCameraAccess(aAllowPermissionRequest) 1434 ->Then(GetCurrentSerialEventTarget(), __func__, 1435 [resolver = std::move(aResolver)]( 1436 const mozilla::camera::CamerasParent:: 1437 CameraAccessRequestPromise::ResolveOrRejectValue& aValue) { 1438 if (aValue.IsResolve()) { 1439 resolver(aValue.ResolveValue()); 1440 } else { 1441 resolver(CamerasAccessStatus::Error); 1442 } 1443 }); 1444 #else 1445 aResolver(CamerasAccessStatus::Error); 1446 #endif 1447 return IPC_OK(); 1448 } 1449 1450 bool BackgroundParentImpl::DeallocPEndpointForReportParent( 1451 PEndpointForReportParent* aActor) { 1452 RefPtr<dom::EndpointForReportParent> actor = 1453 dont_AddRef(static_cast<dom::EndpointForReportParent*>(aActor)); 1454 return true; 1455 } 1456 1457 mozilla::ipc::IPCResult BackgroundParentImpl::RecvRemoveEndpoint( 1458 const nsAString& aGroupName, const nsACString& aEndpointURL, 1459 const PrincipalInfo& aPrincipalInfo) { 1460 NS_DispatchToMainThread(NS_NewRunnableFunction( 1461 "BackgroundParentImpl::RecvRemoveEndpoint(", 1462 [aGroupName = nsString(aGroupName), 1463 aEndpointURL = nsCString(aEndpointURL), aPrincipalInfo]() { 1464 dom::ReportingHeader::RemoveEndpoint(aGroupName, aEndpointURL, 1465 aPrincipalInfo); 1466 })); 1467 1468 return IPC_OK(); 1469 } 1470 1471 mozilla::ipc::IPCResult BackgroundParentImpl::RecvPLockManagerConstructor( 1472 PLockManagerParent* aActor, mozilla::NotNull<nsIPrincipal*> aPrincipalInfo, 1473 const Maybe<nsID>& aClientId) { 1474 AssertIsInMainProcess(); 1475 AssertIsOnBackgroundThread(); 1476 MOZ_ASSERT(aActor); 1477 1478 // If the IsOtherProcessActor is true, then we're dealing with some kind of 1479 // content process, and we do not expect the system principal to send this 1480 // kind of constructor message. 1481 if (aPrincipalInfo->IsSystemPrincipal() && 1482 BackgroundParent::IsOtherProcessActor(this)) { 1483 return IPC_FAIL_NO_REASON(this); 1484 } 1485 1486 return IPC_OK(); 1487 } 1488 1489 already_AddRefed<dom::locks::PLockManagerParent> 1490 BackgroundParentImpl::AllocPLockManagerParent(NotNull<nsIPrincipal*> aPrincipal, 1491 const Maybe<nsID>& aClientId) { 1492 return MakeAndAddRef<dom::locks::LockManagerParent>(aPrincipal, aClientId); 1493 } 1494 1495 already_AddRefed<dom::PFetchParent> BackgroundParentImpl::AllocPFetchParent() { 1496 return MakeAndAddRef<dom::FetchParent>(); 1497 } 1498 1499 } // namespace mozilla::ipc 1500 1501 void TestParent::ActorDestroy(ActorDestroyReason aWhy) { 1502 mozilla::ipc::AssertIsInMainProcess(); 1503 AssertIsOnBackgroundThread(); 1504 }