MediaStream API: Changing the device enumeration to be async
When we stared to implement this in chrome we discovered that sometimes
device enumeration could take some time and therefore the API needed
to be adjusted. This has been discussed on the W3C email list without
objections but not yet reached the editors draft.
The old name getSourceInfos got changed to getSources as well.

BUG=

Review URL: https://chromiumcodereview.appspot.com/16778002

git-svn-id: svn://svn.chromium.org/blink/trunk@152771 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-getSourceInfos-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-getSourceInfos-expected.txt
deleted file mode 100644
index 40a2d0a..0000000
--- a/LayoutTests/fast/mediastream/MediaStreamTrack-getSourceInfos-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Tests MediaStreamTrack::getSourceInfos.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS sources = MediaStreamTrack.getSourceInfos(); did not throw exception.
-PASS sources.length > 0 is true
-PASS sources = MediaStreamTrack.getSourceInfos(); did not throw exception.
-PASS sources.length > 0 is true
-PASS sources[0].id === previousId is true
-PASS sources[0].label.length > 0 is true
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-getSources-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-getSources-expected.txt
new file mode 100644
index 0000000..2e6d9c2
--- /dev/null
+++ b/LayoutTests/fast/mediastream/MediaStreamTrack-getSources-expected.txt
@@ -0,0 +1,18 @@
+Tests MediaStreamTrack::getSources.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS MediaStreamTrack.getSources(gotSources1); did not throw exception.
+PASS gotSources1 was called.
+PASS sources.length > 0 is true
+PASS gotStream was called.
+PASS MediaStreamTrack.getSources(gotSources2); did not throw exception.
+PASS gotSources2 was called.
+PASS sources.length > 0 is true
+PASS sources[0].id === previousId is true
+PASS sources[0].label.length > 0 is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-getSourceInfos.html b/LayoutTests/fast/mediastream/MediaStreamTrack-getSources.html
similarity index 64%
rename from LayoutTests/fast/mediastream/MediaStreamTrack-getSourceInfos.html
rename to LayoutTests/fast/mediastream/MediaStreamTrack-getSources.html
index a4f7ad1..4a20bab 100644
--- a/LayoutTests/fast/mediastream/MediaStreamTrack-getSourceInfos.html
+++ b/LayoutTests/fast/mediastream/MediaStreamTrack-getSources.html
@@ -8,7 +8,7 @@
 <p id="description"></p>
 <div id="console"></div>
 <script>
-description("Tests MediaStreamTrack::getSourceInfos.");
+description("Tests MediaStreamTrack::getSources.");
 
 var sources = null;
 var previousId;
@@ -27,19 +27,32 @@
     }
 }
 
