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 <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 } | 47 } |
48 | 48 |
49 bool start_initialization_is_called_; | 49 bool start_initialization_is_called_; |
50 | 50 |
51 private: | 51 private: |
52 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager); | 52 DISALLOW_COPY_AND_ASSIGN(FakeMidiManager); |
53 }; | 53 }; |
54 | 54 |
55 class FakeMidiManagerClient : public MidiManagerClient { | 55 class FakeMidiManagerClient : public MidiManagerClient { |
56 public: | 56 public: |
57 explicit FakeMidiManagerClient(int client_id) | 57 FakeMidiManagerClient() |
58 : client_id_(client_id), | 58 : result_(MIDI_NOT_SUPPORTED), |
59 result_(MIDI_NOT_SUPPORTED), | |
60 wait_for_result_(true) {} | 59 wait_for_result_(true) {} |
61 virtual ~FakeMidiManagerClient() {} | 60 virtual ~FakeMidiManagerClient() {} |
62 | 61 |
63 // MidiManagerClient implementation. | 62 // MidiManagerClient implementation. |
64 virtual void CompleteStartSession(int client_id, MidiResult result) override { | 63 virtual void CompleteStartSession(MidiResult result) override { |
65 EXPECT_TRUE(wait_for_result_); | 64 EXPECT_TRUE(wait_for_result_); |
66 CHECK_EQ(client_id_, client_id); | |
67 result_ = result; | 65 result_ = result; |
68 wait_for_result_ = false; | 66 wait_for_result_ = false; |
69 } | 67 } |
70 | 68 |
71 virtual void ReceiveMidiData(uint32 port_index, const uint8* data, | 69 virtual void ReceiveMidiData(uint32 port_index, const uint8* data, |
72 size_t size, double timestamp) override {} | 70 size_t size, double timestamp) override {} |
73 virtual void AccumulateMidiBytesSent(size_t size) override {} | 71 virtual void AccumulateMidiBytesSent(size_t size) override {} |
74 | 72 |
75 int client_id() const { return client_id_; } | |
76 MidiResult result() const { return result_; } | 73 MidiResult result() const { return result_; } |
77 | 74 |
78 void HandleContinuationMessage() { | 75 void HandleContinuationMessage() { |
79 // Stop posting a dummy message once CompleteStartSession() is invoked. | 76 // Stop posting a dummy message once CompleteStartSession() is invoked. |
80 if (!wait_for_result_) | 77 if (!wait_for_result_) |
81 return; | 78 return; |
82 base::MessageLoop::current()->PostTask( | 79 base::MessageLoop::current()->PostTask( |
83 FROM_HERE, | 80 FROM_HERE, |
84 base::Bind(&FakeMidiManagerClient::HandleContinuationMessage, | 81 base::Bind(&FakeMidiManagerClient::HandleContinuationMessage, |
85 base::Unretained(this))); | 82 base::Unretained(this))); |
86 } | 83 } |
87 | 84 |
88 | 85 |
89 MidiResult WaitForResult() { | 86 MidiResult WaitForResult() { |
90 base::RunLoop run_loop; | 87 base::RunLoop run_loop; |
91 // Post a dummy task not to stop the following event loop. | 88 // Post a dummy task not to stop the following event loop. |
92 HandleContinuationMessage(); | 89 HandleContinuationMessage(); |
93 // CompleteStartSession() is called inside the message loop on the same | 90 // CompleteStartSession() is called inside the message loop on the same |
94 // thread. Protection for |wait_for_result_| is not needed. | 91 // thread. Protection for |wait_for_result_| is not needed. |
95 run_loop.RunUntilIdle(); | 92 run_loop.RunUntilIdle(); |
96 return result(); | 93 return result(); |
97 } | 94 } |
98 | 95 |
99 private: | 96 private: |
100 int client_id_; | |
101 MidiResult result_; | 97 MidiResult result_; |
102 bool wait_for_result_; | 98 bool wait_for_result_; |
103 | 99 |
104 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient); | 100 DISALLOW_COPY_AND_ASSIGN(FakeMidiManagerClient); |
105 }; | 101 }; |
106 | 102 |
107 class MidiManagerTest : public ::testing::Test { | 103 class MidiManagerTest : public ::testing::Test { |
108 public: | 104 public: |
109 MidiManagerTest() | 105 MidiManagerTest() |
110 : manager_(new FakeMidiManager), | 106 : manager_(new FakeMidiManager), |
111 message_loop_(new base::MessageLoop) {} | 107 message_loop_(new base::MessageLoop) {} |
112 virtual ~MidiManagerTest() {} | 108 virtual ~MidiManagerTest() {} |
113 | 109 |
114 protected: | 110 protected: |
115 void StartTheFirstSession(FakeMidiManagerClient* client) { | 111 void StartTheFirstSession(FakeMidiManagerClient* client) { |
116 EXPECT_FALSE(manager_->start_initialization_is_called_); | 112 EXPECT_FALSE(manager_->start_initialization_is_called_); |
117 EXPECT_EQ(0U, manager_->GetClientCount()); | 113 EXPECT_EQ(0U, manager_->GetClientCount()); |
118 EXPECT_EQ(0U, manager_->GetPendingClientCount()); | 114 EXPECT_EQ(0U, manager_->GetPendingClientCount()); |
119 manager_->StartSession(client, client->client_id()); | 115 manager_->StartSession(client); |
120 EXPECT_EQ(0U, manager_->GetClientCount()); | 116 EXPECT_EQ(0U, manager_->GetClientCount()); |
121 EXPECT_EQ(1U, manager_->GetPendingClientCount()); | 117 EXPECT_EQ(1U, manager_->GetPendingClientCount()); |
122 EXPECT_TRUE(manager_->start_initialization_is_called_); | 118 EXPECT_TRUE(manager_->start_initialization_is_called_); |
123 EXPECT_EQ(0U, manager_->GetClientCount()); | 119 EXPECT_EQ(0U, manager_->GetClientCount()); |
124 EXPECT_EQ(1U, manager_->GetPendingClientCount()); | 120 EXPECT_EQ(1U, manager_->GetPendingClientCount()); |
125 EXPECT_TRUE(manager_->start_initialization_is_called_); | 121 EXPECT_TRUE(manager_->start_initialization_is_called_); |
126 } | 122 } |
127 | 123 |
128 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) { | 124 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) { |
129 EXPECT_EQ(nth != 1, manager_->start_initialization_is_called_); | 125 EXPECT_EQ(nth != 1, manager_->start_initialization_is_called_); |
130 EXPECT_EQ(0U, manager_->GetClientCount()); | 126 EXPECT_EQ(0U, manager_->GetClientCount()); |
131 EXPECT_EQ(nth - 1, manager_->GetPendingClientCount()); | 127 EXPECT_EQ(nth - 1, manager_->GetPendingClientCount()); |
132 | 128 |
133 // StartInitialization() should not be called for the second and later | 129 // StartInitialization() should not be called for the second and later |
134 // sessions. | 130 // sessions. |
135 manager_->start_initialization_is_called_ = false; | 131 manager_->start_initialization_is_called_ = false; |
136 manager_->StartSession(client, client->client_id()); | 132 manager_->StartSession(client); |
137 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_); | 133 EXPECT_EQ(nth == 1, manager_->start_initialization_is_called_); |
138 manager_->start_initialization_is_called_ = true; | 134 manager_->start_initialization_is_called_ = true; |
139 } | 135 } |
140 | 136 |
141 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) { | 137 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) { |
142 EXPECT_EQ(before, manager_->GetClientCount()); | 138 EXPECT_EQ(before, manager_->GetClientCount()); |
143 manager_->EndSession(client); | 139 manager_->EndSession(client); |
144 EXPECT_EQ(after, manager_->GetClientCount()); | 140 EXPECT_EQ(after, manager_->GetClientCount()); |
145 } | 141 } |
146 | 142 |
(...skipping 10 matching lines...) Expand all Loading... |
157 scoped_ptr<FakeMidiManager> manager_; | 153 scoped_ptr<FakeMidiManager> manager_; |
158 | 154 |
159 private: | 155 private: |
160 scoped_ptr<base::MessageLoop> message_loop_; | 156 scoped_ptr<base::MessageLoop> message_loop_; |
161 | 157 |
162 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest); | 158 DISALLOW_COPY_AND_ASSIGN(MidiManagerTest); |
163 }; | 159 }; |
164 | 160 |
165 TEST_F(MidiManagerTest, StartAndEndSession) { | 161 TEST_F(MidiManagerTest, StartAndEndSession) { |
166 scoped_ptr<FakeMidiManagerClient> client; | 162 scoped_ptr<FakeMidiManagerClient> client; |
167 client.reset(new FakeMidiManagerClient(0)); | 163 client.reset(new FakeMidiManagerClient); |
168 | 164 |
169 StartTheFirstSession(client.get()); | 165 StartTheFirstSession(client.get()); |
170 CompleteInitialization(MIDI_OK); | 166 CompleteInitialization(MIDI_OK); |
171 EXPECT_EQ(MIDI_OK, client->WaitForResult()); | 167 EXPECT_EQ(MIDI_OK, client->WaitForResult()); |
172 EndSession(client.get(), 1U, 0U); | 168 EndSession(client.get(), 1U, 0U); |
173 } | 169 } |
174 | 170 |
175 TEST_F(MidiManagerTest, StartAndEndSessionWithError) { | 171 TEST_F(MidiManagerTest, StartAndEndSessionWithError) { |
176 scoped_ptr<FakeMidiManagerClient> client; | 172 scoped_ptr<FakeMidiManagerClient> client; |
177 client.reset(new FakeMidiManagerClient(1)); | 173 client.reset(new FakeMidiManagerClient); |
178 | 174 |
179 StartTheFirstSession(client.get()); | 175 StartTheFirstSession(client.get()); |
180 CompleteInitialization(MIDI_INITIALIZATION_ERROR); | 176 CompleteInitialization(MIDI_INITIALIZATION_ERROR); |
181 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, client->WaitForResult()); | 177 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, client->WaitForResult()); |
182 EndSession(client.get(), 0U, 0U); | 178 EndSession(client.get(), 0U, 0U); |
183 } | 179 } |
184 | 180 |
185 TEST_F(MidiManagerTest, StartMultipleSessions) { | 181 TEST_F(MidiManagerTest, StartMultipleSessions) { |
186 scoped_ptr<FakeMidiManagerClient> client1; | 182 scoped_ptr<FakeMidiManagerClient> client1; |
187 scoped_ptr<FakeMidiManagerClient> client2; | 183 scoped_ptr<FakeMidiManagerClient> client2; |
188 scoped_ptr<FakeMidiManagerClient> client3; | 184 scoped_ptr<FakeMidiManagerClient> client3; |
189 client1.reset(new FakeMidiManagerClient(0)); | 185 client1.reset(new FakeMidiManagerClient); |
190 client2.reset(new FakeMidiManagerClient(1)); | 186 client2.reset(new FakeMidiManagerClient); |
191 client3.reset(new FakeMidiManagerClient(1)); | 187 client3.reset(new FakeMidiManagerClient); |
192 | 188 |
193 StartTheFirstSession(client1.get()); | 189 StartTheFirstSession(client1.get()); |
194 StartTheNthSession(client2.get(), 2); | 190 StartTheNthSession(client2.get(), 2); |
195 StartTheNthSession(client3.get(), 3); | 191 StartTheNthSession(client3.get(), 3); |
196 CompleteInitialization(MIDI_OK); | 192 CompleteInitialization(MIDI_OK); |
197 EXPECT_EQ(MIDI_OK, client1->WaitForResult()); | 193 EXPECT_EQ(MIDI_OK, client1->WaitForResult()); |
198 EXPECT_EQ(MIDI_OK, client2->WaitForResult()); | 194 EXPECT_EQ(MIDI_OK, client2->WaitForResult()); |
199 EXPECT_EQ(MIDI_OK, client3->WaitForResult()); | 195 EXPECT_EQ(MIDI_OK, client3->WaitForResult()); |
200 EndSession(client1.get(), 3U, 2U); | 196 EndSession(client1.get(), 3U, 2U); |
201 EndSession(client2.get(), 2U, 1U); | 197 EndSession(client2.get(), 2U, 1U); |
202 EndSession(client3.get(), 1U, 0U); | 198 EndSession(client3.get(), 1U, 0U); |
203 } | 199 } |
204 | 200 |
205 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple | 201 // TODO(toyoshim): Add a test for a MidiManagerClient that has multiple |
206 // sessions with multiple client_id. | 202 // sessions with multiple client_id. |
207 | 203 |
208 TEST_F(MidiManagerTest, TooManyPendingSessions) { | 204 TEST_F(MidiManagerTest, TooManyPendingSessions) { |
209 // Push as many client requests for starting session as possible. | 205 // Push as many client requests for starting session as possible. |
210 ScopedVector<FakeMidiManagerClient> many_existing_clients; | 206 ScopedVector<FakeMidiManagerClient> many_existing_clients; |
211 many_existing_clients.resize(MidiManager::kMaxPendingClientCount); | 207 many_existing_clients.resize(MidiManager::kMaxPendingClientCount); |
212 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) { | 208 for (size_t i = 0; i < MidiManager::kMaxPendingClientCount; ++i) { |
213 many_existing_clients[i] = new FakeMidiManagerClient(i); | 209 many_existing_clients[i] = new FakeMidiManagerClient; |
214 StartTheNthSession(many_existing_clients[i], i + 1); | 210 StartTheNthSession(many_existing_clients[i], i + 1); |
215 } | 211 } |
216 | 212 |
217 // Push the last client that should be rejected for too many pending requests. | 213 // Push the last client that should be rejected for too many pending requests. |
218 scoped_ptr<FakeMidiManagerClient> additional_client( | 214 scoped_ptr<FakeMidiManagerClient> additional_client( |
219 new FakeMidiManagerClient(MidiManager::kMaxPendingClientCount)); | 215 new FakeMidiManagerClient); |
220 manager_->start_initialization_is_called_ = false; | 216 manager_->start_initialization_is_called_ = false; |
221 manager_->StartSession(additional_client.get(), | 217 manager_->StartSession(additional_client.get()); |
222 additional_client->client_id()); | |
223 EXPECT_FALSE(manager_->start_initialization_is_called_); | 218 EXPECT_FALSE(manager_->start_initialization_is_called_); |
224 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result()); | 219 EXPECT_EQ(MIDI_INITIALIZATION_ERROR, additional_client->result()); |
225 | 220 |
226 // Other clients still should not receive a result. | 221 // Other clients still should not receive a result. |
227 RunLoopUntilIdle(); | 222 RunLoopUntilIdle(); |
228 for (size_t i = 0; i < many_existing_clients.size(); ++i) | 223 for (size_t i = 0; i < many_existing_clients.size(); ++i) |
229 EXPECT_EQ(MIDI_NOT_SUPPORTED, many_existing_clients[i]->result()); | 224 EXPECT_EQ(MIDI_NOT_SUPPORTED, many_existing_clients[i]->result()); |
230 | 225 |
231 // The result MIDI_OK should be distributed to other clients. | 226 // The result MIDI_OK should be distributed to other clients. |
232 CompleteInitialization(MIDI_OK); | 227 CompleteInitialization(MIDI_OK); |
233 for (size_t i = 0; i < many_existing_clients.size(); ++i) | 228 for (size_t i = 0; i < many_existing_clients.size(); ++i) |
234 EXPECT_EQ(MIDI_OK, many_existing_clients[i]->WaitForResult()); | 229 EXPECT_EQ(MIDI_OK, many_existing_clients[i]->WaitForResult()); |
235 | 230 |
236 // Close all successful sessions in FIFO order. | 231 // Close all successful sessions in FIFO order. |
237 size_t sessions = many_existing_clients.size(); | 232 size_t sessions = many_existing_clients.size(); |
238 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions) | 233 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions) |
239 EndSession(many_existing_clients[i], sessions, sessions - 1); | 234 EndSession(many_existing_clients[i], sessions, sessions - 1); |
240 } | 235 } |
241 | 236 |
242 TEST_F(MidiManagerTest, AbortSession) { | 237 TEST_F(MidiManagerTest, AbortSession) { |
243 // A client starting a session can be destructed while an asynchronous | 238 // A client starting a session can be destructed while an asynchronous |
244 // initialization is performed. | 239 // initialization is performed. |
245 scoped_ptr<FakeMidiManagerClient> client; | 240 scoped_ptr<FakeMidiManagerClient> client; |
246 client.reset(new FakeMidiManagerClient(0)); | 241 client.reset(new FakeMidiManagerClient); |
247 | 242 |
248 StartTheFirstSession(client.get()); | 243 StartTheFirstSession(client.get()); |
249 EndSession(client.get(), 0, 0); | 244 EndSession(client.get(), 0, 0); |
250 client.reset(); | 245 client.reset(); |
251 | 246 |
252 // Following function should not call the destructed |client| function. | 247 // Following function should not call the destructed |client| function. |
253 CompleteInitialization(MIDI_OK); | 248 CompleteInitialization(MIDI_OK); |
254 base::RunLoop run_loop; | 249 base::RunLoop run_loop; |
255 run_loop.RunUntilIdle(); | 250 run_loop.RunUntilIdle(); |
256 } | 251 } |
257 | 252 |
258 TEST_F(MidiManagerTest, CreateMidiManager) { | 253 TEST_F(MidiManagerTest, CreateMidiManager) { |
259 scoped_ptr<FakeMidiManagerClient> client; | 254 scoped_ptr<FakeMidiManagerClient> client; |
260 client.reset(new FakeMidiManagerClient(0)); | 255 client.reset(new FakeMidiManagerClient); |
261 | 256 |
262 scoped_ptr<MidiManager> manager(MidiManager::Create()); | 257 scoped_ptr<MidiManager> manager(MidiManager::Create()); |
263 manager->StartSession(client.get(), client->client_id()); | 258 manager->StartSession(client.get()); |
264 | 259 |
265 MidiResult result = client->WaitForResult(); | 260 MidiResult result = client->WaitForResult(); |
266 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc. | 261 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc. |
267 // Do not change the condition for disabling this test. | 262 // Do not change the condition for disabling this test. |
268 #if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \ | 263 #if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(USE_ALSA) && \ |
269 !defined(OS_ANDROID) && !defined(OS_CHROMEOS) | 264 !defined(OS_ANDROID) && !defined(OS_CHROMEOS) |
270 EXPECT_EQ(MIDI_NOT_SUPPORTED, result); | 265 EXPECT_EQ(MIDI_NOT_SUPPORTED, result); |
271 #elif defined(USE_ALSA) | 266 #elif defined(USE_ALSA) |
272 // Temporary until http://crbug.com/371230 is resolved. | 267 // Temporary until http://crbug.com/371230 is resolved. |
273 EXPECT_TRUE((result == MIDI_OK) || (result == MIDI_INITIALIZATION_ERROR)); | 268 EXPECT_TRUE((result == MIDI_OK) || (result == MIDI_INITIALIZATION_ERROR)); |
274 #else | 269 #else |
275 EXPECT_EQ(MIDI_OK, result); | 270 EXPECT_EQ(MIDI_OK, result); |
276 #endif | 271 #endif |
277 } | 272 } |
278 | 273 |
279 } // namespace | 274 } // namespace |
280 | 275 |
281 } // namespace media | 276 } // namespace media |
OLD | NEW |