From 76ab2ee06e1b726c38ee5116718a59474abe684a Mon Sep 17 00:00:00 2001 From: toyoshim Date: Thu, 19 Feb 2015 20:53:55 -0800 Subject: [PATCH] Web MIDI: add unit tests for event notification of MidiManagerMac Add a unit test to check if MidiManagerMac correctly notify clients. Core MIDI requires that the thread calling MIDIClientCreate() should run CFRunLoop. MidiManagerMac uses base::Thread to call MIDIClientCreate() on an assumption that it uses CFRunLoop() inside. To make the assumption confirmed, implement a test for MidiManagerMac. The test creates a MIDIDestination and checks if AddOutputPort() is called responded to the MIDIDestination. BUG=422333 TEST=media_unittests Review URL: https://codereview.chromium.org/666693002 Cr-Commit-Position: refs/heads/master@{#317247} --- media/BUILD.gn | 6 +- media/media.gyp | 1 + media/midi/midi_manager_mac_unittest.cc | 126 ++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 media/midi/midi_manager_mac_unittest.cc diff --git a/media/BUILD.gn b/media/BUILD.gn index 9ab1e7297060..6fe18e56077e 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -662,8 +662,10 @@ test("media_unittests") { } if (is_mac) { - sources += - [ "video/capture/mac/video_capture_device_factory_mac_unittest.mm" ] + sources += [ + "midi/midi_manager_mac_unittest.cc", + "video/capture/mac/video_capture_device_factory_mac_unittest.mm", + ] } # include_dirs += [ diff --git a/media/media.gyp b/media/media.gyp index 0de3fada3d6f..a5941dbe3bec 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -1391,6 +1391,7 @@ }], ['OS=="mac"', { 'sources': [ + 'midi/midi_manager_mac_unittest.cc', 'video/capture/mac/video_capture_device_factory_mac_unittest.mm', ] }], diff --git a/media/midi/midi_manager_mac_unittest.cc b/media/midi/midi_manager_mac_unittest.cc new file mode 100644 index 000000000000..e608d7c6ede7 --- /dev/null +++ b/media/midi/midi_manager_mac_unittest.cc @@ -0,0 +1,126 @@ +// Copyright 2015 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_mac.h" + +#include + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +namespace { + +void Noop(const MIDIPacketList*, void*, void*) {} + +class FakeMidiManagerClient : public MidiManagerClient { + public: + FakeMidiManagerClient() + : result_(MIDI_NOT_SUPPORTED), + wait_for_result_(true), + wait_for_port_(true) {} + + // MidiManagerClient implementation. + void AddInputPort(const MidiPortInfo& info) override {} + void AddOutputPort(const MidiPortInfo& info) override { + CHECK(!wait_for_result_); + info_ = info; + wait_for_port_ = false; + } + void SetInputPortState(uint32 port_index, MidiPortState state) override {} + void SetOutputPortState(uint32 port_index, MidiPortState state) override {} + + void CompleteStartSession(MidiResult result) override { + EXPECT_TRUE(wait_for_result_); + result_ = result; + wait_for_result_ = false; + } + + void ReceiveMidiData(uint32 port_index, const uint8* data, size_t size, + double timestamp) override {} + void AccumulateMidiBytesSent(size_t size) override {} + + MidiResult WaitForResult() { + while (wait_for_result_) { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + return result_; + } + MidiPortInfo WaitForPort() { + while (wait_for_port_) { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + return info_; + } + + private: + MidiResult result_; + bool wait_for_result_; + MidiPortInfo info_; + bool wait_for_port_; + + DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient); +}; + +class MidiManagerMacTest : public ::testing::Test { + public: + MidiManagerMacTest() + : manager_(new MidiManagerMac), + message_loop_(new base::MessageLoop) {} + + protected: + void StartSession(MidiManagerClient* client) { + manager_->StartSession(client); + } + void EndSession(MidiManagerClient* client) { + manager_->EndSession(client); + } + + private: + scoped_ptr manager_; + scoped_ptr message_loop_; + + DISALLOW_COPY_AND_ASSIGN(MidiManagerMacTest); +}; + + +TEST_F(MidiManagerMacTest, MidiNotification) { + scoped_ptr client(new FakeMidiManagerClient); + StartSession(client.get()); + + MidiResult result = client->WaitForResult(); + EXPECT_EQ(MIDI_OK, result); + + // Create MIDIClient, and MIDIEndpoint as a MIDIDestination. This should + // notify MIDIManagerMac as a MIDIObjectAddRemoveNotification. + MIDIClientRef midi_client = 0; + OSStatus status = MIDIClientCreate( + CFSTR("MidiManagerMacTest"), nullptr, nullptr, &midi_client); + EXPECT_EQ(noErr, status); + + MIDIEndpointRef ep = 0; + status = MIDIDestinationCreate( + midi_client, CFSTR("DestinationTest"), Noop, nullptr, &ep); + EXPECT_EQ(noErr, status); + + // Wait until the created device is notified to MidiManagerMac. + MidiPortInfo info = client->WaitForPort(); + EXPECT_EQ("DestinationTest", info.name); + + EndSession(client.get()); + if (ep) + MIDIEndpointDispose(ep); + if (midi_client) + MIDIClientDispose(midi_client); +} + +} // namespace + +} // namespace media -- 2.11.4.GIT