Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / media / midi / midi_manager_unittest.cc
blob1b6f638ee7be6e78303f6518775022502d827ea8
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/midi/midi_manager.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "base/system_monitor/system_monitor.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace media {
19 namespace midi {
21 namespace {
23 class FakeMidiManager : public MidiManager {
24 public:
25 FakeMidiManager() : start_initialization_is_called_(false) {}
26 ~FakeMidiManager() override {}
28 // MidiManager implementation.
29 void StartInitialization() override {
30 start_initialization_is_called_ = true;
33 void DispatchSendMidiData(MidiManagerClient* client,
34 uint32 port_index,
35 const std::vector<uint8>& data,
36 double timestamp) override {}
38 // Utility functions for testing.
39 void CallCompleteInitialization(MidiResult result) {
40 CompleteInitialization(result);
43 size_t GetClientCount() const {
44 return clients_size_for_testing();
47 size_t GetPendingClientCount() const {
48 return pending_clients_size_for_testing();
51 bool start_initialization_is_called_;
53 private:
54 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager);
57 class FakeMidiManagerClient : public MidiManagerClient {
58 public:
59 FakeMidiManagerClient()
60 : result_(MIDI_NOT_SUPPORTED),
61 wait_for_result_(true) {}
62 ~FakeMidiManagerClient() override {}
64 // MidiManagerClient implementation.
65 void AddInputPort(const MidiPortInfo& info) override {}
66 void AddOutputPort(const MidiPortInfo& info) override {}
67 void SetInputPortState(uint32 port_index, MidiPortState state) override {}
68 void SetOutputPortState(uint32 port_index, MidiPortState state) override {}
70 void CompleteStartSession(MidiResult result) override {
71 EXPECT_TRUE(wait_for_result_);
72 result_ = result;
73 wait_for_result_ = false;
76 void ReceiveMidiData(uint32 port_index,
77 const uint8* data,
78 size_t size,
79 double timestamp) override {}
80 void AccumulateMidiBytesSent(size_t size) override {}
82 MidiResult result() const { return result_; }
84 MidiResult WaitForResult() {
85 while (wait_for_result_) {
86 base::RunLoop run_loop;
87 run_loop.RunUntilIdle();
89 return result();
92 private:
93 MidiResult result_;
94 bool wait_for_result_;
96 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient);
99 class MidiManagerTest : public ::testing::Test {
100 public:
101 MidiManagerTest()
102 : manager_(new FakeMidiManager),
103 message_loop_(new base::MessageLoop) {}
104 ~MidiManagerTest() override {}
106 protected:
107 void StartTheFirstSession(FakeMidiManagerClient* client) {
108 EXPECT_FALSE(manager_->start_initialization_is_called_);
109 EXPECT_EQ(0U, manager_->GetClientCount());
110 EXPECT_EQ(0U, manager_->GetPendingClientCount());
111 manager_->StartSession(client);
112 EXPECT_EQ(0U, manager_->GetClientCount());
113 EXPECT_EQ(1U, manager_->GetPendingClientCount());
114 EXPECT_TRUE(manager_->start_initialization_is_called_);
115 EXPECT_EQ(0U, manager_->GetClientCount());
116 EXPECT_EQ(1U, manager_->GetPendingClientCount());
117 EXPECT_TRUE(manager_->start_initialization_is_called_);
120 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) {
121 EXPECT_EQ(nth != 1, manager_->start_initialization_is_called_);
122 EXPECT_EQ(0U, manager_->GetClientCount());
123 EXPECT_EQ(nth - 1, manager_->GetPendingClientCount());
125 // StartInitialization() should not be called for the second and later
126 // sessions.
127 manager_->start_initialization_is_called_ = false;
128 manager_->StartSession(client);
129 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_);
130 manager_->start_initialization_is_called_ = true;
133 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) {
134 EXPECT_EQ(before, manager_->GetClientCount());
135 manager_->EndSession(client);
136 EXPECT_EQ(after, manager_->GetClientCount());
139 void CompleteInitialization(MidiResult result) {
140 manager_->CallCompleteInitialization(result);
143 void RunLoopUntilIdle() {
144 base::RunLoop run_loop;
145 run_loop.RunUntilIdle();
148 protected:
149 scoped_ptr<FakeMidiManager> manager_;
151 private:
152 scoped_ptr<base::MessageLoop> message_loop_;
154 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest);
157 TEST_F(MidiManagerTest, StartAndEndSession) {
158 scoped_ptr<FakeMidiManagerClient> client;
159 client.reset(new FakeMidiManagerClient);
161 StartTheFirstSession(client.get());
162 CompleteInitialization(MIDI_OK);
163 EXPECT_EQ(MIDI_OK, client->WaitForResult());
164 EndSession(client.get(), 1U, 0U);
167 TEST_F(MidiManagerTest, StartAndEndSessionWithError) {
168 scoped_ptr<FakeMidiManagerClient> client;
169 client.reset(new FakeMidiManagerClient);
171 StartTheFirstSession(client.get());
172 CompleteInitialization(MIDI_INITIALIZATION_ERROR);
173 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, client->WaitForResult());
174 EndSession(client.get(), 0U, 0U);
177 TEST_F(MidiManagerTest, StartMultipleSessions) {
178 scoped_ptr<FakeMidiManagerClient> client1;
179 scoped_ptr<FakeMidiManagerClient> client2;
180 scoped_ptr<FakeMidiManagerClient> client3;
181 client1.reset(new FakeMidiManagerClient);
182 client2.reset(new FakeMidiManagerClient);
183 client3.reset(new FakeMidiManagerClient);
185 StartTheFirstSession(client1.get());
186 StartTheNthSession(client2.get(), 2);
187 StartTheNthSession(client3.get(), 3);
188 CompleteInitialization(MIDI_OK);
189 EXPECT_EQ(MIDI_OK, client1->WaitForResult());
190 EXPECT_EQ(MIDI_OK, client2->WaitForResult());
191 EXPECT_EQ(MIDI_OK, client3->WaitForResult());
192 EndSession(client1.get(), 3U, 2U);
193 EndSession(client2.get(), 2U, 1U);
194 EndSession(client3.get(), 1U, 0U);
197 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple
198 // sessions with multiple client_id.
200 TEST_F(MidiManagerTest, TooManyPendingSessions) {
201 // Push as many client requests for starting session as possible.
202 ScopedVector<FakeMidiManagerClient> many_existing_clients;
203 many_existing_clients.resize(MidiManager::kMaxPendingClientCount);
204 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) {
205 many_existing_clients[i] = new FakeMidiManagerClient;
206 StartTheNthSession(many_existing_clients[i], i + 1);
209 // Push the last client that should be rejected for too many pending requests.
210 scoped_ptr<FakeMidiManagerClient> additional_client(
211 new FakeMidiManagerClient);
212 manager_->start_initialization_is_called_ = false;
213 manager_->StartSession(additional_client.get());
214 EXPECT_FALSE(manager_->start_initialization_is_called_);
215 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result());
217 // Other clients still should not receive a result.
218 RunLoopUntilIdle();
219 for (size_t i = 0; i < many_existing_clients.size(); ++i)
220 EXPECT_EQ(MIDI_NOT_SUPPORTED, many_existing_clients[i]->result());
222 // The result MIDI_OK should be distributed to other clients.
223 CompleteInitialization(MIDI_OK);
224 for (size_t i = 0; i < many_existing_clients.size(); ++i)
225 EXPECT_EQ(MIDI_OK, many_existing_clients[i]->WaitForResult());
227 // Close all successful sessions in FIFO order.
228 size_t sessions = many_existing_clients.size();
229 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions)
230 EndSession(many_existing_clients[i], sessions, sessions - 1);
233 TEST_F(MidiManagerTest, AbortSession) {
234 // A client starting a session can be destructed while an asynchronous
235 // initialization is performed.
236 scoped_ptr<FakeMidiManagerClient> client;
237 client.reset(new FakeMidiManagerClient);
239 StartTheFirstSession(client.get());
240 EndSession(client.get(), 0, 0);
241 client.reset();
243 // Following function should not call the destructed |client| function.
244 CompleteInitialization(MIDI_OK);
245 base::RunLoop run_loop;
246 run_loop.RunUntilIdle();
249 TEST_F(MidiManagerTest, CreateMidiManager) {
250 // SystemMonitor is needed on Windows.
251 base::SystemMonitor system_monitor;
253 scoped_ptr<FakeMidiManagerClient> client;
254 client.reset(new FakeMidiManagerClient);
256 scoped_ptr<MidiManager> manager(MidiManager::Create());
257 manager->StartSession(client.get());
259 MidiResult result = client->WaitForResult();
260 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
261 // Do not change the condition for disabling this test.
262 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \
263 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID)
264 EXPECT_EQ(MIDI_NOT_SUPPORTED, result);
265 #elif defined(USE_ALSA)
266 // Temporary until http://crbug.com/371230 is resolved.
267 EXPECT_TRUE((result == MIDI_OK) || (result == MIDI_INITIALIZATION_ERROR));
268 #else
269 EXPECT_EQ(MIDI_OK, result);
270 #endif
273 } // namespace
275 } // namespace midi
276 } // namespace media