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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "content/common/media/midi_messages.h" | 13 #include "content/common/media/midi_messages.h" |
14 #include "content/renderer/render_thread_impl.h" | 14 #include "content/renderer/render_thread_impl.h" |
15 #include "ipc/ipc_logging.h" | 15 #include "ipc/ipc_logging.h" |
16 | 16 |
17 using media::MidiPortInfoList; | 17 using media::MidiPortInfoList; |
18 using base::AutoLock; | 18 using base::AutoLock; |
19 | 19 |
20 // The maximum number of bytes which we're allowed to send to the browser | 20 // The maximum number of bytes which we're allowed to send to the browser |
21 // before getting acknowledgement back from the browser that they've been | 21 // before getting acknowledgement back from the browser that they've been |
22 // successfully sent. | 22 // successfully sent. |
23 static const size_t kMaxUnacknowledgedBytesSent = 10 * 1024 * 1024; // 10 MB. | 23 static const size_t kMaxUnacknowledgedBytesSent = 10 * 1024 * 1024; // 10 MB. |
24 | 24 |
25 namespace content { | 25 namespace content { |
26 | 26 |
27 // TODO(crbug.com/425389): Rewrite this class as a RenderFrameObserver. | 27 // TODO(crbug.com/425389): Rewrite this class as a RenderFrameObserver. |
28 MidiMessageFilter::MidiMessageFilter( | 28 MidiMessageFilter::MidiMessageFilter( |
29 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) | 29 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) |
30 : sender_(NULL), | 30 : sender_(nullptr), |
31 io_message_loop_(io_message_loop), | 31 io_message_loop_(io_message_loop), |
32 main_message_loop_(base::MessageLoopProxy::current()), | 32 main_message_loop_(base::MessageLoopProxy::current()), |
33 session_result_(media::MIDI_NOT_INITIALIZED), | 33 session_result_(media::MIDI_NOT_INITIALIZED), |
34 unacknowledged_bytes_sent_(0u) { | 34 unacknowledged_bytes_sent_(0u) { |
35 } | 35 } |
36 | 36 |
37 MidiMessageFilter::~MidiMessageFilter() {} | 37 MidiMessageFilter::~MidiMessageFilter() {} |
38 | 38 |
39 void MidiMessageFilter::AddClient(blink::WebMIDIAccessorClient* client) { | 39 void MidiMessageFilter::AddClient(blink::WebMIDIAccessorClient* client) { |
40 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 40 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
(...skipping 10 matching lines...) Expand all Loading... |
51 void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) { | 51 void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) { |
52 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 52 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
53 clients_.erase(client); | 53 clients_.erase(client); |
54 ClientsQueue::iterator it = std::find(clients_waiting_session_queue_.begin(), | 54 ClientsQueue::iterator it = std::find(clients_waiting_session_queue_.begin(), |
55 clients_waiting_session_queue_.end(), | 55 clients_waiting_session_queue_.end(), |
56 client); | 56 client); |
57 if (it != clients_waiting_session_queue_.end()) | 57 if (it != clients_waiting_session_queue_.end()) |
58 clients_waiting_session_queue_.erase(it); | 58 clients_waiting_session_queue_.erase(it); |
59 if (clients_.empty() && clients_waiting_session_queue_.empty()) { | 59 if (clients_.empty() && clients_waiting_session_queue_.empty()) { |
60 session_result_ = media::MIDI_NOT_INITIALIZED; | 60 session_result_ = media::MIDI_NOT_INITIALIZED; |
| 61 inputs_.clear(); |
| 62 outputs_.clear(); |
61 io_message_loop_->PostTask(FROM_HERE, | 63 io_message_loop_->PostTask(FROM_HERE, |
62 base::Bind(&MidiMessageFilter::EndSessionOnIOThread, this)); | 64 base::Bind(&MidiMessageFilter::EndSessionOnIOThread, this)); |
63 } | 65 } |
64 } | 66 } |
65 | 67 |
66 void MidiMessageFilter::SendMidiData(uint32 port, | 68 void MidiMessageFilter::SendMidiData(uint32 port, |
67 const uint8* data, | 69 const uint8* data, |
68 size_t length, | 70 size_t length, |
69 double timestamp) { | 71 double timestamp) { |
70 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 72 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 } else { | 107 } else { |
106 sender_->Send(message); | 108 sender_->Send(message); |
107 } | 109 } |
108 } | 110 } |
109 | 111 |
110 bool MidiMessageFilter::OnMessageReceived(const IPC::Message& message) { | 112 bool MidiMessageFilter::OnMessageReceived(const IPC::Message& message) { |
111 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 113 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
112 bool handled = true; | 114 bool handled = true; |
113 IPC_BEGIN_MESSAGE_MAP(MidiMessageFilter, message) | 115 IPC_BEGIN_MESSAGE_MAP(MidiMessageFilter, message) |
114 IPC_MESSAGE_HANDLER(MidiMsg_SessionStarted, OnSessionStarted) | 116 IPC_MESSAGE_HANDLER(MidiMsg_SessionStarted, OnSessionStarted) |
| 117 IPC_MESSAGE_HANDLER(MidiMsg_AddInputPort, OnAddInputPort) |
| 118 IPC_MESSAGE_HANDLER(MidiMsg_AddOutputPort, OnAddOutputPort) |
115 IPC_MESSAGE_HANDLER(MidiMsg_DataReceived, OnDataReceived) | 119 IPC_MESSAGE_HANDLER(MidiMsg_DataReceived, OnDataReceived) |
116 IPC_MESSAGE_HANDLER(MidiMsg_AcknowledgeSentData, OnAcknowledgeSentData) | 120 IPC_MESSAGE_HANDLER(MidiMsg_AcknowledgeSentData, OnAcknowledgeSentData) |
117 IPC_MESSAGE_UNHANDLED(handled = false) | 121 IPC_MESSAGE_UNHANDLED(handled = false) |
118 IPC_END_MESSAGE_MAP() | 122 IPC_END_MESSAGE_MAP() |
119 return handled; | 123 return handled; |
120 } | 124 } |
121 | 125 |
122 void MidiMessageFilter::OnFilterAdded(IPC::Sender* sender) { | 126 void MidiMessageFilter::OnFilterAdded(IPC::Sender* sender) { |
123 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 127 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
124 sender_ = sender; | 128 sender_ = sender; |
125 } | 129 } |
126 | 130 |
127 void MidiMessageFilter::OnFilterRemoved() { | 131 void MidiMessageFilter::OnFilterRemoved() { |
128 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 132 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
129 // Once removed, a filter will not be used again. At this time all | 133 // Once removed, a filter will not be used again. At this time all |
130 // delegates must be notified so they release their reference. | 134 // delegates must be notified so they release their reference. |
131 OnChannelClosing(); | 135 OnChannelClosing(); |
132 } | 136 } |
133 | 137 |
134 void MidiMessageFilter::OnChannelClosing() { | 138 void MidiMessageFilter::OnChannelClosing() { |
135 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 139 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
136 sender_ = NULL; | 140 sender_ = nullptr; |
137 } | 141 } |
138 | 142 |
139 void MidiMessageFilter::OnSessionStarted(media::MidiResult result, | 143 void MidiMessageFilter::OnSessionStarted(media::MidiResult result) { |
140 MidiPortInfoList inputs, | |
141 MidiPortInfoList outputs) { | |
142 TRACE_EVENT0("midi", "MidiMessageFilter::OnSessionStarted"); | 144 TRACE_EVENT0("midi", "MidiMessageFilter::OnSessionStarted"); |
143 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 145 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
144 // TODO(toyoshim): |inputs_| and |outputs_| should not be updated on | |
145 // |io_message_loop_|. This should be fixed in a following change not to | |
146 // distribute MidiPortInfo via OnSessionStarted(). | |
147 // For now, this is safe because these are not updated later. | |
148 inputs_ = inputs; | |
149 outputs_ = outputs; | |
150 // Handle on the main JS thread. | 146 // Handle on the main JS thread. |
151 main_message_loop_->PostTask( | 147 main_message_loop_->PostTask( |
152 FROM_HERE, | 148 FROM_HERE, |
153 base::Bind(&MidiMessageFilter::HandleClientAdded, this, result)); | 149 base::Bind(&MidiMessageFilter::HandleClientAdded, this, result)); |
154 } | 150 } |
155 | 151 |
| 152 void MidiMessageFilter::OnAddInputPort(media::MidiPortInfo info) { |
| 153 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 154 main_message_loop_->PostTask( |
| 155 FROM_HERE, |
| 156 base::Bind(&MidiMessageFilter::HandleAddInputPort, this, info)); |
| 157 } |
| 158 |
| 159 void MidiMessageFilter::OnAddOutputPort(media::MidiPortInfo info) { |
| 160 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
| 161 main_message_loop_->PostTask( |
| 162 FROM_HERE, |
| 163 base::Bind(&MidiMessageFilter::HandleAddOutputPort, this, info)); |
| 164 } |
| 165 |
156 void MidiMessageFilter::OnDataReceived(uint32 port, | 166 void MidiMessageFilter::OnDataReceived(uint32 port, |
157 const std::vector<uint8>& data, | 167 const std::vector<uint8>& data, |
158 double timestamp) { | 168 double timestamp) { |
159 TRACE_EVENT0("midi", "MidiMessageFilter::OnDataReceived"); | 169 TRACE_EVENT0("midi", "MidiMessageFilter::OnDataReceived"); |
160 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 170 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
161 // Handle on the main JS thread. | 171 // Handle on the main JS thread. |
162 main_message_loop_->PostTask( | 172 main_message_loop_->PostTask( |
163 FROM_HERE, | 173 FROM_HERE, |
164 base::Bind(&MidiMessageFilter::HandleDataReceived, this, port, data, | 174 base::Bind(&MidiMessageFilter::HandleDataReceived, this, port, data, |
165 timestamp)); | 175 timestamp)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 base::UTF8ToUTF16(info.version), | 228 base::UTF8ToUTF16(info.version), |
219 active); | 229 active); |
220 } | 230 } |
221 } | 231 } |
222 client->didStartSession(result == media::MIDI_OK, error16, message16); | 232 client->didStartSession(result == media::MIDI_OK, error16, message16); |
223 clients_.insert(client); | 233 clients_.insert(client); |
224 } | 234 } |
225 clients_waiting_session_queue_.clear(); | 235 clients_waiting_session_queue_.clear(); |
226 } | 236 } |
227 | 237 |
| 238 void MidiMessageFilter::HandleAddInputPort(media::MidiPortInfo info) { |
| 239 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
| 240 inputs_.push_back(info); |
| 241 // TODO(toyoshim): Notify to clients that were already added. |
| 242 } |
| 243 |
| 244 void MidiMessageFilter::HandleAddOutputPort(media::MidiPortInfo info) { |
| 245 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
| 246 outputs_.push_back(info); |
| 247 // TODO(toyoshim): Notify to clients that were already added. |
| 248 } |
| 249 |
228 void MidiMessageFilter::HandleDataReceived(uint32 port, | 250 void MidiMessageFilter::HandleDataReceived(uint32 port, |
229 const std::vector<uint8>& data, | 251 const std::vector<uint8>& data, |
230 double timestamp) { | 252 double timestamp) { |
231 TRACE_EVENT0("midi", "MidiMessageFilter::HandleDataReceived"); | 253 TRACE_EVENT0("midi", "MidiMessageFilter::HandleDataReceived"); |
232 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 254 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
233 DCHECK(!data.empty()); | 255 DCHECK(!data.empty()); |
234 | 256 |
235 for (blink::WebMIDIAccessorClient* client : clients_) | 257 for (blink::WebMIDIAccessorClient* client : clients_) |
236 client->didReceiveMIDIData(port, &data[0], data.size(), timestamp); | 258 client->didReceiveMIDIData(port, &data[0], data.size(), timestamp); |
237 } | 259 } |
238 | 260 |
239 void MidiMessageFilter::HandleAckknowledgeSentData(size_t bytes_sent) { | 261 void MidiMessageFilter::HandleAckknowledgeSentData(size_t bytes_sent) { |
240 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 262 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
241 DCHECK_GE(unacknowledged_bytes_sent_, bytes_sent); | 263 DCHECK_GE(unacknowledged_bytes_sent_, bytes_sent); |
242 if (unacknowledged_bytes_sent_ >= bytes_sent) | 264 if (unacknowledged_bytes_sent_ >= bytes_sent) |
243 unacknowledged_bytes_sent_ -= bytes_sent; | 265 unacknowledged_bytes_sent_ -= bytes_sent; |
244 } | 266 } |
245 | 267 |
246 } // namespace content | 268 } // namespace content |
OLD | NEW |