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"
21 template<typename T
, size_t N
>
22 std::vector
<T
> ToVector(const T (&array
)[N
]) {
23 return std::vector
<T
>(array
, array
+ N
);
31 void AddLog(const std::string
& message
) { log_
+= message
; }
32 std::string
TakeLog() {
41 DISALLOW_COPY_AND_ASSIGN(Logger
);
44 class FakeUsbMidiDevice
: public UsbMidiDevice
{
46 explicit FakeUsbMidiDevice(Logger
* logger
) : logger_(logger
) {}
47 ~FakeUsbMidiDevice() override
{}
49 std::vector
<uint8
> GetDescriptors() override
{
50 logger_
->AddLog("UsbMidiDevice::GetDescriptors\n");
54 std::string
GetManufacturer() override
{ return manufacturer_
; }
55 std::string
GetProductName() override
{ return product_name_
; }
56 std::string
GetDeviceVersion() override
{ return device_version_
; }
58 void Send(int endpoint_number
, const std::vector
<uint8
>& data
) override
{
59 logger_
->AddLog("UsbMidiDevice::Send ");
60 logger_
->AddLog(base::StringPrintf("endpoint = %d data =",
62 for (size_t i
= 0; i
< data
.size(); ++i
)
63 logger_
->AddLog(base::StringPrintf(" 0x%02x", data
[i
]));
64 logger_
->AddLog("\n");
67 void SetDescriptors(const std::vector
<uint8
> descriptors
) {
68 descriptors_
= descriptors
;
70 void SetManufacturer(const std::string
& manufacturer
) {
71 manufacturer_
= manufacturer
;
73 void SetProductName(const std::string
& product_name
) {
74 product_name_
= product_name
;
76 void SetDeviceVersion(const std::string
& device_version
) {
77 device_version_
= device_version
;
81 std::vector
<uint8
> descriptors_
;
82 std::string manufacturer_
;
83 std::string product_name_
;
84 std::string device_version_
;
87 DISALLOW_COPY_AND_ASSIGN(FakeUsbMidiDevice
);
90 class FakeMidiManagerClient
: public MidiManagerClient
{
92 explicit FakeMidiManagerClient(Logger
* logger
)
93 : complete_start_session_(false),
94 result_(MIDI_NOT_SUPPORTED
),
96 ~FakeMidiManagerClient() override
{}
98 void AddInputPort(const MidiPortInfo
& info
) override
{
99 input_ports_
.push_back(info
);
102 void AddOutputPort(const MidiPortInfo
& info
) override
{
103 output_ports_
.push_back(info
);
106 void SetInputPortState(uint32 port_index
, MidiPortState state
) override
{}
108 void SetOutputPortState(uint32 port_index
, MidiPortState state
) override
{}
110 void CompleteStartSession(MidiResult result
) override
{
111 complete_start_session_
= true;
115 void ReceiveMidiData(uint32 port_index
,
118 double timestamp
) override
{
119 logger_
->AddLog("MidiManagerClient::ReceiveMidiData ");
120 logger_
->AddLog(base::StringPrintf("port_index = %d data =", port_index
));
121 for (size_t i
= 0; i
< size
; ++i
)
122 logger_
->AddLog(base::StringPrintf(" 0x%02x", data
[i
]));
123 logger_
->AddLog("\n");
126 void AccumulateMidiBytesSent(size_t size
) override
{
127 logger_
->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
128 // Windows has no "%zu".
129 logger_
->AddLog(base::StringPrintf("size = %u\n",
130 static_cast<unsigned>(size
)));
133 bool complete_start_session_
;
135 MidiPortInfoList input_ports_
;
136 MidiPortInfoList output_ports_
;
141 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient
);
144 class TestUsbMidiDeviceFactory
: public UsbMidiDevice::Factory
{
146 TestUsbMidiDeviceFactory() {}
147 ~TestUsbMidiDeviceFactory() override
{}
148 void EnumerateDevices(UsbMidiDeviceDelegate
* device
,
149 Callback callback
) override
{
150 callback_
= callback
;
156 DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDeviceFactory
);
159 class MidiManagerUsbForTesting
: public MidiManagerUsb
{
161 explicit MidiManagerUsbForTesting(
162 scoped_ptr
<UsbMidiDevice::Factory
> device_factory
)
163 : MidiManagerUsb(device_factory
.Pass()) {}
164 ~MidiManagerUsbForTesting() override
{}
166 void CallCompleteInitialization(MidiResult result
) {
167 CompleteInitialization(result
);
168 base::RunLoop run_loop
;
169 run_loop
.RunUntilIdle();
173 DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbForTesting
);
176 class MidiManagerUsbTest
: public ::testing::Test
{
178 MidiManagerUsbTest() : message_loop_(new base::MessageLoop
) {
179 scoped_ptr
<TestUsbMidiDeviceFactory
> factory(new TestUsbMidiDeviceFactory
);
180 factory_
= factory
.get();
181 manager_
.reset(new MidiManagerUsbForTesting(factory
.Pass()));
183 ~MidiManagerUsbTest() override
{
184 std::string leftover_logs
= logger_
.TakeLog();
185 if (!leftover_logs
.empty()) {
186 ADD_FAILURE() << "Log should be empty: " << leftover_logs
;
192 client_
.reset(new FakeMidiManagerClient(&logger_
));
193 manager_
->StartSession(client_
.get());
197 manager_
->EndSession(client_
.get());
200 bool IsInitializationCallbackInvoked() {
201 return client_
->complete_start_session_
;
204 MidiResult
GetInitializationResult() {
205 return client_
->result_
;
208 void RunCallbackUntilCallbackInvoked(
209 bool result
, UsbMidiDevice::Devices
* devices
) {
210 factory_
->callback_
.Run(result
, devices
);
211 while (!client_
->complete_start_session_
) {
212 base::RunLoop run_loop
;
213 run_loop
.RunUntilIdle();
217 const MidiPortInfoList
& input_ports() { return client_
->input_ports_
; }
218 const MidiPortInfoList
& output_ports() { return client_
->output_ports_
; }
220 scoped_ptr
<MidiManagerUsbForTesting
> manager_
;
221 scoped_ptr
<FakeMidiManagerClient
> client_
;
222 // Owned by manager_.
223 TestUsbMidiDeviceFactory
* factory_
;
227 scoped_ptr
<base::MessageLoop
> message_loop_
;
229 DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbTest
);
233 TEST_F(MidiManagerUsbTest
, Initialize
) {
234 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
235 uint8 descriptors
[] = {
236 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
237 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
238 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
239 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
240 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
241 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
242 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
243 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
244 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
245 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
246 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
247 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
248 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
249 0x05, 0x25, 0x01, 0x01, 0x07,
251 device
->SetDescriptors(ToVector(descriptors
));
252 device
->SetManufacturer("vendor1");
253 device
->SetProductName("device1");
254 device
->SetDeviceVersion("1.02");
257 ScopedVector
<UsbMidiDevice
> devices
;
258 devices
.push_back(device
.Pass());
259 EXPECT_FALSE(IsInitializationCallbackInvoked());
260 RunCallbackUntilCallbackInvoked(true, &devices
);
261 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
263 ASSERT_EQ(1u, input_ports().size());
264 EXPECT_EQ("port-0-2", input_ports()[0].id
);
265 EXPECT_EQ("vendor1", input_ports()[0].manufacturer
);
266 EXPECT_EQ("device1", input_ports()[0].name
);
267 EXPECT_EQ("1.02", input_ports()[0].version
);
269 ASSERT_EQ(2u, output_ports().size());
270 EXPECT_EQ("port-0-0", output_ports()[0].id
);
271 EXPECT_EQ("vendor1", output_ports()[0].manufacturer
);
272 EXPECT_EQ("device1", output_ports()[0].name
);
273 EXPECT_EQ("1.02", output_ports()[0].version
);
274 EXPECT_EQ("port-0-1", output_ports()[1].id
);
275 EXPECT_EQ("vendor1", output_ports()[1].manufacturer
);
276 EXPECT_EQ("device1", output_ports()[1].name
);
277 EXPECT_EQ("1.02", output_ports()[1].version
);
279 ASSERT_TRUE(manager_
->input_stream());
280 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
281 ASSERT_EQ(2u, manager_
->output_streams().size());
282 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
283 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
284 ASSERT_EQ(1u, jacks
.size());
285 EXPECT_EQ(2, jacks
[0].endpoint_number());
287 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());
290 TEST_F(MidiManagerUsbTest
, InitializeMultipleDevices
) {
291 scoped_ptr
<FakeUsbMidiDevice
> device1(new FakeUsbMidiDevice(&logger_
));
292 scoped_ptr
<FakeUsbMidiDevice
> device2(new FakeUsbMidiDevice(&logger_
));
293 uint8 descriptors
[] = {
294 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
295 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
296 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
297 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
298 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
299 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
300 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
301 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
302 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
303 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
304 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
307 device1
->SetDescriptors(ToVector(descriptors
));
308 device1
->SetManufacturer("vendor1");
309 device1
->SetProductName("device1");
310 device1
->SetDeviceVersion("1.02");
311 device2
->SetDescriptors(ToVector(descriptors
));
312 device2
->SetManufacturer("vendor2");
313 device2
->SetProductName("device2");
314 device2
->SetDeviceVersion("98.76");
317 ScopedVector
<UsbMidiDevice
> devices
;
318 devices
.push_back(device1
.Pass());
319 devices
.push_back(device2
.Pass());
320 EXPECT_FALSE(IsInitializationCallbackInvoked());
321 RunCallbackUntilCallbackInvoked(true, &devices
);
322 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
324 ASSERT_EQ(2u, input_ports().size());
325 EXPECT_EQ("port-0-2", input_ports()[0].id
);
326 EXPECT_EQ("vendor1", input_ports()[0].manufacturer
);
327 EXPECT_EQ("device1", input_ports()[0].name
);
328 EXPECT_EQ("1.02", input_ports()[0].version
);
329 EXPECT_EQ("port-1-2", input_ports()[1].id
);
330 EXPECT_EQ("vendor2", input_ports()[1].manufacturer
);
331 EXPECT_EQ("device2", input_ports()[1].name
);
332 EXPECT_EQ("98.76", input_ports()[1].version
);
334 ASSERT_EQ(4u, output_ports().size());
335 EXPECT_EQ("port-0-0", output_ports()[0].id
);
336 EXPECT_EQ("vendor1", output_ports()[0].manufacturer
);
337 EXPECT_EQ("device1", output_ports()[0].name
);
338 EXPECT_EQ("1.02", output_ports()[0].version
);
339 EXPECT_EQ("port-0-1", output_ports()[1].id
);
340 EXPECT_EQ("vendor1", output_ports()[1].manufacturer
);
341 EXPECT_EQ("device1", output_ports()[1].name
);
342 EXPECT_EQ("1.02", output_ports()[1].version
);
343 EXPECT_EQ("port-1-0", output_ports()[2].id
);
344 EXPECT_EQ("vendor2", output_ports()[2].manufacturer
);
345 EXPECT_EQ("device2", output_ports()[2].name
);
346 EXPECT_EQ("98.76", output_ports()[2].version
);
347 EXPECT_EQ("port-1-1", output_ports()[3].id
);
348 EXPECT_EQ("vendor2", output_ports()[3].manufacturer
);
349 EXPECT_EQ("device2", output_ports()[3].name
);
350 EXPECT_EQ("98.76", output_ports()[3].version
);
352 ASSERT_TRUE(manager_
->input_stream());
353 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
354 ASSERT_EQ(4u, manager_
->output_streams().size());
355 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
356 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
357 ASSERT_EQ(2u, jacks
.size());
358 EXPECT_EQ(2, jacks
[0].endpoint_number());
361 "UsbMidiDevice::GetDescriptors\n"
362 "UsbMidiDevice::GetDescriptors\n",
366 TEST_F(MidiManagerUsbTest
, InitializeFail
) {
369 EXPECT_FALSE(IsInitializationCallbackInvoked());
370 RunCallbackUntilCallbackInvoked(false, NULL
);
371 EXPECT_EQ(MIDI_INITIALIZATION_ERROR
, GetInitializationResult());
374 TEST_F(MidiManagerUsbTest
, InitializeFailBecauseOfInvalidDescriptors
) {
375 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
376 uint8 descriptors
[] = {0x04};
377 device
->SetDescriptors(ToVector(descriptors
));
380 ScopedVector
<UsbMidiDevice
> devices
;
381 devices
.push_back(device
.Pass());
382 EXPECT_FALSE(IsInitializationCallbackInvoked());
383 RunCallbackUntilCallbackInvoked(true, &devices
);
384 EXPECT_EQ(MIDI_INITIALIZATION_ERROR
, GetInitializationResult());
385 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());
388 TEST_F(MidiManagerUsbTest
, Send
) {
390 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
391 uint8 descriptors
[] = {
392 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
393 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
394 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
395 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
396 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
397 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
398 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
399 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
400 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
401 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
402 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
403 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
404 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
405 0x05, 0x25, 0x01, 0x01, 0x07,
408 device
->SetDescriptors(ToVector(descriptors
));
411 0xf0, 0x00, 0x01, 0xf7,
414 ScopedVector
<UsbMidiDevice
> devices
;
415 devices
.push_back(device
.Pass());
416 EXPECT_FALSE(IsInitializationCallbackInvoked());
417 RunCallbackUntilCallbackInvoked(true, &devices
);
418 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
419 ASSERT_EQ(2u, manager_
->output_streams().size());
421 manager_
->DispatchSendMidiData(client_
.get(), 1, ToVector(data
), 0);
422 // Since UsbMidiDevice::Send is posted as a task, RunLoop should run to
424 base::RunLoop run_loop
;
425 run_loop
.RunUntilIdle();
426 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
427 "UsbMidiDevice::Send endpoint = 2 data = "
428 "0x19 0x90 0x45 0x7f "
429 "0x14 0xf0 0x00 0x01 "
430 "0x15 0xf7 0x00 0x00\n"
431 "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
435 TEST_F(MidiManagerUsbTest
, SendFromCompromizedRenderer
) {
436 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
437 uint8 descriptors
[] = {
438 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
439 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
440 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
441 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
442 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
443 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
444 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
445 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
446 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
447 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
448 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
449 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
450 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
451 0x05, 0x25, 0x01, 0x01, 0x07,
454 device
->SetDescriptors(ToVector(descriptors
));
457 0xf0, 0x00, 0x01, 0xf7,
461 ScopedVector
<UsbMidiDevice
> devices
;
462 devices
.push_back(device
.Pass());
463 EXPECT_FALSE(IsInitializationCallbackInvoked());
464 RunCallbackUntilCallbackInvoked(true, &devices
);
465 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
466 ASSERT_EQ(2u, manager_
->output_streams().size());
467 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());
469 // The specified port index is invalid. The manager must ignore the request.
470 manager_
->DispatchSendMidiData(client_
.get(), 99, ToVector(data
), 0);
471 EXPECT_EQ("", logger_
.TakeLog());
473 // The specified port index is invalid. The manager must ignore the request.
474 manager_
->DispatchSendMidiData(client_
.get(), 2, ToVector(data
), 0);
475 EXPECT_EQ("", logger_
.TakeLog());
478 TEST_F(MidiManagerUsbTest
, Receive
) {
479 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
480 uint8 descriptors
[] = {
481 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
482 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
483 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
484 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
485 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
486 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
487 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
488 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
489 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
490 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
491 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
492 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
493 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
494 0x05, 0x25, 0x01, 0x01, 0x07,
497 device
->SetDescriptors(ToVector(descriptors
));
499 0x09, 0x90, 0x45, 0x7f,
500 0x04, 0xf0, 0x00, 0x01,
501 0x49, 0x90, 0x88, 0x99, // This data should be ignored (CN = 4).
502 0x05, 0xf7, 0x00, 0x00,
506 ScopedVector
<UsbMidiDevice
> devices
;
507 UsbMidiDevice
* device_raw
= device
.get();
508 devices
.push_back(device
.Pass());
509 EXPECT_FALSE(IsInitializationCallbackInvoked());
510 RunCallbackUntilCallbackInvoked(true, &devices
);
511 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
513 manager_
->ReceiveUsbMidiData(device_raw
, 2, data
, arraysize(data
),
517 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
518 "MidiManagerClient::ReceiveMidiData port_index = 0 "
519 "data = 0x90 0x45 0x7f\n"
520 "MidiManagerClient::ReceiveMidiData port_index = 0 "
521 "data = 0xf0 0x00 0x01\n"
522 "MidiManagerClient::ReceiveMidiData port_index = 0 data = 0xf7\n",
526 TEST_F(MidiManagerUsbTest
, AttachDevice
) {
527 uint8 descriptors
[] = {
528 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
529 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
530 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
531 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
532 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
533 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
534 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
535 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
536 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
537 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
538 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
539 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
540 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
541 0x05, 0x25, 0x01, 0x01, 0x07,
545 ScopedVector
<UsbMidiDevice
> devices
;
546 EXPECT_FALSE(IsInitializationCallbackInvoked());
547 RunCallbackUntilCallbackInvoked(true, &devices
);
548 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
550 ASSERT_EQ(0u, input_ports().size());
551 ASSERT_EQ(0u, output_ports().size());
552 ASSERT_TRUE(manager_
->input_stream());
553 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
554 ASSERT_EQ(0u, manager_
->output_streams().size());
555 ASSERT_EQ(0u, jacks
.size());
556 EXPECT_EQ("", logger_
.TakeLog());
558 scoped_ptr
<FakeUsbMidiDevice
> new_device(new FakeUsbMidiDevice(&logger_
));
559 new_device
->SetDescriptors(ToVector(descriptors
));
560 manager_
->OnDeviceAttached(new_device
.Pass());
562 ASSERT_EQ(1u, input_ports().size());
563 ASSERT_EQ(2u, output_ports().size());
564 ASSERT_TRUE(manager_
->input_stream());
565 jacks
= manager_
->input_stream()->jacks();
566 ASSERT_EQ(2u, manager_
->output_streams().size());
567 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
568 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
569 ASSERT_EQ(1u, jacks
.size());
570 EXPECT_EQ(2, jacks
[0].endpoint_number());
571 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_
.TakeLog());