| 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 |