Commit 363ab5a5 authored by yhirano@chromium.org's avatar yhirano@chromium.org

Decouple MIDIAccess initialization from MIDIAccess class.

Introduce a new class MIDIAccessInitializer which initializes MIDIAccess.
Previously the initialization code were on MIDIAccess itself, but this CL
decouples it.

This CL changes the various initialization-related resource ownerships.
In this CL MIDIAccessInitializer owns all initialization related resources
and when the initialization is done (no matter whether successfull or not)
it releases such resources.

Unfortunately MIDIAccess owns MIDIAccessInitializer in this CL because
there is no other natural owner of MIDIAccessInitializer.
Hopefully MIDIAccess will stop owning MIDIAccessInitializer when [1] lands.

1. https://codereview.chromium.org/311733004/

BUG=361041

Review URL: https://codereview.chromium.org/311773003

git-svn-id: svn://svn.chromium.org/blink/trunk@175952 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 86ddf6ee
...@@ -894,6 +894,8 @@ ...@@ -894,6 +894,8 @@
'webdatabase/sqlite/SQLiteTransaction.h', 'webdatabase/sqlite/SQLiteTransaction.h',
'webmidi/MIDIAccess.cpp', 'webmidi/MIDIAccess.cpp',
'webmidi/MIDIAccess.h', 'webmidi/MIDIAccess.h',
'webmidi/MIDIAccessInitializer.cpp',
'webmidi/MIDIAccessInitializer.h',
'webmidi/MIDIAccessor.cpp', 'webmidi/MIDIAccessor.cpp',
'webmidi/MIDIAccessor.h', 'webmidi/MIDIAccessor.h',
'webmidi/MIDIAccessorClient.h', 'webmidi/MIDIAccessorClient.h',
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "core/dom/Document.h" #include "core/dom/Document.h"
#include "core/loader/DocumentLoadTiming.h" #include "core/loader/DocumentLoadTiming.h"
#include "core/loader/DocumentLoader.h" #include "core/loader/DocumentLoader.h"
#include "modules/webmidi/MIDIAccessInitializer.h"
#include "modules/webmidi/MIDIConnectionEvent.h" #include "modules/webmidi/MIDIConnectionEvent.h"
#include "modules/webmidi/MIDIController.h" #include "modules/webmidi/MIDIController.h"
#include "modules/webmidi/MIDIOptions.h" #include "modules/webmidi/MIDIOptions.h"
...@@ -48,24 +49,6 @@ ...@@ -48,24 +49,6 @@
namespace WebCore { namespace WebCore {
class MIDIAccess::PostAction : public ScriptFunction {
public:
static PassOwnPtr<MIDIAccess::PostAction> create(v8::Isolate* isolate, WeakPtr<MIDIAccess> owner, State state) { return adoptPtr(new PostAction(isolate, owner, state)); }
private:
PostAction(v8::Isolate* isolate, WeakPtr<MIDIAccess> owner, State state): ScriptFunction(isolate), m_owner(owner), m_state(state) { }
virtual ScriptValue call(ScriptValue value) OVERRIDE
{
if (!m_owner.get())
return value;
m_owner->doPostAction(m_state);
return value;
}
WeakPtr<MIDIAccess> m_owner;
State m_state;
};
ScriptPromise MIDIAccess::request(const MIDIOptions& options, ScriptState* scriptState) ScriptPromise MIDIAccess::request(const MIDIOptions& options, ScriptState* scriptState)
{ {
RefPtrWillBeRawPtr<MIDIAccess> midiAccess(adoptRefWillBeRefCountedGarbageCollected(new MIDIAccess(options, scriptState->executionContext()))); RefPtrWillBeRawPtr<MIDIAccess> midiAccess(adoptRefWillBeRefCountedGarbageCollected(new MIDIAccess(options, scriptState->executionContext())));
...@@ -73,8 +56,8 @@ ScriptPromise MIDIAccess::request(const MIDIOptions& options, ScriptState* scrip ...@@ -73,8 +56,8 @@ ScriptPromise MIDIAccess::request(const MIDIOptions& options, ScriptState* scrip
// Create a wrapper to expose this object to the V8 GC so that // Create a wrapper to expose this object to the V8 GC so that
// hasPendingActivity takes effect. // hasPendingActivity takes effect.
toV8NoInline(midiAccess.get(), scriptState->context()->Global(), scriptState->isolate()); toV8NoInline(midiAccess.get(), scriptState->context()->Global(), scriptState->isolate());
// Now this object is retained because m_state equals to Requesting. // Now this object is retained because hasPending returns true.
return midiAccess->startRequest(scriptState); return midiAccess->m_initializer->initialize(scriptState);
} }
MIDIAccess::~MIDIAccess() MIDIAccess::~MIDIAccess()
...@@ -83,146 +66,80 @@ MIDIAccess::~MIDIAccess() ...@@ -83,146 +66,80 @@ MIDIAccess::~MIDIAccess()
MIDIAccess::MIDIAccess(const MIDIOptions& options, ExecutionContext* context) MIDIAccess::MIDIAccess(const MIDIOptions& options, ExecutionContext* context)
: ActiveDOMObject(context) : ActiveDOMObject(context)
, m_state(Requesting) , m_initializer(MIDIAccessInitializer::create(options, this))
, m_weakPtrFactory(this)
, m_options(options)
, m_sysexEnabled(false)
{ {
ScriptWrappable::init(this); ScriptWrappable::init(this);
m_accessor = MIDIAccessor::create(this);
}
void MIDIAccess::setSysexEnabled(bool enable)
{
m_sysexEnabled = enable;
if (enable) {
m_accessor->startSession();
} else {
m_resolver->reject(DOMError::create("SecurityError"));
}
} }
void MIDIAccess::didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version) void MIDIAccess::didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version)
{ {
ASSERT(isMainThread()); ASSERT(isMainThread());
m_inputs.append(MIDIInput::create(this, id, manufacturer, name, version)); m_inputs.append(MIDIInput::create(this, id, manufacturer, name, version));
} }
void MIDIAccess::didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version) void MIDIAccess::didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version)
{ {
ASSERT(isMainThread()); ASSERT(isMainThread());
unsigned portIndex = m_outputs.size(); unsigned portIndex = m_outputs.size();
m_outputs.append(MIDIOutput::create(this, portIndex, id, manufacturer, name, version)); m_outputs.append(MIDIOutput::create(this, portIndex, id, manufacturer, name, version));
} }
void MIDIAccess::didStartSession(bool success, const String& error, const String& message)
{
ASSERT(isMainThread());
if (success)
m_resolver->resolve(this);
else
m_resolver->reject(DOMError::create(error, message));
}
void MIDIAccess::didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp) void MIDIAccess::didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp)
{ {
ASSERT(isMainThread()); ASSERT(isMainThread());
if (portIndex >= m_inputs.size())
return;
if (m_state == Resolved && portIndex < m_inputs.size()) { // Convert from time in seconds which is based on the time coordinate system of monotonicallyIncreasingTime()
// Convert from time in seconds which is based on the time coordinate system of monotonicallyIncreasingTime() // into time in milliseconds (a DOMHighResTimeStamp) according to the same time coordinate system as performance.now().
// into time in milliseconds (a DOMHighResTimeStamp) according to the same time coordinate system as performance.now(). // This is how timestamps are defined in the Web MIDI spec.
// This is how timestamps are defined in the Web MIDI spec. Document* document = toDocument(executionContext());
Document* document = toDocument(executionContext()); ASSERT(document);
ASSERT(document);
double timeStampInMilliseconds = 1000 * document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(timeStamp); double timeStampInMilliseconds = 1000 * document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(timeStamp);
m_inputs[portIndex]->didReceiveMIDIData(portIndex, data, length, timeStampInMilliseconds); m_inputs[portIndex]->didReceiveMIDIData(portIndex, data, length, timeStampInMilliseconds);
}
} }
void MIDIAccess::sendMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStampInMilliseconds) void MIDIAccess::sendMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStampInMilliseconds)
{ {
if (m_state == Resolved && portIndex < m_outputs.size() && data && length > 0) { if (!data || !length || portIndex >= m_outputs.size())
// Convert from a time in milliseconds (a DOMHighResTimeStamp) according to the same time coordinate system as performance.now()
// into a time in seconds which is based on the time coordinate system of monotonicallyIncreasingTime().
double timeStamp;
if (!timeStampInMilliseconds) {
// We treat a value of 0 (which is the default value) as special, meaning "now".
// We need to translate it exactly to 0 seconds.
timeStamp = 0;
} else {
Document* document = toDocument(executionContext());
ASSERT(document);
double documentStartTime = document->loader()->timing()->referenceMonotonicTime();
timeStamp = documentStartTime + 0.001 * timeStampInMilliseconds;
}
m_accessor->sendMIDIData(portIndex, data, length, timeStamp);
}
}
void MIDIAccess::stop()
{
if (m_state == Stopped)
return; return;
m_accessor.clear(); // Convert from a time in milliseconds (a DOMHighResTimeStamp) according to the same time coordinate system as performance.now()
m_weakPtrFactory.revokeAll(); // into a time in seconds which is based on the time coordinate system of monotonicallyIncreasingTime().
if (m_state == Requesting) { double timeStamp;
if (!timeStampInMilliseconds) {
// We treat a value of 0 (which is the default value) as special, meaning "now".
// We need to translate it exactly to 0 seconds.
timeStamp = 0;
} else {
Document* document = toDocument(executionContext()); Document* document = toDocument(executionContext());
ASSERT(document); ASSERT(document);
MIDIController* controller = MIDIController::from(document->frame()); double documentStartTime = document->loader()->timing()->referenceMonotonicTime();
ASSERT(controller); timeStamp = documentStartTime + 0.001 * timeStampInMilliseconds;
controller->cancelSysexPermissionRequest(this);
} }
m_state = Stopped;
}
bool MIDIAccess::hasPendingActivity() const m_accessor->sendMIDIData(portIndex, data, length, timeStamp);
{
return m_state == Requesting;
} }
void MIDIAccess::permissionDenied() void MIDIAccess::stop()
{ {
ASSERT(isMainThread()); m_accessor.clear();
m_resolver->reject(DOMError::create("SecurityError")); m_initializer->cancel();
} }
ScriptPromise MIDIAccess::startRequest(ScriptState* scriptState) bool MIDIAccess::hasPendingActivity() const
{ {
m_resolver = ScriptPromiseResolverWithContext::create(scriptState); return m_initializer->hasPendingActivity();
ScriptPromise promise = m_resolver->promise();
promise.then(PostAction::create(scriptState->isolate(), m_weakPtrFactory.createWeakPtr(), Resolved),
PostAction::create(scriptState->isolate(), m_weakPtrFactory.createWeakPtr(), Stopped));
if (!m_options.sysex) {
m_accessor->startSession();
return promise;
}
Document* document = toDocument(executionContext());
ASSERT(document);
MIDIController* controller = MIDIController::from(document->frame());
if (controller) {
controller->requestSysexPermission(this);
} else {
m_resolver->reject(DOMError::create("SecurityError"));
}
return promise;
} }
void MIDIAccess::doPostAction(State state) void MIDIAccess::initialize(PassOwnPtr<MIDIAccessor> accessor, bool sysexEnabled)
{ {
ASSERT(m_state == Requesting); ASSERT(accessor);
ASSERT(state == Resolved || state == Stopped); m_accessor = accessor;
if (state == Stopped) { m_accessor->setClient(this);
m_accessor.clear(); m_sysexEnabled = sysexEnabled;
}
m_weakPtrFactory.revokeAll();
m_state = state;
} }
void MIDIAccess::trace(Visitor* visitor) void MIDIAccess::trace(Visitor* visitor)
......
...@@ -32,14 +32,12 @@ ...@@ -32,14 +32,12 @@
#define MIDIAccess_h #define MIDIAccess_h
#include "bindings/v8/ScriptPromise.h" #include "bindings/v8/ScriptPromise.h"
#include "bindings/v8/ScriptPromiseResolverWithContext.h"
#include "bindings/v8/ScriptWrappable.h" #include "bindings/v8/ScriptWrappable.h"
#include "core/dom/ActiveDOMObject.h" #include "core/dom/ActiveDOMObject.h"
#include "modules/EventTargetModules.h" #include "modules/EventTargetModules.h"
#include "modules/webmidi/MIDIAccessor.h" #include "modules/webmidi/MIDIAccessor.h"
#include "modules/webmidi/MIDIAccessorClient.h" #include "modules/webmidi/MIDIAccessorClient.h"
#include "modules/webmidi/MIDIInput.h" #include "modules/webmidi/MIDIInput.h"
#include "modules/webmidi/MIDIOptions.h"
#include "modules/webmidi/MIDIOutput.h" #include "modules/webmidi/MIDIOutput.h"
#include "platform/AsyncMethodRunner.h" #include "platform/AsyncMethodRunner.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
...@@ -50,6 +48,8 @@ ...@@ -50,6 +48,8 @@
namespace WebCore { namespace WebCore {
class ExecutionContext; class ExecutionContext;
class MIDIAccessInitializer;
struct MIDIOptions;
class MIDIAccess FINAL : public RefCountedWillBeRefCountedGarbageCollected<MIDIAccess>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MIDIAccessorClient { class MIDIAccess FINAL : public RefCountedWillBeRefCountedGarbageCollected<MIDIAccess>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MIDIAccessorClient {
REFCOUNTED_EVENT_TARGET(MIDIAccess); REFCOUNTED_EVENT_TARGET(MIDIAccess);
...@@ -65,7 +65,6 @@ public: ...@@ -65,7 +65,6 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(connect); DEFINE_ATTRIBUTE_EVENT_LISTENER(connect);
DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect); DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect);
void setSysexEnabled(bool);
bool sysexEnabled() const { return m_sysexEnabled; } bool sysexEnabled() const { return m_sysexEnabled; }
// EventTarget // EventTarget
...@@ -79,38 +78,32 @@ public: ...@@ -79,38 +78,32 @@ public:
// MIDIAccessorClient // MIDIAccessorClient
virtual void didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version) OVERRIDE; virtual void didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version) OVERRIDE;
virtual void didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version) OVERRIDE; virtual void didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version) OVERRIDE;
virtual void didStartSession(bool success, const String& error, const String& message) OVERRIDE; virtual void didStartSession(bool success, const String& error, const String& message) OVERRIDE
{
// This method is for MIDIAccess initialization: MIDIAccessInitializer
// has the implementation.
ASSERT_NOT_REACHED();
}
virtual void didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp) OVERRIDE; virtual void didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp) OVERRIDE;
// |timeStampInMilliseconds| is in the same time coordinate system as performance.now(). // |timeStampInMilliseconds| is in the same time coordinate system as performance.now().
void sendMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStampInMilliseconds); void sendMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStampInMilliseconds);
// Initialize this object before exposing it to JavaScript.
void initialize(PassOwnPtr<MIDIAccessor>, bool sysexEnabled);
virtual void trace(Visitor*) OVERRIDE; virtual void trace(Visitor*) OVERRIDE;
private: private:
class PostAction;
enum State {
Requesting,
Resolved,
Stopped,
};
MIDIAccess(const MIDIOptions&, ExecutionContext*); MIDIAccess(const MIDIOptions&, ExecutionContext*);
ScriptPromise startRequest(ScriptState*);
void permissionDenied();
// Called when the promise is resolved or rejected.
void doPostAction(State);
State m_state;
WeakPtrFactory<MIDIAccess> m_weakPtrFactory;
MIDIInputVector m_inputs; MIDIInputVector m_inputs;
MIDIOutputVector m_outputs; MIDIOutputVector m_outputs;
OwnPtr<MIDIAccessor> m_accessor; OwnPtr<MIDIAccessor> m_accessor;
MIDIOptions m_options;
bool m_sysexEnabled; bool m_sysexEnabled;
RefPtr<ScriptPromiseResolverWithContext> m_resolver;
// FIXME: Stop owning initializer in this class.
OwnPtr<MIDIAccessInitializer> m_initializer;
}; };
} // namespace WebCore } // namespace WebCore
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "modules/webmidi/MIDIAccessInitializer.h"
#include "bindings/v8/ScriptFunction.h"
#include "bindings/v8/ScriptPromise.h"
#include "bindings/v8/ScriptPromiseResolverWithContext.h"
#include "core/dom/DOMError.h"
#include "core/dom/Document.h"
#include "modules/webmidi/MIDIAccess.h"
#include "modules/webmidi/MIDIController.h"
#include "modules/webmidi/MIDIOptions.h"
namespace WebCore {
class MIDIAccessInitializer::PostAction : public ScriptFunction {
public:
static PassOwnPtr<MIDIAccessInitializer::PostAction> create(v8::Isolate* isolate, WeakPtr<MIDIAccessInitializer> owner, State state) { return adoptPtr(new PostAction(isolate, owner, state)); }
private:
PostAction(v8::Isolate* isolate, WeakPtr<MIDIAccessInitializer> owner, State state): ScriptFunction(isolate), m_owner(owner), m_state(state) { }
virtual ScriptValue call(ScriptValue value) OVERRIDE
{
if (!m_owner.get())
return value;
m_owner->doPostAction(m_state);
return value;
}
WeakPtr<MIDIAccessInitializer> m_owner;
State m_state;
};
MIDIAccessInitializer::~MIDIAccessInitializer()
{
ASSERT(m_state != Requesting);
}
MIDIAccessInitializer::MIDIAccessInitializer(const MIDIOptions& options, MIDIAccess* access)
: m_state(Requesting)
, m_weakPtrFactory(this)
, m_options(options)
, m_sysexEnabled(false)
, m_access(access)
{
m_accessor = MIDIAccessor::create(this);
}
void MIDIAccessInitializer::didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version)
{
m_access->didAddInputPort(id, manufacturer, name, version);
}
void MIDIAccessInitializer::didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version)
{
m_access->didAddOutputPort(id, manufacturer, name, version);
}
void MIDIAccessInitializer::didStartSession(bool success, const String& error, const String& message)
{
if (success)
m_resolver->resolve(m_access);
else
m_resolver->reject(DOMError::create(error, message));
}
void MIDIAccessInitializer::setSysexEnabled(bool enable)
{
m_sysexEnabled = enable;
if (enable)
m_accessor->startSession();
else
m_resolver->reject(DOMError::create("SecurityError"));
}
SecurityOrigin* MIDIAccessInitializer::securityOrigin() const
{
return m_access->executionContext()->securityOrigin();
}
void MIDIAccessInitializer::cancel()
{
if (m_state != Requesting)
return;
m_accessor.clear();
m_weakPtrFactory.revokeAll();
Document* document = toDocument(executionContext());
ASSERT(document);
MIDIController* controller = MIDIController::from(document->frame());
ASSERT(controller);
controller->cancelSysexPermissionRequest(this);
m_state = Stopped;
}
ExecutionContext* MIDIAccessInitializer::executionContext() const
{
return m_access->executionContext();
}
void MIDIAccessInitializer::permissionDenied()
{
ASSERT(isMainThread());
m_resolver->reject(DOMError::create("SecurityError"));
}
ScriptPromise MIDIAccessInitializer::initialize(ScriptState* scriptState)
{
m_resolver = ScriptPromiseResolverWithContext::create(scriptState);
ScriptPromise promise = m_resolver->promise();
promise.then(PostAction::create(scriptState->isolate(), m_weakPtrFactory.createWeakPtr(), Resolved),
PostAction::create(scriptState->isolate(), m_weakPtrFactory.createWeakPtr(), Stopped));
if (!m_options.sysex) {
m_accessor->startSession();
return promise;
}
Document* document = toDocument(executionContext());
ASSERT(document);
MIDIController* controller = MIDIController::from(document->frame());
if (controller) {
controller->requestSysexPermission(this);
} else {
m_resolver->reject(DOMError::create("SecurityError"));
}
return promise;
}
void MIDIAccessInitializer::doPostAction(State state)
{
ASSERT(m_state == Requesting);
ASSERT(state == Resolved || state == Stopped);
if (state == Resolved) {
m_access->initialize(m_accessor.release(), m_sysexEnabled);
}
m_accessor.clear();
m_weakPtrFactory.revokeAll();
m_state = state;
}
} // namespace WebCore
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MIDIAccessInitializer_h
#define MIDIAccessInitializer_h
#include "bindings/v8/ScriptPromise.h"
#include "modules/webmidi/MIDIAccessor.h"
#include "modules/webmidi/MIDIAccessorClient.h"
#include "modules/webmidi/MIDIOptions.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
class MIDIAccess;
class ScriptState;
class ScriptPromiseResolverWithContext;
class MIDIAccessInitializer : public MIDIAccessorClient {
public:
static PassOwnPtr<MIDIAccessInitializer> create(const MIDIOptions& options, MIDIAccess* access)
{
return adoptPtr(new MIDIAccessInitializer(options, access));
}
virtual ~MIDIAccessInitializer();
ScriptPromise initialize(ScriptState*);
void cancel();
bool hasPendingActivity() const { return m_state == Requesting; }
// MIDIAccessorClient
virtual void didAddInputPort(const String& id, const String& manufacturer, const String& name, const String& version) OVERRIDE;
virtual void didAddOutputPort(const String& id, const String& manufacturer, const String& name, const String& version) OVERRIDE;
virtual void didStartSession(bool success, const String& error, const String& message) OVERRIDE;
virtual void didReceiveMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp) OVERRIDE { }
void setSysexEnabled(bool value);
SecurityOrigin* securityOrigin() const;
private:
class PostAction;
enum State {
Requesting,
Resolved,
Stopped,
};
MIDIAccessInitializer(const MIDIOptions&, MIDIAccess*);
ExecutionContext* executionContext() const;
void permissionDenied();
void doPostAction(State);
State m_state;
WeakPtrFactory<MIDIAccessInitializer> m_weakPtrFactory;
RefPtr<ScriptPromiseResolverWithContext> m_resolver;
OwnPtr<MIDIAccessor> m_accessor;
MIDIOptions m_options;
bool m_sysexEnabled;
// m_access has this object, so it's safe to have the raw pointer.
MIDIAccess* m_access;
};
} // namespace WebCore
#endif // MIDIAccessInitializer_h
...@@ -48,6 +48,10 @@ public: ...@@ -48,6 +48,10 @@ public:
void startSession(); void startSession();
void sendMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp); void sendMIDIData(unsigned portIndex, const unsigned char* data, size_t length, double timeStamp);
// MIDIAccessInitializer and MIDIAccess are both MIDIAccessClient.
// MIDIAccessInitializer is the first client and MIDIAccess takes over it
// once the initialization successfully finishes.
void setClient(MIDIAccessorClient* client) { m_client = client; }
// blink::WebMIDIAccessorClient // blink::WebMIDIAccessorClient
virtual void didAddInputPort(const blink::WebString& id, const blink::WebString& manufacturer, const blink::WebString& name, const blink::WebString& version) OVERRIDE; virtual void didAddInputPort(const blink::WebString& id, const blink::WebString& manufacturer, const blink::WebString& name, const blink::WebString& version) OVERRIDE;
......
...@@ -36,12 +36,12 @@ ...@@ -36,12 +36,12 @@
namespace WebCore { namespace WebCore {
class LocalFrame; class LocalFrame;
class MIDIAccess; class MIDIAccessInitializer;
class MIDIClient { class MIDIClient {
public: public:
virtual void requestSysexPermission(PassRefPtrWillBeRawPtr<MIDIAccess>) = 0; virtual void requestSysexPermission(MIDIAccessInitializer*) = 0;
virtual void cancelSysexPermissionRequest(MIDIAccess*) = 0; virtual void cancelSysexPermissionRequest(MIDIAccessInitializer*) = 0;
virtual ~MIDIClient() { } virtual ~MIDIClient() { }
}; };
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "config.h" #include "config.h"
#include "modules/webmidi/MIDIClientMock.h" #include "modules/webmidi/MIDIClientMock.h"
#include "modules/webmidi/MIDIAccess.h" #include "modules/webmidi/MIDIAccessInitializer.h"
namespace WebCore { namespace WebCore {
...@@ -54,12 +54,12 @@ void MIDIClientMock::resetMock() ...@@ -54,12 +54,12 @@ void MIDIClientMock::resetMock()
m_allowed = false; m_allowed = false;
} }
void MIDIClientMock::requestSysexPermission(PassRefPtrWillBeRawPtr<MIDIAccess> access) void MIDIClientMock::requestSysexPermission(MIDIAccessInitializer* initializer)
{ {
access->setSysexEnabled(m_allowed); initializer->setSysexEnabled(m_allowed);
} }
void MIDIClientMock::cancelSysexPermissionRequest(MIDIAccess*) void MIDIClientMock::cancelSysexPermissionRequest(MIDIAccessInitializer*)
{ {
} }
......
...@@ -46,8 +46,8 @@ public: ...@@ -46,8 +46,8 @@ public:
void resetMock(); void resetMock();
// MIDIClient // MIDIClient
virtual void requestSysexPermission(PassRefPtrWillBeRawPtr<MIDIAccess>) OVERRIDE; virtual void requestSysexPermission(MIDIAccessInitializer*) OVERRIDE;
virtual void cancelSysexPermissionRequest(MIDIAccess*) OVERRIDE; virtual void cancelSysexPermissionRequest(MIDIAccessInitializer*) OVERRIDE;
private: private:
bool m_allowed; bool m_allowed;
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "config.h" #include "config.h"
#include "modules/webmidi/MIDIController.h" #include "modules/webmidi/MIDIController.h"
#include "modules/webmidi/MIDIAccess.h" #include "modules/webmidi/MIDIAccessInitializer.h"
#include "modules/webmidi/MIDIClient.h" #include "modules/webmidi/MIDIClient.h"
namespace WebCore { namespace WebCore {
...@@ -56,14 +56,14 @@ PassOwnPtrWillBeRawPtr<MIDIController> MIDIController::create(PassOwnPtr<MIDICli ...@@ -56,14 +56,14 @@ PassOwnPtrWillBeRawPtr<MIDIController> MIDIController::create(PassOwnPtr<MIDICli
return adoptPtrWillBeNoop(new MIDIController(client)); return adoptPtrWillBeNoop(new MIDIController(client));
} }
void MIDIController::requestSysexPermission(PassRefPtrWillBeRawPtr<MIDIAccess> access) void MIDIController::requestSysexPermission(MIDIAccessInitializer* initializer)
{ {
m_client->requestSysexPermission(access); m_client->requestSysexPermission(initializer);
} }
void MIDIController::cancelSysexPermissionRequest(MIDIAccess* access) void MIDIController::cancelSysexPermissionRequest(MIDIAccessInitializer* initializer)
{ {
m_client->cancelSysexPermissionRequest(access); m_client->cancelSysexPermissionRequest(initializer);
} }
void provideMIDITo(LocalFrame& frame, PassOwnPtr<MIDIClient> client) void provideMIDITo(LocalFrame& frame, PassOwnPtr<MIDIClient> client)
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
namespace WebCore { namespace WebCore {
class MIDIAccess; class MIDIAccessInitializer;
class MIDIClient; class MIDIClient;
class MIDIController FINAL : public NoBaseWillBeGarbageCollectedFinalized<MIDIController>, public WillBeHeapSupplement<LocalFrame> { class MIDIController FINAL : public NoBaseWillBeGarbageCollectedFinalized<MIDIController>, public WillBeHeapSupplement<LocalFrame> {
...@@ -44,8 +44,8 @@ class MIDIController FINAL : public NoBaseWillBeGarbageCollectedFinalized<MIDICo ...@@ -44,8 +44,8 @@ class MIDIController FINAL : public NoBaseWillBeGarbageCollectedFinalized<MIDICo
public: public:
virtual ~MIDIController(); virtual ~MIDIController();
void requestSysexPermission(PassRefPtrWillBeRawPtr<MIDIAccess>); void requestSysexPermission(MIDIAccessInitializer*);
void cancelSysexPermissionRequest(MIDIAccess*); void cancelSysexPermissionRequest(MIDIAccessInitializer*);
static PassOwnPtrWillBeRawPtr<MIDIController> create(PassOwnPtr<MIDIClient>); static PassOwnPtrWillBeRawPtr<MIDIController> create(PassOwnPtr<MIDIClient>);
static const char* supplementName(); static const char* supplementName();
......
...@@ -31,12 +31,10 @@ ...@@ -31,12 +31,10 @@
#include "config.h" #include "config.h"
#include "web/MIDIClientProxy.h" #include "web/MIDIClientProxy.h"
#include "modules/webmidi/MIDIAccess.h" #include "modules/webmidi/MIDIAccessInitializer.h"
#include "public/web/WebMIDIClient.h" #include "public/web/WebMIDIClient.h"
#include "public/web/WebMIDIPermissionRequest.h" #include "public/web/WebMIDIPermissionRequest.h"
using WebCore::MIDIAccess;
namespace blink { namespace blink {
MIDIClientProxy::MIDIClientProxy(WebMIDIClient* client) MIDIClientProxy::MIDIClientProxy(WebMIDIClient* client)
...@@ -44,18 +42,18 @@ MIDIClientProxy::MIDIClientProxy(WebMIDIClient* client) ...@@ -44,18 +42,18 @@ MIDIClientProxy::MIDIClientProxy(WebMIDIClient* client)
{ {
} }
void MIDIClientProxy::requestSysexPermission(PassRefPtrWillBeRawPtr<MIDIAccess> access) void MIDIClientProxy::requestSysexPermission(WebCore::MIDIAccessInitializer* initializer)
{ {
if (m_client) if (m_client)
m_client->requestSysexPermission(WebMIDIPermissionRequest(access)); m_client->requestSysexPermission(WebMIDIPermissionRequest(initializer));
else else
access->setSysexEnabled(false); initializer->setSysexEnabled(false);
} }
void MIDIClientProxy::cancelSysexPermissionRequest(MIDIAccess* access) void MIDIClientProxy::cancelSysexPermissionRequest(WebCore::MIDIAccessInitializer* initializer)
{ {
if (m_client) if (m_client)
m_client->cancelSysexPermissionRequest(WebMIDIPermissionRequest(access)); m_client->cancelSysexPermissionRequest(WebMIDIPermissionRequest(initializer));
} }
} // namespace blink } // namespace blink
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
namespace WebCore { namespace WebCore {
class MIDIAccess; class MIDIAccessInitializer;
} }
namespace blink { namespace blink {
...@@ -50,8 +50,8 @@ public: ...@@ -50,8 +50,8 @@ public:
} }
// WebCore::MIDIClient // WebCore::MIDIClient
virtual void requestSysexPermission(PassRefPtrWillBeRawPtr<WebCore::MIDIAccess>) OVERRIDE; virtual void requestSysexPermission(WebCore::MIDIAccessInitializer*) OVERRIDE;
virtual void cancelSysexPermissionRequest(WebCore::MIDIAccess*) OVERRIDE; virtual void cancelSysexPermissionRequest(WebCore::MIDIAccessInitializer*) OVERRIDE;
private: private:
explicit MIDIClientProxy(WebMIDIClient*); explicit MIDIClientProxy(WebMIDIClient*);
......
...@@ -54,12 +54,12 @@ void WebMIDIClientMock::resetMock() ...@@ -54,12 +54,12 @@ void WebMIDIClientMock::resetMock()
void WebMIDIClientMock::requestSysexPermission(const WebMIDIPermissionRequest& request) void WebMIDIClientMock::requestSysexPermission(const WebMIDIPermissionRequest& request)
{ {
m_clientMock->requestSysexPermission(request.midiAccess()); m_clientMock->requestSysexPermission(request.midiAccessInitializer());
} }
void WebMIDIClientMock::cancelSysexPermissionRequest(const WebMIDIPermissionRequest& request) void WebMIDIClientMock::cancelSysexPermissionRequest(const WebMIDIPermissionRequest& request)
{ {
m_clientMock->cancelSysexPermissionRequest(request.midiAccess()); m_clientMock->cancelSysexPermissionRequest(request.midiAccessInitializer());
} }
void WebMIDIClientMock::reset() void WebMIDIClientMock::reset()
......
...@@ -31,43 +31,30 @@ ...@@ -31,43 +31,30 @@
#include "config.h" #include "config.h"
#include "public/web/WebMIDIPermissionRequest.h" #include "public/web/WebMIDIPermissionRequest.h"
#include "core/dom/Document.h" #include "modules/webmidi/MIDIAccessInitializer.h"
#include "modules/webmidi/MIDIAccess.h"
#include "platform/weborigin/SecurityOrigin.h" #include "platform/weborigin/SecurityOrigin.h"
#include "public/web/WebSecurityOrigin.h" #include "public/web/WebSecurityOrigin.h"
using namespace WebCore;
namespace blink { namespace blink {
WebMIDIPermissionRequest::WebMIDIPermissionRequest(const PassRefPtrWillBeRawPtr<WebCore::MIDIAccess>& midi) WebMIDIPermissionRequest::WebMIDIPermissionRequest(WebCore::MIDIAccessInitializer* initializer)
: m_private(midi) : m_initializer(initializer)
{
}
void WebMIDIPermissionRequest::reset()
{
m_private.reset();
}
void WebMIDIPermissionRequest::assign(const WebMIDIPermissionRequest& other)
{ {
m_private = other.m_private;
} }
bool WebMIDIPermissionRequest::equals(const WebMIDIPermissionRequest& n) const bool WebMIDIPermissionRequest::equals(const WebMIDIPermissionRequest& n) const
{ {
return m_private.get() == n.m_private.get(); return m_initializer == n.m_initializer;
} }
WebSecurityOrigin WebMIDIPermissionRequest::securityOrigin() const WebSecurityOrigin WebMIDIPermissionRequest::securityOrigin() const
{ {
return WebSecurityOrigin(m_private->executionContext()->securityOrigin()); return WebSecurityOrigin(m_initializer->securityOrigin());
} }
void WebMIDIPermissionRequest::setIsAllowed(bool allowed) void WebMIDIPermissionRequest::setIsAllowed(bool allowed)
{ {
m_private->setSysexEnabled(allowed); m_initializer->setSysexEnabled(allowed);
} }
} // namespace blink } // namespace blink
...@@ -38,10 +38,17 @@ class WebMIDIClient { ...@@ -38,10 +38,17 @@ class WebMIDIClient {
public: public:
virtual ~WebMIDIClient() { } virtual ~WebMIDIClient() { }
// Request a permission to use system exclusive messages. Called when MIDIOptions.sysex is true. // Request a permission to use system exclusive messages. Called when
virtual void requestSysexPermission(const WebMIDIPermissionRequest&) = 0; // MIDIOptions.sysex is true.
// Cancel the request since the requesting frame may be moving to a new page. // Once the request is done, any WebMIDIPermissionRequest instances equal to
virtual void cancelSysexPermissionRequest(const WebMIDIPermissionRequest&) = 0; // |request| must not be accessed after that.
virtual void requestSysexPermission(const WebMIDIPermissionRequest& /* request */) = 0;
// Cancel the request since the requesting frame may be moving to
// a new page.
// Once canceled, any WebMIDIPermissionRequest instances equal to
// |request| must not be accessed after that.
virtual void cancelSysexPermissionRequest(const WebMIDIPermissionRequest& /* request */) = 0;
}; };
} // namespace blink } // namespace blink
......
...@@ -32,41 +32,37 @@ ...@@ -32,41 +32,37 @@
#define WebMIDIPermissionRequest_h #define WebMIDIPermissionRequest_h
#include "../platform/WebCommon.h" #include "../platform/WebCommon.h"
#include "../platform/WebPrivatePtr.h"
namespace WebCore { namespace WebCore {
class MIDIAccess; class MIDIAccessInitializer;
} }
namespace blink { namespace blink {
class WebSecurityOrigin; class WebSecurityOrigin;
// WebMIDIPermissionRequest encapsulates a WebCore MIDIAccess object and represents // WebMIDIPermissionRequest encapsulates a WebCore MIDIAccessInitializer
// a request from WebCore for permissions. // object and represents a request from WebCore for permissions.
// The underlying MIDIAccess object is guaranteed to be valid until the invocation of // The request must not outlive the underlying initializer object.
// either WebMIDIPermissionRequest::setIsAllowed (request complete) or // In other words, the request must be canceled when the underlying
// WebMIDIClient::cancelPermissionRequest (request canceled). // initializer dies while requesting,
class WebMIDIPermissionRequest { class WebMIDIPermissionRequest {
public: public:
WebMIDIPermissionRequest(const WebMIDIPermissionRequest& o) { assign(o); } BLINK_EXPORT WebMIDIPermissionRequest(const WebMIDIPermissionRequest& other)
~WebMIDIPermissionRequest() { reset(); }; : m_initializer(other.m_initializer) { }
BLINK_EXPORT WebSecurityOrigin securityOrigin() const; BLINK_EXPORT WebSecurityOrigin securityOrigin() const;
BLINK_EXPORT void setIsAllowed(bool); BLINK_EXPORT void setIsAllowed(bool);
BLINK_EXPORT void reset();
BLINK_EXPORT void assign(const WebMIDIPermissionRequest&);
BLINK_EXPORT bool equals(const WebMIDIPermissionRequest&) const; BLINK_EXPORT bool equals(const WebMIDIPermissionRequest&) const;
#if BLINK_IMPLEMENTATION #if BLINK_IMPLEMENTATION
explicit WebMIDIPermissionRequest(const PassRefPtrWillBeRawPtr<WebCore::MIDIAccess>&); explicit WebMIDIPermissionRequest(WebCore::MIDIAccessInitializer*);
WebCore::MIDIAccess* midiAccess() const { return m_private.get(); } WebCore::MIDIAccessInitializer* midiAccessInitializer() const { return m_initializer; }
#endif #endif
private: private:
WebPrivatePtr<WebCore::MIDIAccess> m_private; WebCore::MIDIAccessInitializer* m_initializer;
}; };
inline bool operator==(const WebMIDIPermissionRequest& a, const WebMIDIPermissionRequest& b) inline bool operator==(const WebMIDIPermissionRequest& a, const WebMIDIPermissionRequest& b)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment