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/renderer/media/midi_message_filter.h" | 5 #include "content/renderer/media/midi_message_filter.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 // successfully sent. | 21 // successfully sent. |
22 static const size_t kMaxUnacknowledgedBytesSent = 10 * 1024 * 1024; // 10 MB. | 22 static const size_t kMaxUnacknowledgedBytesSent = 10 * 1024 * 1024; // 10 MB. |
23 | 23 |
24 namespace content { | 24 namespace content { |
25 | 25 |
26 MidiMessageFilter::MidiMessageFilter( | 26 MidiMessageFilter::MidiMessageFilter( |
27 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) | 27 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) |
28 : sender_(nullptr), | 28 : sender_(nullptr), |
29 io_task_runner_(io_task_runner), | 29 io_task_runner_(io_task_runner), |
30 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 30 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
31 session_result_(media::midi::Result::NOT_INITIALIZED), | 31 session_result_(midi::Result::NOT_INITIALIZED), |
32 unacknowledged_bytes_sent_(0u) { | 32 unacknowledged_bytes_sent_(0u) { |
33 } | 33 } |
34 | 34 |
35 MidiMessageFilter::~MidiMessageFilter() {} | 35 MidiMessageFilter::~MidiMessageFilter() {} |
36 | 36 |
37 void MidiMessageFilter::AddClient(blink::WebMIDIAccessorClient* client) { | 37 void MidiMessageFilter::AddClient(blink::WebMIDIAccessorClient* client) { |
38 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 38 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
39 TRACE_EVENT0("midi", "MidiMessageFilter::AddClient"); | 39 TRACE_EVENT0("midi", "MidiMessageFilter::AddClient"); |
40 clients_waiting_session_queue_.push_back(client); | 40 clients_waiting_session_queue_.push_back(client); |
41 if (session_result_ != media::midi::Result::NOT_INITIALIZED) { | 41 if (session_result_ != midi::Result::NOT_INITIALIZED) { |
42 HandleClientAdded(session_result_); | 42 HandleClientAdded(session_result_); |
43 } else if (clients_waiting_session_queue_.size() == 1u) { | 43 } else if (clients_waiting_session_queue_.size() == 1u) { |
44 io_task_runner_->PostTask( | 44 io_task_runner_->PostTask( |
45 FROM_HERE, | 45 FROM_HERE, |
46 base::Bind(&MidiMessageFilter::StartSessionOnIOThread, this)); | 46 base::Bind(&MidiMessageFilter::StartSessionOnIOThread, this)); |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) { | 50 void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) { |
51 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 51 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
52 clients_.erase(client); | 52 clients_.erase(client); |
53 ClientsQueue::iterator it = std::find(clients_waiting_session_queue_.begin(), | 53 ClientsQueue::iterator it = std::find(clients_waiting_session_queue_.begin(), |
54 clients_waiting_session_queue_.end(), | 54 clients_waiting_session_queue_.end(), |
55 client); | 55 client); |
56 if (it != clients_waiting_session_queue_.end()) | 56 if (it != clients_waiting_session_queue_.end()) |
57 clients_waiting_session_queue_.erase(it); | 57 clients_waiting_session_queue_.erase(it); |
58 if (clients_.empty() && clients_waiting_session_queue_.empty()) { | 58 if (clients_.empty() && clients_waiting_session_queue_.empty()) { |
59 session_result_ = media::midi::Result::NOT_INITIALIZED; | 59 session_result_ = midi::Result::NOT_INITIALIZED; |
60 inputs_.clear(); | 60 inputs_.clear(); |
61 outputs_.clear(); | 61 outputs_.clear(); |
62 io_task_runner_->PostTask( | 62 io_task_runner_->PostTask( |
63 FROM_HERE, base::Bind(&MidiMessageFilter::EndSessionOnIOThread, this)); | 63 FROM_HERE, base::Bind(&MidiMessageFilter::EndSessionOnIOThread, this)); |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
67 void MidiMessageFilter::SendMidiData(uint32_t port, | 67 void MidiMessageFilter::SendMidiData(uint32_t port, |
68 const uint8_t* data, | 68 const uint8_t* data, |
69 size_t length, | 69 size_t length, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 // Once removed, a filter will not be used again. At this time all | 135 // Once removed, a filter will not be used again. At this time all |
136 // delegates must be notified so they release their reference. | 136 // delegates must be notified so they release their reference. |
137 OnChannelClosing(); | 137 OnChannelClosing(); |
138 } | 138 } |
139 | 139 |
140 void MidiMessageFilter::OnChannelClosing() { | 140 void MidiMessageFilter::OnChannelClosing() { |
141 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 141 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
142 sender_ = nullptr; | 142 sender_ = nullptr; |
143 } | 143 } |
144 | 144 |
145 void MidiMessageFilter::OnSessionStarted(media::midi::Result result) { | 145 void MidiMessageFilter::OnSessionStarted(midi::Result result) { |
146 TRACE_EVENT0("midi", "MidiMessageFilter::OnSessionStarted"); | 146 TRACE_EVENT0("midi", "MidiMessageFilter::OnSessionStarted"); |
147 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 147 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
148 // Handle on the main JS thread. | 148 // Handle on the main JS thread. |
149 main_task_runner_->PostTask( | 149 main_task_runner_->PostTask( |
150 FROM_HERE, | 150 FROM_HERE, |
151 base::Bind(&MidiMessageFilter::HandleClientAdded, this, result)); | 151 base::Bind(&MidiMessageFilter::HandleClientAdded, this, result)); |
152 } | 152 } |
153 | 153 |
154 void MidiMessageFilter::OnAddInputPort(media::midi::MidiPortInfo info) { | 154 void MidiMessageFilter::OnAddInputPort(midi::MidiPortInfo info) { |
155 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 155 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
156 main_task_runner_->PostTask( | 156 main_task_runner_->PostTask( |
157 FROM_HERE, | 157 FROM_HERE, |
158 base::Bind(&MidiMessageFilter::HandleAddInputPort, this, info)); | 158 base::Bind(&MidiMessageFilter::HandleAddInputPort, this, info)); |
159 } | 159 } |
160 | 160 |
161 void MidiMessageFilter::OnAddOutputPort(media::midi::MidiPortInfo info) { | 161 void MidiMessageFilter::OnAddOutputPort(midi::MidiPortInfo info) { |
162 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 162 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
163 main_task_runner_->PostTask( | 163 main_task_runner_->PostTask( |
164 FROM_HERE, | 164 FROM_HERE, |
165 base::Bind(&MidiMessageFilter::HandleAddOutputPort, this, info)); | 165 base::Bind(&MidiMessageFilter::HandleAddOutputPort, this, info)); |
166 } | 166 } |
167 | 167 |
168 void MidiMessageFilter::OnSetInputPortState(uint32_t port, | 168 void MidiMessageFilter::OnSetInputPortState(uint32_t port, |
169 media::midi::MidiPortState state) { | 169 midi::MidiPortState state) { |
170 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 170 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
171 main_task_runner_->PostTask( | 171 main_task_runner_->PostTask( |
172 FROM_HERE, base::Bind(&MidiMessageFilter::HandleSetInputPortState, this, | 172 FROM_HERE, base::Bind(&MidiMessageFilter::HandleSetInputPortState, this, |
173 port, state)); | 173 port, state)); |
174 } | 174 } |
175 | 175 |
176 void MidiMessageFilter::OnSetOutputPortState(uint32_t port, | 176 void MidiMessageFilter::OnSetOutputPortState(uint32_t port, |
177 media::midi::MidiPortState state) { | 177 midi::MidiPortState state) { |
178 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 178 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
179 main_task_runner_->PostTask( | 179 main_task_runner_->PostTask( |
180 FROM_HERE, base::Bind(&MidiMessageFilter::HandleSetOutputPortState, this, | 180 FROM_HERE, base::Bind(&MidiMessageFilter::HandleSetOutputPortState, this, |
181 port, state)); | 181 port, state)); |
182 } | 182 } |
183 | 183 |
184 void MidiMessageFilter::OnDataReceived(uint32_t port, | 184 void MidiMessageFilter::OnDataReceived(uint32_t port, |
185 const std::vector<uint8_t>& data, | 185 const std::vector<uint8_t>& data, |
186 double timestamp) { | 186 double timestamp) { |
187 TRACE_EVENT0("midi", "MidiMessageFilter::OnDataReceived"); | 187 TRACE_EVENT0("midi", "MidiMessageFilter::OnDataReceived"); |
188 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 188 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
189 // Handle on the main JS thread. | 189 // Handle on the main JS thread. |
190 main_task_runner_->PostTask( | 190 main_task_runner_->PostTask( |
191 FROM_HERE, base::Bind(&MidiMessageFilter::HandleDataReceived, this, port, | 191 FROM_HERE, base::Bind(&MidiMessageFilter::HandleDataReceived, this, port, |
192 data, timestamp)); | 192 data, timestamp)); |
193 } | 193 } |
194 | 194 |
195 void MidiMessageFilter::OnAcknowledgeSentData(size_t bytes_sent) { | 195 void MidiMessageFilter::OnAcknowledgeSentData(size_t bytes_sent) { |
196 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 196 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
197 main_task_runner_->PostTask( | 197 main_task_runner_->PostTask( |
198 FROM_HERE, base::Bind(&MidiMessageFilter::HandleAckknowledgeSentData, | 198 FROM_HERE, base::Bind(&MidiMessageFilter::HandleAckknowledgeSentData, |
199 this, bytes_sent)); | 199 this, bytes_sent)); |
200 } | 200 } |
201 | 201 |
202 void MidiMessageFilter::HandleClientAdded(media::midi::Result result) { | 202 void MidiMessageFilter::HandleClientAdded(midi::Result result) { |
203 TRACE_EVENT0("midi", "MidiMessageFilter::HandleClientAdded"); | 203 TRACE_EVENT0("midi", "MidiMessageFilter::HandleClientAdded"); |
204 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 204 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
205 session_result_ = result; | 205 session_result_ = result; |
206 std::string error; | 206 std::string error; |
207 std::string message; | 207 std::string message; |
208 switch (result) { | 208 switch (result) { |
209 case media::midi::Result::OK: | 209 case midi::Result::OK: |
210 break; | 210 break; |
211 case media::midi::Result::NOT_SUPPORTED: | 211 case midi::Result::NOT_SUPPORTED: |
212 error = "NotSupportedError"; | 212 error = "NotSupportedError"; |
213 break; | 213 break; |
214 case media::midi::Result::INITIALIZATION_ERROR: | 214 case midi::Result::INITIALIZATION_ERROR: |
215 error = "InvalidStateError"; | 215 error = "InvalidStateError"; |
216 message = "Platform dependent initialization failed."; | 216 message = "Platform dependent initialization failed."; |
217 break; | 217 break; |
218 default: | 218 default: |
219 NOTREACHED(); | 219 NOTREACHED(); |
220 error = "InvalidStateError"; | 220 error = "InvalidStateError"; |
221 message = "Unknown internal error occurred."; | 221 message = "Unknown internal error occurred."; |
222 break; | 222 break; |
223 } | 223 } |
224 base::string16 error16 = base::UTF8ToUTF16(error); | 224 base::string16 error16 = base::UTF8ToUTF16(error); |
225 base::string16 message16 = base::UTF8ToUTF16(message); | 225 base::string16 message16 = base::UTF8ToUTF16(message); |
226 | 226 |
227 // A for-loop using iterators does not work because |client| may touch | 227 // A for-loop using iterators does not work because |client| may touch |
228 // |clients_waiting_session_queue_| in callbacks. | 228 // |clients_waiting_session_queue_| in callbacks. |
229 while (!clients_waiting_session_queue_.empty()) { | 229 while (!clients_waiting_session_queue_.empty()) { |
230 auto* client = clients_waiting_session_queue_.back(); | 230 auto* client = clients_waiting_session_queue_.back(); |
231 clients_waiting_session_queue_.pop_back(); | 231 clients_waiting_session_queue_.pop_back(); |
232 if (result == media::midi::Result::OK) { | 232 if (result == midi::Result::OK) { |
233 // Add the client's input and output ports. | 233 // Add the client's input and output ports. |
234 for (const auto& info : inputs_) { | 234 for (const auto& info : inputs_) { |
235 client->didAddInputPort( | 235 client->didAddInputPort( |
236 base::UTF8ToUTF16(info.id), | 236 base::UTF8ToUTF16(info.id), |
237 base::UTF8ToUTF16(info.manufacturer), | 237 base::UTF8ToUTF16(info.manufacturer), |
238 base::UTF8ToUTF16(info.name), | 238 base::UTF8ToUTF16(info.name), |
239 base::UTF8ToUTF16(info.version), | 239 base::UTF8ToUTF16(info.version), |
240 ToBlinkState(info.state)); | 240 ToBlinkState(info.state)); |
241 } | 241 } |
242 | 242 |
243 for (const auto& info : outputs_) { | 243 for (const auto& info : outputs_) { |
244 client->didAddOutputPort( | 244 client->didAddOutputPort( |
245 base::UTF8ToUTF16(info.id), | 245 base::UTF8ToUTF16(info.id), |
246 base::UTF8ToUTF16(info.manufacturer), | 246 base::UTF8ToUTF16(info.manufacturer), |
247 base::UTF8ToUTF16(info.name), | 247 base::UTF8ToUTF16(info.name), |
248 base::UTF8ToUTF16(info.version), | 248 base::UTF8ToUTF16(info.version), |
249 ToBlinkState(info.state)); | 249 ToBlinkState(info.state)); |
250 } | 250 } |
251 } | 251 } |
252 client->didStartSession(result == media::midi::Result::OK, error16, | 252 client->didStartSession(result == midi::Result::OK, error16, |
253 message16); | 253 message16); |
254 clients_.insert(client); | 254 clients_.insert(client); |
255 } | 255 } |
256 } | 256 } |
257 | 257 |
258 void MidiMessageFilter::HandleAddInputPort(media::midi::MidiPortInfo info) { | 258 void MidiMessageFilter::HandleAddInputPort(midi::MidiPortInfo info) { |
259 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 259 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
260 inputs_.push_back(info); | 260 inputs_.push_back(info); |
261 const base::string16 id = base::UTF8ToUTF16(info.id); | 261 const base::string16 id = base::UTF8ToUTF16(info.id); |
262 const base::string16 manufacturer = base::UTF8ToUTF16(info.manufacturer); | 262 const base::string16 manufacturer = base::UTF8ToUTF16(info.manufacturer); |
263 const base::string16 name = base::UTF8ToUTF16(info.name); | 263 const base::string16 name = base::UTF8ToUTF16(info.name); |
264 const base::string16 version = base::UTF8ToUTF16(info.version); | 264 const base::string16 version = base::UTF8ToUTF16(info.version); |
265 const blink::WebMIDIAccessorClient::MIDIPortState state = | 265 const blink::WebMIDIAccessorClient::MIDIPortState state = |
266 ToBlinkState(info.state); | 266 ToBlinkState(info.state); |
267 for (auto* client : clients_) | 267 for (auto* client : clients_) |
268 client->didAddInputPort(id, manufacturer, name, version, state); | 268 client->didAddInputPort(id, manufacturer, name, version, state); |
269 } | 269 } |
270 | 270 |
271 void MidiMessageFilter::HandleAddOutputPort(media::midi::MidiPortInfo info) { | 271 void MidiMessageFilter::HandleAddOutputPort(midi::MidiPortInfo info) { |
272 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 272 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
273 outputs_.push_back(info); | 273 outputs_.push_back(info); |
274 const base::string16 id = base::UTF8ToUTF16(info.id); | 274 const base::string16 id = base::UTF8ToUTF16(info.id); |
275 const base::string16 manufacturer = base::UTF8ToUTF16(info.manufacturer); | 275 const base::string16 manufacturer = base::UTF8ToUTF16(info.manufacturer); |
276 const base::string16 name = base::UTF8ToUTF16(info.name); | 276 const base::string16 name = base::UTF8ToUTF16(info.name); |
277 const base::string16 version = base::UTF8ToUTF16(info.version); | 277 const base::string16 version = base::UTF8ToUTF16(info.version); |
278 const blink::WebMIDIAccessorClient::MIDIPortState state = | 278 const blink::WebMIDIAccessorClient::MIDIPortState state = |
279 ToBlinkState(info.state); | 279 ToBlinkState(info.state); |
280 for (auto* client : clients_) | 280 for (auto* client : clients_) |
281 client->didAddOutputPort(id, manufacturer, name, version, state); | 281 client->didAddOutputPort(id, manufacturer, name, version, state); |
(...skipping 12 matching lines...) Expand all Loading... |
294 | 294 |
295 void MidiMessageFilter::HandleAckknowledgeSentData(size_t bytes_sent) { | 295 void MidiMessageFilter::HandleAckknowledgeSentData(size_t bytes_sent) { |
296 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 296 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
297 DCHECK_GE(unacknowledged_bytes_sent_, bytes_sent); | 297 DCHECK_GE(unacknowledged_bytes_sent_, bytes_sent); |
298 if (unacknowledged_bytes_sent_ >= bytes_sent) | 298 if (unacknowledged_bytes_sent_ >= bytes_sent) |
299 unacknowledged_bytes_sent_ -= bytes_sent; | 299 unacknowledged_bytes_sent_ -= bytes_sent; |
300 } | 300 } |
301 | 301 |
302 void MidiMessageFilter::HandleSetInputPortState( | 302 void MidiMessageFilter::HandleSetInputPortState( |
303 uint32_t port, | 303 uint32_t port, |
304 media::midi::MidiPortState state) { | 304 midi::MidiPortState state) { |
305 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 305 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
306 inputs_[port].state = state; | 306 inputs_[port].state = state; |
307 for (auto* client : clients_) | 307 for (auto* client : clients_) |
308 client->didSetInputPortState(port, ToBlinkState(state)); | 308 client->didSetInputPortState(port, ToBlinkState(state)); |
309 } | 309 } |
310 | 310 |
311 void MidiMessageFilter::HandleSetOutputPortState( | 311 void MidiMessageFilter::HandleSetOutputPortState( |
312 uint32_t port, | 312 uint32_t port, |
313 media::midi::MidiPortState state) { | 313 midi::MidiPortState state) { |
314 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 314 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
315 outputs_[port].state = state; | 315 outputs_[port].state = state; |
316 for (auto* client : clients_) | 316 for (auto* client : clients_) |
317 client->didSetOutputPortState(port, ToBlinkState(state)); | 317 client->didSetOutputPortState(port, ToBlinkState(state)); |
318 } | 318 } |
319 | 319 |
320 } // namespace content | 320 } // namespace content |
OLD | NEW |