-function gotStream(s) {
-    shouldNotThrow('sources = MediaStreamTrack.getSourceInfos();');
+function gotSources2(s) {
+    testPassed('gotSources2 was called.');
+    sources = s;
     shouldBeTrue('sources.length > 0');
     shouldBeTrue('sources[0].id === previousId');
     shouldBeTrue('sources[0].label.length > 0');
+
     finishJSTest();
 }
 
-shouldNotThrow('sources = MediaStreamTrack.getSourceInfos();');
-shouldBeTrue('sources.length > 0');
-previousId = sources[0].id;
+function gotStream(s) {
+    testPassed('gotStream was called.');
 
-getUserMedia({audio:true, video:true}, gotStream);
+    shouldNotThrow('MediaStreamTrack.getSources(gotSources2);');
+}
+
+function gotSources1(s) {
+    testPassed('gotSources1 was called.');
+    sources = s;
+    shouldBeTrue('sources.length > 0');
+    previousId = sources[0].id;
+
+    getUserMedia({audio:true, video:true}, gotStream);
+}
+
+shouldNotThrow('MediaStreamTrack.getSources(gotSources1);');
 
 window.jsTestIsAsync = true;
 window.successfullyParsed = true;
diff --git a/Source/core/platform/mediastream/MediaStreamCenter.cpp b/Source/core/platform/mediastream/MediaStreamCenter.cpp
index 1bb1a24..7343402 100644
--- a/Source/core/platform/mediastream/MediaStreamCenter.cpp
+++ b/Source/core/platform/mediastream/MediaStreamCenter.cpp
@@ -34,10 +34,13 @@
 #include "core/platform/mediastream/MediaStreamCenter.h"
 
 #include "core/platform/mediastream/MediaStreamDescriptor.h"
+#include "core/platform/mediastream/MediaStreamSourcesQueryClient.h"
+#include "modules/mediastream/MediaStreamTrackSourcesRequest.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebMediaStream.h"
 #include "public/platform/WebMediaStreamCenter.h"
 #include "public/platform/WebMediaStreamTrack.h"
+#include "public/platform/WebMediaStreamTrackSourcesRequest.h"
 #include "wtf/MainThread.h"
 #include "wtf/PassOwnPtr.h"
 
@@ -59,9 +62,9 @@
 {
 }
 
-bool MediaStreamCenter::getSourceInfos(const String& url, WebKit::WebVector<WebKit::WebSourceInfo>& sourceInfos)
+bool MediaStreamCenter::getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequest> request)
 {
-    return m_private && m_private->getSourceInfos(url, sourceInfos);
+    return m_private && m_private->getMediaStreamTrackSources(request);
 }
 
 void MediaStreamCenter::didSetMediaStreamTrackEnabled(MediaStreamDescriptor* stream,  MediaStreamComponent* component)
diff --git a/Source/core/platform/mediastream/MediaStreamCenter.h b/Source/core/platform/mediastream/MediaStreamCenter.h
index 92a8eae..674ca97 100644
--- a/Source/core/platform/mediastream/MediaStreamCenter.h
+++ b/Source/core/platform/mediastream/MediaStreamCenter.h
@@ -43,7 +43,6 @@
 class WebMediaStream;
 class WebMediaStreamCenter;
 class WebMediaStreamTrack;
