OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/media/midi_host.h" | 5 #include "content/browser/media/midi_host.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/process/process.h" | 10 #include "base/process/process.h" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 | 45 |
46 } // namespace | 46 } // namespace |
47 | 47 |
48 using media::kSysExByte; | 48 using media::kSysExByte; |
49 using media::kEndOfSysExByte; | 49 using media::kEndOfSysExByte; |
50 | 50 |
51 MidiHost::MidiHost(int renderer_process_id, media::MidiManager* midi_manager) | 51 MidiHost::MidiHost(int renderer_process_id, media::MidiManager* midi_manager) |
52 : BrowserMessageFilter(MidiMsgStart), | 52 : BrowserMessageFilter(MidiMsgStart), |
53 renderer_process_id_(renderer_process_id), | 53 renderer_process_id_(renderer_process_id), |
54 has_sys_ex_permission_(false), | 54 has_sys_ex_permission_(false), |
| 55 is_session_requested_(false), |
55 midi_manager_(midi_manager), | 56 midi_manager_(midi_manager), |
56 sent_bytes_in_flight_(0), | 57 sent_bytes_in_flight_(0), |
57 bytes_sent_since_last_acknowledgement_(0) { | 58 bytes_sent_since_last_acknowledgement_(0) { |
| 59 CHECK(midi_manager_); |
58 } | 60 } |
59 | 61 |
60 MidiHost::~MidiHost() { | 62 MidiHost::~MidiHost() { |
61 if (midi_manager_) | 63 // Close an open session, or abort opening a session. |
| 64 if (is_session_requested_) |
62 midi_manager_->EndSession(this); | 65 midi_manager_->EndSession(this); |
63 } | 66 } |
64 | 67 |
65 void MidiHost::OnDestruct() const { | 68 void MidiHost::OnDestruct() const { |
66 BrowserThread::DeleteOnIOThread::Destruct(this); | 69 BrowserThread::DeleteOnIOThread::Destruct(this); |
67 } | 70 } |
68 | 71 |
69 // IPC Messages handler | 72 // IPC Messages handler |
70 bool MidiHost::OnMessageReceived(const IPC::Message& message) { | 73 bool MidiHost::OnMessageReceived(const IPC::Message& message) { |
71 bool handled = true; | 74 bool handled = true; |
72 IPC_BEGIN_MESSAGE_MAP(MidiHost, message) | 75 IPC_BEGIN_MESSAGE_MAP(MidiHost, message) |
73 IPC_MESSAGE_HANDLER(MidiHostMsg_StartSession, OnStartSession) | 76 IPC_MESSAGE_HANDLER(MidiHostMsg_StartSession, OnStartSession) |
74 IPC_MESSAGE_HANDLER(MidiHostMsg_SendData, OnSendData) | 77 IPC_MESSAGE_HANDLER(MidiHostMsg_SendData, OnSendData) |
| 78 IPC_MESSAGE_HANDLER(MidiHostMsg_EndSession, OnEndSession) |
75 IPC_MESSAGE_UNHANDLED(handled = false) | 79 IPC_MESSAGE_UNHANDLED(handled = false) |
76 IPC_END_MESSAGE_MAP() | 80 IPC_END_MESSAGE_MAP() |
77 | 81 |
78 return handled; | 82 return handled; |
79 } | 83 } |
80 | 84 |
81 void MidiHost::OnStartSession(int client_id) { | 85 void MidiHost::OnStartSession() { |
82 if (midi_manager_) | 86 is_session_requested_ = true; |
83 midi_manager_->StartSession(this, client_id); | 87 midi_manager_->StartSession(this); |
84 } | 88 } |
85 | 89 |
86 void MidiHost::OnSendData(uint32 port, | 90 void MidiHost::OnSendData(uint32 port, |
87 const std::vector<uint8>& data, | 91 const std::vector<uint8>& data, |
88 double timestamp) { | 92 double timestamp) { |
89 if (!midi_manager_) | |
90 return; | |
91 | |
92 if (data.empty()) | 93 if (data.empty()) |
93 return; | 94 return; |
94 | 95 |
95 // Blink running in a renderer checks permission to raise a SecurityError | 96 // Blink running in a renderer checks permission to raise a SecurityError |
96 // in JavaScript. The actual permission check for security purposes | 97 // in JavaScript. The actual permission check for security purposes |
97 // happens here in the browser process. | 98 // happens here in the browser process. |
98 if (!has_sys_ex_permission_ && | 99 if (!has_sys_ex_permission_ && |
99 std::find(data.begin(), data.end(), kSysExByte) != data.end()) { | 100 std::find(data.begin(), data.end(), kSysExByte) != data.end()) { |
100 RecordAction(base::UserMetricsAction("BadMessageTerminate_MIDI")); | 101 RecordAction(base::UserMetricsAction("BadMessageTerminate_MIDI")); |
101 BadMessageReceived(); | 102 BadMessageReceived(); |
102 return; | 103 return; |
103 } | 104 } |
104 | 105 |
105 if (!IsValidWebMIDIData(data)) | 106 if (!IsValidWebMIDIData(data)) |
106 return; | 107 return; |
107 | 108 |
108 { | 109 { |
109 base::AutoLock auto_lock(in_flight_lock_); | 110 base::AutoLock auto_lock(in_flight_lock_); |
110 // Sanity check that we won't send too much data. | 111 // Sanity check that we won't send too much data. |
111 // TODO(yukawa): Consider to send an error event back to the renderer | 112 // TODO(yukawa): Consider to send an error event back to the renderer |
112 // after some future discussion in W3C. | 113 // after some future discussion in W3C. |
113 if (data.size() + sent_bytes_in_flight_ > kMaxInFlightBytes) | 114 if (data.size() + sent_bytes_in_flight_ > kMaxInFlightBytes) |
114 return; | 115 return; |
115 sent_bytes_in_flight_ += data.size(); | 116 sent_bytes_in_flight_ += data.size(); |
116 } | 117 } |
117 midi_manager_->DispatchSendMidiData(this, port, data, timestamp); | 118 midi_manager_->DispatchSendMidiData(this, port, data, timestamp); |
118 } | 119 } |
119 | 120 |
120 void MidiHost::CompleteStartSession(int client_id, media::MidiResult result) { | 121 void MidiHost::OnEndSession() { |
| 122 is_session_requested_ = false; |
| 123 midi_manager_->EndSession(this); |
| 124 } |
| 125 |
| 126 void MidiHost::CompleteStartSession(media::MidiResult result) { |
| 127 DCHECK(is_session_requested_); |
121 MidiPortInfoList input_ports; | 128 MidiPortInfoList input_ports; |
122 MidiPortInfoList output_ports; | 129 MidiPortInfoList output_ports; |
123 | 130 |
124 if (result == media::MIDI_OK) { | 131 if (result == media::MIDI_OK) { |
125 input_ports = midi_manager_->input_ports(); | 132 input_ports = midi_manager_->input_ports(); |
126 output_ports = midi_manager_->output_ports(); | 133 output_ports = midi_manager_->output_ports(); |
127 received_messages_queues_.clear(); | 134 received_messages_queues_.clear(); |
128 received_messages_queues_.resize(input_ports.size()); | 135 received_messages_queues_.resize(input_ports.size()); |
129 // ChildSecurityPolicy is set just before OnStartSession by | 136 // ChildSecurityPolicy is set just before OnStartSession by |
130 // MidiDispatcherHost. So we can safely cache the policy. | 137 // MidiDispatcherHost. So we can safely cache the policy. |
131 has_sys_ex_permission_ = ChildProcessSecurityPolicyImpl::GetInstance()-> | 138 has_sys_ex_permission_ = ChildProcessSecurityPolicyImpl::GetInstance()-> |
132 CanSendMidiSysExMessage(renderer_process_id_); | 139 CanSendMidiSysExMessage(renderer_process_id_); |
133 } | 140 } |
134 | 141 |
135 Send(new MidiMsg_SessionStarted(client_id, | 142 Send(new MidiMsg_SessionStarted(result, |
136 result, | |
137 input_ports, | 143 input_ports, |
138 output_ports)); | 144 output_ports)); |
139 } | 145 } |
140 | 146 |
141 void MidiHost::ReceiveMidiData( | 147 void MidiHost::ReceiveMidiData( |
142 uint32 port, | 148 uint32 port, |
143 const uint8* data, | 149 const uint8* data, |
144 size_t length, | 150 size_t length, |
145 double timestamp) { | 151 double timestamp) { |
146 TRACE_EVENT0("midi", "MidiHost::ReceiveMidiData"); | 152 TRACE_EVENT0("midi", "MidiHost::ReceiveMidiData"); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 } | 222 } |
217 waiting_data_length = media::GetMidiMessageLength(current); | 223 waiting_data_length = media::GetMidiMessageLength(current); |
218 if (waiting_data_length == 0) | 224 if (waiting_data_length == 0) |
219 return false; // Error: |current| should have been a valid status byte. | 225 return false; // Error: |current| should have been a valid status byte. |
220 --waiting_data_length; // Found status byte | 226 --waiting_data_length; // Found status byte |
221 } | 227 } |
222 return waiting_data_length == 0 && !in_sysex; | 228 return waiting_data_length == 0 && !in_sysex; |
223 } | 229 } |
224 | 230 |
225 } // namespace content | 231 } // namespace content |
OLD | NEW |