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