tor-browser

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

WorkletImpl.cpp (4895B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      6 
      7 #include "WorkletImpl.h"
      8 
      9 #include "Worklet.h"
     10 #include "WorkletThread.h"
     11 #include "mozilla/BasePrincipal.h"
     12 #include "mozilla/NullPrincipal.h"
     13 #include "mozilla/dom/DocGroup.h"
     14 #include "mozilla/dom/Document.h"
     15 #include "mozilla/dom/RegisterWorkletBindings.h"
     16 #include "mozilla/dom/ScriptSettings.h"
     17 #include "mozilla/dom/WorkletBinding.h"
     18 #include "mozilla/dom/WorkletGlobalScope.h"
     19 #include "mozilla/dom/worklet/WorkletModuleLoader.h"
     20 #include "nsGlobalWindowInner.h"
     21 
     22 using mozilla::dom::loader::WorkletModuleLoader;
     23 using mozilla::dom::loader::WorkletScriptLoader;
     24 
     25 namespace mozilla {
     26 // ---------------------------------------------------------------------------
     27 // WorkletLoadInfo
     28 
     29 WorkletLoadInfo::WorkletLoadInfo(nsPIDOMWindowInner* aWindow)
     30    : mInnerWindowID(aWindow->WindowID()) {
     31  MOZ_ASSERT(NS_IsMainThread());
     32  nsPIDOMWindowOuter* outerWindow = aWindow->GetOuterWindow();
     33  if (outerWindow) {
     34    mOuterWindowID = outerWindow->WindowID();
     35  } else {
     36    mOuterWindowID = 0;
     37  }
     38 }
     39 
     40 // ---------------------------------------------------------------------------
     41 // WorkletImpl
     42 
     43 WorkletImpl::WorkletImpl(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal)
     44    : mPrincipal(NullPrincipal::CreateWithInheritedAttributes(aPrincipal)),
     45      mWorkletLoadInfo(aWindow),
     46      mTerminated(false),
     47      mFinishedOnExecutionThread(false),
     48      mIsPrivateBrowsing(false),
     49      mTrials(OriginTrials::FromWindow(nsGlobalWindowInner::Cast(aWindow))) {
     50  (void)NS_WARN_IF(
     51      NS_FAILED(ipc::PrincipalToPrincipalInfo(mPrincipal, &mPrincipalInfo)));
     52 
     53  if (aWindow->GetDocGroup()) {
     54    mAgentClusterId.emplace(aWindow->GetDocGroup()->AgentClusterId());
     55  }
     56 
     57  mSharedMemoryAllowed =
     58      nsGlobalWindowInner::Cast(aWindow)->IsSharedMemoryAllowed();
     59 
     60  mShouldResistFingerprinting = aWindow->AsGlobal()->ShouldResistFingerprinting(
     61      RFPTarget::IsAlwaysEnabledForPrecompute);
     62 
     63  RefPtr<dom::Document> doc = nsGlobalWindowInner::Cast(aWindow)->GetDocument();
     64  if (doc) {
     65    mIsPrivateBrowsing = doc->IsInPrivateBrowsing();
     66    mOverriddenFingerprintingSettings =
     67        doc->GetOverriddenFingerprintingSettings();
     68  }
     69 }
     70 
     71 WorkletImpl::~WorkletImpl() { MOZ_ASSERT(!mGlobalScope); }
     72 
     73 JSObject* WorkletImpl::WrapWorklet(JSContext* aCx, dom::Worklet* aWorklet,
     74                                   JS::Handle<JSObject*> aGivenProto) {
     75  MOZ_ASSERT(NS_IsMainThread());
     76  return dom::Worklet_Binding::Wrap(aCx, aWorklet, aGivenProto);
     77 }
     78 
     79 dom::WorkletGlobalScope* WorkletImpl::GetGlobalScope() {
     80  dom::WorkletThread::AssertIsOnWorkletThread();
     81 
     82  if (mGlobalScope) {
     83    return mGlobalScope;
     84  }
     85  if (mFinishedOnExecutionThread) {
     86    return nullptr;
     87  }
     88 
     89  dom::AutoJSAPI jsapi;
     90  jsapi.Init();
     91  JSContext* cx = jsapi.cx();
     92 
     93  mGlobalScope = ConstructGlobalScope(cx);
     94 
     95  JS::Rooted<JSObject*> global(cx);
     96  NS_ENSURE_TRUE(mGlobalScope->WrapGlobalObject(cx, &global), nullptr);
     97 
     98  JSAutoRealm ar(cx, global);
     99 
    100  // Init Web IDL bindings
    101  if (!dom::RegisterWorkletBindings(cx, global)) {
    102    return nullptr;
    103  }
    104 
    105  JS_FireOnNewGlobalObject(cx, global);
    106 
    107  MOZ_ASSERT(!mGlobalScope->GetModuleLoader(cx));
    108 
    109  RefPtr<WorkletScriptLoader> scriptLoader = new WorkletScriptLoader();
    110  RefPtr<WorkletModuleLoader> moduleLoader =
    111      new WorkletModuleLoader(scriptLoader, mGlobalScope);
    112  mGlobalScope->InitModuleLoader(moduleLoader);
    113 
    114  return mGlobalScope;
    115 }
    116 
    117 void WorkletImpl::NotifyWorkletFinished() {
    118  MOZ_ASSERT(NS_IsMainThread());
    119 
    120  if (mTerminated) {
    121    return;
    122  }
    123 
    124  // Release global scope on its thread.
    125  SendControlMessage(
    126      NS_NewRunnableFunction("WorkletImpl::NotifyWorkletFinished",
    127                             [self = RefPtr<WorkletImpl>(this)]() {
    128                               self->mFinishedOnExecutionThread = true;
    129                               self->mGlobalScope = nullptr;
    130                             }));
    131 
    132  mTerminated = true;
    133  if (mWorkletThread) {
    134    mWorkletThread->Terminate();
    135    mWorkletThread = nullptr;
    136  }
    137 }
    138 
    139 nsresult WorkletImpl::SendControlMessage(
    140    already_AddRefed<nsIRunnable> aRunnable) {
    141  MOZ_ASSERT(NS_IsMainThread());
    142  RefPtr<nsIRunnable> runnable = std::move(aRunnable);
    143 
    144  // TODO: bug 1492011 re ConsoleWorkletRunnable.
    145  if (mTerminated) {
    146    return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
    147  }
    148 
    149  if (!mWorkletThread) {
    150    // Thread creation. FIXME: this will change.
    151    mWorkletThread = dom::WorkletThread::Create(this);
    152    if (!mWorkletThread) {
    153      return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
    154    }
    155  }
    156 
    157  return mWorkletThread->DispatchRunnable(runnable.forget());
    158 }
    159 
    160 }  // namespace mozilla