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

Side by Side Diff: media/midi/dynamically_initialized_midi_manager_win.cc

Issue 2698413003: Web MIDI: implement sending for dynamic manager instantiation on Windows (Closed)
Patch Set: set cl dependency Created 3 years, 9 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 | « media/midi/dynamically_initialized_midi_manager_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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 "media/midi/dynamically_initialized_midi_manager_win.h" 5 #include "media/midi/dynamically_initialized_midi_manager_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include <mmreg.h> 9 #include <mmreg.h>
10 #include <mmsystem.h> 10 #include <mmsystem.h>
(...skipping 21 matching lines...) Expand all
32 // Calculates event time from elapsed time that system provides. 32 // Calculates event time from elapsed time that system provides.
33 base::TimeTicks CalculateInEventTime(size_t index, uint32_t elapsed_ms) const; 33 base::TimeTicks CalculateInEventTime(size_t index, uint32_t elapsed_ms) const;
34 34
35 // Registers HMIDIIN handle to resolve port index. 35 // Registers HMIDIIN handle to resolve port index.
36 void RegisterInHandle(HMIDIIN handle, size_t index); 36 void RegisterInHandle(HMIDIIN handle, size_t index);
37 37
38 // Unregisters HMIDIIN handle. 38 // Unregisters HMIDIIN handle.
39 void UnregisterInHandle(HMIDIIN handle); 39 void UnregisterInHandle(HMIDIIN handle);
40 40
41 // Finds HMIDIIN handle and fullfil |out_index| with the port index. 41 // Finds HMIDIIN handle and fullfil |out_index| with the port index.
42 bool FindHandle(HMIDIIN hmi, size_t* out_index); 42 bool FindInHandle(HMIDIIN hmi, size_t* out_index);
43 43
44 // Restores used input buffer for the next data receive. 44 // Restores used input buffer for the next data receive.
45 void RestoreInBuffer(size_t index); 45 void RestoreInBuffer(size_t index);
46 46
47 // Ports accessors. 47 // Ports accessors.
48 std::vector<std::unique_ptr<InPort>>* inputs() { return &input_ports_; } 48 std::vector<std::unique_ptr<InPort>>* inputs() { return &input_ports_; }
49 std::vector<std::unique_ptr<OutPort>>* outputs() { return &output_ports_; } 49 std::vector<std::unique_ptr<OutPort>>* outputs() { return &output_ports_; }
50 50
51 // Handles MIDI input port callbacks that runs on a system provided thread. 51 // Handles MIDI input port callbacks that runs on a system provided thread.
52 static void CALLBACK HandleMidiInCallback(HMIDIIN hmi, 52 static void CALLBACK HandleMidiInCallback(HMIDIIN hmi,
53 UINT msg, 53 UINT msg,
54 DWORD_PTR instance, 54 DWORD_PTR instance,
55 DWORD_PTR param1, 55 DWORD_PTR param1,
56 DWORD_PTR param2); 56 DWORD_PTR param2);
57 57
58 // Handles MIDI output port callbacks that runs on a system provided thread.
59 static void CALLBACK HandleMidiOutCallback(HMIDIOUT hmo,
60 UINT msg,
61 DWORD_PTR instance,
62 DWORD_PTR param1,
63 DWORD_PTR param2);
64
58 private: 65 private:
59 // Holds all MIDI input or output ports connected once. 66 // Holds all MIDI input or output ports connected once.
60 std::vector<std::unique_ptr<InPort>> input_ports_; 67 std::vector<std::unique_ptr<InPort>> input_ports_;
61 std::vector<std::unique_ptr<OutPort>> output_ports_; 68 std::vector<std::unique_ptr<OutPort>> output_ports_;
62 69
63 // Map to resolve MIDI input port index from HMIDIIN. 70 // Map to resolve MIDI input port index from HMIDIIN.
64 std::map<HMIDIIN, size_t> hmidiin_to_index_map_; 71 std::map<HMIDIIN, size_t> hmidiin_to_index_map_;
65 }; 72 };
66 73
67 namespace { 74 namespace {
68 75
69 // Assumes that nullptr represents an invalid MIDI handle. 76 // Assumes that nullptr represents an invalid MIDI handle.
70 constexpr HMIDIIN kInvalidInHandle = nullptr; 77 constexpr HMIDIIN kInvalidInHandle = nullptr;
71 constexpr HMIDIOUT kInvalidOutHandle = nullptr; 78 constexpr HMIDIOUT kInvalidOutHandle = nullptr;
72 79
80 // Defines SysEx message size limit.
81 // TODO(crbug.com/383578): This restriction should be removed once Web MIDI
82 // defines a standardized way to handle large sysex messages.
83 // Note for built-in USB-MIDI driver:
84 // From an observation on Windows 7/8.1 with a USB-MIDI keyboard,
85 // midiOutLongMsg() will be always blocked. Sending 64 bytes or less data takes
86 // roughly 300 usecs. Sending 2048 bytes or more data takes roughly
87 // |message.size() / (75 * 1024)| secs in practice. Here we put 256 KB size
88 // limit on SysEx message, with hoping that midiOutLongMsg will be blocked at
89 // most 4 sec or so with a typical USB-MIDI device.
90 // TODO(toyoshim): Consider to use linked small buffers so that midiOutReset()
91 // can abort sending unhandled following buffers.
92 constexpr size_t kSysExSizeLimit = 256 * 1024;
93
73 // Defines input buffer size. 94 // Defines input buffer size.
74 constexpr size_t kBufferLength = 32 * 1024; 95 constexpr size_t kBufferLength = 32 * 1024;
75 96
76 // Global variables to identify MidiManager instance. 97 // Global variables to identify MidiManager instance.
77 constexpr int kInvalidInstanceId = -1; 98 constexpr int kInvalidInstanceId = -1;
78 int g_active_instance_id = kInvalidInstanceId; 99 int g_active_instance_id = kInvalidInstanceId;
79 DynamicallyInitializedMidiManagerWin* g_manager_instance = nullptr; 100 DynamicallyInitializedMidiManagerWin* g_manager_instance = nullptr;
80 101
81 // Obtains base::Lock instance pointer to lock instance_id. 102 // Obtains base::Lock instance pointer to lock instance_id.
82 base::Lock* GetInstanceIdLock() { 103 base::Lock* GetInstanceIdLock() {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 midiInReset(handle); 175 midiInReset(handle);
155 176
156 // Obtains MIDIHDR ownership to release allocated buffers. 177 // Obtains MIDIHDR ownership to release allocated buffers.
157 ScopedMIDIHDR hdr(lphdr); 178 ScopedMIDIHDR hdr(lphdr);
158 if (hdr) 179 if (hdr)
159 midiInUnprepareHeader(handle, hdr.get(), sizeof(*hdr)); 180 midiInUnprepareHeader(handle, hdr.get(), sizeof(*hdr));
160 midiInClose(handle); 181 midiInClose(handle);
161 } 182 }
162 183
163 void FinalizeOutPort(HMIDIOUT handle) { 184 void FinalizeOutPort(HMIDIOUT handle) {
185 // Resets inflight buffers. This will cancel sending data that system
186 // holds and were not sent yet.
187 midiOutReset(handle);
164 midiOutClose(handle); 188 midiOutClose(handle);
165 } 189 }
166 190
167 // Handles MIDI output port callbacks that runs on a system provided thread.
168 void CALLBACK HandleMidiOutCallback(HMIDIOUT hmo,
169 UINT msg,
170 DWORD_PTR instance,
171 DWORD_PTR param1,
172 DWORD_PTR param2) {
173 // TODO(toyoshim): Following patches will implement actual functions.
174 }
175
176 // All instances of Port subclasses are always accessed behind a lock of 191 // All instances of Port subclasses are always accessed behind a lock of
177 // *GetTaskLock(). Port and subclasses implementation do not need to 192 // *GetTaskLock(). Port and subclasses implementation do not need to
178 // consider thread safety. 193 // consider thread safety.
179 class Port { 194 class Port {
180 public: 195 public:
181 Port(const std::string& type, 196 Port(const std::string& type,
182 uint32_t device_id, 197 uint32_t device_id,
183 uint16_t manufacturer_id, 198 uint16_t manufacturer_id,
184 uint16_t product_id, 199 uint16_t product_id,
185 uint32_t driver_version, 200 uint32_t driver_version,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 uint32_t device_id_; 267 uint32_t device_id_;
253 const uint16_t manufacturer_id_; 268 const uint16_t manufacturer_id_;
254 const uint16_t product_id_; 269 const uint16_t product_id_;
255 const uint32_t driver_version_; 270 const uint32_t driver_version_;
256 const std::string product_name_; 271 const std::string product_name_;
257 MidiPortInfo info_; 272 MidiPortInfo info_;
258 }; // class Port 273 }; // class Port
259 274
260 } // namespace 275 } // namespace
261 276
262 // TODO(toyoshim): Following patches will implement actual functions.
263 class DynamicallyInitializedMidiManagerWin::InPort final : public Port { 277 class DynamicallyInitializedMidiManagerWin::InPort final : public Port {
264 public: 278 public:
265 InPort(DynamicallyInitializedMidiManagerWin* manager, 279 InPort(DynamicallyInitializedMidiManagerWin* manager,
266 int instance_id, 280 int instance_id,
267 UINT device_id, 281 UINT device_id,
268 const MIDIINCAPS2W& caps) 282 const MIDIINCAPS2W& caps)
269 : Port("input", 283 : Port("input",
270 device_id, 284 device_id,
271 caps.wMid, 285 caps.wMid,
272 caps.wPid, 286 caps.wPid,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 } 384 }
371 385
372 private: 386 private:
373 DynamicallyInitializedMidiManagerWin* manager_; 387 DynamicallyInitializedMidiManagerWin* manager_;
374 HMIDIIN in_handle_; 388 HMIDIIN in_handle_;
375 ScopedMIDIHDR hdr_; 389 ScopedMIDIHDR hdr_;
376 base::TimeTicks start_time_; 390 base::TimeTicks start_time_;
377 int instance_id_; 391 int instance_id_;
378 }; 392 };
379 393
380 // TODO(toyoshim): Following patches will implement actual functions.
381 class DynamicallyInitializedMidiManagerWin::OutPort final : public Port { 394 class DynamicallyInitializedMidiManagerWin::OutPort final : public Port {
382 public: 395 public:
383 OutPort(UINT device_id, const MIDIOUTCAPS2W& caps) 396 OutPort(UINT device_id, const MIDIOUTCAPS2W& caps)
384 : Port("output", 397 : Port("output",
385 device_id, 398 device_id,
386 caps.wMid, 399 caps.wMid,
387 caps.wPid, 400 caps.wPid,
388 caps.vDriverVersion, 401 caps.vDriverVersion,
389 base::WideToUTF8( 402 base::WideToUTF8(
390 base::string16(caps.szPname, wcslen(caps.szPname)))), 403 base::string16(caps.szPname, wcslen(caps.szPname)))),
(...skipping 28 matching lines...) Expand all
419 base::Bind(&DynamicallyInitializedMidiManagerWin::SetOutputPortState, 432 base::Bind(&DynamicallyInitializedMidiManagerWin::SetOutputPortState,
420 base::Unretained(manager), index_, info_.state)); 433 base::Unretained(manager), index_, info_.state));
421 } 434 }
422 435
423 void NotifyPortAdded(DynamicallyInitializedMidiManagerWin* manager) { 436 void NotifyPortAdded(DynamicallyInitializedMidiManagerWin* manager) {
424 manager->PostReplyTask( 437 manager->PostReplyTask(
425 base::Bind(&DynamicallyInitializedMidiManagerWin::AddOutputPort, 438 base::Bind(&DynamicallyInitializedMidiManagerWin::AddOutputPort,
426 base::Unretained(manager), info_)); 439 base::Unretained(manager), info_));
427 } 440 }
428 441
442 void Send(const std::vector<uint8_t>& data) {
443 if (out_handle_ == kInvalidOutHandle)
444 return;
445
446 if (data.size() <= 3) {
447 DWORD message = 0;
yhirano 2017/03/01 01:48:49 [optional] I would prefer defining |message| as a
Takashi Toyoshima 2017/03/01 03:38:02 changed to uint32_t. cast is not needed to pass it
448 for (size_t i = 0; i < data.size(); ++i)
449 message |= (static_cast<uint32_t>(data[i]) << (i * 8));
450 midiOutShortMsg(out_handle_, message);
451 } else {
452 if (data.size() > kSysExSizeLimit) {
453 LOG(ERROR) << "Ignoring SysEx message due to the size limit"
454 << ", size = " << data.size();
455 // TODO(toyoshim): Consider to report metrics here.
456 return;
457 }
458 ScopedMIDIHDR hdr(CreateMIDIHDR(data));
459 MMRESULT result =
460 midiOutPrepareHeader(out_handle_, hdr.get(), sizeof(*hdr));
461 if (result != MMSYSERR_NOERROR)
462 return;
463 result = midiOutLongMsg(out_handle_, hdr.get(), sizeof(*hdr));
464 if (result != MMSYSERR_NOERROR)
465 midiOutUnprepareHeader(out_handle_, hdr.get(), sizeof(*hdr));
466 else
467 ignore_result(hdr.release());
468 // MIDIHDR will be released on MOM_DONE.
469 }
470 }
471
429 // Port overrides: 472 // Port overrides:
430 bool Connect() override { 473 bool Connect() override {
431 // Until |software| option is supported, disable Microsoft GS Wavetable 474 // Until |software| option is supported, disable Microsoft GS Wavetable
432 // Synth that has a known security issue. 475 // Synth that has a known security issue.
433 if (software_ && manufacturer_id_ == MM_MICROSOFT && 476 if (software_ && manufacturer_id_ == MM_MICROSOFT &&
434 (product_id_ == MM_MSFT_WDMAUDIO_MIDIOUT || 477 (product_id_ == MM_MSFT_WDMAUDIO_MIDIOUT ||
435 product_id_ == MM_MSFT_GENERIC_MIDISYNTH)) { 478 product_id_ == MM_MSFT_GENERIC_MIDISYNTH)) {
436 return false; 479 return false;
437 } 480 }
438 return Port::Connect(); 481 return Port::Connect();
439 } 482 }
440 483
441 bool Disconnect() override { 484 bool Disconnect() override {
442 if (out_handle_ != kInvalidOutHandle) { 485 if (out_handle_ != kInvalidOutHandle) {
443 // Following API call may fail because device was already disconnected. 486 // Following API call may fail because device was already disconnected.
444 // But just in case. 487 // But just in case.
445 midiOutClose(out_handle_); 488 midiOutClose(out_handle_);
446 out_handle_ = kInvalidOutHandle; 489 out_handle_ = kInvalidOutHandle;
447 } 490 }
448 return Port::Disconnect(); 491 return Port::Disconnect();
449 } 492 }
450 493
451 void Open() override { 494 void Open() override {
452 MMRESULT result = 495 MMRESULT result = midiOutOpen(
453 midiOutOpen(&out_handle_, device_id_, 496 &out_handle_, device_id_,
454 reinterpret_cast<DWORD_PTR>(&HandleMidiOutCallback), 0, 497 reinterpret_cast<DWORD_PTR>(&PortManager::HandleMidiOutCallback), 0,
455 CALLBACK_FUNCTION); 498 CALLBACK_FUNCTION);
456 if (result == MMSYSERR_NOERROR) { 499 if (result == MMSYSERR_NOERROR) {
457 Port::Open(); 500 Port::Open();
458 } else { 501 } else {
459 out_handle_ = kInvalidOutHandle; 502 out_handle_ = kInvalidOutHandle;
460 Disconnect(); 503 Disconnect();
461 } 504 }
462 } 505 }
463 506
464 const bool software_; 507 const bool software_;
465 HMIDIOUT out_handle_; 508 HMIDIOUT out_handle_;
(...skipping 14 matching lines...) Expand all
480 GetTaskLock()->AssertAcquired(); 523 GetTaskLock()->AssertAcquired();
481 hmidiin_to_index_map_[handle] = index; 524 hmidiin_to_index_map_[handle] = index;
482 } 525 }
483 526
484 void DynamicallyInitializedMidiManagerWin::PortManager::UnregisterInHandle( 527 void DynamicallyInitializedMidiManagerWin::PortManager::UnregisterInHandle(
485 HMIDIIN handle) { 528 HMIDIIN handle) {
486 GetTaskLock()->AssertAcquired(); 529 GetTaskLock()->AssertAcquired();
487 hmidiin_to_index_map_.erase(handle); 530 hmidiin_to_index_map_.erase(handle);
488 } 531 }
489 532
490 bool DynamicallyInitializedMidiManagerWin::PortManager::FindHandle( 533 bool DynamicallyInitializedMidiManagerWin::PortManager::FindInHandle(
491 HMIDIIN hmi, 534 HMIDIIN hmi,
492 size_t* out_index) { 535 size_t* out_index) {
493 GetTaskLock()->AssertAcquired(); 536 GetTaskLock()->AssertAcquired();
494 auto found = hmidiin_to_index_map_.find(hmi); 537 auto found = hmidiin_to_index_map_.find(hmi);
495 if (found == hmidiin_to_index_map_.end()) 538 if (found == hmidiin_to_index_map_.end())
496 return false; 539 return false;
497 *out_index = found->second; 540 *out_index = found->second;
498 return true; 541 return true;
499 } 542 }
500 543
(...skipping 20 matching lines...) Expand all
521 // and to access member variables that are used on TaskRunner. 564 // and to access member variables that are used on TaskRunner.
522 base::AutoLock task_lock(*GetTaskLock()); 565 base::AutoLock task_lock(*GetTaskLock());
523 { 566 {
524 base::AutoLock lock(*GetInstanceIdLock()); 567 base::AutoLock lock(*GetInstanceIdLock());
525 if (instance_id != g_active_instance_id) 568 if (instance_id != g_active_instance_id)
526 return; 569 return;
527 manager = g_manager_instance; 570 manager = g_manager_instance;
528 } 571 }
529 572
530 size_t index; 573 size_t index;
531 if (!manager->port_manager()->FindHandle(hmi, &index)) 574 if (!manager->port_manager()->FindInHandle(hmi, &index))
532 return; 575 return;
533 576
534 DCHECK(msg == MIM_DATA || msg == MIM_LONGDATA); 577 DCHECK(msg == MIM_DATA || msg == MIM_LONGDATA);
535 if (msg == MIM_DATA) { 578 if (msg == MIM_DATA) {
536 const uint8_t status_byte = static_cast<uint8_t>(param1 & 0xff); 579 const uint8_t status_byte = static_cast<uint8_t>(param1 & 0xff);
537 const uint8_t first_data_byte = static_cast<uint8_t>((param1 >> 8) & 0xff); 580 const uint8_t first_data_byte = static_cast<uint8_t>((param1 >> 8) & 0xff);
538 const uint8_t second_data_byte = 581 const uint8_t second_data_byte =
539 static_cast<uint8_t>((param1 >> 16) & 0xff); 582 static_cast<uint8_t>((param1 >> 16) & 0xff);
540 const size_t len = GetMessageLength(status_byte); 583 const size_t len = GetMessageLength(status_byte);
541 const uint8_t kData[] = {status_byte, first_data_byte, second_data_byte}; 584 const uint8_t kData[] = {status_byte, first_data_byte, second_data_byte};
(...skipping 14 matching lines...) Expand all
556 &DynamicallyInitializedMidiManagerWin::ReceiveMidiData, 599 &DynamicallyInitializedMidiManagerWin::ReceiveMidiData,
557 base::Unretained(manager), index, data, 600 base::Unretained(manager), index, data,
558 manager->port_manager()->CalculateInEventTime(index, param2))); 601 manager->port_manager()->CalculateInEventTime(index, param2)));
559 } 602 }
560 manager->PostTask(base::Bind( 603 manager->PostTask(base::Bind(
561 &DynamicallyInitializedMidiManagerWin::PortManager::RestoreInBuffer, 604 &DynamicallyInitializedMidiManagerWin::PortManager::RestoreInBuffer,
562 base::Unretained(manager->port_manager()), index)); 605 base::Unretained(manager->port_manager()), index));
563 } 606 }
564 } 607 }
565 608
609 void CALLBACK
610 DynamicallyInitializedMidiManagerWin::PortManager::HandleMidiOutCallback(
611 HMIDIOUT hmo,
612 UINT msg,
613 DWORD_PTR instance,
614 DWORD_PTR param1,
615 DWORD_PTR param2) {
616 if (msg == MOM_DONE) {
617 ScopedMIDIHDR hdr(reinterpret_cast<LPMIDIHDR>(param1));
618 if (!hdr)
619 return;
620 // TODO(toyoshim): Call midiOutUnprepareHeader outside the callback.
621 // Since this callback may be invoked after the manager is destructed,
622 // and can not send a task to the TaskRunner in such case, we need to
623 // consider to track MIDIHDR per port, and clean it in port finalization
624 // steps, too.
625 midiOutUnprepareHeader(hmo, hdr.get(), sizeof(*hdr));
626 }
627 }
628
566 DynamicallyInitializedMidiManagerWin::DynamicallyInitializedMidiManagerWin( 629 DynamicallyInitializedMidiManagerWin::DynamicallyInitializedMidiManagerWin(
567 MidiService* service) 630 MidiService* service)
568 : MidiManager(service), 631 : MidiManager(service),
569 instance_id_(IssueNextInstanceId()), 632 instance_id_(IssueNextInstanceId()),
570 port_manager_(base::MakeUnique<PortManager>()) { 633 port_manager_(base::MakeUnique<PortManager>()) {
571 base::AutoLock lock(*GetInstanceIdLock()); 634 base::AutoLock lock(*GetInstanceIdLock());
572 CHECK_EQ(kInvalidInstanceId, g_active_instance_id); 635 CHECK_EQ(kInvalidInstanceId, g_active_instance_id);
573 636
574 // Obtains the task runner for the current thread that hosts this instnace. 637 // Obtains the task runner for the current thread that hosts this instnace.
575 thread_runner_ = base::ThreadTaskRunnerHandle::Get(); 638 thread_runner_ = base::ThreadTaskRunnerHandle::Get();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 port->Finalize(service()->GetTaskRunner(kTaskRunner)); 689 port->Finalize(service()->GetTaskRunner(kTaskRunner));
627 for (const auto& port : *port_manager_->outputs()) 690 for (const auto& port : *port_manager_->outputs())
628 port->Finalize(service()->GetTaskRunner(kTaskRunner)); 691 port->Finalize(service()->GetTaskRunner(kTaskRunner));
629 } 692 }
630 693
631 void DynamicallyInitializedMidiManagerWin::DispatchSendMidiData( 694 void DynamicallyInitializedMidiManagerWin::DispatchSendMidiData(
632 MidiManagerClient* client, 695 MidiManagerClient* client,
633 uint32_t port_index, 696 uint32_t port_index,
634 const std::vector<uint8_t>& data, 697 const std::vector<uint8_t>& data,
635 double timestamp) { 698 double timestamp) {
636 // TODO(toyoshim): Following patches will implement. 699 if (timestamp != 0.0) {
700 base::TimeTicks time = base::TimeTicks() +
701 base::TimeDelta::FromMicroseconds(
702 timestamp * base::Time::kMicrosecondsPerSecond);
703 base::TimeTicks now = base::TimeTicks::Now();
704 if (now < time) {
705 PostDelayedTask(
706 base::Bind(&DynamicallyInitializedMidiManagerWin::SendOnTaskRunner,
707 base::Unretained(this), client, port_index, data),
708 time - now);
709 return;
710 }
711 }
712 PostTask(base::Bind(&DynamicallyInitializedMidiManagerWin::SendOnTaskRunner,
713 base::Unretained(this), client, port_index, data));
637 } 714 }
638 715
639 void DynamicallyInitializedMidiManagerWin::OnDevicesChanged( 716 void DynamicallyInitializedMidiManagerWin::OnDevicesChanged(
640 base::SystemMonitor::DeviceType device_type) { 717 base::SystemMonitor::DeviceType device_type) {
641 // Notified on the I/O thread. 718 // Notified on the I/O thread.
642 CHECK(thread_runner_->BelongsToCurrentThread()); 719 CHECK(thread_runner_->BelongsToCurrentThread());
643 720
644 switch (device_type) { 721 switch (device_type) {
645 case base::SystemMonitor::DEVTYPE_AUDIO: 722 case base::SystemMonitor::DEVTYPE_AUDIO:
646 case base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE: 723 case base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE:
(...skipping 19 matching lines...) Expand all
666 service() 743 service()
667 ->GetTaskRunner(kTaskRunner) 744 ->GetTaskRunner(kTaskRunner)
668 ->PostTask(FROM_HERE, base::Bind(&RunTask, instance_id_, task)); 745 ->PostTask(FROM_HERE, base::Bind(&RunTask, instance_id_, task));
669 } 746 }
670 747
671 void DynamicallyInitializedMidiManagerWin::PostReplyTask( 748 void DynamicallyInitializedMidiManagerWin::PostReplyTask(
672 const base::Closure& task) { 749 const base::Closure& task) {
673 thread_runner_->PostTask(FROM_HERE, base::Bind(&RunTask, instance_id_, task)); 750 thread_runner_->PostTask(FROM_HERE, base::Bind(&RunTask, instance_id_, task));
674 } 751 }
675 752
753 void DynamicallyInitializedMidiManagerWin::PostDelayedTask(
754 const base::Closure& task,
755 base::TimeDelta delay) {
756 service()
757 ->GetTaskRunner(kTaskRunner)
758 ->PostDelayedTask(FROM_HERE, base::Bind(&RunTask, instance_id_, task),
759 delay);
760 }
761
676 void DynamicallyInitializedMidiManagerWin::InitializeOnTaskRunner() { 762 void DynamicallyInitializedMidiManagerWin::InitializeOnTaskRunner() {
677 UpdateDeviceListOnTaskRunner(); 763 UpdateDeviceListOnTaskRunner();
678 PostReplyTask( 764 PostReplyTask(
679 base::Bind(&DynamicallyInitializedMidiManagerWin::CompleteInitialization, 765 base::Bind(&DynamicallyInitializedMidiManagerWin::CompleteInitialization,
680 base::Unretained(this), mojom::Result::OK)); 766 base::Unretained(this), mojom::Result::OK));
681 } 767 }
682 768
683 void DynamicallyInitializedMidiManagerWin::UpdateDeviceListOnTaskRunner() { 769 void DynamicallyInitializedMidiManagerWin::UpdateDeviceListOnTaskRunner() {
684 std::vector<std::unique_ptr<InPort>> active_input_ports = 770 std::vector<std::unique_ptr<InPort>> active_input_ports =
685 InPort::EnumerateActivePorts(this, instance_id_); 771 InPort::EnumerateActivePorts(this, instance_id_);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 }) == known_ports->end()) { 809 }) == known_ports->end()) {
724 size_t index = known_ports->size(); 810 size_t index = known_ports->size();
725 port->set_index(index); 811 port->set_index(index);
726 known_ports->push_back(std::move(port)); 812 known_ports->push_back(std::move(port));
727 (*known_ports)[index]->Connect(); 813 (*known_ports)[index]->Connect();
728 (*known_ports)[index]->NotifyPortAdded(this); 814 (*known_ports)[index]->NotifyPortAdded(this);
729 } 815 }
730 } 816 }
731 } 817 }
732 818
819 void DynamicallyInitializedMidiManagerWin::SendOnTaskRunner(
820 MidiManagerClient* client,
821 uint32_t port_index,
822 const std::vector<uint8_t>& data) {
823 CHECK_GT(port_manager_->outputs()->size(), port_index);
824 (*port_manager_->outputs())[port_index]->Send(data);
825 // |client| will be checked inside MidiManager::AccumulateMidiBytesSent.
826 PostReplyTask(
827 base::Bind(&DynamicallyInitializedMidiManagerWin::AccumulateMidiBytesSent,
828 base::Unretained(this), client, data.size()));
829 }
830
733 } // namespace midi 831 } // namespace midi
OLDNEW
« no previous file with comments | « media/midi/dynamically_initialized_midi_manager_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698