OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/midi/midi_manager.h" | 5 #include "media/midi/midi_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 25 matching lines...) Expand all Loading... |
36 } | 36 } |
37 | 37 |
38 void Finalize() override { finalize_is_called_ = true; } | 38 void Finalize() override { finalize_is_called_ = true; } |
39 | 39 |
40 void DispatchSendMidiData(MidiManagerClient* client, | 40 void DispatchSendMidiData(MidiManagerClient* client, |
41 uint32_t port_index, | 41 uint32_t port_index, |
42 const std::vector<uint8_t>& data, | 42 const std::vector<uint8_t>& data, |
43 double timestamp) override {} | 43 double timestamp) override {} |
44 | 44 |
45 // Utility functions for testing. | 45 // Utility functions for testing. |
46 void CallCompleteInitialization(Result result) { | 46 void CallCompleteInitialization(mojom::Result result) { |
47 CompleteInitialization(result); | 47 CompleteInitialization(result); |
48 } | 48 } |
49 | 49 |
50 size_t GetClientCount() const { | 50 size_t GetClientCount() const { |
51 return clients_size_for_testing(); | 51 return clients_size_for_testing(); |
52 } | 52 } |
53 | 53 |
54 size_t GetPendingClientCount() const { | 54 size_t GetPendingClientCount() const { |
55 return pending_clients_size_for_testing(); | 55 return pending_clients_size_for_testing(); |
56 } | 56 } |
57 | 57 |
58 bool start_initialization_is_called_; | 58 bool start_initialization_is_called_; |
59 bool finalize_is_called_; | 59 bool finalize_is_called_; |
60 | 60 |
61 private: | 61 private: |
62 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager); | 62 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager); |
63 }; | 63 }; |
64 | 64 |
65 class FakeMidiManagerClient : public MidiManagerClient { | 65 class FakeMidiManagerClient : public MidiManagerClient { |
66 public: | 66 public: |
67 FakeMidiManagerClient() | 67 FakeMidiManagerClient() |
68 : result_(Result::NOT_SUPPORTED), wait_for_result_(true) {} | 68 : result_(mojom::Result::NOT_SUPPORTED), wait_for_result_(true) {} |
69 ~FakeMidiManagerClient() override {} | 69 ~FakeMidiManagerClient() override {} |
70 | 70 |
71 // MidiManagerClient implementation. | 71 // MidiManagerClient implementation. |
72 void AddInputPort(const MidiPortInfo& info) override {} | 72 void AddInputPort(const MidiPortInfo& info) override {} |
73 void AddOutputPort(const MidiPortInfo& info) override {} | 73 void AddOutputPort(const MidiPortInfo& info) override {} |
74 void SetInputPortState(uint32_t port_index, MidiPortState state) override {} | 74 void SetInputPortState(uint32_t port_index, MidiPortState state) override {} |
75 void SetOutputPortState(uint32_t port_index, MidiPortState state) override {} | 75 void SetOutputPortState(uint32_t port_index, MidiPortState state) override {} |
76 | 76 |
77 void CompleteStartSession(Result result) override { | 77 void CompleteStartSession(mojom::Result result) override { |
78 EXPECT_TRUE(wait_for_result_); | 78 EXPECT_TRUE(wait_for_result_); |
79 result_ = result; | 79 result_ = result; |
80 wait_for_result_ = false; | 80 wait_for_result_ = false; |
81 } | 81 } |
82 | 82 |
83 void ReceiveMidiData(uint32_t port_index, | 83 void ReceiveMidiData(uint32_t port_index, |
84 const uint8_t* data, | 84 const uint8_t* data, |
85 size_t size, | 85 size_t size, |
86 double timestamp) override {} | 86 double timestamp) override {} |
87 void AccumulateMidiBytesSent(size_t size) override {} | 87 void AccumulateMidiBytesSent(size_t size) override {} |
88 void Detach() override {} | 88 void Detach() override {} |
89 | 89 |
90 Result result() const { return result_; } | 90 mojom::Result result() const { return result_; } |
91 | 91 |
92 Result WaitForResult() { | 92 mojom::Result WaitForResult() { |
93 while (wait_for_result_) { | 93 while (wait_for_result_) { |
94 base::RunLoop run_loop; | 94 base::RunLoop run_loop; |
95 run_loop.RunUntilIdle(); | 95 run_loop.RunUntilIdle(); |
96 } | 96 } |
97 return result(); | 97 return result(); |
98 } | 98 } |
99 | 99 |
100 private: | 100 private: |
101 Result result_; | 101 mojom::Result result_; |
102 bool wait_for_result_; | 102 bool wait_for_result_; |
103 | 103 |
104 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient); | 104 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient); |
105 }; | 105 }; |
106 | 106 |
107 class MidiManagerTest : public ::testing::Test { | 107 class MidiManagerTest : public ::testing::Test { |
108 public: | 108 public: |
109 MidiManagerTest() | 109 MidiManagerTest() |
110 : manager_(new FakeMidiManager), | 110 : manager_(new FakeMidiManager), |
111 message_loop_(new base::MessageLoop) {} | 111 message_loop_(new base::MessageLoop) {} |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_); | 143 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_); |
144 manager_->start_initialization_is_called_ = true; | 144 manager_->start_initialization_is_called_ = true; |
145 } | 145 } |
146 | 146 |
147 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) { | 147 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) { |
148 EXPECT_EQ(before, manager_->GetClientCount()); | 148 EXPECT_EQ(before, manager_->GetClientCount()); |
149 manager_->EndSession(client); | 149 manager_->EndSession(client); |
150 EXPECT_EQ(after, manager_->GetClientCount()); | 150 EXPECT_EQ(after, manager_->GetClientCount()); |
151 } | 151 } |
152 | 152 |
153 void CompleteInitialization(Result result) { | 153 void CompleteInitialization(mojom::Result result) { |
154 manager_->CallCompleteInitialization(result); | 154 manager_->CallCompleteInitialization(result); |
155 } | 155 } |
156 | 156 |
157 void RunLoopUntilIdle() { | 157 void RunLoopUntilIdle() { |
158 base::RunLoop run_loop; | 158 base::RunLoop run_loop; |
159 run_loop.RunUntilIdle(); | 159 run_loop.RunUntilIdle(); |
160 } | 160 } |
161 | 161 |
162 protected: | 162 protected: |
163 std::unique_ptr<FakeMidiManager> manager_; | 163 std::unique_ptr<FakeMidiManager> manager_; |
164 | 164 |
165 private: | 165 private: |
166 std::unique_ptr<base::MessageLoop> message_loop_; | 166 std::unique_ptr<base::MessageLoop> message_loop_; |
167 | 167 |
168 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest); | 168 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest); |
169 }; | 169 }; |
170 | 170 |
171 TEST_F(MidiManagerTest, StartAndEndSession) { | 171 TEST_F(MidiManagerTest, StartAndEndSession) { |
172 std::unique_ptr<FakeMidiManagerClient> client; | 172 std::unique_ptr<FakeMidiManagerClient> client; |
173 client.reset(new FakeMidiManagerClient); | 173 client.reset(new FakeMidiManagerClient); |
174 | 174 |
175 StartTheFirstSession(client.get()); | 175 StartTheFirstSession(client.get()); |
176 CompleteInitialization(Result::OK); | 176 CompleteInitialization(mojom::Result::OK); |
177 EXPECT_EQ(Result::OK, client->WaitForResult()); | 177 EXPECT_EQ(mojom::Result::OK, client->WaitForResult()); |
178 EndSession(client.get(), 1U, 0U); | 178 EndSession(client.get(), 1U, 0U); |
179 } | 179 } |
180 | 180 |
181 TEST_F(MidiManagerTest, StartAndEndSessionWithError) { | 181 TEST_F(MidiManagerTest, StartAndEndSessionWithError) { |
182 std::unique_ptr<FakeMidiManagerClient> client; | 182 std::unique_ptr<FakeMidiManagerClient> client; |
183 client.reset(new FakeMidiManagerClient); | 183 client.reset(new FakeMidiManagerClient); |
184 | 184 |
185 StartTheFirstSession(client.get()); | 185 StartTheFirstSession(client.get()); |
186 CompleteInitialization(Result::INITIALIZATION_ERROR); | 186 CompleteInitialization(mojom::Result::INITIALIZATION_ERROR); |
187 EXPECT_EQ(Result::INITIALIZATION_ERROR, client->WaitForResult()); | 187 EXPECT_EQ(mojom::Result::INITIALIZATION_ERROR, client->WaitForResult()); |
188 EndSession(client.get(), 0U, 0U); | 188 EndSession(client.get(), 0U, 0U); |
189 } | 189 } |
190 | 190 |
191 TEST_F(MidiManagerTest, StartMultipleSessions) { | 191 TEST_F(MidiManagerTest, StartMultipleSessions) { |
192 std::unique_ptr<FakeMidiManagerClient> client1; | 192 std::unique_ptr<FakeMidiManagerClient> client1; |
193 std::unique_ptr<FakeMidiManagerClient> client2; | 193 std::unique_ptr<FakeMidiManagerClient> client2; |
194 std::unique_ptr<FakeMidiManagerClient> client3; | 194 std::unique_ptr<FakeMidiManagerClient> client3; |
195 client1.reset(new FakeMidiManagerClient); | 195 client1.reset(new FakeMidiManagerClient); |
196 client2.reset(new FakeMidiManagerClient); | 196 client2.reset(new FakeMidiManagerClient); |
197 client3.reset(new FakeMidiManagerClient); | 197 client3.reset(new FakeMidiManagerClient); |
198 | 198 |
199 StartTheFirstSession(client1.get()); | 199 StartTheFirstSession(client1.get()); |
200 StartTheNthSession(client2.get(), 2); | 200 StartTheNthSession(client2.get(), 2); |
201 StartTheNthSession(client3.get(), 3); | 201 StartTheNthSession(client3.get(), 3); |
202 CompleteInitialization(Result::OK); | 202 CompleteInitialization(mojom::Result::OK); |
203 EXPECT_EQ(Result::OK, client1->WaitForResult()); | 203 EXPECT_EQ(mojom::Result::OK, client1->WaitForResult()); |
204 EXPECT_EQ(Result::OK, client2->WaitForResult()); | 204 EXPECT_EQ(mojom::Result::OK, client2->WaitForResult()); |
205 EXPECT_EQ(Result::OK, client3->WaitForResult()); | 205 EXPECT_EQ(mojom::Result::OK, client3->WaitForResult()); |
206 EndSession(client1.get(), 3U, 2U); | 206 EndSession(client1.get(), 3U, 2U); |
207 EndSession(client2.get(), 2U, 1U); | 207 EndSession(client2.get(), 2U, 1U); |
208 EndSession(client3.get(), 1U, 0U); | 208 EndSession(client3.get(), 1U, 0U); |
209 } | 209 } |
210 | 210 |
211 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple | 211 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple |
212 // sessions with multiple client_id. | 212 // sessions with multiple client_id. |
213 | 213 |
214 TEST_F(MidiManagerTest, TooManyPendingSessions) { | 214 TEST_F(MidiManagerTest, TooManyPendingSessions) { |
215 // Push as many client requests for starting session as possible. | 215 // Push as many client requests for starting session as possible. |
216 ScopedVector<FakeMidiManagerClient> many_existing_clients; | 216 ScopedVector<FakeMidiManagerClient> many_existing_clients; |
217 many_existing_clients.resize(MidiManager::kMaxPendingClientCount); | 217 many_existing_clients.resize(MidiManager::kMaxPendingClientCount); |
218 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) { | 218 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) { |
219 many_existing_clients[i] = new FakeMidiManagerClient; | 219 many_existing_clients[i] = new FakeMidiManagerClient; |
220 StartTheNthSession(many_existing_clients[i], i + 1); | 220 StartTheNthSession(many_existing_clients[i], i + 1); |
221 } | 221 } |
222 EXPECT_TRUE(manager_->start_initialization_is_called_); | 222 EXPECT_TRUE(manager_->start_initialization_is_called_); |
223 | 223 |
224 // Push the last client that should be rejected for too many pending requests. | 224 // Push the last client that should be rejected for too many pending requests. |
225 std::unique_ptr<FakeMidiManagerClient> additional_client( | 225 std::unique_ptr<FakeMidiManagerClient> additional_client( |
226 new FakeMidiManagerClient); | 226 new FakeMidiManagerClient); |
227 manager_->start_initialization_is_called_ = false; | 227 manager_->start_initialization_is_called_ = false; |
228 manager_->StartSession(additional_client.get()); | 228 manager_->StartSession(additional_client.get()); |
229 EXPECT_FALSE(manager_->start_initialization_is_called_); | 229 EXPECT_FALSE(manager_->start_initialization_is_called_); |
230 manager_->start_initialization_is_called_ = true; | 230 manager_->start_initialization_is_called_ = true; |
231 EXPECT_EQ(Result::INITIALIZATION_ERROR, additional_client->result()); | 231 EXPECT_EQ(mojom::Result::INITIALIZATION_ERROR, additional_client->result()); |
232 | 232 |
233 // Other clients still should not receive a result. | 233 // Other clients still should not receive a result. |
234 RunLoopUntilIdle(); | 234 RunLoopUntilIdle(); |
235 for (size_t i = 0; i < many_existing_clients.size(); ++i) | 235 for (size_t i = 0; i < many_existing_clients.size(); ++i) |
236 EXPECT_EQ(Result::NOT_SUPPORTED, many_existing_clients[i]->result()); | 236 EXPECT_EQ(mojom::Result::NOT_SUPPORTED, many_existing_clients[i]->result()); |
237 | 237 |
238 // The Result::OK should be distributed to other clients. | 238 // The mojom::Result::OK should be distributed to other clients. |
239 CompleteInitialization(Result::OK); | 239 CompleteInitialization(mojom::Result::OK); |
240 for (size_t i = 0; i < many_existing_clients.size(); ++i) | 240 for (size_t i = 0; i < many_existing_clients.size(); ++i) |
241 EXPECT_EQ(Result::OK, many_existing_clients[i]->WaitForResult()); | 241 EXPECT_EQ(mojom::Result::OK, many_existing_clients[i]->WaitForResult()); |
242 | 242 |
243 // Close all successful sessions in FIFO order. | 243 // Close all successful sessions in FIFO order. |
244 size_t sessions = many_existing_clients.size(); | 244 size_t sessions = many_existing_clients.size(); |
245 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions) | 245 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions) |
246 EndSession(many_existing_clients[i], sessions, sessions - 1); | 246 EndSession(many_existing_clients[i], sessions, sessions - 1); |
247 } | 247 } |
248 | 248 |
249 TEST_F(MidiManagerTest, AbortSession) { | 249 TEST_F(MidiManagerTest, AbortSession) { |
250 // A client starting a session can be destructed while an asynchronous | 250 // A client starting a session can be destructed while an asynchronous |
251 // initialization is performed. | 251 // initialization is performed. |
252 std::unique_ptr<FakeMidiManagerClient> client; | 252 std::unique_ptr<FakeMidiManagerClient> client; |
253 client.reset(new FakeMidiManagerClient); | 253 client.reset(new FakeMidiManagerClient); |
254 | 254 |
255 StartTheFirstSession(client.get()); | 255 StartTheFirstSession(client.get()); |
256 EndSession(client.get(), 0, 0); | 256 EndSession(client.get(), 0, 0); |
257 client.reset(); | 257 client.reset(); |
258 | 258 |
259 // Following function should not call the destructed |client| function. | 259 // Following function should not call the destructed |client| function. |
260 CompleteInitialization(Result::OK); | 260 CompleteInitialization(mojom::Result::OK); |
261 base::RunLoop run_loop; | 261 base::RunLoop run_loop; |
262 run_loop.RunUntilIdle(); | 262 run_loop.RunUntilIdle(); |
263 } | 263 } |
264 | 264 |
265 TEST_F(MidiManagerTest, CreateMidiManager) { | 265 TEST_F(MidiManagerTest, CreateMidiManager) { |
266 // SystemMonitor is needed on Windows. | 266 // SystemMonitor is needed on Windows. |
267 base::SystemMonitor system_monitor; | 267 base::SystemMonitor system_monitor; |
268 | 268 |
269 std::unique_ptr<FakeMidiManagerClient> client; | 269 std::unique_ptr<FakeMidiManagerClient> client; |
270 client.reset(new FakeMidiManagerClient); | 270 client.reset(new FakeMidiManagerClient); |
271 | 271 |
272 std::unique_ptr<MidiManager> manager(MidiManager::Create()); | 272 std::unique_ptr<MidiManager> manager(MidiManager::Create()); |
273 manager->StartSession(client.get()); | 273 manager->StartSession(client.get()); |
274 | 274 |
275 Result result = client->WaitForResult(); | 275 mojom::Result result = client->WaitForResult(); |
276 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc. | 276 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc. |
277 // Do not change the condition for disabling this test. | 277 // Do not change the condition for disabling this test. |
278 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ | 278 #if !defined(OS_MACOSX) && !defined(OS_WIN) && \ |
279 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) | 279 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID) |
280 EXPECT_EQ(Result::NOT_SUPPORTED, result); | 280 EXPECT_EQ(mojom::Result::NOT_SUPPORTED, result); |
281 #elif defined(USE_ALSA) | 281 #elif defined(USE_ALSA) |
282 // Temporary until http://crbug.com/371230 is resolved. | 282 // Temporary until http://crbug.com/371230 is resolved. |
283 EXPECT_TRUE(result == Result::OK || result == Result::INITIALIZATION_ERROR); | 283 EXPECT_TRUE(result == mojom::Result::OK || |
| 284 result == mojom::Result::INITIALIZATION_ERROR); |
284 #else | 285 #else |
285 EXPECT_EQ(Result::OK, result); | 286 EXPECT_EQ(mojom::Result::OK, result); |
286 #endif | 287 #endif |
287 | 288 |
288 manager->Shutdown(); | 289 manager->Shutdown(); |
289 base::RunLoop run_loop; | 290 base::RunLoop run_loop; |
290 run_loop.RunUntilIdle(); | 291 run_loop.RunUntilIdle(); |
291 } | 292 } |
292 | 293 |
293 // TODO(toyoshim): Add multi-threaded unit tests to check races around | 294 // TODO(toyoshim): Add multi-threaded unit tests to check races around |
294 // StartInitialization(), CompleteInitialization(), and Finalize(). | 295 // StartInitialization(), CompleteInitialization(), and Finalize(). |
295 | 296 |
296 } // namespace | 297 } // namespace |
297 | 298 |
298 } // namespace midi | 299 } // namespace midi |
OLD | NEW |