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