Chromium Code Reviews| Index: Source/modules/webmidi/MIDIPort.cpp |
| diff --git a/Source/modules/webmidi/MIDIPort.cpp b/Source/modules/webmidi/MIDIPort.cpp |
| index 519de7fa4cc98b9707f8da8b4ae30b82768f1b8a..3fc72a648e0f492a693a89adf9bbbbe909ed1bc9 100644 |
| --- a/Source/modules/webmidi/MIDIPort.cpp |
| +++ b/Source/modules/webmidi/MIDIPort.cpp |
| @@ -40,37 +40,48 @@ namespace blink { |
| using PortState = MIDIAccessor::MIDIPortState; |
| -MIDIPort::MIDIPort(MIDIAccess* access, const String& id, const String& manufacturer, const String& name, MIDIPortTypeCode type, const String& version, PortState state) |
| +MIDIPort::MIDIPort(MIDIAccess* access, const String& id, const String& manufacturer, const String& name, TypeCode type, const String& version, PortState state) |
| : m_id(id) |
| , m_manufacturer(manufacturer) |
| , m_name(name) |
| , m_type(type) |
| , m_version(version) |
| , m_access(access) |
| + , m_connection(ConnectionStateClosed) |
| { |
| ASSERT(access); |
| - ASSERT(type == MIDIPortTypeInput || type == MIDIPortTypeOutput); |
| + ASSERT(type == TypeInput || type == TypeOutput); |
| ASSERT(state == PortState::MIDIPortStateDisconnected |
| || state == PortState::MIDIPortStateConnected |
| || state == PortState::MIDIPortStateOpened); |
| - // FIXME: Remove following code once blink API has a real open and close |
| - // operations. |
| + // TODO(toyoshim): Remove following code once blink API has a real open and |
| + // close operations. |
| if (state == PortState::MIDIPortStateOpened) |
| state = PortState::MIDIPortStateConnected; |
| m_state = state; |
| } |
| +String MIDIPort::connection() const |
| +{ |
| + switch (m_connection) { |
| + case ConnectionStateOpen: |
| + return "open"; |
| + case ConnectionStateClosed: |
| + return "closed"; |
| + case ConnectionStatePending: |
| + return "pending"; |
| + } |
| + return emptyString(); |
| +} |
| + |
| String MIDIPort::state() const |
| { |
| switch (m_state) { |
| case PortState::MIDIPortStateDisconnected: |
| return "disconnected"; |
| case PortState::MIDIPortStateConnected: |
| - return "connected"; |
| case PortState::MIDIPortStateOpened: |
| - return "opened"; |
| - default: |
| - ASSERT_NOT_REACHED(); |
| + return "connected"; |
| } |
| return emptyString(); |
| } |
| @@ -78,28 +89,25 @@ String MIDIPort::state() const |
| String MIDIPort::type() const |
| { |
| switch (m_type) { |
| - case MIDIPortTypeInput: |
| + case TypeInput: |
| return "input"; |
| - case MIDIPortTypeOutput: |
| + case TypeOutput: |
| return "output"; |
| - default: |
| - ASSERT_NOT_REACHED(); |
| } |
| return emptyString(); |
| } |
| ScriptPromise MIDIPort::open(ScriptState* scriptState) |
| { |
| + // TODO(toyoshim): Implement the latest open() algorithm. |
| switch (m_state) { |
| case PortState::MIDIPortStateDisconnected: |
| return reject(scriptState, InvalidStateError, "The port has been disconnected."); |
| case PortState::MIDIPortStateConnected: |
| - // FIXME: Add blink API to perform a real open operation. |
| - setState(PortState::MIDIPortStateOpened); |
| - // fall through |
| + // TODO(toyoshim): Add blink API to perform a real open operation. |
| + return setStates(m_state, ConnectionStateOpen)->accept(scriptState); |
| case PortState::MIDIPortStateOpened: |
| - return accept(scriptState); |
| - default: |
| + // TODO(toyoshim): Remove PortState::MIDIPortStateOpened. |
| ASSERT_NOT_REACHED(); |
| } |
| return reject(scriptState, InvalidStateError, "The port is in unknown state."); |
| @@ -107,16 +115,15 @@ ScriptPromise MIDIPort::open(ScriptState* scriptState) |
| ScriptPromise MIDIPort::close(ScriptState* scriptState) |
| { |
| + // TODO(toyoshim): Implement the latest close() algorithm. |
| switch (m_state) { |
| case PortState::MIDIPortStateDisconnected: |
| return reject(scriptState, InvalidStateError, "The port has been disconnected."); |
| - case PortState::MIDIPortStateOpened: |
| - // FIXME: Add blink API to perform a real close operation. |
| - setState(PortState::MIDIPortStateConnected); |
| - // fall through |
| case PortState::MIDIPortStateConnected: |
| - return accept(scriptState); |
| - default: |
| + // TODO(toyoshim): Add blink API to perform a real close operation. |
| + return setStates(m_state, ConnectionStateClosed)->accept(scriptState); |
| + case PortState::MIDIPortStateOpened: |
| + // TODO(toyoshim): Remove PortState::MIDIPortStateOpened. |
| ASSERT_NOT_REACHED(); |
| } |
| return reject(scriptState, InvalidStateError, "The port is in unknown state."); |
| @@ -124,10 +131,7 @@ ScriptPromise MIDIPort::close(ScriptState* scriptState) |
| void MIDIPort::setState(PortState state) |
| { |
| - if (m_state == state) |
| - return; |
| - m_state = state; |
| - dispatchEvent(MIDIConnectionEvent::create(this)); |
| + setStates(state, m_connection); |
| } |
| ExecutionContext* MIDIPort::executionContext() const |
| @@ -151,4 +155,19 @@ ScriptPromise MIDIPort::reject(ScriptState* scriptState, ExceptionCode ec, const |
| return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(ec, message)); |
| } |
| +// Note: setStates() dispatches a event and JavaScript may release this object |
| +// inside the handler. Caller should consider to retain |this|. |
| +MIDIPort* MIDIPort::setStates(PortState state, ConnectionState connection) |
| +{ |
| + // Retain |this| since an event handler may release it inside setStates(). |
| + MIDIPort* self = this; |
|
tkent
2015/03/31 01:26:10
Ah, MIDIPort is already on Oilpan. Then you need
yhirano
2015/03/31 02:23:37
But I think we should protect the wrapper in order
|
| + |
| + if (m_state == state && m_connection == connection) |
| + return self; |
| + m_state = state; |
| + m_connection = connection; |
| + dispatchEvent(MIDIConnectionEvent::create(this)); |
| + return self; |
| +} |
| + |
| } // namespace blink |