-class WebSourceInfo;
 }
 
 namespace WebCore {
@@ -51,6 +50,7 @@
 class MediaStreamComponent;
 class MediaStreamDescriptor;
 class MediaStreamSourcesQueryClient;
+class MediaStreamTrackSourcesRequest;
 
 class MediaStreamCenter : public WebKit::WebMediaStreamCenterClient {
 public:
@@ -58,7 +58,7 @@
 
     static MediaStreamCenter& instance();
 
-    bool getSourceInfos(const String& url, WebKit::WebVector<WebKit::WebSourceInfo>&);
+    bool getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequest>);
     void didSetMediaStreamTrackEnabled(MediaStreamDescriptor*, MediaStreamComponent*);
     bool didAddMediaStreamTrack(MediaStreamDescriptor*, MediaStreamComponent*);
     bool didRemoveMediaStreamTrack(MediaStreamDescriptor*, MediaStreamComponent*);
diff --git a/Source/modules/mediastream/MediaStreamTrack.cpp b/Source/modules/mediastream/MediaStreamTrack.cpp
index fe6ceaf..a0aaca3 100644
--- a/Source/modules/mediastream/MediaStreamTrack.cpp
+++ b/Source/modules/mediastream/MediaStreamTrack.cpp
@@ -30,8 +30,9 @@
 #include "core/dom/ScriptExecutionContext.h"
 #include "core/platform/mediastream/MediaStreamCenter.h"
 #include "core/platform/mediastream/MediaStreamComponent.h"
+#include "modules/mediastream/MediaStreamTrackSourcesCallback.h"
+#include "modules/mediastream/MediaStreamTrackSourcesRequest.h"
 #include "public/platform/WebSourceInfo.h"
-#include "weborigin/SecurityOrigin.h"
 
 namespace WebCore {
 
@@ -118,20 +119,12 @@
     return String();
 }
 
-SourceInfoVector MediaStreamTrack::getSourceInfos(ScriptExecutionContext* context, ExceptionCode& ec)
+void MediaStreamTrack::getSources(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback, ExceptionCode& ec)
 {
-    WebKit::WebVector<WebKit::WebSourceInfo> webSourceInfos;
-    bool ok = MediaStreamCenter::instance().getSourceInfos(context->securityOrigin()->toString(), webSourceInfos);
-    if (!ok) {
+    RefPtr<MediaStreamTrackSourcesRequest> request = MediaStreamTrackSourcesRequest::create(context, callback);
+    bool ok = MediaStreamCenter::instance().getMediaStreamTrackSources(request.release());
+    if (!ok)
         ec = NOT_SUPPORTED_ERR;
-        return SourceInfoVector();
-    }
-
-    SourceInfoVector sourceInfos;
-    for (size_t i = 0; i < webSourceInfos.size(); ++i)
-        sourceInfos.append(SourceInfo::create(webSourceInfos[i]));
-
-    return sourceInfos;
 }
 
 bool MediaStreamTrack::ended() const
diff --git a/Source/modules/mediastream/MediaStreamTrack.h b/Source/modules/mediastream/MediaStreamTrack.h
index 1bf3f38..b7c8ee5 100644
--- a/Source/modules/mediastream/MediaStreamTrack.h
+++ b/Source/modules/mediastream/MediaStreamTrack.h
@@ -41,6 +41,7 @@
 namespace WebCore {
 
 class MediaStreamComponent;
+class MediaStreamTrackSourcesCallback;
 
 class MediaStreamTrack : public RefCounted<MediaStreamTrack>, public ScriptWrappable, public ActiveDOMObject, public EventTarget, public MediaStreamSource::Observer {
 public:
@@ -58,7 +59,7 @@
 
     String readyState() const;
 
-    static SourceInfoVector getSourceInfos(ScriptExecutionContext*, ExceptionCode&);
+    static void getSources(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>, ExceptionCode&);
 
     DEFINE_ATTRIBUTE_EVENT_LISTENER(mute);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(unmute);
diff --git a/Source/modules/mediastream/MediaStreamTrack.idl b/Source/modules/mediastream/MediaStreamTrack.idl
index 116cc33..d02d8ed 100644
--- a/Source/modules/mediastream/MediaStreamTrack.idl
+++ b/Source/modules/mediastream/MediaStreamTrack.idl
@@ -37,7 +37,7 @@
     attribute EventListener onunmute;
     attribute EventListener onended;
 
-    [CallWith=ScriptExecutionContext, RaisesException] static sequence<SourceInfo> getSourceInfos();
+    [CallWith=ScriptExecutionContext, RaisesException] static void getSources(MediaStreamTrackSourcesCallback callback);
 
     // EventTarget interface
     void addEventListener(DOMString type,
diff --git a/Source/modules/mediastream/MediaStreamTrackSourcesCallback.h b/Source/modules/mediastream/MediaStreamTrackSourcesCallback.h
new file mode 100644
index 0000000..585031f
--- /dev/null
+++ b/Source/modules/mediastream/MediaStreamTrackSourcesCallback.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaStreamTrackSourcesCallback_h
+#define MediaStreamTrackSourcesCallback_h
+
+#include "modules/mediastream/SourceInfo.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class MediaStreamTrackSourcesResponse;
+
+class MediaStreamTrackSourcesCallback : public RefCounted<MediaStreamTrackSourcesCallback> {
+public:
+    virtual ~MediaStreamTrackSourcesCallback() { }
+    virtual bool handleEvent(SourceInfoVector) = 0;
+};
+
+} // namespace WebCore
+
+#endif // MediaStreamTrackSourcesCallback_h
diff --git a/Source/modules/mediastream/MediaStreamTrackSourcesCallback.idl b/Source/modules/mediastream/MediaStreamTrackSourcesCallback.idl
new file mode 100644
index 0000000..ce89327
--- /dev/null
+++ b/Source/modules/mediastream/MediaStreamTrackSourcesCallback.idl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+callback interface MediaStreamTrackSourcesCallback {
+    boolean handleEvent(sequence<SourceInfo> sources);
+};
+
diff --git a/Source/modules/mediastream/MediaStreamTrackSourcesRequest.cpp b/Source/modules/mediastream/MediaStreamTrackSourcesRequest.cpp
new file mode 100644
index 0000000..5d1c2d8
--- /dev/null
+++ b/Source/modules/mediastream/MediaStreamTrackSourcesRequest.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "modules/mediastream/MediaStreamTrackSourcesRequest.h"
+
+#include "core/dom/ScriptExecutionContext.h"
+#include "modules/mediastream/MediaStreamTrackSourcesCallback.h"
+#include "public/platform/WebSourceInfo.h"
+#include "weborigin/SecurityOrigin.h"
+
+namespace WebCore {
+
+PassRefPtr<MediaStreamTrackSourcesRequest> MediaStreamTrackSourcesRequest::create(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback)
+{
+    return adoptRef(new MediaStreamTrackSourcesRequest(context, callback));
+}
+
+MediaStreamTrackSourcesRequest::MediaStreamTrackSourcesRequest(ScriptExecutionContext* context, PassRefPtr<MediaStreamTrackSourcesCallback> callback)
+    : m_callback(callback)
+    , m_scheduledEventTimer(this, &MediaStreamTrackSourcesRequest::scheduledEventTimerFired)
+{
+    m_origin = context->securityOrigin()->toString();
+}
+
+MediaStreamTrackSourcesRequest::~MediaStreamTrackSourcesRequest()
+{
+}
+
+void MediaStreamTrackSourcesRequest::requestSucceeded(const WebKit::WebVector<WebKit::WebSourceInfo>& webSourceInfos)
+{
+    ASSERT(m_callback && !m_scheduledEventTimer.isActive());
+
+    for (size_t i = 0; i < webSourceInfos.size(); ++i)
+        m_sourceInfos.append(SourceInfo::create(webSourceInfos[i]));
+
+    m_protect = this;
+    m_scheduledEventTimer.startOneShot(0);
+}
+
+void MediaStreamTrackSourcesRequest::scheduledEventTimerFired(Timer<MediaStreamTrackSourcesRequest>*)
+{
+    m_callback->handleEvent(m_sourceInfos);
+    m_callback.clear();
+    m_protect.release();
+}
+
+} // namespace WebCore
diff --git a/Source/modules/mediastream/MediaStreamTrackSourcesRequest.h b/Source/modules/mediastream/MediaStreamTrackSourcesRequest.h
new file mode 100644
index 0000000..86ffec2
--- /dev/null
+++ b/Source/modules/mediastream/MediaStreamTrackSourcesRequest.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MediaStreamTrackSourcesRequest_h
+#define MediaStreamTrackSourcesRequest_h
+
+#include "core/platform/Timer.h"
+#include "modules/mediastream/SourceInfo.h"
+#include "public/platform/WebVector.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebKit {
+class WebSourceInfo;
+}
+
+namespace WebCore {
+
+class MediaStreamTrackSourcesCallback;
+class ScriptExecutionContext;
+
+class MediaStreamTrackSourcesRequest : public RefCounted<MediaStreamTrackSourcesRequest> {
+public:
+    class ExtraData : public RefCounted<ExtraData> {
+    public:
+        virtual ~ExtraData() { }
+    };
+
+    static PassRefPtr<MediaStreamTrackSourcesRequest> create(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>);
+    virtual ~MediaStreamTrackSourcesRequest();
+
+    String origin() { return m_origin; }
+
+    void requestSucceeded(const WebKit::WebVector<WebKit::WebSourceInfo>&);
+
+    PassRefPtr<ExtraData> extraData() const { return m_extraData; }
+    void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
+
+private:
+    MediaStreamTrackSourcesRequest(ScriptExecutionContext*, PassRefPtr<MediaStreamTrackSourcesCallback>);
+
+    void scheduledEventTimerFired(Timer<MediaStreamTrackSourcesRequest>*);
+
+    RefPtr<MediaStreamTrackSourcesCallback> m_callback;
+    RefPtr<ExtraData> m_extraData;
+    String m_origin;
+    Timer<MediaStreamTrackSourcesRequest> m_scheduledEventTimer;
+    SourceInfoVector m_sourceInfos;
+    RefPtr<MediaStreamTrackSourcesRequest> m_protect;
+};
+
+} // namespace WebCore
+
+#endif // MediaStreamTrackSourcesRequest_h
diff --git a/Source/modules/mediastream/WebMediaStreamTrackSourcesRequest.cpp b/Source/modules/mediastream/WebMediaStreamTrackSourcesRequest.cpp
new file mode 100644
index 0000000..4a0665b
--- /dev/null
+++ b/Source/modules/mediastream/WebMediaStreamTrackSourcesRequest.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "public/platform/WebMediaStreamTrackSourcesRequest.h"
+
+#include "modules/mediastream/MediaStreamTrackSourcesRequest.h"
+#include "public/platform/WebSourceInfo.h"
+#include "wtf/PassOwnPtr.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+namespace {
+
+class ExtraDataContainer : public MediaStreamTrackSourcesRequest::ExtraData {
+public:
+    ExtraDataContainer(WebMediaStreamTrackSourcesRequest::ExtraData* extraData) : m_extraData(adoptPtr(extraData)) { }
+
+    WebMediaStreamTrackSourcesRequest::ExtraData* extraData() { return m_extraData.get(); }
+
+private:
+    OwnPtr<WebMediaStreamTrackSourcesRequest::ExtraData> m_extraData;
+};
+
+} // namespace
+
+WebMediaStreamTrackSourcesRequest::WebMediaStreamTrackSourcesRequest(const PassRefPtr<MediaStreamTrackSourcesRequest>& request)
+    : m_private(request)
+{
+}
+
+void WebMediaStreamTrackSourcesRequest::assign(const WebMediaStreamTrackSourcesRequest& other)
+{
+    m_private = other.m_private;
+}
+
+void WebMediaStreamTrackSourcesRequest::reset()
+{
+    m_private.reset();
+}
+
+WebString WebMediaStreamTrackSourcesRequest::origin() const
+{
+    ASSERT(m_private.get());
+    return m_private->origin();
+}
+
+void WebMediaStreamTrackSourcesRequest::requestSucceeded(const WebVector<WebSourceInfo>& sourceInfos) const
+{
+    ASSERT(m_private.get());
+    m_private->requestSucceeded(sourceInfos);
+}
+
+WebMediaStreamTrackSourcesRequest::ExtraData* WebMediaStreamTrackSourcesRequest::extraData() const
+{
+    RefPtr<MediaStreamTrackSourcesRequest::ExtraData> data = m_private->extraData();
+    if (!data)
+        return 0;
+    return static_cast<ExtraDataContainer*>(data.get())->extraData();
+}
+
+void WebMediaStreamTrackSourcesRequest::setExtraData(ExtraData* extraData)
+{
+    m_private->setExtraData(adoptRef(new ExtraDataContainer(extraData)));
+}
+
+} // namespace WebKit
+
diff --git a/Source/modules/modules.gypi b/Source/modules/modules.gypi
index 4167be9..b814903 100644
--- a/Source/modules/modules.gypi
+++ b/Source/modules/modules.gypi
@@ -84,6 +84,7 @@
       'mediastream/MediaStreamEvent.idl',
       'mediastream/MediaStreamTrack.idl',
       'mediastream/MediaStreamTrackEvent.idl',
