blob: c7713f54e2fb86fca24fecfad6aceb46c548427f [file] [log] [blame]
yhirano@chromium.org3cecb692014-01-29 09:27:41 +00001// 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.
4
5#include "media/midi/midi_manager_usb.h"
6
avi793390d2015-12-22 22:22:36 -08007#include <stddef.h>
8#include <stdint.h>
danakj75afea02016-04-25 20:36:04 -07009#include <memory>
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000010#include <string>
dchengc2aeece2015-12-27 00:54:00 -080011#include <utility>
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000012
Lei Zhang21a44532021-05-26 19:26:48 +000013#include "base/cxx17_backports.h"
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +000014#include "base/run_loop.h"
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000015#include "base/strings/stringprintf.h"
Carlos Caballero10135c22019-12-02 08:40:23 +000016#include "base/test/task_environment.h"
yhirano@chromium.orgcfa642c2014-05-01 08:54:41 +000017#include "base/time/time.h"
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +000018#include "media/midi/midi_service.h"
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000019#include "media/midi/usb_midi_device.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
toyoshime147c5e2015-05-07 21:58:31 -070022namespace midi {
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000023
24namespace {
25
toyoshimec2570a2016-10-21 02:15:27 -070026using mojom::PortState;
toyoshim2f3a48f2016-10-17 01:54:13 -070027using mojom::Result;
28
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000029template<typename T, size_t N>
30std::vector<T> ToVector(const T (&array)[N]) {
31 return std::vector<T>(array, array + N);
32}
33
34class Logger {
35 public:
Chris Watkinsc6cbcf62017-12-01 03:08:01 +000036 Logger() = default;
Peter Boström53634032021-09-22 20:24:34 +000037
38 Logger(const Logger&) = delete;
39 Logger& operator=(const Logger&) = delete;
40
Chris Watkinsc6cbcf62017-12-01 03:08:01 +000041 ~Logger() = default;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000042
43 void AddLog(const std::string& message) { log_ += message; }
44 std::string TakeLog() {
45 std::string result;
46 result.swap(log_);
47 return result;
48 }
49
50 private:
51 std::string log_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000052};
53
54class FakeUsbMidiDevice : public UsbMidiDevice {
55 public:
56 explicit FakeUsbMidiDevice(Logger* logger) : logger_(logger) {}
Peter Boström53634032021-09-22 20:24:34 +000057
58 FakeUsbMidiDevice(const FakeUsbMidiDevice&) = delete;
59 FakeUsbMidiDevice& operator=(const FakeUsbMidiDevice&) = delete;
60
Chris Watkinsc6cbcf62017-12-01 03:08:01 +000061 ~FakeUsbMidiDevice() override = default;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000062
Avi Drissman3528fd02015-12-18 20:11:31 -050063 std::vector<uint8_t> GetDescriptors() override {
yhirano8e5f3742015-04-23 23:06:15 -070064 logger_->AddLog("UsbMidiDevice::GetDescriptors\n");
65 return descriptors_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000066 }
67
yhirano8e5f3742015-04-23 23:06:15 -070068 std::string GetManufacturer() override { return manufacturer_; }
69 std::string GetProductName() override { return product_name_; }
70 std::string GetDeviceVersion() override { return device_version_; }
71
Avi Drissman3528fd02015-12-18 20:11:31 -050072 void Send(int endpoint_number, const std::vector<uint8_t>& data) override {
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000073 logger_->AddLog("UsbMidiDevice::Send ");
74 logger_->AddLog(base::StringPrintf("endpoint = %d data =",
75 endpoint_number));
76 for (size_t i = 0; i < data.size(); ++i)
77 logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
78 logger_->AddLog("\n");
79 }
80
Avi Drissman3528fd02015-12-18 20:11:31 -050081 void SetDescriptors(const std::vector<uint8_t> descriptors) {
yhirano8e5f3742015-04-23 23:06:15 -070082 descriptors_ = descriptors;
83 }
84 void SetManufacturer(const std::string& manufacturer) {
85 manufacturer_ = manufacturer;
86 }
87 void SetProductName(const std::string& product_name) {
88 product_name_ = product_name;
89 }
90 void SetDeviceVersion(const std::string& device_version) {
91 device_version_ = device_version;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000092 }
93
94 private:
Avi Drissman3528fd02015-12-18 20:11:31 -050095 std::vector<uint8_t> descriptors_;
yhirano8e5f3742015-04-23 23:06:15 -070096 std::string manufacturer_;
97 std::string product_name_;
98 std::string device_version_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +000099 Logger* logger_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000100};
101
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +0000102class FakeMidiManagerClient : public MidiManagerClient {
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000103 public:
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000104 explicit FakeMidiManagerClient(Logger* logger)
105 : complete_start_session_(false),
toyoshimf1b88962015-07-09 14:14:51 -0700106 result_(Result::NOT_SUPPORTED),
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000107 logger_(logger) {}
Peter Boström53634032021-09-22 20:24:34 +0000108
109 FakeMidiManagerClient(const FakeMidiManagerClient&) = delete;
110 FakeMidiManagerClient& operator=(const FakeMidiManagerClient&) = delete;
111
Chris Watkinsc6cbcf62017-12-01 03:08:01 +0000112 ~FakeMidiManagerClient() override = default;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000113
Adithya Srinivasan33252732018-10-17 15:59:40 +0000114 void AddInputPort(const mojom::PortInfo& info) override {
toyoshima62d6742014-10-23 09:05:03 -0700115 input_ports_.push_back(info);
116 }
117
Adithya Srinivasan33252732018-10-17 15:59:40 +0000118 void AddOutputPort(const mojom::PortInfo& info) override {
toyoshima62d6742014-10-23 09:05:03 -0700119 output_ports_.push_back(info);
120 }
121
toyoshimec2570a2016-10-21 02:15:27 -0700122 void SetInputPortState(uint32_t port_index, PortState state) override {}
toyoshim5c6fe4b2015-02-18 23:28:09 -0800123
toyoshimec2570a2016-10-21 02:15:27 -0700124 void SetOutputPortState(uint32_t port_index, PortState state) override {}
toyoshim5c6fe4b2015-02-18 23:28:09 -0800125
toyoshimf1b88962015-07-09 14:14:51 -0700126 void CompleteStartSession(Result result) override {
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000127 complete_start_session_ = true;
128 result_ = result;
toyoshim@chromium.orgf77a1e62014-04-11 13:16:24 +0000129 }
130
Avi Drissman3528fd02015-12-18 20:11:31 -0500131 void ReceiveMidiData(uint32_t port_index,
132 const uint8_t* data,
dcheng63ccbc32014-10-21 05:23:27 -0700133 size_t size,
tzik925e2c62018-02-02 07:39:45 +0000134 base::TimeTicks timestamp) override {
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +0000135 logger_->AddLog("MidiManagerClient::ReceiveMidiData ");
yhiranobc742d82015-09-17 07:41:44 -0700136 logger_->AddLog(
137 base::StringPrintf("usb:port_index = %d data =", port_index));
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000138 for (size_t i = 0; i < size; ++i)
139 logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
140 logger_->AddLog("\n");
141 }
142
dcheng63ccbc32014-10-21 05:23:27 -0700143 void AccumulateMidiBytesSent(size_t size) override {
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +0000144 logger_->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000145 // Windows has no "%zu".
146 logger_->AddLog(base::StringPrintf("size = %u\n",
147 static_cast<unsigned>(size)));
148 }
149
toyoshim7a809662015-10-06 00:54:21 -0700150 void Detach() override {}
151
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000152 bool complete_start_session_;
toyoshimf1b88962015-07-09 14:14:51 -0700153 Result result_;
Adithya Srinivasan33252732018-10-17 15:59:40 +0000154 std::vector<mojom::PortInfo> input_ports_;
155 std::vector<mojom::PortInfo> output_ports_;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000156
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000157 private:
158 Logger* logger_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000159};
160
161class TestUsbMidiDeviceFactory : public UsbMidiDevice::Factory {
162 public:
Chris Watkinsc6cbcf62017-12-01 03:08:01 +0000163 TestUsbMidiDeviceFactory() = default;
Peter Boström53634032021-09-22 20:24:34 +0000164
165 TestUsbMidiDeviceFactory(const TestUsbMidiDeviceFactory&) = delete;
166 TestUsbMidiDeviceFactory& operator=(const TestUsbMidiDeviceFactory&) = delete;
167
Chris Watkinsc6cbcf62017-12-01 03:08:01 +0000168 ~TestUsbMidiDeviceFactory() override = default;
dcheng63ccbc32014-10-21 05:23:27 -0700169 void EnumerateDevices(UsbMidiDeviceDelegate* device,
170 Callback callback) override {
Takashi Toyoshimad2bdc592017-09-13 10:02:54 +0000171 callback_ = std::move(callback);
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000172 }
173
174 Callback callback_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000175};
176
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000177class MidiManagerUsbForTesting : public MidiManagerUsb {
178 public:
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000179 MidiManagerUsbForTesting(
180 std::unique_ptr<UsbMidiDevice::Factory> device_factory,
181 MidiService* service)
182 : MidiManagerUsb(service, std::move(device_factory)) {}
Peter Boström53634032021-09-22 20:24:34 +0000183
184 MidiManagerUsbForTesting(const MidiManagerUsbForTesting&) = delete;
185 MidiManagerUsbForTesting& operator=(const MidiManagerUsbForTesting&) = delete;
186
Chris Watkinsc6cbcf62017-12-01 03:08:01 +0000187 ~MidiManagerUsbForTesting() override = default;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000188
toyoshimf1b88962015-07-09 14:14:51 -0700189 void CallCompleteInitialization(Result result) {
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000190 CompleteInitialization(result);
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000191 base::RunLoop run_loop;
192 run_loop.RunUntilIdle();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000193 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000194};
195
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000196class MidiManagerFactoryForTesting : public midi::MidiService::ManagerFactory {
197 public:
198 MidiManagerFactoryForTesting() = default;
199 ~MidiManagerFactoryForTesting() override = default;
200 std::unique_ptr<midi::MidiManager> Create(
201 midi::MidiService* service) override {
202 std::unique_ptr<TestUsbMidiDeviceFactory> device_factory =
203 std::make_unique<TestUsbMidiDeviceFactory>();
204 device_factory_ = device_factory.get();
205 std::unique_ptr<MidiManagerUsbForTesting> manager =
206 std::make_unique<MidiManagerUsbForTesting>(std::move(device_factory),
207 service);
208 // |manager| will be owned by the caller MidiService instance, and valid
209 // while the MidiService instance is running.
210 // MidiService::Shutdown() or destructor will destruct it, and |manager_|
211 // get to be invalid after that.
212 manager_ = manager.get();
213 return manager;
214 }
215 MidiManagerUsb* manager() {
216 DCHECK(manager_);
217 return manager_;
218 }
219 TestUsbMidiDeviceFactory* device_factory() {
220 DCHECK(device_factory_);
221 return device_factory_;
222 }
223
224 private:
225 TestUsbMidiDeviceFactory* device_factory_ = nullptr;
226 MidiManagerUsbForTesting* manager_ = nullptr;
227};
228
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000229class MidiManagerUsbTest : public ::testing::Test {
230 public:
Carlos Caballero10135c22019-12-02 08:40:23 +0000231 MidiManagerUsbTest() {
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000232 std::unique_ptr<MidiManagerFactoryForTesting> factory =
233 std::make_unique<MidiManagerFactoryForTesting>();
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000234 factory_ = factory.get();
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000235 service_ = std::make_unique<MidiService>(std::move(factory));
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000236 }
Peter Boström53634032021-09-22 20:24:34 +0000237
238 MidiManagerUsbTest(const MidiManagerUsbTest&) = delete;
239 MidiManagerUsbTest& operator=(const MidiManagerUsbTest&) = delete;
240
dcheng9e8524d2014-10-27 15:18:50 -0700241 ~MidiManagerUsbTest() override {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900242 service_->Shutdown();
toyoshim7a809662015-10-06 00:54:21 -0700243 base::RunLoop run_loop;
244 run_loop.RunUntilIdle();
245
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000246 std::string leftover_logs = logger_.TakeLog();
247 if (!leftover_logs.empty()) {
248 ADD_FAILURE() << "Log should be empty: " << leftover_logs;
249 }
250 }
251
252 protected:
253 void Initialize() {
Peter Boström78053ff2021-04-02 23:09:28 +0000254 client_ = std::make_unique<FakeMidiManagerClient>(&logger_);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900255 service_->StartSession(client_.get());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000256 }
257
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900258 void Finalize() { service_->EndSession(client_.get()); }
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000259
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000260 bool IsInitializationCallbackInvoked() {
261 return client_->complete_start_session_;
262 }
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000263
toyoshimf1b88962015-07-09 14:14:51 -0700264 Result GetInitializationResult() { return client_->result_; }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000265
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000266 void RunCallbackUntilCallbackInvoked(
267 bool result, UsbMidiDevice::Devices* devices) {
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000268 std::move(factory_->device_factory()->callback_).Run(result, devices);
toyoshim11f7d572014-10-20 02:37:10 -0700269 while (!client_->complete_start_session_) {
270 base::RunLoop run_loop;
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000271 run_loop.RunUntilIdle();
toyoshim11f7d572014-10-20 02:37:10 -0700272 }
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000273 }
274
Adithya Srinivasan33252732018-10-17 15:59:40 +0000275 const std::vector<mojom::PortInfo>& input_ports() {
276 return client_->input_ports_;
277 }
278 const std::vector<mojom::PortInfo>& output_ports() {
279 return client_->output_ports_;
280 }
toyoshima62d6742014-10-23 09:05:03 -0700281
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000282 MidiManagerUsb* manager() { return factory_->manager(); }
283
284 MidiManagerFactoryForTesting* factory_;
danakj75afea02016-04-25 20:36:04 -0700285 std::unique_ptr<FakeMidiManagerClient> client_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000286 Logger logger_;
287
288 private:
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000289 std::unique_ptr<MidiService> service_;
Carlos Caballero10135c22019-12-02 08:40:23 +0000290 base::test::SingleThreadTaskEnvironment task_environment_;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000291};
292
293
294TEST_F(MidiManagerUsbTest, Initialize) {
danakj75afea02016-04-25 20:36:04 -0700295 std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
Avi Drissman3528fd02015-12-18 20:11:31 -0500296 uint8_t descriptors[] = {
297 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
298 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
299 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
300 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
301 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
302 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
303 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
304 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
305 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
306 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
307 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
308 0x01, 0x01, 0x07,
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000309 };
yhirano8e5f3742015-04-23 23:06:15 -0700310 device->SetDescriptors(ToVector(descriptors));
311 device->SetManufacturer("vendor1");
312 device->SetProductName("device1");
313 device->SetDeviceVersion("1.02");
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000314
315 Initialize();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700316 UsbMidiDevice::Devices devices;
dchengc2aeece2015-12-27 00:54:00 -0800317 devices.push_back(std::move(device));
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000318 EXPECT_FALSE(IsInitializationCallbackInvoked());
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000319 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700320 EXPECT_EQ(Result::OK, GetInitializationResult());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000321
toyoshima62d6742014-10-23 09:05:03 -0700322 ASSERT_EQ(1u, input_ports().size());
yhiranobc742d82015-09-17 07:41:44 -0700323 EXPECT_EQ("usb:port-0-2", input_ports()[0].id);
yhirano8e5f3742015-04-23 23:06:15 -0700324 EXPECT_EQ("vendor1", input_ports()[0].manufacturer);
325 EXPECT_EQ("device1", input_ports()[0].name);
326 EXPECT_EQ("1.02", input_ports()[0].version);
327
toyoshima62d6742014-10-23 09:05:03 -0700328 ASSERT_EQ(2u, output_ports().size());
yhiranobc742d82015-09-17 07:41:44 -0700329 EXPECT_EQ("usb:port-0-0", output_ports()[0].id);
yhirano8e5f3742015-04-23 23:06:15 -0700330 EXPECT_EQ("vendor1", output_ports()[0].manufacturer);
331 EXPECT_EQ("device1", output_ports()[0].name);
332 EXPECT_EQ("1.02", output_ports()[0].version);
yhiranobc742d82015-09-17 07:41:44 -0700333 EXPECT_EQ("usb:port-0-1", output_ports()[1].id);
yhirano8e5f3742015-04-23 23:06:15 -0700334 EXPECT_EQ("vendor1", output_ports()[1].manufacturer);
335 EXPECT_EQ("device1", output_ports()[1].name);
336 EXPECT_EQ("1.02", output_ports()[1].version);
337
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000338 ASSERT_TRUE(manager()->input_stream());
339 std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
340 ASSERT_EQ(2u, manager()->output_streams().size());
341 EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
342 EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
yhirano807f97f2015-02-26 18:44:10 -0800343 ASSERT_EQ(1u, jacks.size());
344 EXPECT_EQ(2, jacks[0].endpoint_number());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000345
yhirano8e5f3742015-04-23 23:06:15 -0700346 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000347}
348
yhirano78a04ac2015-02-25 07:32:38 -0800349TEST_F(MidiManagerUsbTest, InitializeMultipleDevices) {
danakj75afea02016-04-25 20:36:04 -0700350 std::unique_ptr<FakeUsbMidiDevice> device1(new FakeUsbMidiDevice(&logger_));
351 std::unique_ptr<FakeUsbMidiDevice> device2(new FakeUsbMidiDevice(&logger_));
Avi Drissman3528fd02015-12-18 20:11:31 -0500352 uint8_t descriptors[] = {
yhirano78a04ac2015-02-25 07:32:38 -0800353 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
354 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
355 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
356 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
357 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
358 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
359 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
360 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
361 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
362 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
363 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
364 0x01, 0x01, 0x07,
365 };
yhirano8e5f3742015-04-23 23:06:15 -0700366 device1->SetDescriptors(ToVector(descriptors));
367 device1->SetManufacturer("vendor1");
368 device1->SetProductName("device1");
369 device1->SetDeviceVersion("1.02");
370 device2->SetDescriptors(ToVector(descriptors));
371 device2->SetManufacturer("vendor2");
372 device2->SetProductName("device2");
373 device2->SetDeviceVersion("98.76");
yhirano78a04ac2015-02-25 07:32:38 -0800374
375 Initialize();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700376 UsbMidiDevice::Devices devices;
dchengc2aeece2015-12-27 00:54:00 -0800377 devices.push_back(std::move(device1));
378 devices.push_back(std::move(device2));
yhirano78a04ac2015-02-25 07:32:38 -0800379 EXPECT_FALSE(IsInitializationCallbackInvoked());
380 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700381 EXPECT_EQ(Result::OK, GetInitializationResult());
yhirano78a04ac2015-02-25 07:32:38 -0800382
383 ASSERT_EQ(2u, input_ports().size());
yhiranobc742d82015-09-17 07:41:44 -0700384 EXPECT_EQ("usb:port-0-2", input_ports()[0].id);
yhirano8e5f3742015-04-23 23:06:15 -0700385 EXPECT_EQ("vendor1", input_ports()[0].manufacturer);
386 EXPECT_EQ("device1", input_ports()[0].name);
387 EXPECT_EQ("1.02", input_ports()[0].version);
yhiranobc742d82015-09-17 07:41:44 -0700388 EXPECT_EQ("usb:port-1-2", input_ports()[1].id);
yhirano8e5f3742015-04-23 23:06:15 -0700389 EXPECT_EQ("vendor2", input_ports()[1].manufacturer);
390 EXPECT_EQ("device2", input_ports()[1].name);
391 EXPECT_EQ("98.76", input_ports()[1].version);
392
yhirano78a04ac2015-02-25 07:32:38 -0800393 ASSERT_EQ(4u, output_ports().size());
yhiranobc742d82015-09-17 07:41:44 -0700394 EXPECT_EQ("usb:port-0-0", output_ports()[0].id);
yhirano8e5f3742015-04-23 23:06:15 -0700395 EXPECT_EQ("vendor1", output_ports()[0].manufacturer);
396 EXPECT_EQ("device1", output_ports()[0].name);
397 EXPECT_EQ("1.02", output_ports()[0].version);
yhiranobc742d82015-09-17 07:41:44 -0700398 EXPECT_EQ("usb:port-0-1", output_ports()[1].id);
yhirano8e5f3742015-04-23 23:06:15 -0700399 EXPECT_EQ("vendor1", output_ports()[1].manufacturer);
400 EXPECT_EQ("device1", output_ports()[1].name);
401 EXPECT_EQ("1.02", output_ports()[1].version);
yhiranobc742d82015-09-17 07:41:44 -0700402 EXPECT_EQ("usb:port-1-0", output_ports()[2].id);
yhirano8e5f3742015-04-23 23:06:15 -0700403 EXPECT_EQ("vendor2", output_ports()[2].manufacturer);
404 EXPECT_EQ("device2", output_ports()[2].name);
405 EXPECT_EQ("98.76", output_ports()[2].version);
yhiranobc742d82015-09-17 07:41:44 -0700406 EXPECT_EQ("usb:port-1-1", output_ports()[3].id);
yhirano8e5f3742015-04-23 23:06:15 -0700407 EXPECT_EQ("vendor2", output_ports()[3].manufacturer);
408 EXPECT_EQ("device2", output_ports()[3].name);
409 EXPECT_EQ("98.76", output_ports()[3].version);
410
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000411 ASSERT_TRUE(manager()->input_stream());
412 std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
413 ASSERT_EQ(4u, manager()->output_streams().size());
414 EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
415 EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
yhirano807f97f2015-02-26 18:44:10 -0800416 ASSERT_EQ(2u, jacks.size());
417 EXPECT_EQ(2, jacks[0].endpoint_number());
yhirano78a04ac2015-02-25 07:32:38 -0800418
419 EXPECT_EQ(
yhirano8e5f3742015-04-23 23:06:15 -0700420 "UsbMidiDevice::GetDescriptors\n"
421 "UsbMidiDevice::GetDescriptors\n",
yhirano78a04ac2015-02-25 07:32:38 -0800422 logger_.TakeLog());
423}
424
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000425TEST_F(MidiManagerUsbTest, InitializeFail) {
426 Initialize();
427
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000428 EXPECT_FALSE(IsInitializationCallbackInvoked());
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000429 RunCallbackUntilCallbackInvoked(false, NULL);
toyoshimf1b88962015-07-09 14:14:51 -0700430 EXPECT_EQ(Result::INITIALIZATION_ERROR, GetInitializationResult());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000431}
432
yhirano8e5f3742015-04-23 23:06:15 -0700433TEST_F(MidiManagerUsbTest, InitializeFailBecauseOfInvalidDescriptors) {
danakj75afea02016-04-25 20:36:04 -0700434 std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
Avi Drissman3528fd02015-12-18 20:11:31 -0500435 uint8_t descriptors[] = {0x04};
yhirano8e5f3742015-04-23 23:06:15 -0700436 device->SetDescriptors(ToVector(descriptors));
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000437
438 Initialize();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700439 UsbMidiDevice::Devices devices;
dchengc2aeece2015-12-27 00:54:00 -0800440 devices.push_back(std::move(device));
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000441 EXPECT_FALSE(IsInitializationCallbackInvoked());
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000442 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700443 EXPECT_EQ(Result::INITIALIZATION_ERROR, GetInitializationResult());
yhirano8e5f3742015-04-23 23:06:15 -0700444 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000445}
446
447TEST_F(MidiManagerUsbTest, Send) {
toyoshim7dd12482015-04-07 07:02:49 -0700448 Initialize();
danakj75afea02016-04-25 20:36:04 -0700449 std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
Avi Drissman3528fd02015-12-18 20:11:31 -0500450 uint8_t descriptors[] = {
451 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
452 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
453 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
454 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
455 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
456 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
457 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
458 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
459 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
460 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
461 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
462 0x01, 0x01, 0x07,
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000463 };
464
yhirano8e5f3742015-04-23 23:06:15 -0700465 device->SetDescriptors(ToVector(descriptors));
Avi Drissman3528fd02015-12-18 20:11:31 -0500466 uint8_t data[] = {
467 0x90, 0x45, 0x7f, 0xf0, 0x00, 0x01, 0xf7,
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000468 };
469
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700470 UsbMidiDevice::Devices devices;
dchengc2aeece2015-12-27 00:54:00 -0800471 devices.push_back(std::move(device));
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000472 EXPECT_FALSE(IsInitializationCallbackInvoked());
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000473 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700474 EXPECT_EQ(Result::OK, GetInitializationResult());
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000475 ASSERT_EQ(2u, manager()->output_streams().size());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000476
tzik925e2c62018-02-02 07:39:45 +0000477 manager()->DispatchSendMidiData(client_.get(), 1, ToVector(data),
478 base::TimeTicks());
toyoshimec5518e2015-04-03 00:53:39 -0700479 // Since UsbMidiDevice::Send is posted as a task, RunLoop should run to
480 // invoke the task.
toyoshimec5518e2015-04-03 00:53:39 -0700481 base::RunLoop run_loop;
482 run_loop.RunUntilIdle();
yhirano8e5f3742015-04-23 23:06:15 -0700483 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000484 "UsbMidiDevice::Send endpoint = 2 data = "
485 "0x19 0x90 0x45 0x7f "
486 "0x14 0xf0 0x00 0x01 "
toyoshim7dd12482015-04-07 07:02:49 -0700487 "0x15 0xf7 0x00 0x00\n"
488 "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000489 logger_.TakeLog());
490}
491
yhirano86da2d82015-02-09 07:13:28 -0800492TEST_F(MidiManagerUsbTest, SendFromCompromizedRenderer) {
danakj75afea02016-04-25 20:36:04 -0700493 std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
Avi Drissman3528fd02015-12-18 20:11:31 -0500494 uint8_t descriptors[] = {
495 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
496 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
497 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
498 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
499 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
500 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
501 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
502 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
503 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
504 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
505 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
506 0x01, 0x01, 0x07,
yhirano86da2d82015-02-09 07:13:28 -0800507 };
508
yhirano8e5f3742015-04-23 23:06:15 -0700509 device->SetDescriptors(ToVector(descriptors));
Avi Drissman3528fd02015-12-18 20:11:31 -0500510 uint8_t data[] = {
511 0x90, 0x45, 0x7f, 0xf0, 0x00, 0x01, 0xf7,
yhirano86da2d82015-02-09 07:13:28 -0800512 };
513
514 Initialize();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700515 UsbMidiDevice::Devices devices;
dchengc2aeece2015-12-27 00:54:00 -0800516 devices.push_back(std::move(device));
yhirano86da2d82015-02-09 07:13:28 -0800517 EXPECT_FALSE(IsInitializationCallbackInvoked());
518 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700519 EXPECT_EQ(Result::OK, GetInitializationResult());
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000520 ASSERT_EQ(2u, manager()->output_streams().size());
yhirano8e5f3742015-04-23 23:06:15 -0700521 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
yhirano86da2d82015-02-09 07:13:28 -0800522
523 // The specified port index is invalid. The manager must ignore the request.
tzik925e2c62018-02-02 07:39:45 +0000524 manager()->DispatchSendMidiData(client_.get(), 99, ToVector(data),
525 base::TimeTicks());
yhirano86da2d82015-02-09 07:13:28 -0800526 EXPECT_EQ("", logger_.TakeLog());
527
528 // The specified port index is invalid. The manager must ignore the request.
tzik925e2c62018-02-02 07:39:45 +0000529 manager()->DispatchSendMidiData(client_.get(), 2, ToVector(data),
530 base::TimeTicks());
yhirano86da2d82015-02-09 07:13:28 -0800531 EXPECT_EQ("", logger_.TakeLog());
532}
533
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000534TEST_F(MidiManagerUsbTest, Receive) {
danakj75afea02016-04-25 20:36:04 -0700535 std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
Avi Drissman3528fd02015-12-18 20:11:31 -0500536 uint8_t descriptors[] = {
537 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
538 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
539 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
540 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
541 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
542 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
543 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
544 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
545 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
546 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
547 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
548 0x01, 0x01, 0x07,
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000549 };
550
yhirano8e5f3742015-04-23 23:06:15 -0700551 device->SetDescriptors(ToVector(descriptors));
Avi Drissman3528fd02015-12-18 20:11:31 -0500552 uint8_t data[] = {
553 0x09, 0x90, 0x45, 0x7f, 0x04, 0xf0, 0x00,
554 0x01, 0x49, 0x90, 0x88, 0x99, // This data should be ignored (CN = 4).
555 0x05, 0xf7, 0x00, 0x00,
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000556 };
557
558 Initialize();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700559 UsbMidiDevice::Devices devices;
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000560 UsbMidiDevice* device_raw = device.get();
dchengc2aeece2015-12-27 00:54:00 -0800561 devices.push_back(std::move(device));
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000562 EXPECT_FALSE(IsInitializationCallbackInvoked());
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000563 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700564 EXPECT_EQ(Result::OK, GetInitializationResult());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000565
Avi Drissman2c637192018-12-25 20:26:39 +0000566 manager()->ReceiveUsbMidiData(device_raw, 2, data, base::size(data),
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000567 base::TimeTicks());
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000568 Finalize();
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000569
yhiranobc742d82015-09-17 07:41:44 -0700570 EXPECT_EQ(
571 "UsbMidiDevice::GetDescriptors\n"
572 "MidiManagerClient::ReceiveMidiData usb:port_index = 0 "
573 "data = 0x90 0x45 0x7f\n"
574 "MidiManagerClient::ReceiveMidiData usb:port_index = 0 "
575 "data = 0xf0 0x00 0x01\n"
576 "MidiManagerClient::ReceiveMidiData usb:port_index = 0 data = 0xf7\n",
577 logger_.TakeLog());
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000578}
579
yhirano33315c62015-02-26 17:01:15 -0800580TEST_F(MidiManagerUsbTest, AttachDevice) {
Avi Drissman3528fd02015-12-18 20:11:31 -0500581 uint8_t descriptors[] = {
582 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
583 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
584 0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
585 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
586 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
587 0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
588 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
589 0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
590 0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
591 0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
592 0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
593 0x01, 0x01, 0x07,
yhirano33315c62015-02-26 17:01:15 -0800594 };
595
596 Initialize();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700597 UsbMidiDevice::Devices devices;
yhirano33315c62015-02-26 17:01:15 -0800598 EXPECT_FALSE(IsInitializationCallbackInvoked());
599 RunCallbackUntilCallbackInvoked(true, &devices);
toyoshimf1b88962015-07-09 14:14:51 -0700600 EXPECT_EQ(Result::OK, GetInitializationResult());
yhirano33315c62015-02-26 17:01:15 -0800601
602 ASSERT_EQ(0u, input_ports().size());
603 ASSERT_EQ(0u, output_ports().size());
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000604 ASSERT_TRUE(manager()->input_stream());
605 std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
606 ASSERT_EQ(0u, manager()->output_streams().size());
yhirano807f97f2015-02-26 18:44:10 -0800607 ASSERT_EQ(0u, jacks.size());
yhirano33315c62015-02-26 17:01:15 -0800608 EXPECT_EQ("", logger_.TakeLog());
609
danakj75afea02016-04-25 20:36:04 -0700610 std::unique_ptr<FakeUsbMidiDevice> new_device(
611 new FakeUsbMidiDevice(&logger_));
yhirano8e5f3742015-04-23 23:06:15 -0700612 new_device->SetDescriptors(ToVector(descriptors));
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000613 manager()->OnDeviceAttached(std::move(new_device));
yhirano33315c62015-02-26 17:01:15 -0800614
615 ASSERT_EQ(1u, input_ports().size());
616 ASSERT_EQ(2u, output_ports().size());
Takashi Toyoshimaf436ca32017-09-11 10:09:44 +0000617 ASSERT_TRUE(manager()->input_stream());
618 jacks = manager()->input_stream()->jacks();
619 ASSERT_EQ(2u, manager()->output_streams().size());
620 EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
621 EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
yhirano807f97f2015-02-26 18:44:10 -0800622 ASSERT_EQ(1u, jacks.size());
623 EXPECT_EQ(2, jacks[0].endpoint_number());
yhirano8e5f3742015-04-23 23:06:15 -0700624 EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
yhirano33315c62015-02-26 17:01:15 -0800625}
626
yhirano@chromium.org3cecb692014-01-29 09:27:41 +0000627} // namespace
628
toyoshime147c5e2015-05-07 21:58:31 -0700629} // namespace midi