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 http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_AudioWorkletGlobalScope_h
8 #define mozilla_dom_AudioWorkletGlobalScope_h
9 
10 #include "mozilla/dom/AudioParamDescriptorMap.h"
11 #include "mozilla/dom/FunctionBinding.h"
12 #include "mozilla/dom/WorkletGlobalScope.h"
13 #include "js/ForOfIterator.h"
14 #include "nsRefPtrHashtable.h"
15 
16 namespace mozilla {
17 
18 class AudioWorkletImpl;
19 
20 namespace dom {
21 
22 class AudioWorkletProcessorConstructor;
23 class MessagePort;
24 class StructuredCloneHolder;
25 class UniqueMessagePortId;
26 
27 class AudioWorkletGlobalScope final : public WorkletGlobalScope {
28  public:
29   NS_DECL_ISUPPORTS_INHERITED
30   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioWorkletGlobalScope,
31                                            WorkletGlobalScope);
32 
33   explicit AudioWorkletGlobalScope(AudioWorkletImpl* aImpl);
34 
35   bool WrapGlobalObject(JSContext* aCx,
36                         JS::MutableHandle<JSObject*> aReflector) override;
37 
38   void RegisterProcessor(JSContext* aCx, const nsAString& aName,
39                          AudioWorkletProcessorConstructor& aProcessorCtor,
40                          ErrorResult& aRv);
41 
42   WorkletImpl* Impl() const override;
43 
44   uint64_t CurrentFrame() const;
45 
46   double CurrentTime() const;
47 
48   float SampleRate() const;
49 
50   // If successful, returns true and sets aRetProcessor, which will be in the
51   // compartment for the realm of this global.  Returns false on failure.
52   MOZ_CAN_RUN_SCRIPT
53   bool ConstructProcessor(JSContext* aCx, const nsAString& aName,
54                           NotNull<StructuredCloneHolder*> aSerializedOptions,
55                           UniqueMessagePortId& aPortIdentifier,
56                           JS::MutableHandle<JSObject*> aRetProcessor);
57 
58   // Returns null if not called during ConstructProcessor() or if the port has
59   // already been taken.
60   RefPtr<MessagePort> TakePortForProcessorCtor();
61 
62  private:
63   ~AudioWorkletGlobalScope() = default;
64 
65   // Returns an AudioParamDescriptorMap filled with AudioParamDescriptor
66   // objects, extracted from JS. Returns an empty map in case of error and set
67   // aRv accordingly.
68   AudioParamDescriptorMap DescriptorsFromJS(JSContext* aCx,
69                                             JS::ForOfIterator* aIter,
70                                             ErrorResult& aRv);
71 
72   const RefPtr<AudioWorkletImpl> mImpl;
73 
74   typedef nsRefPtrHashtable<nsStringHashKey, AudioWorkletProcessorConstructor>
75       NodeNameToProcessorDefinitionMap;
76   NodeNameToProcessorDefinitionMap mNameToProcessorMap;
77   // https://webaudio.github.io/web-audio-api/#pending-processor-construction-data-transferred-port
78   // This does not need to be traversed during cycle-collection because it is
79   // only set while this AudioWorkletGlobalScope is on the stack.
80   RefPtr<MessagePort> mPortForProcessor;
81 };
82 
83 }  // namespace dom
84 }  // namespace mozilla
85 
86 #endif  // mozilla_dom_AudioWorkletGlobalScope_h
87