Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(647)

Unified Diff: third_party/WebKit/Source/modules/audio_output_devices/HTMLMediaElementAudioOutputDevice.cpp

Issue 1416123005: Implement setSinkId() for media elements without src. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
}

Powered by Google App Engine
This is Rietveld 408576698