Only the first call to 'stop' method of AudioBufferSourceNode must be entertained.
[WebKit-https.git] / Source / WebCore / Modules / webaudio / AudioScheduledSourceNode.cpp
index b84f69f..0361b8b 100644 (file)
@@ -31,6 +31,7 @@
 #include "AudioContext.h"
 #include "AudioUtilities.h"
 #include "Event.h"
+#include "ScriptController.h"
 #include <algorithm>
 #include <wtf/MathExtras.h>
 
@@ -41,7 +42,7 @@ namespace WebCore {
 const double AudioScheduledSourceNode::UnknownTime = -1;
 
 AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* context, float sampleRate)
-    : AudioSourceNode(context, sampleRate)
+    : AudioNode(context, sampleRate)
     , m_playbackState(UNSCHEDULED_STATE)
     , m_startTime(0)
     , m_endTime(UnknownTime)
@@ -134,42 +135,50 @@ void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize,
     return;
 }
 
-void AudioScheduledSourceNode::start(double when)
+void AudioScheduledSourceNode::start(double when, ExceptionCode& ec)
 {
     ASSERT(isMainThread());
-    if (m_playbackState != UNSCHEDULED_STATE)
+
+    if (ScriptController::processingUserGesture())
+        context()->removeBehaviorRestriction(AudioContext::RequireUserGestureForAudioStartRestriction);
+
+    if (m_playbackState != UNSCHEDULED_STATE) {
+        ec = INVALID_STATE_ERR;
         return;
+    }
 
     m_startTime = when;
     m_playbackState = SCHEDULED_STATE;
 }
 
-void AudioScheduledSourceNode::stop(double when)
+void AudioScheduledSourceNode::stop(double when, ExceptionCode& ec)
 {
     ASSERT(isMainThread());
-    if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE))
+    if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE) || (m_endTime != UnknownTime)) {
+        ec = INVALID_STATE_ERR;
         return;
+    }
     
     when = max(0.0, when);
     m_endTime = when;
 }
 
 #if ENABLE(LEGACY_WEB_AUDIO)
-void AudioScheduledSourceNode::noteOn(double when)
+void AudioScheduledSourceNode::noteOn(double when, ExceptionCode& ec)
 {
-    start(when);
+    start(when, ec);
 }
 
-void AudioScheduledSourceNode::noteOff(double when)
+void AudioScheduledSourceNode::noteOff(double when, ExceptionCode& ec)
 {
-    stop(when);
+    stop(when, ec);
 }
 #endif
 
 void AudioScheduledSourceNode::setOnended(PassRefPtr<EventListener> listener)
 {
-    setAttributeEventListener(eventNames().endedEvent, listener);
     m_hasEndedListener = listener;
+    setAttributeEventListener(eventNames().endedEvent, listener);
 }
 
 void AudioScheduledSourceNode::finish()
@@ -181,7 +190,7 @@ void AudioScheduledSourceNode::finish()
         context()->decrementActiveSourceCount();
     }
 
-    if (m_hasEndedListener);
+    if (m_hasEndedListener)
         callOnMainThread(&AudioScheduledSourceNode::notifyEndedDispatch, this);
 }