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 "modules/webaudio/AudioContext.h" | 5 #include "modules/webaudio/AudioContext.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionMessages.h" | 7 #include "bindings/core/v8/ExceptionMessages.h" |
8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.h" |
10 #include "core/dom/DOMException.h" | 10 #include "core/dom/DOMException.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 ScriptPromise promise = resolver->promise(); | 106 ScriptPromise promise = resolver->promise(); |
107 | 107 |
108 if (contextState() == Closed) { | 108 if (contextState() == Closed) { |
109 resolver->reject(DOMException::create( | 109 resolver->reject(DOMException::create( |
110 InvalidStateError, "Cannot suspend a context that has been closed")); | 110 InvalidStateError, "Cannot suspend a context that has been closed")); |
111 } else { | 111 } else { |
112 // Stop rendering now. | 112 // Stop rendering now. |
113 if (destination()) | 113 if (destination()) |
114 stopRendering(); | 114 stopRendering(); |
115 | 115 |
116 // Since we don't have any way of knowing when the hardware actually stops,
we'll just | 116 // Since we don't have any way of knowing when the hardware actually stops, |
117 // resolve the promise now. | 117 // we'll just resolve the promise now. |
118 resolver->resolve(); | 118 resolver->resolve(); |
119 } | 119 } |
120 | 120 |
121 return promise; | 121 return promise; |
122 } | 122 } |
123 | 123 |
124 ScriptPromise AudioContext::resumeContext(ScriptState* scriptState) { | 124 ScriptPromise AudioContext::resumeContext(ScriptState* scriptState) { |
125 DCHECK(isMainThread()); | 125 DCHECK(isMainThread()); |
126 | 126 |
127 if (isContextClosed()) { | 127 if (isContextClosed()) { |
128 return ScriptPromise::rejectWithDOMException( | 128 return ScriptPromise::rejectWithDOMException( |
129 scriptState, | 129 scriptState, |
130 DOMException::create(InvalidAccessError, | 130 DOMException::create(InvalidAccessError, |
131 "cannot resume a closed AudioContext")); | 131 "cannot resume a closed AudioContext")); |
132 } | 132 } |
133 | 133 |
134 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 134 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
135 ScriptPromise promise = resolver->promise(); | 135 ScriptPromise promise = resolver->promise(); |
136 | 136 |
137 // Restart the destination node to pull on the audio graph. | 137 // Restart the destination node to pull on the audio graph. |
138 if (destination()) { | 138 if (destination()) { |
139 maybeUnlockUserGesture(); | 139 maybeUnlockUserGesture(); |
140 if (isAllowedToStart()) | 140 if (isAllowedToStart()) |
141 startRendering(); | 141 startRendering(); |
142 } | 142 } |
143 | 143 |
144 // Save the resolver which will get resolved when the destination node starts
pulling on the | 144 // Save the resolver which will get resolved when the destination node starts |
145 // graph again. | 145 // pulling on the graph again. |
146 { | 146 { |
147 AutoLocker locker(this); | 147 AutoLocker locker(this); |
148 m_resumeResolvers.append(resolver); | 148 m_resumeResolvers.append(resolver); |
149 } | 149 } |
150 | 150 |
151 return promise; | 151 return promise; |
152 } | 152 } |
153 | 153 |
154 ScriptPromise AudioContext::closeContext(ScriptState* scriptState) { | 154 ScriptPromise AudioContext::closeContext(ScriptState* scriptState) { |
155 if (isContextClosed()) { | 155 if (isContextClosed()) { |
156 // We've already closed the context previously, but it hasn't yet been resol
ved, so just | 156 // We've already closed the context previously, but it hasn't yet been |
157 // create a new promise and reject it. | 157 // resolved, so just create a new promise and reject it. |
158 return ScriptPromise::rejectWithDOMException( | 158 return ScriptPromise::rejectWithDOMException( |
159 scriptState, | 159 scriptState, |
160 DOMException::create(InvalidStateError, | 160 DOMException::create(InvalidStateError, |
161 "Cannot close a context that is being closed or " | 161 "Cannot close a context that is being closed or " |
162 "has already been closed.")); | 162 "has already been closed.")); |
163 } | 163 } |
164 | 164 |
165 // Save the current sample rate for any subsequent decodeAudioData calls. | 165 // Save the current sample rate for any subsequent decodeAudioData calls. |
166 setClosedContextSampleRate(sampleRate()); | 166 setClosedContextSampleRate(sampleRate()); |
167 | 167 |
168 m_closeResolver = ScriptPromiseResolver::create(scriptState); | 168 m_closeResolver = ScriptPromiseResolver::create(scriptState); |
169 ScriptPromise promise = m_closeResolver->promise(); | 169 ScriptPromise promise = m_closeResolver->promise(); |
170 | 170 |
171 // Stop the audio context. This will stop the destination node from pulling au
dio anymore. And | 171 // Stop the audio context. This will stop the destination node from pulling |
172 // since we have disconnected the destination from the audio graph, and thus h
as no references, | 172 // audio anymore. And since we have disconnected the destination from the |
173 // the destination node can GCed if JS has no references. uninitialize() will
also resolve the Promise | 173 // audio graph, and thus has no references, the destination node can GCed if |
174 // created here. | 174 // JS has no references. uninitialize() will also resolve the Promise created |
| 175 // here. |
175 uninitialize(); | 176 uninitialize(); |
176 | 177 |
177 return promise; | 178 return promise; |
178 } | 179 } |
179 | 180 |
180 void AudioContext::didClose() { | 181 void AudioContext::didClose() { |
181 // This is specific to AudioContexts. OfflineAudioContexts | 182 // This is specific to AudioContexts. OfflineAudioContexts |
182 // are closed in their completion event. | 183 // are closed in their completion event. |
183 setContextState(Closed); | 184 setContextState(Closed); |
184 | 185 |
(...skipping 13 matching lines...) Expand all Loading... |
198 DCHECK(destination()); | 199 DCHECK(destination()); |
199 | 200 |
200 if (contextState() == Running) { | 201 if (contextState() == Running) { |
201 destination()->audioDestinationHandler().stopRendering(); | 202 destination()->audioDestinationHandler().stopRendering(); |
202 setContextState(Suspended); | 203 setContextState(Suspended); |
203 deferredTaskHandler().clearHandlersToBeDeleted(); | 204 deferredTaskHandler().clearHandlersToBeDeleted(); |
204 } | 205 } |
205 } | 206 } |
206 | 207 |
207 } // namespace blink | 208 } // namespace blink |
OLD | NEW |