Chromium Code Reviews| Index: third_party/WebKit/Source/modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.cpp |
| diff --git a/third_party/WebKit/Source/modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.cpp b/third_party/WebKit/Source/modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.cpp |
| index 930dc3c40b88e366c893b33e4f2691cb812f706b..55207135dddeaced0982f8c0faa3530f9fe7d589 100644 |
| --- a/third_party/WebKit/Source/modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.cpp |
| +++ b/third_party/WebKit/Source/modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.cpp |
| @@ -8,11 +8,77 @@ |
| #include "bindings/core/v8/ScriptPromiseResolver.h" |
| #include "bindings/core/v8/ScriptState.h" |
| #include "core/dom/ExecutionContext.h" |
| +#include "modules/audio_output_devices/AudioOutputDeviceClient.h" |
| #include "modules/audio_output_devices/SetSinkIdCallbacks.h" |
| #include "public/platform/WebSecurityOrigin.h" |
| namespace blink { |
| +class SetSinkIdResolver : public ScriptPromiseResolver { |
|
Peter Beverloo
2015/11/12 16:45:42
note: you've split out the smaller SetSinkIdCallba
Guido Urdaneta
2015/11/12 18:45:44
Done.
|
| + WTF_MAKE_NONCOPYABLE(SetSinkIdResolver); |
| +public: |
| + static SetSinkIdResolver* create(ScriptState*, HTMLMediaElement&, const String& sinkId); |
| + ~SetSinkIdResolver() = default; |
|
Peter Beverloo
2015/11/12 16:45:42
+override
Guido Urdaneta
2015/11/12 18:45:44
Done.
|
| + |
| + DECLARE_VIRTUAL_TRACE(); |
| + |
| +private: |
| + SetSinkIdResolver(ScriptState*, HTMLMediaElement&, const String& sinkId); |
| + void timerFired(Timer<SetSinkIdResolver>*); |
| + |
| + RefPtrWillBeMember<HTMLMediaElement> m_element; |
| + String m_sinkId; |
| + Timer<SetSinkIdResolver> m_timer; |
| +}; |
| + |
| +SetSinkIdResolver* SetSinkIdResolver::create(ScriptState* scriptState, HTMLMediaElement& element, const String& sinkId) |
| +{ |
| + SetSinkIdResolver* resolver = new SetSinkIdResolver(scriptState, element, sinkId); |
| + resolver->suspendIfNeeded(); |
| + resolver->keepAliveWhilePending(); |
| + return resolver; |
| +} |
| + |
| +SetSinkIdResolver::SetSinkIdResolver(ScriptState* scriptState, HTMLMediaElement& element, const String& sinkId) |
| + : ScriptPromiseResolver(scriptState) |
| + , m_element(element) |
| + , m_sinkId(sinkId) |
| + , m_timer(this, &SetSinkIdResolver::timerFired) |
| +{ |
| + m_timer.startOneShot(0, BLINK_FROM_HERE); |
| +} |
| + |
| +void SetSinkIdResolver::timerFired(Timer<SetSinkIdResolver>* timer) |
| +{ |
| + if (m_sinkId == HTMLMediaElementAudioOutputDevice::sinkId(*m_element)) { |
|
Peter Beverloo
2015/11/12 16:45:42
nit: since we can do this check synchronously, we
Guido Urdaneta
2015/11/12 18:45:44
Done.
|
| + resolve(); |
| + return; |
| + } |
| + |
| + ExecutionContext* context = executionContext(); |
| + ASSERT(context && context->isDocument()); |
| + OwnPtr<SetSinkIdCallbacks> callbacks = adoptPtr(new SetSinkIdCallbacks(this, *m_element, m_sinkId)); |
| + WebMediaPlayer* webMediaPlayer = m_element->webMediaPlayer(); |
| + if (webMediaPlayer) { |
| + // Using leakPtr() to transfer ownership because |webMediaPlayer| is a platform object that takes raw pointers |
| + webMediaPlayer->setSinkId(m_sinkId, WebSecurityOrigin(context->securityOrigin()), callbacks.leakPtr()); |
| + } else { |
| + if (AudioOutputDeviceClient* client = AudioOutputDeviceClient::from(context)) { |
| + client->checkIfAudioSinkExistsAndIsAuthorized(context, m_sinkId, callbacks.release()); |
|
Peter Beverloo
2015/11/12 16:45:42
Note that there will still be a gap between updati
Guido Urdaneta
2015/11/12 18:45:44
Acknowledged.
|
| + } else { |
| + // The context has been detached. Impossible to get a security origin to check. |
| + ASSERT(context->activeDOMObjectsAreStopped()); |
| + reject(DOMException::create(SecurityError, "Impossible to authorize device for detached context")); |
| + } |
| + } |
| +} |
| + |
| +DEFINE_TRACE(SetSinkIdResolver) |
| +{ |
| + visitor->trace(m_element); |
| + ScriptPromiseResolver::trace(visitor); |
| +} |
| + |
| HTMLMediaElementAudioOutputDevice::HTMLMediaElementAudioOutputDevice() |
| : m_sinkId("") |
| { |
| @@ -31,17 +97,7 @@ void HTMLMediaElementAudioOutputDevice::setSinkId(const String& sinkId) |
| ScriptPromise HTMLMediaElementAudioOutputDevice::setSinkId(ScriptState* scriptState, HTMLMediaElement& element, const String& sinkId) |
| { |
| - ASSERT(scriptState); |
| - |
| - WebMediaPlayer* webMediaPlayer = element.webMediaPlayer(); |
| - if (!webMediaPlayer) |
| - return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "No media player available")); |
| - |
| - ExecutionContext* context = scriptState->executionContext(); |
| - ASSERT(context && context->isDocument()); |
| - |
| - ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| - webMediaPlayer->setSinkId(sinkId, WebSecurityOrigin(context->securityOrigin()), new SetSinkIdCallbacks(resolver, element, sinkId)); |
| + SetSinkIdResolver* resolver = SetSinkIdResolver::create(scriptState, element, sinkId); |
| return resolver->promise(); |
| } |