Add ICU message format support
[chromium-blink-merge.git] / content / browser / media / midi_host_unittest.cc
blobbfe0c2f051bcaf41e12fac2500d3e3bc96412ebd
1 // Copyright 2013 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 "content/browser/media/midi_host.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "content/common/media/midi_messages.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "media/midi/midi_manager.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace content {
16 namespace {
18 const uint8 kGMOn[] = { 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7 };
19 const uint8 kGSOn[] = {
20 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7,
22 const uint8 kNoteOn[] = { 0x90, 0x3c, 0x7f };
23 const uint8 kNoteOnWithRunningStatus[] = {
24 0x90, 0x3c, 0x7f, 0x3c, 0x7f, 0x3c, 0x7f,
26 const uint8 kChannelPressure[] = { 0xd0, 0x01 };
27 const uint8 kChannelPressureWithRunningStatus[] = {
28 0xd0, 0x01, 0x01, 0x01,
30 const uint8 kTimingClock[] = { 0xf8 };
31 const uint8 kBrokenData1[] = { 0x90 };
32 const uint8 kBrokenData2[] = { 0xf7 };
33 const uint8 kBrokenData3[] = { 0xf2, 0x00 };
34 const uint8 kDataByte0[] = { 0x00 };
36 const int kRenderProcessId = 0;
38 template <typename T, size_t N>
39 const std::vector<T> AsVector(const T(&data)[N]) {
40 std::vector<T> buffer;
41 buffer.insert(buffer.end(), data, data + N);
42 return buffer;
45 template <typename T, size_t N>
46 void PushToVector(const T(&data)[N], std::vector<T>* buffer) {
47 buffer->insert(buffer->end(), data, data + N);
50 enum MidiEventType {
51 DISPATCH_SEND_MIDI_DATA,
54 struct MidiEvent {
55 MidiEvent(MidiEventType in_type,
56 uint32 in_port_index,
57 const std::vector<uint8>& in_data,
58 double in_timestamp)
59 : type(in_type),
60 port_index(in_port_index),
61 data(in_data),
62 timestamp(in_timestamp) {}
64 MidiEventType type;
65 uint32 port_index;
66 std::vector<uint8> data;
67 double timestamp;
70 class FakeMidiManager : public media::midi::MidiManager {
71 public:
72 void DispatchSendMidiData(media::midi::MidiManagerClient* client,
73 uint32 port_index,
74 const std::vector<uint8>& data,
75 double timestamp) override {
76 events_.push_back(MidiEvent(DISPATCH_SEND_MIDI_DATA,
77 port_index,
78 data,
79 timestamp));
81 std::vector<MidiEvent> events_;
84 class MidiHostForTesting : public MidiHost {
85 public:
86 MidiHostForTesting(int renderer_process_id,
87 media::midi::MidiManager* midi_manager)
88 : MidiHost(renderer_process_id, midi_manager) {}
90 private:
91 ~MidiHostForTesting() override {}
93 // BrowserMessageFilter implementation.
94 // Override ShutdownForBadMessage() to do nothing since the original
95 // implementation to kill a malicious renderer process causes a check failure
96 // in unit tests.
97 void ShutdownForBadMessage() override {}
100 class MidiHostTest : public testing::Test {
101 public:
102 MidiHostTest()
103 : io_browser_thread_(BrowserThread::IO, &message_loop_),
104 host_(new MidiHostForTesting(kRenderProcessId, &manager_)),
105 data_(kNoteOn, kNoteOn + arraysize(kNoteOn)),
106 port_id_(0) {}
108 protected:
109 void AddOutputPort() {
110 const std::string id = base::StringPrintf("i-can-%d", port_id_++);
111 const std::string manufacturer("yukatan");
112 const std::string name("doki-doki-pi-pine");
113 const std::string version("3.14159265359");
114 media::midi::MidiPortState state = media::midi::MIDI_PORT_CONNECTED;
115 media::midi::MidiPortInfo info(id, manufacturer, name, version, state);
117 host_->AddOutputPort(info);
120 void OnSendData(uint32 port) {
121 scoped_ptr<IPC::Message> message(
122 new MidiHostMsg_SendData(port, data_, 0.0));
123 host_->OnMessageReceived(*message.get());
126 size_t GetEventSize() const {
127 return manager_.events_.size();
130 void CheckSendEventAt(size_t at, uint32 port) {
131 EXPECT_EQ(DISPATCH_SEND_MIDI_DATA, manager_.events_[at].type);
132 EXPECT_EQ(port, manager_.events_[at].port_index);
133 EXPECT_EQ(data_, manager_.events_[at].data);
134 EXPECT_EQ(0.0, manager_.events_[at].timestamp);
137 void RunLoopUntilIdle() {
138 base::RunLoop run_loop;
139 run_loop.RunUntilIdle();
142 private:
143 base::MessageLoop message_loop_;
144 TestBrowserThread io_browser_thread_;
146 FakeMidiManager manager_;
147 scoped_refptr<MidiHostForTesting> host_;
148 std::vector<uint8> data_;
149 int32 port_id_;
151 DISALLOW_COPY_AND_ASSIGN(MidiHostTest);
154 } // namespace
156 TEST_F(MidiHostTest, IsValidWebMIDIData) {
157 // Test single event scenario
158 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(AsVector(kGMOn)));
159 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(AsVector(kGSOn)));
160 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(AsVector(kNoteOn)));
161 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(AsVector(kChannelPressure)));
162 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(AsVector(kTimingClock)));
163 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(AsVector(kBrokenData1)));
164 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(AsVector(kBrokenData2)));
165 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(AsVector(kBrokenData3)));
166 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(AsVector(kDataByte0)));
168 // MIDI running status should be disallowed
169 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(
170 AsVector(kNoteOnWithRunningStatus)));
171 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(
172 AsVector(kChannelPressureWithRunningStatus)));
174 // Multiple messages are allowed as long as each of them is complete.
176 std::vector<uint8> buffer;
177 PushToVector(kGMOn, &buffer);
178 PushToVector(kNoteOn, &buffer);
179 PushToVector(kGSOn, &buffer);
180 PushToVector(kTimingClock, &buffer);
181 PushToVector(kNoteOn, &buffer);
182 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(buffer));
183 PushToVector(kBrokenData1, &buffer);
184 EXPECT_FALSE(MidiHost::IsValidWebMIDIData(buffer));
187 // MIDI realtime message can be placed at any position.
189 const uint8 kNoteOnWithRealTimeClock[] = {
190 0x90, 0xf8, 0x3c, 0x7f, 0x90, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8,
192 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(
193 AsVector(kNoteOnWithRealTimeClock)));
195 const uint8 kGMOnWithRealTimeClock[] = {
196 0xf0, 0xf8, 0x7e, 0x7f, 0x09, 0x01, 0xf8, 0xf7,
198 EXPECT_TRUE(MidiHost::IsValidWebMIDIData(
199 AsVector(kGMOnWithRealTimeClock)));
203 // Test if sending data to out of range port is ignored.
204 TEST_F(MidiHostTest, OutputPortCheck) {
205 // Only one output port is available.
206 AddOutputPort();
208 // Sending data to port 0 should be delivered.
209 uint32 port0 = 0;
210 OnSendData(port0);
211 RunLoopUntilIdle();
212 EXPECT_EQ(1U, GetEventSize());
213 CheckSendEventAt(0, port0);
215 // Sending data to port 1 should not be delivered.
216 uint32 port1 = 1;
217 OnSendData(port1);
218 RunLoopUntilIdle();
219 EXPECT_EQ(1U, GetEventSize());
221 // Two output ports are available from now on.
222 AddOutputPort();
224 // Sending data to port 0 and 1 should be delivered now.
225 OnSendData(port0);
226 OnSendData(port1);
227 RunLoopUntilIdle();
228 EXPECT_EQ(3U, GetEventSize());
229 CheckSendEventAt(1, port0);
230 CheckSendEventAt(2, port1);
233 } // namespace conent