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.
4
5 #include "media/midi/usb_midi_input_stream.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <string>
12 #include <vector>
13
14 #include "base/stl_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/time/time.h"
17 #include "media/midi/usb_midi_device.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using base::TimeTicks;
21
22 namespace midi {
23
24 namespace {
25
26 class TestUsbMidiDevice : public UsbMidiDevice {
27 public:
28 TestUsbMidiDevice() = default;
29 ~TestUsbMidiDevice() override = default;
GetDescriptors()30 std::vector<uint8_t> GetDescriptors() override {
31 return std::vector<uint8_t>();
32 }
GetManufacturer()33 std::string GetManufacturer() override { return std::string(); }
GetProductName()34 std::string GetProductName() override { return std::string(); }
GetDeviceVersion()35 std::string GetDeviceVersion() override { return std::string(); }
Send(int endpoint_number,const std::vector<uint8_t> & data)36 void Send(int endpoint_number, const std::vector<uint8_t>& data) override {}
37
38 private:
39 DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDevice);
40 };
41
42 class MockDelegate : public UsbMidiInputStream::Delegate {
43 public:
44 MockDelegate() = default;
45 ~MockDelegate() override = default;
OnReceivedData(size_t jack_index,const uint8_t * data,size_t size,base::TimeTicks time)46 void OnReceivedData(size_t jack_index,
47 const uint8_t* data,
48 size_t size,
49 base::TimeTicks time) override {
50 for (size_t i = 0; i < size; ++i)
51 received_data_ += base::StringPrintf("0x%02x ", data[i]);
52 received_data_ += "\n";
53 }
54
received_data() const55 const std::string& received_data() const { return received_data_; }
56
57 private:
58 std::string received_data_;
59 DISALLOW_COPY_AND_ASSIGN(MockDelegate);
60 };
61
62 class UsbMidiInputStreamTest : public ::testing::Test {
63 protected:
UsbMidiInputStreamTest()64 UsbMidiInputStreamTest() {
65 stream_.reset(new UsbMidiInputStream(&delegate_));
66
67 stream_->Add(UsbMidiJack(&device1_,
68 84, // jack_id
69 4, // cable_number
70 135)); // endpoint_address
71 stream_->Add(UsbMidiJack(&device2_,
72 85,
73 5,
74 137));
75 stream_->Add(UsbMidiJack(&device2_,
76 84,
77 4,
78 135));
79 stream_->Add(UsbMidiJack(&device1_,
80 85,
81 5,
82 135));
83 }
84
85 TestUsbMidiDevice device1_;
86 TestUsbMidiDevice device2_;
87 MockDelegate delegate_;
88 std::unique_ptr<UsbMidiInputStream> stream_;
89
90 private:
91 DISALLOW_COPY_AND_ASSIGN(UsbMidiInputStreamTest);
92 };
93
TEST_F(UsbMidiInputStreamTest,UnknownMessage)94 TEST_F(UsbMidiInputStreamTest, UnknownMessage) {
95 uint8_t data[] = {
96 0x40, 0xff, 0xff, 0xff, 0x41, 0xff, 0xff, 0xff,
97 };
98
99 stream_->OnReceivedData(&device1_, 7, data, base::size(data), TimeTicks());
100 EXPECT_EQ("", delegate_.received_data());
101 }
102
TEST_F(UsbMidiInputStreamTest,SystemCommonMessage)103 TEST_F(UsbMidiInputStreamTest, SystemCommonMessage) {
104 uint8_t data[] = {
105 0x45, 0xf8, 0x00, 0x00, 0x42, 0xf3, 0x22, 0x00, 0x43, 0xf2, 0x33, 0x44,
106 };
107
108 stream_->OnReceivedData(&device1_, 7, data, base::size(data), TimeTicks());
109 EXPECT_EQ("0xf8 \n"
110 "0xf3 0x22 \n"
111 "0xf2 0x33 0x44 \n", delegate_.received_data());
112 }
113
TEST_F(UsbMidiInputStreamTest,SystemExclusiveMessage)114 TEST_F(UsbMidiInputStreamTest, SystemExclusiveMessage) {
115 uint8_t data[] = {
116 0x44, 0xf0, 0x11, 0x22, 0x45, 0xf7, 0x00, 0x00,
117 0x46, 0xf0, 0xf7, 0x00, 0x47, 0xf0, 0x33, 0xf7,
118 };
119
120 stream_->OnReceivedData(&device1_, 7, data, base::size(data), TimeTicks());
121 EXPECT_EQ("0xf0 0x11 0x22 \n"
122 "0xf7 \n"
123 "0xf0 0xf7 \n"
124 "0xf0 0x33 0xf7 \n", delegate_.received_data());
125 }
126
TEST_F(UsbMidiInputStreamTest,ChannelMessage)127 TEST_F(UsbMidiInputStreamTest, ChannelMessage) {
128 uint8_t data[] = {
129 0x48, 0x80, 0x11, 0x22, 0x49, 0x90, 0x33, 0x44, 0x4a, 0xa0,
130 0x55, 0x66, 0x4b, 0xb0, 0x77, 0x88, 0x4c, 0xc0, 0x99, 0x00,
131 0x4d, 0xd0, 0xaa, 0x00, 0x4e, 0xe0, 0xbb, 0xcc,
132 };
133
134 stream_->OnReceivedData(&device1_, 7, data, base::size(data), TimeTicks());
135 EXPECT_EQ("0x80 0x11 0x22 \n"
136 "0x90 0x33 0x44 \n"
137 "0xa0 0x55 0x66 \n"
138 "0xb0 0x77 0x88 \n"
139 "0xc0 0x99 \n"
140 "0xd0 0xaa \n"
141 "0xe0 0xbb 0xcc \n", delegate_.received_data());
142 }
143
TEST_F(UsbMidiInputStreamTest,SingleByteMessage)144 TEST_F(UsbMidiInputStreamTest, SingleByteMessage) {
145 uint8_t data[] = {
146 0x4f, 0xf8, 0x00, 0x00,
147 };
148
149 stream_->OnReceivedData(&device1_, 7, data, base::size(data), TimeTicks());
150 EXPECT_EQ("0xf8 \n", delegate_.received_data());
151 }
152
TEST_F(UsbMidiInputStreamTest,DispatchForMultipleCables)153 TEST_F(UsbMidiInputStreamTest, DispatchForMultipleCables) {
154 uint8_t data[] = {
155 0x4f, 0xf8, 0x00, 0x00, 0x5f, 0xfa, 0x00, 0x00, 0x6f, 0xfb, 0x00, 0x00,
156 };
157
158 stream_->OnReceivedData(&device1_, 7, data, base::size(data), TimeTicks());
159 EXPECT_EQ("0xf8 \n0xfa \n", delegate_.received_data());
160 }
161
TEST_F(UsbMidiInputStreamTest,DispatchForDevice2)162 TEST_F(UsbMidiInputStreamTest, DispatchForDevice2) {
163 uint8_t data[] = {0x4f, 0xf8, 0x00, 0x00};
164
165 stream_->OnReceivedData(&device2_, 7, data, base::size(data), TimeTicks());
166 EXPECT_EQ("0xf8 \n", delegate_.received_data());
167 }
168
169 } // namespace
170
171 } // namespace midi
172