+      'mediastream/MediaStreamTrackSourcesCallback.idl',
       'mediastream/NavigatorMediaStream.idl',
       'mediastream/NavigatorUserMediaError.idl',
       'mediastream/NavigatorUserMediaErrorCallback.idl',
@@ -381,6 +382,9 @@
       'mediastream/MediaStreamTrack.h',
       'mediastream/MediaStreamTrackEvent.cpp',
       'mediastream/MediaStreamTrackEvent.h',
+      'mediastream/MediaStreamTrackSourcesCallback.h',
+      'mediastream/MediaStreamTrackSourcesRequest.cpp',
+      'mediastream/MediaStreamTrackSourcesRequest.h',
       'mediastream/NavigatorMediaStream.cpp',
       'mediastream/NavigatorMediaStream.h',
       'mediastream/NavigatorUserMediaError.h',
@@ -421,6 +425,7 @@
       'mediastream/UserMediaController.h',
       'mediastream/UserMediaRequest.cpp',
       'mediastream/UserMediaRequest.h',
+      'mediastream/WebMediaStreamTrackSourcesRequest.cpp',
       'navigatorcontentutils/NavigatorContentUtils.cpp',
       'navigatorcontentutils/NavigatorContentUtils.h',
       'navigatorcontentutils/NavigatorContentUtilsClient.h',
