15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/midi/usb_midi_input_stream.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector>
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/time/time.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/midi/usb_midi_device.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing base::TimeTicks;
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestUsbMidiDevice : public UsbMidiDevice {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestUsbMidiDevice() {}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~TestUsbMidiDevice() {}
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual std::vector<uint8> GetDescriptor() OVERRIDE {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::vector<uint8>();
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Send(int endpoint_number,
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    const std::vector<uint8>& data) OVERRIDE {}
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDevice);
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MockDelegate : public UsbMidiInputStream::Delegate {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockDelegate() {}
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~MockDelegate() {}
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnReceivedData(size_t jack_index,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              const uint8* data,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              size_t size,
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              base::TimeTicks time) OVERRIDE {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < size; ++i)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      received_data_ += base::StringPrintf("0x%02x ", data[i]);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    received_data_ += "\n";
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::string& received_data() const { return received_data_; }
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string received_data_;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockDelegate);
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class UsbMidiInputStreamTest : public ::testing::Test {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UsbMidiInputStreamTest() {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<UsbMidiJack> jacks;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jacks.push_back(UsbMidiJack(&device1_,
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                84,  // jack_id
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                4,  // cable_number
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                135));  // endpoint_address
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jacks.push_back(UsbMidiJack(&device2_,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                85,
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                5,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                137));
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jacks.push_back(UsbMidiJack(&device2_,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                84,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                4,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                135));
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    jacks.push_back(UsbMidiJack(&device1_,
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                85,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                5,
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                135));
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stream_.reset(new UsbMidiInputStream(jacks, &delegate_));
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestUsbMidiDevice device1_;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestUsbMidiDevice device2_;
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockDelegate delegate_;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<UsbMidiInputStream> stream_;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UsbMidiInputStreamTest);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, UnknownMessage) {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x40, 0xff, 0xff, 0xff,
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x41, 0xff, 0xff, 0xff,
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device1_, 7, data, arraysize(data), TimeTicks());
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("", delegate_.received_data());
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, SystemCommonMessage) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x45, 0xf8, 0x00, 0x00,
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x42, 0xf3, 0x22, 0x00,
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x43, 0xf2, 0x33, 0x44,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device1_, 7, data, arraysize(data), TimeTicks());
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0xf8 \n"
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xf3 0x22 \n"
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xf2 0x33 0x44 \n", delegate_.received_data());
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, SystemExclusiveMessage) {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x44, 0xf0, 0x11, 0x22,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x45, 0xf7, 0x00, 0x00,
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x46, 0xf0, 0xf7, 0x00,
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x47, 0xf0, 0x33, 0xf7,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device1_, 7, data, arraysize(data), TimeTicks());
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0xf0 0x11 0x22 \n"
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xf7 \n"
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xf0 0xf7 \n"
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xf0 0x33 0xf7 \n", delegate_.received_data());
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, ChannelMessage) {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x48, 0x80, 0x11, 0x22,
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x49, 0x90, 0x33, 0x44,
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4a, 0xa0, 0x55, 0x66,
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4b, 0xb0, 0x77, 0x88,
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4c, 0xc0, 0x99, 0x00,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4d, 0xd0, 0xaa, 0x00,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4e, 0xe0, 0xbb, 0xcc,
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device1_, 7, data, arraysize(data), TimeTicks());
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0x80 0x11 0x22 \n"
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0x90 0x33 0x44 \n"
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xa0 0x55 0x66 \n"
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xb0 0x77 0x88 \n"
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xc0 0x99 \n"
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xd0 0xaa \n"
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0xe0 0xbb 0xcc \n", delegate_.received_data());
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, SingleByteMessage) {
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4f, 0xf8, 0x00, 0x00,
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device1_, 7, data, arraysize(data), TimeTicks());
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0xf8 \n", delegate_.received_data());
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, DispatchForMultipleCables) {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x4f, 0xf8, 0x00, 0x00,
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x5f, 0xfa, 0x00, 0x00,
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x6f, 0xfb, 0x00, 0x00,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device1_, 7, data, arraysize(data), TimeTicks());
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0xf8 \n0xfa \n", delegate_.received_data());
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(UsbMidiInputStreamTest, DispatchForDevice2) {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = { 0x4f, 0xf8, 0x00, 0x00 };
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  stream_->OnReceivedData(&device2_, 7, data, arraysize(data), TimeTicks());
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0xf8 \n", delegate_.received_data());
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
179