tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }