OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "modules/webaudio/AudioContext.h" | 6 #include "modules/webaudio/AudioContext.h" |
7 | 7 |
8 #include "bindings/core/v8/ExceptionMessages.h" | 8 #include "bindings/core/v8/ExceptionMessages.h" |
9 #include "bindings/core/v8/ExceptionState.h" | 9 #include "bindings/core/v8/ExceptionState.h" |
10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 fprintf(stderr, "%p: AudioContext::~AudioContext(): %u\n", this, m_contextId
); | 70 fprintf(stderr, "%p: AudioContext::~AudioContext(): %u\n", this, m_contextId
); |
71 #endif | 71 #endif |
72 } | 72 } |
73 | 73 |
74 DEFINE_TRACE(AudioContext) | 74 DEFINE_TRACE(AudioContext) |
75 { | 75 { |
76 visitor->trace(m_closeResolver); | 76 visitor->trace(m_closeResolver); |
77 AbstractAudioContext::trace(visitor); | 77 AbstractAudioContext::trace(visitor); |
78 } | 78 } |
79 | 79 |
80 ScriptPromise AudioContext::closeContext(ScriptState* scriptState) | |
81 { | |
82 if (isContextClosed()) { | |
83 // We've already closed the context previously, but it hasn't yet been r
esolved, so just | |
84 // create a new promise and reject it. | |
85 return ScriptPromise::rejectWithDOMException( | |
86 scriptState, | |
87 DOMException::create(InvalidStateError, | |
88 "Cannot close a context that is being closed or has already been
closed.")); | |
89 } | |
90 | |
91 m_closeResolver = ScriptPromiseResolver::create(scriptState); | |
92 ScriptPromise promise = m_closeResolver->promise(); | |
93 | |
94 // Stop the audio context. This will stop the destination node from pulling
audio anymore. And | |
95 // since we have disconnected the destination from the audio graph, and thus
has no references, | |
96 // the destination node can GCed if JS has no references. uninitialize() wil
l also resolve the Promise | |
97 // created here. | |
98 uninitialize(); | |
99 | |
100 return promise; | |
101 } | |
102 | |
103 ScriptPromise AudioContext::suspendContext(ScriptState* scriptState) | 80 ScriptPromise AudioContext::suspendContext(ScriptState* scriptState) |
104 { | 81 { |
105 ASSERT(isMainThread()); | 82 ASSERT(isMainThread()); |
106 AutoLocker locker(this); | 83 AutoLocker locker(this); |
107 | 84 |
108 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 85 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); |
109 ScriptPromise promise = resolver->promise(); | 86 ScriptPromise promise = resolver->promise(); |
110 | 87 |
111 if (contextState() == Closed) { | 88 if (contextState() == Closed) { |
112 resolver->reject( | 89 resolver->reject( |
113 DOMException::create(InvalidStateError, "Cannot suspend a context th
at has been closed")); | 90 DOMException::create(InvalidStateError, "Cannot suspend a context th
at has been closed")); |
114 } else { | 91 } else { |
115 // Stop rendering now. | 92 // Stop rendering now. |
116 if (destination()) | 93 if (destination()) |
117 stopRendering(); | 94 stopRendering(); |
118 | 95 |
119 // Since we don't have any way of knowing when the hardware actually sto
ps, we'll just | 96 // Since we don't have any way of knowing when the hardware actually sto
ps, we'll just |
120 // resolve the promise now. | 97 // resolve the promise now. |
121 resolver->resolve(); | 98 resolver->resolve(); |
122 } | 99 } |
123 | 100 |
124 return promise; | 101 return promise; |
125 } | 102 } |
126 | 103 |
127 ScriptPromise AudioContext::suspendContext(ScriptState* scriptState, double susp
endTime) | |
128 { | |
129 // This CANNOT be called on AudioContext; it is to implement the pure | |
130 // virtual interface from AbstractAudioContext. | |
131 RELEASE_ASSERT_NOT_REACHED(); | |
132 | |
133 return ScriptPromise(); | |
134 } | |
135 | |
136 ScriptPromise AudioContext::resumeContext(ScriptState* scriptState) | 104 ScriptPromise AudioContext::resumeContext(ScriptState* scriptState) |
137 { | 105 { |
138 ASSERT(isMainThread()); | 106 ASSERT(isMainThread()); |
139 | 107 |
140 if (isContextClosed()) { | 108 if (isContextClosed()) { |
141 return ScriptPromise::rejectWithDOMException( | 109 return ScriptPromise::rejectWithDOMException( |
142 scriptState, | 110 scriptState, |
143 DOMException::create( | 111 DOMException::create( |
144 InvalidAccessError, | 112 InvalidAccessError, |
145 "cannot resume a closed AudioContext")); | 113 "cannot resume a closed AudioContext")); |
146 } | 114 } |
147 | 115 |
148 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 116 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); |
149 ScriptPromise promise = resolver->promise(); | 117 ScriptPromise promise = resolver->promise(); |
150 | 118 |
151 // Restart the destination node to pull on the audio graph. | 119 // Restart the destination node to pull on the audio graph. |
152 if (destination()) | 120 if (destination()) |
153 startRendering(); | 121 startRendering(); |
154 | 122 |
155 // Save the resolver which will get resolved when the destination node start
s pulling on the | 123 // Save the resolver which will get resolved when the destination node start
s pulling on the |
156 // graph again. | 124 // graph again. |
157 { | 125 { |
158 AutoLocker(this); | 126 AutoLocker locker(this); |
159 m_resumeResolvers.append(resolver); | 127 m_resumeResolvers.append(resolver); |
160 } | 128 } |
161 | 129 |
162 return promise; | 130 return promise; |
163 } | 131 } |
| 132 |
| 133 ScriptPromise AudioContext::closeContext(ScriptState* scriptState) |
| 134 { |
| 135 if (isContextClosed()) { |
| 136 // We've already closed the context previously, but it hasn't yet been r
esolved, so just |
| 137 // create a new promise and reject it. |
| 138 return ScriptPromise::rejectWithDOMException( |
| 139 scriptState, |
| 140 DOMException::create(InvalidStateError, |
| 141 "Cannot close a context that is being closed or has already been
closed.")); |
| 142 } |
| 143 |
| 144 m_closeResolver = ScriptPromiseResolver::create(scriptState); |
| 145 ScriptPromise promise = m_closeResolver->promise(); |
| 146 |
| 147 // Stop the audio context. This will stop the destination node from pulling
audio anymore. And |
| 148 // since we have disconnected the destination from the audio graph, and thus
has no references, |
| 149 // the destination node can GCed if JS has no references. uninitialize() wil
l also resolve the Promise |
| 150 // created here. |
| 151 uninitialize(); |
| 152 |
| 153 return promise; |
| 154 } |
164 | 155 |
165 void AudioContext::didClose() | 156 void AudioContext::didClose() |
166 { | 157 { |
167 // This is specific to AudioContexts. OfflineAudioContexts | 158 // This is specific to AudioContexts. OfflineAudioContexts |
168 // are closed in their completion event. | 159 // are closed in their completion event. |
169 setContextState(Closed); | 160 setContextState(Closed); |
170 | 161 |
171 ASSERT(s_hardwareContextCount); | 162 ASSERT(s_hardwareContextCount); |
172 --s_hardwareContextCount; | 163 --s_hardwareContextCount; |
173 | 164 |
(...skipping 14 matching lines...) Expand all Loading... |
188 if (contextState() == Running) { | 179 if (contextState() == Running) { |
189 destination()->audioDestinationHandler().stopRendering(); | 180 destination()->audioDestinationHandler().stopRendering(); |
190 setContextState(Suspended); | 181 setContextState(Suspended); |
191 deferredTaskHandler().clearHandlersToBeDeleted(); | 182 deferredTaskHandler().clearHandlersToBeDeleted(); |
192 } | 183 } |
193 } | 184 } |
194 | 185 |
195 } // namespace blink | 186 } // namespace blink |
196 | 187 |
197 #endif // ENABLE(WEB_AUDIO) | 188 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |