// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/midi/midi_manager_usb.h"

#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>

#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "media/midi/midi_service.h"
#include "media/midi/usb_midi_device.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace midi {

namespace {

using mojom::PortState;
using mojom::Result;

template<typename T, size_t N>
std::vector<T> ToVector(const T (&array)[N]) {
  return std::vector<T>(array, array + N);
}

class Logger {
 public:
  Logger() = default;
  ~Logger() = default;

  void AddLog(const std::string& message) { log_ += message; }
  std::string TakeLog() {
    std::string result;
    result.swap(log_);
    return result;
  }

 private:
  std::string log_;

  DISALLOW_COPY_AND_ASSIGN(Logger);
};

class FakeUsbMidiDevice : public UsbMidiDevice {
 public:
  explicit FakeUsbMidiDevice(Logger* logger) : logger_(logger) {}
  ~FakeUsbMidiDevice() override = default;

  std::vector<uint8_t> GetDescriptors() override {
    logger_->AddLog("UsbMidiDevice::GetDescriptors\n");
    return descriptors_;
  }

  std::string GetManufacturer() override { return manufacturer_; }
  std::string GetProductName() override { return product_name_; }
  std::string GetDeviceVersion() override { return device_version_; }

  void Send(int endpoint_number, const std::vector<uint8_t>& data) override {
    logger_->AddLog("UsbMidiDevice::Send ");
    logger_->AddLog(base::StringPrintf("endpoint = %d data =",
                                       endpoint_number));
    for (size_t i = 0; i < data.size(); ++i)
      logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
    logger_->AddLog("\n");
  }

  void SetDescriptors(const std::vector<uint8_t> descriptors) {
    descriptors_ = descriptors;
  }
  void SetManufacturer(const std::string& manufacturer) {
    manufacturer_ = manufacturer;
  }
  void SetProductName(const std::string& product_name) {
    product_name_ = product_name;
  }
  void SetDeviceVersion(const std::string& device_version) {
    device_version_ = device_version;
  }

 private:
  std::vector<uint8_t> descriptors_;
  std::string manufacturer_;
  std::string product_name_;
  std::string device_version_;
  Logger* logger_;

  DISALLOW_COPY_AND_ASSIGN(FakeUsbMidiDevice);
};

class FakeMidiManagerClient : public MidiManagerClient {
 public:
  explicit FakeMidiManagerClient(Logger* logger)
      : complete_start_session_(false),
        result_(Result::NOT_SUPPORTED),
        logger_(logger) {}
  ~FakeMidiManagerClient() override = default;

  void AddInputPort(const MidiPortInfo& info) override {
    input_ports_.push_back(info);
  }

  void AddOutputPort(const MidiPortInfo& info) override {
    output_ports_.push_back(info);
  }

  void SetInputPortState(uint32_t port_index, PortState state) override {}

  void SetOutputPortState(uint32_t port_index, PortState state) override {}

  void CompleteStartSession(Result result) override {
    complete_start_session_ = true;
    result_ = result;
  }

  void ReceiveMidiData(uint32_t port_index,
                       const uint8_t* data,
                       size_t size,
                       double timestamp) override {
    logger_->AddLog("MidiManagerClient::ReceiveMidiData ");
    logger_->AddLog(
        base::StringPrintf("usb:port_index = %d data =", port_index));
    for (size_t i = 0; i < size; ++i)
      logger_->AddLog(base::StringPrintf(" 0x%02x", data[i]));
    logger_->AddLog("\n");
  }

  void AccumulateMidiBytesSent(size_t size) override {
    logger_->AddLog("MidiManagerClient::AccumulateMidiBytesSent ");
    // Windows has no "%zu".
    logger_->AddLog(base::StringPrintf("size = %u\n",
                                       static_cast<unsigned>(size)));
  }

  void Detach() override {}

  bool complete_start_session_;
  Result result_;
  MidiPortInfoList input_ports_;
  MidiPortInfoList output_ports_;

 private:
  Logger* logger_;

  DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient);
};

class TestUsbMidiDeviceFactory : public UsbMidiDevice::Factory {
 public:
  TestUsbMidiDeviceFactory() = default;
  ~TestUsbMidiDeviceFactory() override = default;
  void EnumerateDevices(UsbMidiDeviceDelegate* device,
                        Callback callback) override {
    callback_ = std::move(callback);
  }

  Callback callback_;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestUsbMidiDeviceFactory);
};

class MidiManagerUsbForTesting : public MidiManagerUsb {
 public:
  MidiManagerUsbForTesting(
      std::unique_ptr<UsbMidiDevice::Factory> device_factory,
      MidiService* service)
      : MidiManagerUsb(service, std::move(device_factory)) {}
  ~MidiManagerUsbForTesting() override = default;

  void CallCompleteInitialization(Result result) {
    CompleteInitialization(result);
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbForTesting);
};

class MidiManagerFactoryForTesting : public midi::MidiService::ManagerFactory {
 public:
  MidiManagerFactoryForTesting() = default;
  ~MidiManagerFactoryForTesting() override = default;
  std::unique_ptr<midi::MidiManager> Create(
      midi::MidiService* service) override {
    std::unique_ptr<TestUsbMidiDeviceFactory> device_factory =
        std::make_unique<TestUsbMidiDeviceFactory>();
    device_factory_ = device_factory.get();
    std::unique_ptr<MidiManagerUsbForTesting> manager =
        std::make_unique<MidiManagerUsbForTesting>(std::move(device_factory),
                                                   service);
    // |manager| will be owned by the caller MidiService instance, and valid
    // while the MidiService instance is running.
    // MidiService::Shutdown() or destructor will destruct it, and |manager_|
    // get to be invalid after that.
    manager_ = manager.get();
    return manager;
  }
  MidiManagerUsb* manager() {
    DCHECK(manager_);
    return manager_;
  }
  TestUsbMidiDeviceFactory* device_factory() {
    DCHECK(device_factory_);
    return device_factory_;
  }

 private:
  TestUsbMidiDeviceFactory* device_factory_ = nullptr;
  MidiManagerUsbForTesting* manager_ = nullptr;
};

class MidiManagerUsbTest : public ::testing::Test {
 public:
  MidiManagerUsbTest() : message_loop_(new base::MessageLoop) {
    std::unique_ptr<MidiManagerFactoryForTesting> factory =
        std::make_unique<MidiManagerFactoryForTesting>();
    factory_ = factory.get();
    service_ = std::make_unique<MidiService>(std::move(factory));
  }
  ~MidiManagerUsbTest() override {
    service_->Shutdown();
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();

    std::string leftover_logs = logger_.TakeLog();
    if (!leftover_logs.empty()) {
      ADD_FAILURE() << "Log should be empty: " << leftover_logs;
    }
  }

 protected:
  void Initialize() {
    client_.reset(new FakeMidiManagerClient(&logger_));
    service_->StartSession(client_.get());
  }

  void Finalize() { service_->EndSession(client_.get()); }

  bool IsInitializationCallbackInvoked() {
    return client_->complete_start_session_;
  }

  Result GetInitializationResult() { return client_->result_; }

  void RunCallbackUntilCallbackInvoked(
      bool result, UsbMidiDevice::Devices* devices) {
    std::move(factory_->device_factory()->callback_).Run(result, devices);
    while (!client_->complete_start_session_) {
      base::RunLoop run_loop;
      run_loop.RunUntilIdle();
    }
  }

  const MidiPortInfoList& input_ports() { return client_->input_ports_; }
  const MidiPortInfoList& output_ports() { return client_->output_ports_; }

  MidiManagerUsb* manager() { return factory_->manager(); }

  MidiManagerFactoryForTesting* factory_;
  std::unique_ptr<FakeMidiManagerClient> client_;
  Logger logger_;

 private:
  std::unique_ptr<MidiService> service_;
  std::unique_ptr<base::MessageLoop> message_loop_;

  DISALLOW_COPY_AND_ASSIGN(MidiManagerUsbTest);
};


TEST_F(MidiManagerUsbTest, Initialize) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };
  device->SetDescriptors(ToVector(descriptors));
  device->SetManufacturer("vendor1");
  device->SetProductName("device1");
  device->SetDeviceVersion("1.02");

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  ASSERT_EQ(1u, input_ports().size());
  EXPECT_EQ("usb:port-0-2", input_ports()[0].id);
  EXPECT_EQ("vendor1", input_ports()[0].manufacturer);
  EXPECT_EQ("device1", input_ports()[0].name);
  EXPECT_EQ("1.02", input_ports()[0].version);

  ASSERT_EQ(2u, output_ports().size());
  EXPECT_EQ("usb:port-0-0", output_ports()[0].id);
  EXPECT_EQ("vendor1", output_ports()[0].manufacturer);
  EXPECT_EQ("device1", output_ports()[0].name);
  EXPECT_EQ("1.02", output_ports()[0].version);
  EXPECT_EQ("usb:port-0-1", output_ports()[1].id);
  EXPECT_EQ("vendor1", output_ports()[1].manufacturer);
  EXPECT_EQ("device1", output_ports()[1].name);
  EXPECT_EQ("1.02", output_ports()[1].version);

  ASSERT_TRUE(manager()->input_stream());
  std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(2u, manager()->output_streams().size());
  EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
  EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
  ASSERT_EQ(1u, jacks.size());
  EXPECT_EQ(2, jacks[0].endpoint_number());

  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, InitializeMultipleDevices) {
  std::unique_ptr<FakeUsbMidiDevice> device1(new FakeUsbMidiDevice(&logger_));
  std::unique_ptr<FakeUsbMidiDevice> device2(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };
  device1->SetDescriptors(ToVector(descriptors));
  device1->SetManufacturer("vendor1");
  device1->SetProductName("device1");
  device1->SetDeviceVersion("1.02");
  device2->SetDescriptors(ToVector(descriptors));
  device2->SetManufacturer("vendor2");
  device2->SetProductName("device2");
  device2->SetDeviceVersion("98.76");

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device1));
  devices.push_back(std::move(device2));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  ASSERT_EQ(2u, input_ports().size());
  EXPECT_EQ("usb:port-0-2", input_ports()[0].id);
  EXPECT_EQ("vendor1", input_ports()[0].manufacturer);
  EXPECT_EQ("device1", input_ports()[0].name);
  EXPECT_EQ("1.02", input_ports()[0].version);
  EXPECT_EQ("usb:port-1-2", input_ports()[1].id);
  EXPECT_EQ("vendor2", input_ports()[1].manufacturer);
  EXPECT_EQ("device2", input_ports()[1].name);
  EXPECT_EQ("98.76", input_ports()[1].version);

  ASSERT_EQ(4u, output_ports().size());
  EXPECT_EQ("usb:port-0-0", output_ports()[0].id);
  EXPECT_EQ("vendor1", output_ports()[0].manufacturer);
  EXPECT_EQ("device1", output_ports()[0].name);
  EXPECT_EQ("1.02", output_ports()[0].version);
  EXPECT_EQ("usb:port-0-1", output_ports()[1].id);
  EXPECT_EQ("vendor1", output_ports()[1].manufacturer);
  EXPECT_EQ("device1", output_ports()[1].name);
  EXPECT_EQ("1.02", output_ports()[1].version);
  EXPECT_EQ("usb:port-1-0", output_ports()[2].id);
  EXPECT_EQ("vendor2", output_ports()[2].manufacturer);
  EXPECT_EQ("device2", output_ports()[2].name);
  EXPECT_EQ("98.76", output_ports()[2].version);
  EXPECT_EQ("usb:port-1-1", output_ports()[3].id);
  EXPECT_EQ("vendor2", output_ports()[3].manufacturer);
  EXPECT_EQ("device2", output_ports()[3].name);
  EXPECT_EQ("98.76", output_ports()[3].version);

  ASSERT_TRUE(manager()->input_stream());
  std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(4u, manager()->output_streams().size());
  EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
  EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
  ASSERT_EQ(2u, jacks.size());
  EXPECT_EQ(2, jacks[0].endpoint_number());

  EXPECT_EQ(
      "UsbMidiDevice::GetDescriptors\n"
      "UsbMidiDevice::GetDescriptors\n",
      logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, InitializeFail) {
  Initialize();

  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(false, NULL);
  EXPECT_EQ(Result::INITIALIZATION_ERROR, GetInitializationResult());
}

TEST_F(MidiManagerUsbTest, InitializeFailBecauseOfInvalidDescriptors) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {0x04};
  device->SetDescriptors(ToVector(descriptors));

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::INITIALIZATION_ERROR, GetInitializationResult());
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, Send) {
  Initialize();
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  device->SetDescriptors(ToVector(descriptors));
  uint8_t data[] = {
      0x90, 0x45, 0x7f, 0xf0, 0x00, 0x01, 0xf7,
  };

  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());
  ASSERT_EQ(2u, manager()->output_streams().size());

  manager()->DispatchSendMidiData(client_.get(), 1, ToVector(data), 0);
  // Since UsbMidiDevice::Send is posted as a task, RunLoop should run to
  // invoke the task.
  base::RunLoop run_loop;
  run_loop.RunUntilIdle();
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n"
            "UsbMidiDevice::Send endpoint = 2 data = "
            "0x19 0x90 0x45 0x7f "
            "0x14 0xf0 0x00 0x01 "
            "0x15 0xf7 0x00 0x00\n"
            "MidiManagerClient::AccumulateMidiBytesSent size = 7\n",
            logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, SendFromCompromizedRenderer) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  device->SetDescriptors(ToVector(descriptors));
  uint8_t data[] = {
      0x90, 0x45, 0x7f, 0xf0, 0x00, 0x01, 0xf7,
  };

  Initialize();
  UsbMidiDevice::Devices devices;
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());
  ASSERT_EQ(2u, manager()->output_streams().size());
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());

  // The specified port index is invalid. The manager must ignore the request.
  manager()->DispatchSendMidiData(client_.get(), 99, ToVector(data), 0);
  EXPECT_EQ("", logger_.TakeLog());

  // The specified port index is invalid. The manager must ignore the request.
  manager()->DispatchSendMidiData(client_.get(), 2, ToVector(data), 0);
  EXPECT_EQ("", logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, Receive) {
  std::unique_ptr<FakeUsbMidiDevice> device(new FakeUsbMidiDevice(&logger_));
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  device->SetDescriptors(ToVector(descriptors));
  uint8_t data[] = {
      0x09, 0x90, 0x45, 0x7f, 0x04, 0xf0, 0x00,
      0x01, 0x49, 0x90, 0x88, 0x99,  // This data should be ignored (CN = 4).
      0x05, 0xf7, 0x00, 0x00,
  };

  Initialize();
  UsbMidiDevice::Devices devices;
  UsbMidiDevice* device_raw = device.get();
  devices.push_back(std::move(device));
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  manager()->ReceiveUsbMidiData(device_raw, 2, data, arraysize(data),
                                base::TimeTicks());
  Finalize();

  EXPECT_EQ(
      "UsbMidiDevice::GetDescriptors\n"
      "MidiManagerClient::ReceiveMidiData usb:port_index = 0 "
      "data = 0x90 0x45 0x7f\n"
      "MidiManagerClient::ReceiveMidiData usb:port_index = 0 "
      "data = 0xf0 0x00 0x01\n"
      "MidiManagerClient::ReceiveMidiData usb:port_index = 0 data = 0xf7\n",
      logger_.TakeLog());
}

TEST_F(MidiManagerUsbTest, AttachDevice) {
  uint8_t descriptors[] = {
      0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x86, 0x1a, 0x2d, 0x75,
      0x54, 0x02, 0x00, 0x02, 0x00, 0x01, 0x09, 0x02, 0x75, 0x00, 0x02, 0x01,
      0x00, 0x80, 0x30, 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
      0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 0x09, 0x04, 0x01,
      0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x07, 0x24, 0x01, 0x00, 0x01, 0x51,
      0x00, 0x06, 0x24, 0x02, 0x01, 0x02, 0x00, 0x06, 0x24, 0x02, 0x01, 0x03,
      0x00, 0x06, 0x24, 0x02, 0x02, 0x06, 0x00, 0x09, 0x24, 0x03, 0x01, 0x07,
      0x01, 0x06, 0x01, 0x00, 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x02, 0x01,
      0x00, 0x09, 0x24, 0x03, 0x02, 0x05, 0x01, 0x03, 0x01, 0x00, 0x09, 0x05,
      0x02, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x01, 0x02, 0x02,
      0x03, 0x09, 0x05, 0x82, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x05, 0x25,
      0x01, 0x01, 0x07,
  };

  Initialize();
  UsbMidiDevice::Devices devices;
  EXPECT_FALSE(IsInitializationCallbackInvoked());
  RunCallbackUntilCallbackInvoked(true, &devices);
  EXPECT_EQ(Result::OK, GetInitializationResult());

  ASSERT_EQ(0u, input_ports().size());
  ASSERT_EQ(0u, output_ports().size());
  ASSERT_TRUE(manager()->input_stream());
  std::vector<UsbMidiJack> jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(0u, manager()->output_streams().size());
  ASSERT_EQ(0u, jacks.size());
  EXPECT_EQ("", logger_.TakeLog());

  std::unique_ptr<FakeUsbMidiDevice> new_device(
      new FakeUsbMidiDevice(&logger_));
  new_device->SetDescriptors(ToVector(descriptors));
  manager()->OnDeviceAttached(std::move(new_device));

  ASSERT_EQ(1u, input_ports().size());
  ASSERT_EQ(2u, output_ports().size());
  ASSERT_TRUE(manager()->input_stream());
  jacks = manager()->input_stream()->jacks();
  ASSERT_EQ(2u, manager()->output_streams().size());
  EXPECT_EQ(2u, manager()->output_streams()[0]->jack().jack_id);
  EXPECT_EQ(3u, manager()->output_streams()[1]->jack().jack_id);
  ASSERT_EQ(1u, jacks.size());
  EXPECT_EQ(2, jacks[0].endpoint_number());
  EXPECT_EQ("UsbMidiDevice::GetDescriptors\n", logger_.TakeLog());
}

}  // namespace

}  // namespace midi
