Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: content/renderer/media/midi_message_filter.cc

Issue 664843002: Web MIDI: distributes MIDIPort information asynchronously (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lifecycle
Patch Set: . => -> Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/media/midi_message_filter.h ('k') | media/midi/midi_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « content/renderer/media/midi_message_filter.h ('k') | media/midi/midi_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698