tor-browser

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

AudioWorkletImpl.cpp (4056B)


      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 "AudioWorkletImpl.h"
      8 
      9 #include "AudioContext.h"
     10 #include "AudioNodeTrack.h"
     11 #include "AudioWorklet.h"
     12 #include "GeckoProfiler.h"
     13 #include "mozilla/dom/AudioWorkletBinding.h"
     14 #include "mozilla/dom/AudioWorkletGlobalScope.h"
     15 #include "mozilla/dom/MessageChannel.h"
     16 #include "mozilla/dom/MessagePort.h"
     17 #include "mozilla/dom/WorkletThread.h"
     18 #include "nsGlobalWindowInner.h"
     19 
     20 namespace mozilla {
     21 
     22 /* static */ already_AddRefed<dom::AudioWorklet>
     23 AudioWorkletImpl::CreateWorklet(dom::AudioContext* aContext, ErrorResult& aRv) {
     24  MOZ_ASSERT(NS_IsMainThread());
     25 
     26  nsGlobalWindowInner* window = aContext->GetOwnerWindow();
     27  if (NS_WARN_IF(!window)) {
     28    aRv.Throw(NS_ERROR_FAILURE);
     29    return nullptr;
     30  }
     31  nsIPrincipal* principal = window->GetPrincipal();
     32  if (NS_WARN_IF(!principal)) {
     33    aRv.Throw(NS_ERROR_FAILURE);
     34    return nullptr;
     35  }
     36 
     37  RefPtr<dom::MessageChannel> messageChannel =
     38      dom::MessageChannel::Constructor(window, aRv);
     39  if (NS_WARN_IF(aRv.Failed())) {
     40    return nullptr;
     41  }
     42 
     43  dom::UniqueMessagePortId globalScopePortId;
     44  messageChannel->Port2()->CloneAndDisentangle(globalScopePortId);
     45 
     46  RefPtr<AudioWorkletImpl> impl =
     47      new AudioWorkletImpl(window, principal, aContext->DestinationTrack(),
     48                           std::move(globalScopePortId));
     49 
     50  // The Worklet owns a reference to the AudioContext so as to keep the graph
     51  // thread running as long as the Worklet is alive by keeping the
     52  // AudioDestinationNode alive.
     53  return MakeAndAddRef<dom::AudioWorklet>(
     54      window, std::move(impl), ToSupports(aContext), messageChannel->Port1());
     55 }
     56 
     57 AudioWorkletImpl::AudioWorkletImpl(nsPIDOMWindowInner* aWindow,
     58                                   nsIPrincipal* aPrincipal,
     59                                   AudioNodeTrack* aDestinationTrack,
     60                                   dom::UniqueMessagePortId&& aPortIdentifier)
     61    : WorkletImpl(aWindow, aPrincipal),
     62      mDestinationTrack(aDestinationTrack),
     63      mGlobalScopePortIdentifier(std::move(aPortIdentifier)) {}
     64 
     65 AudioWorkletImpl::~AudioWorkletImpl() = default;
     66 
     67 JSObject* AudioWorkletImpl::WrapWorklet(JSContext* aCx, dom::Worklet* aWorklet,
     68                                        JS::Handle<JSObject*> aGivenProto) {
     69  MOZ_ASSERT(NS_IsMainThread());
     70  return dom::AudioWorklet_Binding::Wrap(
     71      aCx, static_cast<dom::AudioWorklet*>(aWorklet), aGivenProto);
     72 }
     73 
     74 nsresult AudioWorkletImpl::SendControlMessage(
     75    already_AddRefed<nsIRunnable> aRunnable) {
     76  mDestinationTrack->SendRunnable(std::move(aRunnable));
     77  return NS_OK;
     78 }
     79 
     80 void AudioWorkletImpl::OnAddModuleStarted() const {
     81 #ifdef MOZ_GECKO_PROFILER
     82  profiler_add_marker(ProfilerStringView("AudioWorklet.addModule"),
     83                      geckoprofiler::category::MEDIA_RT,
     84                      {MarkerTiming::IntervalStart()});
     85 #endif
     86 }
     87 
     88 void AudioWorkletImpl::OnAddModulePromiseSettled() const {
     89 #ifdef MOZ_GECKO_PROFILER
     90  profiler_add_marker(ProfilerStringView("AudioWorklet.addModule"),
     91                      geckoprofiler::category::MEDIA_RT,
     92                      {MarkerTiming::IntervalEnd()});
     93 #endif
     94 }
     95 
     96 already_AddRefed<dom::WorkletGlobalScope>
     97 AudioWorkletImpl::ConstructGlobalScope(JSContext* aCx) {
     98  dom::WorkletThread::AssertIsOnWorkletThread();
     99 
    100  RefPtr<dom::AudioWorkletGlobalScope> globalScope =
    101      new dom::AudioWorkletGlobalScope(this);
    102 
    103  ErrorResult rv;
    104  RefPtr<dom::MessagePort> deserializedPort =
    105      dom::MessagePort::Create(globalScope, mGlobalScopePortIdentifier, rv);
    106  if (NS_WARN_IF(rv.MaybeSetPendingException(aCx))) {
    107    // The exception will be propagated into the global
    108    return globalScope.forget();
    109  }
    110 
    111  globalScope->SetPort(deserializedPort);
    112 
    113  return globalScope.forget();
    114 }
    115 
    116 }  // namespace mozilla