diff --git a/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.cpp b/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.cpp
index 3f5ffb4..bb58265 100644
--- a/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.cpp
+++ b/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.cpp
@@ -35,6 +35,7 @@
 #include "public/platform/WebMediaStreamCenterClient.h"
 #include "public/platform/WebMediaStreamSource.h"
 #include "public/platform/WebMediaStreamTrack.h"
+#include "public/platform/WebMediaStreamTrackSourcesRequest.h"
 #include "public/platform/WebSourceInfo.h"
 #include "public/platform/WebVector.h"
 
@@ -46,13 +47,13 @@
 {
 }
 
-bool MockWebMediaStreamCenter::getSourceInfos(const WebString& url, WebVector<WebSourceInfo>& webSourceInfoVector)
+bool MockWebMediaStreamCenter::getMediaStreamTrackSources(const WebMediaStreamTrackSourcesRequest& request)
 {
     size_t size = 2;
     WebVector<WebSourceInfo> results(size);
     results[0].initialize("MockAudioDevice#1", WebSourceInfo::SourceKindAudio, "Mock audio device", WebSourceInfo::VideoFacingModeNone);
     results[1].initialize("MockVideoDevice#1", WebSourceInfo::SourceKindVideo, "Mock video device", WebSourceInfo::VideoFacingModeEnvironment);
-    webSourceInfoVector.swap(results);
+    request.requestSucceeded(results);
     return true;
 }
 
