midi_manager_usb_unittest.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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/midi_manager_usb.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/stringprintf.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/midi/usb_midi_device.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<typename T, size_t N>
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector<T> ToVector(const T (&array)[N]) {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::vector<T>(array, array + N);
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Logger {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Logger() {}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~Logger() {}
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AddLog(const std::string& message) { log_ += message; }
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string TakeLog() {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string result;
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result.swap(log_);
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return result;
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string log_;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Logger);
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FakeUsbMidiDevice : public UsbMidiDevice {
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit FakeUsbMidiDevice(Logger* logger) : logger_(logger) {}
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~FakeUsbMidiDevice() {}
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual std::vector<uint8> GetDescriptor() OVERRIDE {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog("UsbMidiDevice::GetDescriptor\n");
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return descriptor_;
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Send(int endpoint_number,
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    const std::vector<uint8>& data) OVERRIDE {
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog("UsbMidiDevice::Send ");
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog(base::StringPrintf("endpoint = %d data =",
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       endpoint_number));
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < data.size(); ++i)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog("\n");
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetDescriptor(const std::vector<uint8> descriptor) {
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    descriptor_ = descriptor;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<uint8> descriptor_;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Logger* logger_;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeUsbMidiDevice);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FakeMidiManagerClient : public MidiManagerClient {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit FakeMidiManagerClient(Logger* logger) : logger_(logger) {}
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~FakeMidiManagerClient() {}
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void CompleteStartSession(int client_id, MidiResult result) OVERRIDE {
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void ReceiveMidiData(uint32 port_index,
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               const uint8* data,
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               size_t size,
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               double timestamp) OVERRIDE {
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog("MidiManagerClient::ReceiveMidiData ");
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog(base::StringPrintf("port_index = %d data =", port_index));
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < size; ++i)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog("\n");
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void AccumulateMidiBytesSent(size_t size) OVERRIDE {
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Windows has no "%zu".
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    logger_->AddLog(base::StringPrintf("size = %u\n",
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       static_cast<unsigned>(size)));
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Logger* logger_;
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient);
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestUsbMidiDeviceFactory : public UsbMidiDevice::Factory {
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestUsbMidiDeviceFactory() {}
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~TestUsbMidiDeviceFactory() {}
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void EnumerateDevices(UsbMidiDeviceDelegate* device,
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                Callback callback) OVERRIDE {
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback_ = callback;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Callback callback_;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDeviceFactory);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MidiManagerUsbTest : public ::testing::Test {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MidiManagerUsbTest()
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : initialize_callback_run_(false), initialize_result_(false) {
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<TestUsbMidiDeviceFactory> factory(new TestUsbMidiDeviceFactory);
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    factory_ = factory.get();
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager_.reset(
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new MidiManagerUsb(factory.PassAs<UsbMidiDevice::Factory>()));
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~MidiManagerUsbTest() {
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string leftover_logs = logger_.TakeLog();
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!leftover_logs.empty()) {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ADD_FAILURE() << "Log should be empty: " << leftover_logs;
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Initialize() {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager_->Initialize(base::Bind(&MidiManagerUsbTest::OnInitializeDone,
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    base::Unretained(this)));
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnInitializeDone(bool result) {
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    initialize_callback_run_ = true;
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    initialize_result_ = result;
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool initialize_callback_run_;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool initialize_result_;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<MidiManagerUsb> manager_;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Owned by manager_.
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestUsbMidiDeviceFactory* factory_;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Logger logger_;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbTest);
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MidiManagerUsbTest, Initialize) {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 descriptor[] = {
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0x25, 0x01, 0x01, 0x07,
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device->SetDescriptor(ToVector(descriptor));
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedVector<UsbMidiDevice> devices;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  devices.push_back(device.release());
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_callback_run_);
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  factory_->callback_.Run(true, &devices);
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(initialize_callback_run_);
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(initialize_result_);
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1u, manager_->input_ports().size());
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2u, manager_->output_ports().size());
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(manager_->input_stream());
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<UsbMidiInputStream::JackUniqueKey> keys =
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      manager_->input_stream()->RegisteredJackKeysForTesting();
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2u, manager_->output_streams().size());
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2u, manager_->output_streams()[0]->jack().jack_id);
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(3u, manager_->output_streams()[1]->jack().jack_id);
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1u, keys.size());
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2, keys[0].endpoint_number);
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MidiManagerUsbTest, InitializeFail) {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_callback_run_);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  factory_->callback_.Run(false, NULL);
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(initialize_callback_run_);
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_result_);
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MidiManagerUsbTest, InitializeFailBecauseOfInvalidDescriptor) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 descriptor[] = {0x04};
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device->SetDescriptor(ToVector(descriptor));
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedVector<UsbMidiDevice> devices;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  devices.push_back(device.release());
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_callback_run_);
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  factory_->callback_.Run(true, &devices);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(initialize_callback_run_);
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_result_);
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("UsbMidiDevice::GetDescriptor\n", logger_.TakeLog());
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MidiManagerUsbTest, Send) {
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeMidiManagerClient client(&logger_);
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 descriptor[] = {
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0x25, 0x01, 0x01, 0x07,
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device->SetDescriptor(ToVector(descriptor));
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x90, 0x45, 0x7f,
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0xf0, 0x00, 0x01, 0xf7,
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedVector<UsbMidiDevice> devices;
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  devices.push_back(device.release());
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_callback_run_);
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  factory_->callback_.Run(true, &devices);
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(initialize_callback_run_);
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(initialize_result_);
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2u, manager_->output_streams().size());
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager_->DispatchSendMidiData(&client, 1, ToVector(data), 0);
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("UsbMidiDevice::GetDescriptor\n"
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "UsbMidiDevice::Send endpoint = 2 data = "
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0x19 0x90 0x45 0x7f "
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0x14 0xf0 0x00 0x01 "
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "0x15 0xf7 0x00 0x00\n"
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            logger_.TakeLog());
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(MidiManagerUsbTest, Receive) {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeMidiManagerClient client(&logger_);
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 descriptor[] = {
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a,
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x2d, 0x75, 0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02,
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x75, 0x00, 0x02, 0x01, 0x00, 0x80, 0x30, 0x09, 0x04, 0x00,
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x09, 0x24, 0x01, 0x00,
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01, 0x00, 0x02,
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02,
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x01, 0x03, 0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09,
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x24, 0x03, 0x01, 0x07, 0x01, 0x06, 0x01, 0x00, 0x09, 0x24,
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x02, 0x04, 0x01, 0x02, 0x01, 0x00, 0x09, 0x24, 0x03,
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05, 0x02, 0x02,
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0x25, 0x01, 0x01, 0x07,
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device->SetDescriptor(ToVector(descriptor));
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint8 data[] = {
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x09, 0x90, 0x45, 0x7f,
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x04, 0xf0, 0x00, 0x01,
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x49, 0x90, 0x88, 0x99,  // This data should be ignored (CN = 4).
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    0x05, 0xf7, 0x00, 0x00,
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Initialize();
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedVector<UsbMidiDevice> devices;
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UsbMidiDevice* device_raw = device.get();
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  devices.push_back(device.release());
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(initialize_callback_run_);
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  factory_->callback_.Run(true, &devices);
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(initialize_callback_run_);
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(initialize_result_);
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
306a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  manager_->StartSession(&client, 0);
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager_->ReceiveUsbMidiData(device_raw, 2, data, arraysize(data), 0);
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  manager_->EndSession(&client);
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("UsbMidiDevice::GetDescriptor\n"
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "MidiManagerClient::ReceiveMidiData port_index = 0 "
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "data = 0x90 0x45 0x7f\n"
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "MidiManagerClient::ReceiveMidiData port_index = 0 "
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "data = 0xf0 0x00 0x01\n"
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            "MidiManagerClient::ReceiveMidiData port_index = 0 data = 0xf7\n",
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            logger_.TakeLog());
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
322