| 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 |