tor-browser

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

JSProcessActorProtocol.cpp (4713B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 
      3 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "mozilla/dom/JSProcessActorProtocol.h"
      9 
     10 #include "JSActorProtocolUtils.h"
     11 #include "mozilla/dom/ContentChild.h"
     12 #include "mozilla/dom/ContentParent.h"
     13 #include "mozilla/dom/InProcessChild.h"
     14 #include "mozilla/dom/JSActorBinding.h"
     15 #include "mozilla/dom/JSProcessActorBinding.h"
     16 #include "mozilla/dom/PContent.h"
     17 #include "nsContentUtils.h"
     18 
     19 namespace mozilla::dom {
     20 
     21 NS_IMPL_CYCLE_COLLECTING_ADDREF(JSProcessActorProtocol)
     22 NS_IMPL_CYCLE_COLLECTING_RELEASE(JSProcessActorProtocol)
     23 
     24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JSProcessActorProtocol)
     25  NS_INTERFACE_MAP_ENTRY(nsIObserver)
     26 NS_INTERFACE_MAP_END
     27 
     28 NS_IMPL_CYCLE_COLLECTION(JSProcessActorProtocol)
     29 
     30 /* static */ already_AddRefed<JSProcessActorProtocol>
     31 JSProcessActorProtocol::FromIPC(const JSProcessActorInfo& aInfo) {
     32  MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess());
     33 
     34  RefPtr<JSProcessActorProtocol> proto =
     35      new JSProcessActorProtocol(aInfo.name());
     36  JSActorProtocolUtils::FromIPCShared(proto, aInfo);
     37 
     38  // Content processes aren't the parent process, so this flag is irrelevant and
     39  // not propagated.
     40  proto->mIncludeParent = false;
     41 
     42  return proto.forget();
     43 }
     44 
     45 JSProcessActorInfo JSProcessActorProtocol::ToIPC() {
     46  MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
     47 
     48  JSProcessActorInfo info;
     49  JSActorProtocolUtils::ToIPCShared(info, this);
     50 
     51  return info;
     52 }
     53 
     54 already_AddRefed<JSProcessActorProtocol>
     55 JSProcessActorProtocol::FromWebIDLOptions(const nsACString& aName,
     56                                          const ProcessActorOptions& aOptions,
     57                                          ErrorResult& aRv) {
     58  MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
     59 
     60  RefPtr<JSProcessActorProtocol> proto = new JSProcessActorProtocol(aName);
     61  if (!JSActorProtocolUtils::FromWebIDLOptionsShared(proto, aOptions, aRv)) {
     62    return nullptr;
     63  }
     64 
     65  proto->mIncludeParent = aOptions.mIncludeParent;
     66 
     67  proto->mLoadInDevToolsLoader = aOptions.mLoadInDevToolsLoader;
     68 
     69  return proto.forget();
     70 }
     71 
     72 NS_IMETHODIMP JSProcessActorProtocol::Observe(nsISupports* aSubject,
     73                                              const char* aTopic,
     74                                              const char16_t* aData) {
     75  MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
     76 
     77  RefPtr<JSActorManager> manager;
     78  if (XRE_IsParentProcess()) {
     79    manager = InProcessChild::Singleton();
     80  } else {
     81    manager = ContentChild::GetSingleton();
     82  }
     83 
     84  // Ensure our actor is present.
     85  AutoJSAPI jsapi;
     86  jsapi.Init();
     87  RefPtr<JSActor> actor = manager->GetActor(jsapi.cx(), mName, IgnoreErrors());
     88  if (!actor || NS_WARN_IF(!actor->GetWrapperPreserveColor())) {
     89    return NS_OK;
     90  }
     91 
     92  // Build a observer callback.
     93  JS::Rooted<JSObject*> global(jsapi.cx(),
     94                               JS::GetNonCCWObjectGlobal(actor->GetWrapper()));
     95  RefPtr<MozObserverCallback> observerCallback =
     96      new MozObserverCallback(actor->GetWrapper(), global, nullptr, nullptr);
     97  observerCallback->Observe(aSubject, nsDependentCString(aTopic),
     98                            aData ? nsDependentString(aData) : VoidString());
     99  return NS_OK;
    100 }
    101 
    102 void JSProcessActorProtocol::AddObservers() {
    103  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
    104  for (auto& topic : mChild.mObservers) {
    105    // This makes the observer service hold an owning reference to the
    106    // JSProcessActorProtocol. The JSWindowActorProtocol objects will be living
    107    // for the full lifetime of the content process, thus the extra strong
    108    // referencec doesn't have a negative impact.
    109    os->AddObserver(this, topic.get(), false);
    110  }
    111 }
    112 
    113 void JSProcessActorProtocol::RemoveObservers() {
    114  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
    115  for (auto& topic : mChild.mObservers) {
    116    os->RemoveObserver(this, topic.get());
    117  }
    118 }
    119 
    120 bool JSProcessActorProtocol::Matches(const nsACString& aRemoteType,
    121                                     ErrorResult& aRv) {
    122  if (!mIncludeParent && aRemoteType.IsEmpty()) {
    123    aRv.ThrowNotSupportedError(nsPrintfCString(
    124        "Process protocol '%s' doesn't match the parent process", mName.get()));
    125    return false;
    126  }
    127 
    128  if (!RemoteTypePrefixMatches(aRemoteType)) {
    129    aRv.ThrowNotSupportedError(nsPrintfCString(
    130        "Process protocol '%s' doesn't support remote type '%s'", mName.get(),
    131        PromiseFlatCString(aRemoteType).get()));
    132    return false;
    133  }
    134 
    135  return true;
    136 }
    137 
    138 }  // namespace mozilla::dom