1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/midi/midi_manager_usb.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/time/time.h"
13 #include "media/midi/usb_midi_device.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 template<typename T
, size_t N
>
21 std::vector
<T
> ToVector(const T (&array
)[N
]) {
22 return std::vector
<T
>(array
, array
+ N
);
30 void AddLog(const std::string
& message
) { log_
+= message
; }
31 std::string
TakeLog() {
40 DISALLOW_COPY_AND_ASSIGN(Logger
);
43 class FakeUsbMidiDevice
: public UsbMidiDevice
{
45 explicit FakeUsbMidiDevice(Logger
* logger
) : logger_(logger
) {}
46 ~FakeUsbMidiDevice() override
{}
48 std::vector
<uint8
> GetDescriptors() override
{
49 logger_
->AddLog("UsbMidiDevice::GetDescriptors\n");
53 std::string
GetManufacturer() override
{ return manufacturer_
; }
54 std::string
GetProductName() override
{ return product_name_
; }
55 std::string
GetDeviceVersion() override
{ return device_version_
; }
57 void Send(int endpoint_number
, const std::vector
<uint8
>& data
) override
{
58 logger_
->AddLog("UsbMidiDevice::Send ");
59 logger_
->AddLog(base::StringPrintf("endpoint = %d data =",
61 for (size_t i
= 0; i
< data
.size(); ++i
)
62 logger_
->AddLog(base::StringPrintf(" 0x%02x", data
[i
]));
63 logger_
->AddLog("\n");
66 void SetDescriptors(const std::vector
<uint8
> descriptors
) {
67 descriptors_
= descriptors
;
69 void SetManufacturer(const std::string
& manufacturer
) {
70 manufacturer_
= manufacturer
;
72 void SetProductName(const std::string
& product_name
) {
73 product_name_
= product_name
;
75 void SetDeviceVersion(const std::string
& device_version
) {
76 device_version_
= device_version
;
80 std::vector
<uint8
> descriptors_
;
81 std::string manufacturer_
;
82 std::string product_name_
;
83 std::string device_version_
;
86 DISALLOW_COPY_AND_ASSIGN(FakeUsbMidiDevice
);
89 class FakeMidiManagerClient
: public MidiManagerClient
{
91 explicit FakeMidiManagerClient(Logger
* logger
)
92 : complete_start_session_(false),
93 result_(MIDI_NOT_SUPPORTED
),
95 ~FakeMidiManagerClient() override
{}
97 void AddInputPort(const MidiPortInfo
& info
) override
{
98 input_ports_
.push_back(info
);
101 void AddOutputPort(const MidiPortInfo
& info
) override
{
102 output_ports_
.push_back(info
);
105 void SetInputPortState(uint32 port_index
, MidiPortState state
) override
{}
107 void SetOutputPortState(uint32 port_index
, MidiPortState state
) override
{}
109 void CompleteStartSession(MidiResult result
) override
{
110 complete_start_session_
= true;
114 void ReceiveMidiData(uint32 port_index
,
117 double timestamp
) override
{
118 logger_
->AddLog("MidiManagerClient::ReceiveMidiData ");
119 logger_
->AddLog(base::StringPrintf("port_index = %d data =", port_index
));
120 for (size_t i
= 0; i
< size
; ++i
)
121 logger_
->AddLog(base::StringPrintf(" 0x%02x", data
[i
]));
122 logger_
->AddLog("\n");
125 void AccumulateMidiBytesSent(size_t size
) override
{
126 logger_
->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
127 // Windows has no "%zu".
128 logger_
->AddLog(base::StringPrintf("size = %u\n",
129 static_cast<unsigned>(size
)));
132 bool complete_start_session_
;
134 MidiPortInfoList input_ports_
;
135 MidiPortInfoList output_ports_
;
140 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient
);
143 class TestUsbMidiDeviceFactory
: public UsbMidiDevice::Factory
{
145 TestUsbMidiDeviceFactory() {}
146 ~TestUsbMidiDeviceFactory() override
{}
147 void EnumerateDevices(UsbMidiDeviceDelegate
* device
,
148 Callback callback
) override
{
149 callback_
= callback
;
155 DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDeviceFactory
);
158 class MidiManagerUsbForTesting
: public MidiManagerUsb
{
160 explicit MidiManagerUsbForTesting(
161 scoped_ptr
<UsbMidiDevice::Factory
> device_factory
)
162 : MidiManagerUsb(device_factory
.Pass()) {}
163 ~MidiManagerUsbForTesting() override
{}
165 void CallCompleteInitialization(MidiResult result
) {
166 CompleteInitialization(result
);
167 base::RunLoop run_loop
;
168 run_loop
.RunUntilIdle();
172 DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbForTesting
);
175 class MidiManagerUsbTest
: public ::testing::Test
{
177 MidiManagerUsbTest() : message_loop_(new base::MessageLoop
) {
178 scoped_ptr
<TestUsbMidiDeviceFactory
> factory(new TestUsbMidiDeviceFactory
);
179 factory_
= factory
.get();
180 manager_
.reset(new MidiManagerUsbForTesting(factory
.Pass()));
182 ~MidiManagerUsbTest() override
{
183 std::string leftover_logs
= logger_
.TakeLog();
184 if (!leftover_logs
.empty()) {
185 ADD_FAILURE() << "Log should be empty: " << leftover_logs
;
191 client_
.reset(new FakeMidiManagerClient(&logger_
));
192 manager_
->StartSession(client_
.get());
196 manager_
->EndSession(client_
.get());
199 bool IsInitializationCallbackInvoked() {
200 return client_
->complete_start_session_
;
203 MidiResult
GetInitializationResult() {
204 return client_
->result_
;
207 void RunCallbackUntilCallbackInvoked(
208 bool result
, UsbMidiDevice::Devices
* devices
) {
209 factory_
->callback_
.Run(result
, devices
);
210 while (!client_
->complete_start_session_
) {
211 base::RunLoop run_loop
;
212 run_loop
.RunUntilIdle();
216 const MidiPortInfoList
& input_ports() { return client_
->input_ports_
; }
217 const MidiPortInfoList
& output_ports() { return client_
->output_ports_
; }
219 scoped_ptr
<MidiManagerUsbForTesting
> manager_
;
220 scoped_ptr
<FakeMidiManagerClient
> client_
;
221 // Owned by manager_.
222 TestUsbMidiDeviceFactory
* factory_
;
226 scoped_ptr
<base::MessageLoop
> message_loop_
;
228 DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbTest
);
232 TEST_F(MidiManagerUsbTest
, Initialize
) {
233 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
234 uint8 descriptors
[] = {
235 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
236 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
237 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
238 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
239 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
240 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
241 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
242 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
243 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
244 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
245 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
246 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
247 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
248 0x05, 0x25, 0x01, 0x01, 0x07,
250 device
->SetDescriptors(ToVector(descriptors
));
251 device
->SetManufacturer("vendor1");
252 device
->SetProductName("device1");
253 device
->SetDeviceVersion("1.02");
256 ScopedVector
<UsbMidiDevice
> devices
;
257 devices
.push_back(device
.release());
258 EXPECT_FALSE(IsInitializationCallbackInvoked());
259 RunCallbackUntilCallbackInvoked(true, &devices
);
260 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
262 ASSERT_EQ(1u, input_ports().size());
263 EXPECT_EQ("port-0-2", input_ports()[0].id
);
264 EXPECT_EQ("vendor1", input_ports()[0].manufacturer
);
265 EXPECT_EQ("device1", input_ports()[0].name
);
266 EXPECT_EQ("1.02", input_ports()[0].version
);
268 ASSERT_EQ(2u, output_ports().size());
269 EXPECT_EQ("port-0-0", output_ports()[0].id
);
270 EXPECT_EQ("vendor1", output_ports()[0].manufacturer
);
271 EXPECT_EQ("device1", output_ports()[0].name
);
272 EXPECT_EQ("1.02", output_ports()[0].version
);
273 EXPECT_EQ("port-0-1", output_ports()[1].id
);
274 EXPECT_EQ("vendor1", output_ports()[1].manufacturer
);
275 EXPECT_EQ("device1", output_ports()[1].name
);
276 EXPECT_EQ("1.02", output_ports()[1].version
);
278 ASSERT_TRUE(manager_
->input_stream());
279 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
280 ASSERT_EQ(2u, manager_
->output_streams().size());
281 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
282 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
283 ASSERT_EQ(1u, jacks
.size());
284 EXPECT_EQ(2, jacks
[0].endpoint_number());
286 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());
289 TEST_F(MidiManagerUsbTest
, InitializeMultipleDevices
) {
290 scoped_ptr
<FakeUsbMidiDevice
> device1(new FakeUsbMidiDevice(&logger_
));
291 scoped_ptr
<FakeUsbMidiDevice
> device2(new FakeUsbMidiDevice(&logger_
));
292 uint8 descriptors
[] = {
293 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
294 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
295 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
296 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
297 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
298 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
299 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
300 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
301 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
302 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
303 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
306 device1
->SetDescriptors(ToVector(descriptors
));
307 device1
->SetManufacturer("vendor1");
308 device1
->SetProductName("device1");
309 device1
->SetDeviceVersion("1.02");
310 device2
->SetDescriptors(ToVector(descriptors
));
311 device2
->SetManufacturer("vendor2");
312 device2
->SetProductName("device2");
313 device2
->SetDeviceVersion("98.76");
316 ScopedVector
<UsbMidiDevice
> devices
;
317 devices
.push_back(device1
.release());
318 devices
.push_back(device2
.release());
319 EXPECT_FALSE(IsInitializationCallbackInvoked());
320 RunCallbackUntilCallbackInvoked(true, &devices
);
321 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
323 ASSERT_EQ(2u, input_ports().size());
324 EXPECT_EQ("port-0-2", input_ports()[0].id
);
325 EXPECT_EQ("vendor1", input_ports()[0].manufacturer
);
326 EXPECT_EQ("device1", input_ports()[0].name
);
327 EXPECT_EQ("1.02", input_ports()[0].version
);
328 EXPECT_EQ("port-1-2", input_ports()[1].id
);
329 EXPECT_EQ("vendor2", input_ports()[1].manufacturer
);
330 EXPECT_EQ("device2", input_ports()[1].name
);
331 EXPECT_EQ("98.76", input_ports()[1].version
);
333 ASSERT_EQ(4u, output_ports().size());
334 EXPECT_EQ("port-0-0", output_ports()[0].id
);
335 EXPECT_EQ("vendor1", output_ports()[0].manufacturer
);
336 EXPECT_EQ("device1", output_ports()[0].name
);
337 EXPECT_EQ("1.02", output_ports()[0].version
);
338 EXPECT_EQ("port-0-1", output_ports()[1].id
);
339 EXPECT_EQ("vendor1", output_ports()[1].manufacturer
);
340 EXPECT_EQ("device1", output_ports()[1].name
);
341 EXPECT_EQ("1.02", output_ports()[1].version
);
342 EXPECT_EQ("port-1-0", output_ports()[2].id
);
343 EXPECT_EQ("vendor2", output_ports()[2].manufacturer
);
344 EXPECT_EQ("device2", output_ports()[2].name
);
345 EXPECT_EQ("98.76", output_ports()[2].version
);
346 EXPECT_EQ("port-1-1", output_ports()[3].id
);
347 EXPECT_EQ("vendor2", output_ports()[3].manufacturer
);
348 EXPECT_EQ("device2", output_ports()[3].name
);
349 EXPECT_EQ("98.76", output_ports()[3].version
);
351 ASSERT_TRUE(manager_
->input_stream());
352 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
353 ASSERT_EQ(4u, manager_
->output_streams().size());
354 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
355 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
356 ASSERT_EQ(2u, jacks
.size());
357 EXPECT_EQ(2, jacks
[0].endpoint_number());
360 "UsbMidiDevice::GetDescriptors\n"
361 "UsbMidiDevice::GetDescriptors\n",
365 TEST_F(MidiManagerUsbTest
, InitializeFail
) {
368 EXPECT_FALSE(IsInitializationCallbackInvoked());
369 RunCallbackUntilCallbackInvoked(false, NULL
);
370 EXPECT_EQ(MIDI_INITIALIZATION_ERROR
, GetInitializationResult());
373 TEST_F(MidiManagerUsbTest
, InitializeFailBecauseOfInvalidDescriptors
) {
374 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
375 uint8 descriptors
[] = {0x04};
376 device
->SetDescriptors(ToVector(descriptors
));
379 ScopedVector
<UsbMidiDevice
> devices
;
380 devices
.push_back(device
.release());
381 EXPECT_FALSE(IsInitializationCallbackInvoked());
382 RunCallbackUntilCallbackInvoked(true, &devices
);
383 EXPECT_EQ(MIDI_INITIALIZATION_ERROR
, GetInitializationResult());
384 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());
387 TEST_F(MidiManagerUsbTest
, Send
) {
389 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
390 uint8 descriptors
[] = {
391 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
392 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
393 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
394 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
395 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
396 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
397 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
398 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
399 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
400 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
401 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
402 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
403 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
404 0x05, 0x25, 0x01, 0x01, 0x07,
407 device
->SetDescriptors(ToVector(descriptors
));
410 0xf0, 0x00, 0x01, 0xf7,
413 ScopedVector
<UsbMidiDevice
> devices
;
414 devices
.push_back(device
.release());
415 EXPECT_FALSE(IsInitializationCallbackInvoked());
416 RunCallbackUntilCallbackInvoked(true, &devices
);
417 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
418 ASSERT_EQ(2u, manager_
->output_streams().size());
420 manager_
->DispatchSendMidiData(client_
.get(), 1, ToVector(data
), 0);
421 // Since UsbMidiDevice::Send is posted as a task, RunLoop should run to
423 base::RunLoop run_loop
;
424 run_loop
.RunUntilIdle();
425 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
426 "UsbMidiDevice::Send endpoint = 2 data = "
427 "0x19 0x90 0x45 0x7f "
428 "0x14 0xf0 0x00 0x01 "
429 "0x15 0xf7 0x00 0x00\n"
430 "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
434 TEST_F(MidiManagerUsbTest
, SendFromCompromizedRenderer
) {
435 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
436 uint8 descriptors
[] = {
437 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
438 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
439 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
440 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
441 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
442 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
443 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
444 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
445 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
446 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
447 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
448 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
449 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
450 0x05, 0x25, 0x01, 0x01, 0x07,
453 device
->SetDescriptors(ToVector(descriptors
));
456 0xf0, 0x00, 0x01, 0xf7,
460 ScopedVector
<UsbMidiDevice
> devices
;
461 devices
.push_back(device
.release());
462 EXPECT_FALSE(IsInitializationCallbackInvoked());
463 RunCallbackUntilCallbackInvoked(true, &devices
);
464 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
465 ASSERT_EQ(2u, manager_
->output_streams().size());
466 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());
468 // The specified port index is invalid. The manager must ignore the request.
469 manager_
->DispatchSendMidiData(client_
.get(), 99, ToVector(data
), 0);
470 EXPECT_EQ("", logger_
.TakeLog());
472 // The specified port index is invalid. The manager must ignore the request.
473 manager_
->DispatchSendMidiData(client_
.get(), 2, ToVector(data
), 0);
474 EXPECT_EQ("", logger_
.TakeLog());
477 TEST_F(MidiManagerUsbTest
, Receive
) {
478 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
479 uint8 descriptors
[] = {
480 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
481 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
482 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
483 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
484 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
485 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
486 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
487 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
488 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
489 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
490 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
491 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
492 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
493 0x05, 0x25, 0x01, 0x01, 0x07,
496 device
->SetDescriptors(ToVector(descriptors
));
498 0x09, 0x90, 0x45, 0x7f,
499 0x04, 0xf0, 0x00, 0x01,
500 0x49, 0x90, 0x88, 0x99, // This data should be ignored (CN = 4).
501 0x05, 0xf7, 0x00, 0x00,
505 ScopedVector
<UsbMidiDevice
> devices
;
506 UsbMidiDevice
* device_raw
= device
.get();
507 devices
.push_back(device
.release());
508 EXPECT_FALSE(IsInitializationCallbackInvoked());
509 RunCallbackUntilCallbackInvoked(true, &devices
);
510 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
512 manager_
->ReceiveUsbMidiData(device_raw
, 2, data
, arraysize(data
),
516 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
517 "MidiManagerClient::ReceiveMidiData port_index = 0 "
518 "data = 0x90 0x45 0x7f\n"
519 "MidiManagerClient::ReceiveMidiData port_index = 0 "
520 "data = 0xf0 0x00 0x01\n"
521 "MidiManagerClient::ReceiveMidiData port_index = 0 data = 0xf7\n",
525 TEST_F(MidiManagerUsbTest
, AttachDevice
) {
526 uint8 descriptors
[] = {
527 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
528 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
529 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
530 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
531 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
532 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
533 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
534 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
535 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
536 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
537 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
538 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
539 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
540 0x05, 0x25, 0x01, 0x01, 0x07,
544 ScopedVector
<UsbMidiDevice
> devices
;
545 EXPECT_FALSE(IsInitializationCallbackInvoked());
546 RunCallbackUntilCallbackInvoked(true, &devices
);
547 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
549 ASSERT_EQ(0u, input_ports().size());
550 ASSERT_EQ(0u, output_ports().size());
551 ASSERT_TRUE(manager_
->input_stream());
552 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
553 ASSERT_EQ(0u, manager_
->output_streams().size());
554 ASSERT_EQ(0u, jacks
.size());
555 EXPECT_EQ("", logger_
.TakeLog());
557 scoped_ptr
<FakeUsbMidiDevice
> new_device(new FakeUsbMidiDevice(&logger_
));
558 new_device
->SetDescriptors(ToVector(descriptors
));
559 manager_
->OnDeviceAttached(new_device
.Pass());
561 ASSERT_EQ(1u, input_ports().size());
562 ASSERT_EQ(2u, output_ports().size());
563 ASSERT_TRUE(manager_
->input_stream());
564 jacks
= manager_
->input_stream()->jacks();
565 ASSERT_EQ(2u, manager_
->output_streams().size());
566 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
567 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
568 ASSERT_EQ(1u, jacks
.size());
569 EXPECT_EQ(2, jacks
[0].endpoint_number());
570 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());