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