forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmidi_manager_mac_unittest.cc
156 lines (125 loc) · 4.16 KB
/
midi_manager_mac_unittest.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// 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 <CoreMIDI/MIDIServices.h>
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/lock.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),
unexpected_callback_(false) {}
// MidiManagerClient implementation.
void AddInputPort(const MidiPortInfo& info) override {}
void AddOutputPort(const MidiPortInfo& info) override {
base::AutoLock lock(lock_);
// AddOutputPort may be called before CompleteStartSession() is invoked
// if one or more MIDI devices including virtual ports are connected.
// Just ignore in such cases.
if (wait_for_result_)
return;
// Check if this is the first call after CompleteStartSession(), and
// the case should not happen twice.
if (!wait_for_port_)
unexpected_callback_ = true;
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 {
base::AutoLock lock(lock_);
if (!wait_for_result_)
unexpected_callback_ = true;
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 {}
bool GetWaitForResult() {
base::AutoLock lock(lock_);
return wait_for_result_;
}
bool GetWaitForPort() {
base::AutoLock lock(lock_);
return wait_for_port_;
}
MidiResult WaitForResult() {
while (GetWaitForResult()) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
}
EXPECT_FALSE(unexpected_callback_);
return result_;
}
MidiPortInfo WaitForPort() {
while (GetWaitForPort()) {
base::RunLoop run_loop;
run_loop.RunUntilIdle();
}
EXPECT_FALSE(unexpected_callback_);
return info_;
}
private:
base::Lock lock_;
MidiResult result_;
bool wait_for_result_;
MidiPortInfo info_;
bool wait_for_port_;
bool unexpected_callback_;
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<MidiManager> manager_;
scoped_ptr<base::MessageLoop> message_loop_;
DISALLOW_COPY_AND_ASSIGN(MidiManagerMacTest);
};
TEST_F(MidiManagerMacTest, MidiNotification) {
scoped_ptr<FakeMidiManagerClient> 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