Index: Source/modules/webmidi/MIDIAccess.cpp |
diff --git a/Source/modules/webmidi/MIDIAccess.cpp b/Source/modules/webmidi/MIDIAccess.cpp |
index 5a572fb276a6af4272f4e980dc12a8416964d21f..888e9d23f2889bfe1a8a334fac65d5b24d1cf28c 100644 |
--- a/Source/modules/webmidi/MIDIAccess.cpp |
+++ b/Source/modules/webmidi/MIDIAccess.cpp |
@@ -31,33 +31,38 @@ |
#include "config.h" |
#include "modules/webmidi/MIDIAccess.h" |
+#include "bindings/v8/ScriptPromise.h" |
+#include "bindings/v8/ScriptPromiseResolver.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 { |
-PassRefPtr<MIDIAccess> MIDIAccess::create(ExecutionContext* context, MIDIAccessPromise* promise) |
+PassRefPtr<MIDIAccess> MIDIAccess::create(const MIDIOptions& options, ExecutionContext* context, NavigatorWebMIDI* navigator) |
{ |
- RefPtr<MIDIAccess> midiAccess(adoptRef(new MIDIAccess(context, promise))); |
+ RefPtr<MIDIAccess> midiAccess(adoptRef(new MIDIAccess(options, context, navigator))); |
midiAccess->suspendIfNeeded(); |
- midiAccess->startRequest(); |
return midiAccess.release(); |
} |
MIDIAccess::~MIDIAccess() |
{ |
stop(); |
+ ASSERT(!m_navigator); |
} |
-MIDIAccess::MIDIAccess(ExecutionContext* context, MIDIAccessPromise* promise) |
+MIDIAccess::MIDIAccess(const MIDIOptions& options, ExecutionContext* context, NavigatorWebMIDI* navigator) |
: ActiveDOMObject(context) |
- , m_promise(promise) |
+ , m_navigator(navigator) |
+ , m_requestState(context) |
+ , m_options(options) |
, m_hasAccess(false) |
, m_sysExEnabled(false) |
, m_requesting(false) |
@@ -68,12 +73,12 @@ MIDIAccess::MIDIAccess(ExecutionContext* context, MIDIAccessPromise* promise) |
void MIDIAccess::setSysExEnabled(bool enable) |
{ |
- m_requesting = false; |
m_sysExEnabled = enable; |
if (enable) |
m_accessor->startSession(); |
else |
- permissionDenied(); |
+ reject(DOMError::create("SecurityError")); |
+ // |this| can be deleted here. |
} |
void MIDIAccess::didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version) |
@@ -94,12 +99,13 @@ void MIDIAccess::didAddOutputPort(const String& id, const String& manufacturer, |
void MIDIAccess::didStartSession(bool success) |
{ |
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")); |
+ // |this| can be deleted here. |
} |
void MIDIAccess::didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp) |
@@ -144,9 +150,12 @@ void MIDIAccess::sendMIDIData(unsigned portIndex, const unsigned char* data, siz |
void MIDIAccess::stop() |
{ |
m_hasAccess = false; |
- if (!m_requesting) |
+ if (!m_requesting) { |
+ // Since MIDIAccess is not pending, this object cannot be registered |
+ // in |m_navigator|. |
+ m_navigator = 0; |
return; |
- m_requesting = false; |
+ } |
Document* document = toDocument(executionContext()); |
ASSERT(document); |
MIDIController* controller = MIDIController::from(document->page()); |
@@ -154,31 +163,69 @@ void MIDIAccess::stop() |
controller->cancelSysExPermissionRequest(this); |
m_accessor.clear(); |
+ reject(DOMError::create("AbortError")); |
+ // |this| can be deleted here. |
} |
-void MIDIAccess::startRequest() |
+void MIDIAccess::permissionDenied() |
+{ |
+ ASSERT(isMainThread()); |
+ reject(DOMError::create("SecurityError")); |
+ // |this| can be deleted here. |
+} |
+ |
+ScriptPromise MIDIAccess::startRequest() |
{ |
- if (!m_promise->options()->sysex) { |
+ ScriptPromise promise = ScriptPromise::createPending(); |
+ m_resolver = ScriptPromiseResolver::create(promise, executionContext()); |
+ m_requesting = true; |
+ ASSERT(m_navigator); |
+ m_navigator->registerPending(this); |
+ 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")); |
+ // |this| can be deleted here. |
+ return promise; |
} |
-void MIDIAccess::permissionDenied() |
+void MIDIAccess::resolve() |
{ |
- ASSERT(isMainThread()); |
+ if (!m_requesting) |
+ return; |
+ DOMRequestState::Scope scope(m_requestState); |
+ m_hasAccess = true; |
+ m_requesting = false; |
+ // FIXME: Care about suspend / stop. |
+ m_resolver->resolve(this, executionContext()); |
+ NavigatorWebMIDI* navigator = m_navigator; |
+ m_navigator = 0; |
+ if (navigator) |
+ navigator->unregisterPending(this); |
+ // |this| can be deleted here. |
+} |
+void MIDIAccess::reject(PassRefPtr<DOMError> error) |
+{ |
+ if (!m_requesting) |
+ return; |
+ DOMRequestState::Scope scope(m_requestState); |
m_hasAccess = false; |
- m_promise->reject(DOMError::create("SecurityError")); |
+ m_requesting = false; |
+ // FIXME: Care about suspend / stop. |
+ m_resolver->reject(error, executionContext()); |
+ NavigatorWebMIDI* navigator = m_navigator; |
+ m_navigator = 0; |
+ if (navigator) |
+ navigator->unregisterPending(this); |
+ // |this| can be deleted here. |
} |
} // namespace WebCore |