diff --git a/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.h b/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.h
index 11f4c54..e8694b9 100644
--- a/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.h
+++ b/Tools/DumpRenderTree/chromium/TestRunner/src/MockWebMediaStreamCenter.h
@@ -44,7 +44,7 @@
 public:
     explicit MockWebMediaStreamCenter(WebKit::WebMediaStreamCenterClient*);
 
-    virtual bool getSourceInfos(const WebKit::WebString& url, WebKit::WebVector<WebKit::WebSourceInfo>&) OVERRIDE;
+    virtual bool getMediaStreamTrackSources(const WebKit::WebMediaStreamTrackSourcesRequest&) OVERRIDE;
     virtual void didEnableMediaStreamTrack(const WebKit::WebMediaStream&, const WebKit::WebMediaStreamTrack&) OVERRIDE;
     virtual void didDisableMediaStreamTrack(const WebKit::WebMediaStream&, const WebKit::WebMediaStreamTrack&) OVERRIDE;
     virtual bool didAddMediaStreamTrack(const WebKit::WebMediaStream&, const WebKit::WebMediaStreamTrack&) OVERRIDE;
diff --git a/public/platform/WebMediaStreamCenter.h b/public/platform/WebMediaStreamCenter.h
index 48e9b7d..61464d5 100644
--- a/public/platform/WebMediaStreamCenter.h
+++ b/public/platform/WebMediaStreamCenter.h
@@ -37,6 +37,7 @@
 class WebMediaStream;
 class WebMediaStreamSourcesRequest;
 class WebMediaStreamTrack;
