Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / Modules / webaudio / AudioContext.cpp
index 5a3dea0..ef28f97 100644 (file)
@@ -181,6 +181,8 @@ void AudioContext::constructCommon()
 #if PLATFORM(COCOA)
     addBehaviorRestriction(RequirePageConsentForAudioStartRestriction);
 #endif
+
+    m_mediaSession->setCanProduceAudio(true);
 }
 
 AudioContext::~AudioContext()
@@ -231,7 +233,7 @@ void AudioContext::clear()
 {
     // We have to release our reference to the destination node before the context will ever be deleted since the destination node holds a reference to the context.
     if (m_destinationNode)
-        m_destinationNode.clear();
+        m_destinationNode = nullptr;
 
     // Audio thread is dead. Nobody will schedule node deletion action. Let's do it ourselves.
     do {
@@ -284,7 +286,7 @@ void AudioContext::addReaction(State state, Promise&& promise)
     if (stateIndex >= m_stateReactions.size())
         m_stateReactions.resize(stateIndex + 1);
 
-    m_stateReactions[stateIndex].append(WTF::move(promise));
+    m_stateReactions[stateIndex].append(WTFMove(promise));
 }
 
 void AudioContext::setState(State state)
@@ -353,7 +355,7 @@ void AudioContext::stop()
     });
 }
 
-bool AudioContext::canSuspendForPageCache() const
+bool AudioContext::canSuspendForDocumentSuspension() const
 {
     // FIXME: We should be able to suspend while rendering as well with some more code.
     return m_state == State::Suspended || m_state == State::Closed;
@@ -370,6 +372,11 @@ Document* AudioContext::document() const
     return downcast<Document>(m_scriptExecutionContext);
 }
 
+const Document* AudioContext::hostingDocument() const
+{
+    return downcast<Document>(m_scriptExecutionContext);
+}
+
 PassRefPtr<AudioBuffer> AudioContext::createBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionCode& ec)
 {
     RefPtr<AudioBuffer> audioBuffer = AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate);
@@ -450,38 +457,40 @@ PassRefPtr<MediaElementAudioSourceNode> AudioContext::createMediaElementSource(H
 #if ENABLE(MEDIA_STREAM)
 PassRefPtr<MediaStreamAudioSourceNode> AudioContext::createMediaStreamSource(MediaStream* mediaStream, ExceptionCode& ec)
 {
+    ASSERT(isMainThread());
+
     ASSERT(mediaStream);
     if (!mediaStream) {
         ec = INVALID_STATE_ERR;
         return nullptr;
     }
 
-    ASSERT(isMainThread());
-    lazyInitialize();
-
-    AudioSourceProvider* provider = nullptr;
-
-    RefPtr<MediaStreamTrack> audioTrack;
+    auto audioTracks = mediaStream->getAudioTracks();
+    if (audioTracks.isEmpty()) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
 
-    // FIXME: get a provider for non-local MediaStreams (like from a remote peer).
-    for (auto& track : mediaStream->getAudioTracks()) {
-        audioTrack = track;
-        if (audioTrack->source()->isAudioStreamSource()) {
-            auto source = static_cast<MediaStreamAudioSource*>(audioTrack->source());
-            ASSERT(!source->deviceId().isEmpty());
-            destination()->enableInput(source->deviceId());
-            provider = destination()->localAudioInputProvider();
+    MediaStreamTrack* providerTrack = nullptr;
+    for (auto& track : audioTracks) {
+        if (track->audioSourceProvider()) {
+            providerTrack = track.get();
             break;
         }
     }
 
-    RefPtr<MediaStreamAudioSourceNode> node = MediaStreamAudioSourceNode::create(this, mediaStream, audioTrack.get(), provider);
+    if (!providerTrack) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    lazyInitialize();
 
-    // FIXME: Only stereo streams are supported right now. We should be able to accept multi-channel streams.
+    auto node = MediaStreamAudioSourceNode::create(*this, *mediaStream, *providerTrack);
     node->setFormat(2, sampleRate());
 
-    refNode(node.get()); // context keeps reference until node is disconnected
-    return node;
+    refNode(&node.get()); // context keeps reference until node is disconnected
+    return &node.get();
 }
 
 PassRefPtr<MediaStreamAudioDestinationNode> AudioContext::createMediaStreamDestination()
@@ -997,7 +1006,7 @@ void AudioContext::nodeWillBeginPlayback()
 bool AudioContext::willBeginPlayback()
 {
     if (userGestureRequiredForAudioStart()) {
-        if (!ScriptController::processingUserGesture())
+        if (!ScriptController::processingUserGestureForMedia())
             return false;
         removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
     }
@@ -1017,7 +1026,7 @@ bool AudioContext::willBeginPlayback()
 bool AudioContext::willPausePlayback()
 {
     if (userGestureRequiredForAudioStart()) {
-        if (!ScriptController::processingUserGesture())
+        if (!ScriptController::processingUserGestureForMedia())
             return false;
         removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
     }
@@ -1064,7 +1073,13 @@ void AudioContext::pageMutedStateDidChange()
 
 void AudioContext::isPlayingAudioDidChange()
 {
-    document()->updateIsPlayingMedia();
+    // Make sure to call Document::updateIsPlayingMedia() on the main thread, since
+    // we could be on the audio I/O thread here and the call into WebCore could block.
+    RefPtr<AudioContext> strongThis(this);
+    callOnMainThread([strongThis] {
+        if (strongThis->document())
+            strongThis->document()->updateIsPlayingMedia();
+    });
 }
 
 void AudioContext::fireCompletionEvent()
@@ -1114,7 +1129,7 @@ void AudioContext::suspend(Promise&& promise)
         return;
     }
 
-    addReaction(State::Suspended, WTF::move(promise));
+    addReaction(State::Suspended, WTFMove(promise));
 
     if (!willPausePlayback())
         return;
@@ -1144,7 +1159,7 @@ void AudioContext::resume(Promise&& promise)
         return;
     }
 
-    addReaction(State::Running, WTF::move(promise));
+    addReaction(State::Running, WTFMove(promise));
 
     if (!willBeginPlayback())
         return;
@@ -1169,7 +1184,7 @@ void AudioContext::close(Promise&& promise)
         return;
     }
 
-    addReaction(State::Closed, WTF::move(promise));
+    addReaction(State::Closed, WTFMove(promise));
 
     lazyInitialize();