Index: Source/modules/webmidi/MIDIAccess.cpp |
diff --git a/Source/modules/webmidi/MIDIAccess.cpp b/Source/modules/webmidi/MIDIAccess.cpp |
index c2e333863039f3d4b554d79c8e5803d74055e8a0..f578938decef481cc01d710814f53d7311bae633 100644 |
--- a/Source/modules/webmidi/MIDIAccess.cpp |
+++ b/Source/modules/webmidi/MIDIAccess.cpp |
@@ -31,35 +31,40 @@ |
#include "config.h" |
#include "modules/webmidi/MIDIAccess.h" |
+#include "bindings/v8/DOMRequestState.h" |
+#include "bindings/v8/DOMWrapperWorld.h" |
+#include "bindings/v8/ScriptPromise.h" |
+#include "bindings/v8/ScriptPromiseResolver.h" |
+#include "bindings/v8/V8Binding.h" |
#include "core/dom/DOMError.h" |
#include "core/dom/Document.h" |
#include "core/loader/DocumentLoadTiming.h" |
#include "core/loader/DocumentLoader.h" |
-#include "modules/webmidi/MIDIAccessPromise.h" |
#include "modules/webmidi/MIDIConnectionEvent.h" |
#include "modules/webmidi/MIDIController.h" |
+#include "modules/webmidi/MIDIOptions.h" |
#include "modules/webmidi/MIDIPort.h" |
+#include "modules/webmidi/NavigatorWebMIDI.h" |
namespace WebCore { |
DEFINE_GC_INFO(MIDIAccess); |
-PassRefPtrWillBeRawPtr<MIDIAccess> MIDIAccess::create(ExecutionContext* context, MIDIAccessPromise* promise) |
+PassRefPtrWillBeRawPtr<MIDIAccess> MIDIAccess::create(const MIDIOptions& options, ExecutionContext* context) |
{ |
- RefPtrWillBeRawPtr<MIDIAccess> midiAccess(adoptRefCountedWillBeRefCountedGarbageCollected(new MIDIAccess(context, promise))); |
+ RefPtrWillBeRawPtr<MIDIAccess> midiAccess(adoptRefCountedWillBeRefCountedGarbageCollected(new MIDIAccess(options, context))); |
midiAccess->suspendIfNeeded(); |
- midiAccess->startRequest(); |
return midiAccess.release(); |
} |
MIDIAccess::~MIDIAccess() |
{ |
- stop(); |
+ ASSERT(!m_requesting); |
} |
-MIDIAccess::MIDIAccess(ExecutionContext* context, MIDIAccessPromise* promise) |
+MIDIAccess::MIDIAccess(const MIDIOptions& options, ExecutionContext* context) |
: ActiveDOMObject(context) |
- , m_promise(promise) |
+ , m_options(options) |
, m_hasAccess(false) |
, m_sysExEnabled(false) |
, m_requesting(false) |
@@ -70,12 +75,12 @@ MIDIAccess::MIDIAccess(ExecutionContext* context, MIDIAccessPromise* promise) |
void MIDIAccess::setSysExEnabled(bool enable) |
{ |
- m_requesting = false; |
+ RefPtr<MIDIAccess> protect(this); |
m_sysExEnabled = enable; |
if (enable) |
m_accessor->startSession(); |
else |
- permissionDenied(); |
+ reject(DOMError::create("SecurityError")); |
} |
void MIDIAccess::didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version) |
@@ -95,13 +100,14 @@ void MIDIAccess::didAddOutputPort(const String& id, const String& manufacturer, |
void MIDIAccess::didStartSession(bool success) |
{ |
+ RefPtr<MIDIAccess> protect(this); |
ASSERT(isMainThread()); |
- |
- m_hasAccess = success; |
+ if (!m_requesting) |
+ return; |
if (success) |
- m_promise->fulfill(); |
+ resolve(); |
else |
- m_promise->reject(DOMError::create("InvalidStateError")); |
+ reject(DOMError::create("InvalidStateError")); |
} |
void MIDIAccess::didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp) |
@@ -145,47 +151,86 @@ void MIDIAccess::sendMIDIData(unsigned portIndex, const unsigned char* data, siz |
void MIDIAccess::stop() |
{ |
+ RefPtr<MIDIAccess> protect(this); |
m_hasAccess = false; |
if (!m_requesting) |
return; |
- m_requesting = false; |
Document* document = toDocument(executionContext()); |
ASSERT(document); |
MIDIController* controller = MIDIController::from(document->page()); |
ASSERT(controller); |
controller->cancelSysExPermissionRequest(this); |
+ |
+ m_accessor.clear(); |
+ reject(DOMError::create("AbortError")); |
} |
-void MIDIAccess::startRequest() |
+void MIDIAccess::permissionDenied() |
+{ |
+ RefPtr<MIDIAccess> protect(this); |
+ ASSERT(isMainThread()); |
+ reject(DOMError::create("SecurityError")); |
+} |
+ |
+ScriptPromise MIDIAccess::startRequest() |
{ |
- if (!m_promise->options()->sysex) { |
+ ASSERT(!m_requesting); |
+ RefPtr<MIDIAccess> protect(this); |
haraken
2014/02/21 11:11:40
Why do you need protection? Is this "just in case"
yhirano
2014/02/21 13:52:35
I think they were introduced by your suggestion.
h
yhirano
2014/02/26 09:18:08
I deleted many of protect(this).
|
+ ScriptPromise promise = ScriptPromise::createPending(); |
+ m_resolver = ScriptPromiseResolver::create(promise, executionContext()); |
+ m_world = RefPtr<DOMWrapperWorld>(DOMWrapperWorld::current(toIsolate(executionContext()))); |
+ m_requesting = true; |
+ setPendingActivity(this); |
haraken
2014/02/21 11:11:40
m_requesting and setPendingActivity should be sync
yhirano
2014/02/21 13:52:35
Done.
|
+ if (!m_options.sysex) { |
m_accessor->startSession(); |
- return; |
+ return promise; |
} |
Document* document = toDocument(executionContext()); |
ASSERT(document); |
MIDIController* controller = MIDIController::from(document->page()); |
- if (controller) { |
- m_requesting = true; |
+ if (controller) |
controller->requestSysExPermission(this); |
- } else { |
- permissionDenied(); |
- } |
+ else |
+ reject(DOMError::create("SecurityError")); |
+ return promise; |
} |
-void MIDIAccess::permissionDenied() |
+void MIDIAccess::resolve() |
{ |
- ASSERT(isMainThread()); |
+ RefPtr<MIDIAccess> protect(this); |
+ if (!m_requesting) |
+ return; |
+ ASSERT(m_world.get()); |
+ DOMRequestState state(executionContext(), m_world); |
+ DOMRequestState::Scope scope(state); |
haraken
2014/02/21 11:11:40
I don't understand why you need DOMRequestState he
yhirano
2014/02/21 13:52:35
I introduced MIDIAccessResolver.
|
+ m_world.clear(); |
+ m_hasAccess = true; |
haraken
2014/02/21 11:11:40
What is m_hasAccess for?
yhirano
2014/02/21 13:52:35
m_hasAccess is used in didReceiveMIDIData and send
|
+ m_requesting = false; |
+ unsetPendingActivity(this); |
+ // FIXME: Care about suspend / stop. |
haraken
2014/02/21 11:11:40
I think you need to fix this in this CL.
yhirano
2014/02/21 13:52:35
Done.
|
+ m_resolver->resolve(this, executionContext()); |
+} |
+void MIDIAccess::reject(PassRefPtr<DOMError> error) |
+{ |
+ RefPtr<MIDIAccess> protect(this); |
+ if (!m_requesting) |
+ return; |
+ ASSERT(m_world.get()); |
+ DOMRequestState state(executionContext(), m_world); |
+ DOMRequestState::Scope scope(state); |
+ m_world.clear(); |
m_hasAccess = false; |
- m_promise->reject(DOMError::create("SecurityError")); |
+ m_requesting = false; |
+ unsetPendingActivity(this); |
+ // FIXME: Care about suspend / stop. |
+ m_resolver->reject(error, executionContext()); |
} |
void MIDIAccess::trace(Visitor* visitor) |
{ |
visitor->trace(m_inputs); |
visitor->trace(m_outputs); |
- visitor->trace(m_promise); |
} |
} // namespace WebCore |