+class WebMediaStreamTrackSourcesRequest;
 class WebSourceInfo;
 class WebString;
 
@@ -47,7 +48,7 @@
     // DEPRECATED
     virtual void queryMediaStreamSources(const WebMediaStreamSourcesRequest&) { }
 
-    virtual bool getSourceInfos(const WebString& url, WebVector<WebSourceInfo>&) { return false; }
+    virtual bool getMediaStreamTrackSources(const WebMediaStreamTrackSourcesRequest&) { return false; }
     virtual void didEnableMediaStreamTrack(const WebMediaStream&, const WebMediaStreamTrack&) = 0;
     virtual void didDisableMediaStreamTrack(const WebMediaStream&, const WebMediaStreamTrack&) = 0;
     virtual bool didAddMediaStreamTrack(const WebMediaStream&, const WebMediaStreamTrack&) { return false; };
diff --git a/public/platform/WebMediaStreamTrackSourcesRequest.h b/public/platform/WebMediaStreamTrackSourcesRequest.h
new file mode 100644
index 0000000..1541fc3
--- /dev/null
+++ b/public/platform/WebMediaStreamTrackSourcesRequest.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebMediaStreamTrackSourcesRequest_h
+#define WebMediaStreamTrackSourcesRequest_h
+
+#include "WebCommon.h"
+#include "WebNonCopyable.h"
+#include "WebPrivatePtr.h"
+#include "WebString.h"
+#include "WebVector.h"
+
+namespace WebCore {
+class MediaStreamTrackSourcesRequest;
+}
+
+namespace WebKit {
+class WebSourceInfo;
+
+class WebMediaStreamTrackSourcesRequest {
+public:
+    class ExtraData {
+    public:
+        virtual ~ExtraData() { }
+    };
+
+    WebMediaStreamTrackSourcesRequest() { }
+    WebMediaStreamTrackSourcesRequest(const WebMediaStreamTrackSourcesRequest& other) { assign(other); }
+    ~WebMediaStreamTrackSourcesRequest() { reset(); }
+
+    WebMediaStreamTrackSourcesRequest& operator=(const WebMediaStreamTrackSourcesRequest& other)
+    {
+        assign(other);
+        return *this;
+    }
+
+    WEBKIT_EXPORT void assign(const WebMediaStreamTrackSourcesRequest&);
+
+    WEBKIT_EXPORT void reset();
+    bool isNull() const { return m_private.isNull(); }
+
+    WEBKIT_EXPORT WebString origin() const;
+    WEBKIT_EXPORT void requestSucceeded(const WebVector<WebSourceInfo>&) const;
+
+    // Extra data associated with this object.
+    // If non-null, the extra data pointer will be deleted when the object is destroyed.
+    // Setting the extra data pointer will cause any existing non-null
+    // extra data pointer to be deleted.
+    WEBKIT_EXPORT ExtraData* extraData() const;
+    WEBKIT_EXPORT void setExtraData(ExtraData*);
+
+#if WEBKIT_IMPLEMENTATION
+    WebMediaStreamTrackSourcesRequest(const WTF::PassRefPtr<WebCore::MediaStreamTrackSourcesRequest>&);
+#endif
+
+private:
+    WebPrivatePtr<WebCore::MediaStreamTrackSourcesRequest> m_private;
+};
+
+} // namespace WebKit
+
+#endif // WebMediaStreamTrackSourcesRequest_h