Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / webaudio / AudioScheduledSourceNode.cpp
index 7aa6439..69d050a 100644 (file)
 
 #include "modules/webaudio/AudioScheduledSourceNode.h"
 
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "core/dom/CrossThreadTask.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/events/Event.h"
-#include "platform/audio/AudioUtilities.h"
+#include "modules/EventModules.h"
 #include "modules/webaudio/AudioContext.h"
-#include <algorithm>
+#include "platform/audio/AudioUtilities.h"
 #include "wtf/MathExtras.h"
+#include <algorithm>
 
-using namespace std;
+namespace blink {
 
-namespace WebCore {
+#if !ENABLE(OILPAN)
+// We need a dedicated specialization for AudioScheduledSourceNode because it
+// doesn't inherit from RefCounted.
+template<> struct CrossThreadCopierBase<false, false, false, PassRefPtr<AudioScheduledSourceNode> > : public CrossThreadCopierPassThrough<PassRefPtr<AudioScheduledSourceNode> > {
+};
+#endif
 
 const double AudioScheduledSourceNode::UnknownTime = -1;
 
@@ -49,7 +54,6 @@ AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* context, float
     , m_startTime(0)
     , m_endTime(UnknownTime)
     , m_hasEndedListener(false)
-    , m_stopCalled(false)
 {
 }
 
@@ -92,11 +96,10 @@ void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize,
     if (m_playbackState == SCHEDULED_STATE) {
         // Increment the active source count only if we're transitioning from SCHEDULED_STATE to PLAYING_STATE.
         m_playbackState = PLAYING_STATE;
-        context()->incrementActiveSourceCount();
     }
 
     quantumFrameOffset = startFrame > quantumStartFrame ? startFrame - quantumStartFrame : 0;
-    quantumFrameOffset = min(quantumFrameOffset, quantumFrameSize); // clamp to valid range
+    quantumFrameOffset = std::min(quantumFrameOffset, quantumFrameSize); // clamp to valid range
     nonSilentFramesToProcess = quantumFrameSize - quantumFrameOffset;
 
     if (!nonSilentFramesToProcess) {
@@ -138,18 +141,14 @@ void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize,
     return;
 }
 
-
-void AudioScheduledSourceNode::start(double when, ExceptionState& es)
+void AudioScheduledSourceNode::start(double when, ExceptionState& exceptionState)
 {
     ASSERT(isMainThread());
 
     if (m_playbackState != UNSCHEDULED_STATE) {
-        es.throwDOMException(
+        exceptionState.throwDOMException(
             InvalidStateError,
-            ExceptionMessages::failedToExecute(
-                "start",
-                "OscillatorNode",
-                "cannot call start more than once."));
+            "cannot call start more than once.");
         return;
     }
 
@@ -157,38 +156,27 @@ void AudioScheduledSourceNode::start(double when, ExceptionState& es)
     m_playbackState = SCHEDULED_STATE;
 }
 
-void AudioScheduledSourceNode::stop(double when, ExceptionState& es)
+void AudioScheduledSourceNode::stop(double when, ExceptionState& exceptionState)
 {
     ASSERT(isMainThread());
 
-    if (m_stopCalled) {
-        es.throwDOMException(
-            InvalidStateError,
-            ExceptionMessages::failedToExecute(
-                "stop",
-                "OscillatorNode",
-                "cannot call stop more than once."));
-    } else if (m_playbackState == UNSCHEDULED_STATE) {
-        es.throwDOMException(
+    if (m_playbackState == UNSCHEDULED_STATE) {
+        exceptionState.throwDOMException(
             InvalidStateError,
-            ExceptionMessages::failedToExecute(
-                "stop",
-                "OscillatorNode",
-                "cannot call stop without calling start first."));
+            "cannot call stop without calling start first.");
     } else {
-        // This can only happen from the SCHEDULED_STATE or PLAYING_STATE. The UNSCHEDULED_STATE is
-        // handled above, and the FINISHED_STATE is only reachable after stop() has been called, and
-        // hence m_stopCalled is true. But that case is handled above.
-        when = max(0.0, when);
+        // stop() can be called more than once, with the last call to stop taking effect, unless the
+        // source has already stopped due to earlier calls to stop. No exceptions are thrown in any
+        // case.
+        when = std::max(0.0, when);
         m_endTime = when;
-        m_stopCalled = true;
     }
 }
 
-void AudioScheduledSourceNode::setOnended(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
+void AudioScheduledSourceNode::setOnended(PassRefPtr<EventListener> listener)
 {
     m_hasEndedListener = listener;
-    setAttributeEventListener(EventTypeNames::ended, listener, isolatedWorld);
+    setAttributeEventListener(EventTypeNames::ended, listener);
 }
 
 void AudioScheduledSourceNode::finish()
@@ -197,35 +185,18 @@ void AudioScheduledSourceNode::finish()
         // Let the context dereference this AudioNode.
         context()->notifyNodeFinishedProcessing(this);
         m_playbackState = FINISHED_STATE;
-        context()->decrementActiveSourceCount();
     }
 
-    if (m_hasEndedListener) {
-        // |task| will keep the AudioScheduledSourceNode alive until the listener has been handled.
-        OwnPtr<NotifyEndedTask> task = adoptPtr(new NotifyEndedTask(this));
-        callOnMainThread(&AudioScheduledSourceNode::notifyEndedDispatch, task.leakPtr());
+    if (m_hasEndedListener && context()->executionContext()) {
+        context()->executionContext()->postTask(createCrossThreadTask(&AudioScheduledSourceNode::notifyEnded, PassRefPtrWillBeRawPtr<AudioScheduledSourceNode>(this)));
     }
 }
 
-void AudioScheduledSourceNode::notifyEndedDispatch(void* userData)
-{
-    OwnPtr<NotifyEndedTask> task = adoptPtr(static_cast<NotifyEndedTask*>(userData));
-
-    task->notifyEnded();
-}
-
-AudioScheduledSourceNode::NotifyEndedTask::NotifyEndedTask(PassRefPtr<AudioScheduledSourceNode> sourceNode)
-    : m_scheduledNode(sourceNode)
-{
-}
-
-void AudioScheduledSourceNode::NotifyEndedTask::notifyEnded()
+void AudioScheduledSourceNode::notifyEnded()
 {
-    RefPtr<Event> event = Event::create(EventTypeNames::ended);
-    event->setTarget(m_scheduledNode);
-    m_scheduledNode->dispatchEvent(event.get());
+    dispatchEvent(Event::create(EventTypeNames::ended));
 }
 
-} // namespace WebCore
+} // namespace blink
 
 #endif // ENABLE(WEB_AUDIO)