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
> GetDescriptor() override
{
49 logger_
->AddLog("UsbMidiDevice::GetDescriptor\n");
53 void Send(int endpoint_number
, const std::vector
<uint8
>& data
) override
{
54 logger_
->AddLog("UsbMidiDevice::Send ");
55 logger_
->AddLog(base::StringPrintf("endpoint = %d data =",
57 for (size_t i
= 0; i
< data
.size(); ++i
)
58 logger_
->AddLog(base::StringPrintf(" 0x%02x", data
[i
]));
59 logger_
->AddLog("\n");
62 void SetDescriptor(const std::vector
<uint8
> descriptor
) {
63 descriptor_
= descriptor
;
67 std::vector
<uint8
> descriptor_
;
70 DISALLOW_COPY_AND_ASSIGN(FakeUsbMidiDevice
);
73 class FakeMidiManagerClient
: public MidiManagerClient
{
75 explicit FakeMidiManagerClient(Logger
* logger
)
76 : complete_start_session_(false),
77 result_(MIDI_NOT_SUPPORTED
),
79 ~FakeMidiManagerClient() override
{}
81 void AddInputPort(const MidiPortInfo
& info
) override
{
82 input_ports_
.push_back(info
);
85 void AddOutputPort(const MidiPortInfo
& info
) override
{
86 output_ports_
.push_back(info
);
89 void SetInputPortState(uint32 port_index
, MidiPortState state
) override
{}
91 void SetOutputPortState(uint32 port_index
, MidiPortState state
) override
{}
93 void CompleteStartSession(MidiResult result
) override
{
94 complete_start_session_
= true;
98 void ReceiveMidiData(uint32 port_index
,
101 double timestamp
) override
{
102 logger_
->AddLog("MidiManagerClient::ReceiveMidiData ");
103 logger_
->AddLog(base::StringPrintf("port_index = %d data =", port_index
));
104 for (size_t i
= 0; i
< size
; ++i
)
105 logger_
->AddLog(base::StringPrintf(" 0x%02x", data
[i
]));
106 logger_
->AddLog("\n");
109 void AccumulateMidiBytesSent(size_t size
) override
{
110 logger_
->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
111 // Windows has no "%zu".
112 logger_
->AddLog(base::StringPrintf("size = %u\n",
113 static_cast<unsigned>(size
)));
116 bool complete_start_session_
;
118 MidiPortInfoList input_ports_
;
119 MidiPortInfoList output_ports_
;
124 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient
);
127 class TestUsbMidiDeviceFactory
: public UsbMidiDevice::Factory
{
129 TestUsbMidiDeviceFactory() {}
130 ~TestUsbMidiDeviceFactory() override
{}
131 void EnumerateDevices(UsbMidiDeviceDelegate
* device
,
132 Callback callback
) override
{
133 callback_
= callback
;
139 DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDeviceFactory
);
142 class MidiManagerUsbForTesting
: public MidiManagerUsb
{
144 explicit MidiManagerUsbForTesting(
145 scoped_ptr
<UsbMidiDevice::Factory
> device_factory
)
146 : MidiManagerUsb(device_factory
.Pass()) {}
147 ~MidiManagerUsbForTesting() override
{}
149 void CallCompleteInitialization(MidiResult result
) {
150 CompleteInitialization(result
);
151 base::RunLoop run_loop
;
152 run_loop
.RunUntilIdle();
156 DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbForTesting
);
159 class MidiManagerUsbTest
: public ::testing::Test
{
161 MidiManagerUsbTest() : message_loop_(new base::MessageLoop
) {
162 scoped_ptr
<TestUsbMidiDeviceFactory
> factory(new TestUsbMidiDeviceFactory
);
163 factory_
= factory
.get();
164 manager_
.reset(new MidiManagerUsbForTesting(factory
.Pass()));
166 ~MidiManagerUsbTest() override
{
167 std::string leftover_logs
= logger_
.TakeLog();
168 if (!leftover_logs
.empty()) {
169 ADD_FAILURE() << "Log should be empty: " << leftover_logs
;
175 client_
.reset(new FakeMidiManagerClient(&logger_
));
176 manager_
->StartSession(client_
.get());
180 manager_
->EndSession(client_
.get());
183 bool IsInitializationCallbackInvoked() {
184 return client_
->complete_start_session_
;
187 MidiResult
GetInitializationResult() {
188 return client_
->result_
;
191 void RunCallbackUntilCallbackInvoked(
192 bool result
, UsbMidiDevice::Devices
* devices
) {
193 factory_
->callback_
.Run(result
, devices
);
194 while (!client_
->complete_start_session_
) {
195 base::RunLoop run_loop
;
196 run_loop
.RunUntilIdle();
200 const MidiPortInfoList
& input_ports() { return client_
->input_ports_
; }
201 const MidiPortInfoList
& output_ports() { return client_
->output_ports_
; }
203 scoped_ptr
<MidiManagerUsbForTesting
> manager_
;
204 scoped_ptr
<FakeMidiManagerClient
> client_
;
205 // Owned by manager_.
206 TestUsbMidiDeviceFactory
* factory_
;
210 scoped_ptr
<base::MessageLoop
> message_loop_
;
212 DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbTest
);
216 TEST_F(MidiManagerUsbTest
, Initialize
) {
217 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
218 uint8 descriptor
[] = {
219 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
220 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
221 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
222 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
223 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
224 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
225 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
226 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
227 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
228 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
229 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
230 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
231 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
232 0x05, 0x25, 0x01, 0x01, 0x07,
234 device
->SetDescriptor(ToVector(descriptor
));
237 ScopedVector
<UsbMidiDevice
> devices
;
238 devices
.push_back(device
.release());
239 EXPECT_FALSE(IsInitializationCallbackInvoked());
240 RunCallbackUntilCallbackInvoked(true, &devices
);
241 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
243 ASSERT_EQ(1u, input_ports().size());
244 ASSERT_EQ(2u, output_ports().size());
245 ASSERT_TRUE(manager_
->input_stream());
246 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
247 ASSERT_EQ(2u, manager_
->output_streams().size());
248 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
249 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
250 ASSERT_EQ(1u, jacks
.size());
251 EXPECT_EQ(2, jacks
[0].endpoint_number());
253 EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_
.TakeLog());
256 TEST_F(MidiManagerUsbTest
, InitializeMultipleDevices
) {
257 scoped_ptr
<FakeUsbMidiDevice
> device1(new FakeUsbMidiDevice(&logger_
));
258 scoped_ptr
<FakeUsbMidiDevice
> device2(new FakeUsbMidiDevice(&logger_
));
259 uint8 descriptor
[] = {
260 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
261 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
262 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
263 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
264 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
265 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
266 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
267 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
268 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
269 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
270 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
273 device1
->SetDescriptor(ToVector(descriptor
));
274 device2
->SetDescriptor(ToVector(descriptor
));
277 ScopedVector
<UsbMidiDevice
> devices
;
278 devices
.push_back(device1
.release());
279 devices
.push_back(device2
.release());
280 EXPECT_FALSE(IsInitializationCallbackInvoked());
281 RunCallbackUntilCallbackInvoked(true, &devices
);
282 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
284 ASSERT_EQ(2u, input_ports().size());
285 ASSERT_EQ(4u, output_ports().size());
286 ASSERT_TRUE(manager_
->input_stream());
287 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
288 ASSERT_EQ(4u, manager_
->output_streams().size());
289 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
290 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
291 ASSERT_EQ(2u, jacks
.size());
292 EXPECT_EQ(2, jacks
[0].endpoint_number());
295 "UsbMidiDevice::GetDescriptor\n"
296 "UsbMidiDevice::GetDescriptor\n",
300 TEST_F(MidiManagerUsbTest
, InitializeFail
) {
303 EXPECT_FALSE(IsInitializationCallbackInvoked());
304 RunCallbackUntilCallbackInvoked(false, NULL
);
305 EXPECT_EQ(MIDI_INITIALIZATION_ERROR
, GetInitializationResult());
308 TEST_F(MidiManagerUsbTest
, InitializeFailBecauseOfInvalidDescriptor
) {
309 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
310 uint8 descriptor
[] = {0x04};
311 device
->SetDescriptor(ToVector(descriptor
));
314 ScopedVector
<UsbMidiDevice
> devices
;
315 devices
.push_back(device
.release());
316 EXPECT_FALSE(IsInitializationCallbackInvoked());
317 RunCallbackUntilCallbackInvoked(true, &devices
);
318 EXPECT_EQ(MIDI_INITIALIZATION_ERROR
, GetInitializationResult());
319 EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_
.TakeLog());
322 TEST_F(MidiManagerUsbTest
, Send
) {
324 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
325 uint8 descriptor
[] = {
326 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
327 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
328 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
329 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
330 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
331 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
332 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
333 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
334 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
335 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
336 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
337 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
338 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
339 0x05, 0x25, 0x01, 0x01, 0x07,
342 device
->SetDescriptor(ToVector(descriptor
));
345 0xf0, 0x00, 0x01, 0xf7,
348 ScopedVector
<UsbMidiDevice
> devices
;
349 devices
.push_back(device
.release());
350 EXPECT_FALSE(IsInitializationCallbackInvoked());
351 RunCallbackUntilCallbackInvoked(true, &devices
);
352 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
353 ASSERT_EQ(2u, manager_
->output_streams().size());
355 manager_
->DispatchSendMidiData(client_
.get(), 1, ToVector(data
), 0);
356 // Since UsbMidiDevice::Send is posted as a task, RunLoop should run to
358 base::RunLoop run_loop
;
359 run_loop
.RunUntilIdle();
360 EXPECT_EQ("UsbMidiDevice::GetDescriptor\n"
361 "UsbMidiDevice::Send endpoint = 2 data = "
362 "0x19 0x90 0x45 0x7f "
363 "0x14 0xf0 0x00 0x01 "
364 "0x15 0xf7 0x00 0x00\n"
365 "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
369 TEST_F(MidiManagerUsbTest
, SendFromCompromizedRenderer
) {
370 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
371 uint8 descriptor
[] = {
372 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
373 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
374 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
375 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
376 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
377 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
378 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
379 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
380 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
381 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
382 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
383 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
384 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
385 0x05, 0x25, 0x01, 0x01, 0x07,
388 device
->SetDescriptor(ToVector(descriptor
));
391 0xf0, 0x00, 0x01, 0xf7,
395 ScopedVector
<UsbMidiDevice
> devices
;
396 devices
.push_back(device
.release());
397 EXPECT_FALSE(IsInitializationCallbackInvoked());
398 RunCallbackUntilCallbackInvoked(true, &devices
);
399 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
400 ASSERT_EQ(2u, manager_
->output_streams().size());
401 EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_
.TakeLog());
403 // The specified port index is invalid. The manager must ignore the request.
404 manager_
->DispatchSendMidiData(client_
.get(), 99, ToVector(data
), 0);
405 EXPECT_EQ("", logger_
.TakeLog());
407 // The specified port index is invalid. The manager must ignore the request.
408 manager_
->DispatchSendMidiData(client_
.get(), 2, ToVector(data
), 0);
409 EXPECT_EQ("", logger_
.TakeLog());
412 TEST_F(MidiManagerUsbTest
, Receive
) {
413 scoped_ptr
<FakeUsbMidiDevice
> device(new FakeUsbMidiDevice(&logger_
));
414 uint8 descriptor
[] = {
415 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
416 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
417 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
418 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
419 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
420 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
421 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
422 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
423 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
424 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
425 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
426 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
427 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
428 0x05, 0x25, 0x01, 0x01, 0x07,
431 device
->SetDescriptor(ToVector(descriptor
));
433 0x09, 0x90, 0x45, 0x7f,
434 0x04, 0xf0, 0x00, 0x01,
435 0x49, 0x90, 0x88, 0x99, // This data should be ignored (CN = 4).
436 0x05, 0xf7, 0x00, 0x00,
440 ScopedVector
<UsbMidiDevice
> devices
;
441 UsbMidiDevice
* device_raw
= device
.get();
442 devices
.push_back(device
.release());
443 EXPECT_FALSE(IsInitializationCallbackInvoked());
444 RunCallbackUntilCallbackInvoked(true, &devices
);
445 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
447 manager_
->ReceiveUsbMidiData(device_raw
, 2, data
, arraysize(data
),
451 EXPECT_EQ("UsbMidiDevice::GetDescriptor\n"
452 "MidiManagerClient::ReceiveMidiData port_index = 0 "
453 "data = 0x90 0x45 0x7f\n"
454 "MidiManagerClient::ReceiveMidiData port_index = 0 "
455 "data = 0xf0 0x00 0x01\n"
456 "MidiManagerClient::ReceiveMidiData port_index = 0 data = 0xf7\n",
460 TEST_F(MidiManagerUsbTest
, AttachDevice
) {
461 uint8 descriptor
[] = {
462 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
463 0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
464 0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
465 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
466 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
467 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
468 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
469 0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
470 0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
471 0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
472 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
473 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
474 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
475 0x05, 0x25, 0x01, 0x01, 0x07,
479 ScopedVector
<UsbMidiDevice
> devices
;
480 EXPECT_FALSE(IsInitializationCallbackInvoked());
481 RunCallbackUntilCallbackInvoked(true, &devices
);
482 EXPECT_EQ(MIDI_OK
, GetInitializationResult());
484 ASSERT_EQ(0u, input_ports().size());
485 ASSERT_EQ(0u, output_ports().size());
486 ASSERT_TRUE(manager_
->input_stream());
487 std::vector
<UsbMidiJack
> jacks
= manager_
->input_stream()->jacks();
488 ASSERT_EQ(0u, manager_
->output_streams().size());
489 ASSERT_EQ(0u, jacks
.size());
490 EXPECT_EQ("", logger_
.TakeLog());
492 scoped_ptr
<FakeUsbMidiDevice
> new_device(new FakeUsbMidiDevice(&logger_
));
493 new_device
->SetDescriptor(ToVector(descriptor
));
494 manager_
->OnDeviceAttached(new_device
.Pass());
496 ASSERT_EQ(1u, input_ports().size());
497 ASSERT_EQ(2u, output_ports().size());
498 ASSERT_TRUE(manager_
->input_stream());
499 jacks
= manager_
->input_stream()->jacks();
500 ASSERT_EQ(2u, manager_
->output_streams().size());
501 EXPECT_EQ(2u, manager_
->output_streams()[0]->jack().jack_id
);
502 EXPECT_EQ(3u, manager_
->output_streams()[1]->jack().jack_id
);
503 ASSERT_EQ(1u, jacks
.size());
504 EXPECT_EQ(2, jacks
[0].endpoint_number());
505 EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_
.TakeLog());