blob: 859f8e501c878d42de8843d952def14d259162c8 [file] [log] [blame]
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +00001// 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.
4
5#include "media/midi/midi_manager.h"
6
avi793390d2015-12-22 22:22:36 -08007#include <stddef.h>
8#include <stdint.h>
9
danakj75afea02016-04-25 20:36:04 -070010#include <memory>
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +000011#include <vector>
12
toyoshimc9f52132014-10-15 05:50:07 -070013#include "base/bind.h"
Hans Wennborg5f6a4612020-04-24 20:55:49 +000014#include "base/check_op.h"
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090015#include "base/memory/weak_ptr.h"
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +000016#include "base/run_loop.h"
Sebastien Marchand21848772018-10-05 15:29:27 +000017#include "base/system/system_monitor.h"
Gabriel Charette69901582019-08-23 03:31:40 +000018#include "base/test/task_environment.h"
avi793390d2015-12-22 22:22:36 -080019#include "build/build_config.h"
toyoshimf4d61522017-02-10 02:03:32 -080020#include "media/midi/midi_service.h"
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +000021#include "media/midi/task_service.h"
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000022#include "testing/gtest/include/gtest/gtest.h"
23
Xiaohan Wang77cc36d2022-01-15 06:19:37 +000024#if BUILDFLAG(IS_WIN)
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +000025#include "media/midi/midi_manager_win.h"
Xiaohan Wang77cc36d2022-01-15 06:19:37 +000026#endif // BUILDFLAG(IS_WIN)
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +000027
toyoshime147c5e2015-05-07 21:58:31 -070028namespace midi {
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000029
30namespace {
31
toyoshimec2570a2016-10-21 02:15:27 -070032using mojom::PortState;
toyoshim2f3a48f2016-10-17 01:54:13 -070033using mojom::Result;
34
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000035class FakeMidiManager : public MidiManager {
36 public:
Jeremy Roman9e1d1a72019-07-09 18:34:37 +000037 explicit FakeMidiManager(MidiService* service) : MidiManager(service) {}
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090038
Peter Boström53634032021-09-22 20:24:34 +000039 FakeMidiManager(const FakeMidiManager&) = delete;
40 FakeMidiManager& operator=(const FakeMidiManager&) = delete;
41
Takashi Toyoshimae8240ab2018-10-03 09:30:11 +000042 ~FakeMidiManager() override = default;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090043
44 base::WeakPtr<FakeMidiManager> GetWeakPtr() {
45 return weak_factory_.GetWeakPtr();
46 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000047
48 // MidiManager implementation.
dcheng63ccbc32014-10-21 05:23:27 -070049 void StartInitialization() override {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090050 DCHECK(!initialized_);
51 initialized_ = true;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000052 }
dcheng63ccbc32014-10-21 05:23:27 -070053 void DispatchSendMidiData(MidiManagerClient* client,
Avi Drissman3528fd02015-12-18 20:11:31 -050054 uint32_t port_index,
55 const std::vector<uint8_t>& data,
tzik925e2c62018-02-02 07:39:45 +000056 base::TimeTicks timestamp) override {}
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000057
58 // Utility functions for testing.
toyoshimf1b88962015-07-09 14:14:51 -070059 void CallCompleteInitialization(Result result) {
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000060 CompleteInitialization(result);
61 }
62
Takashi Toyoshimad4f37cd2018-10-01 07:43:39 +000063 size_t GetClientCount() { return GetClientCountForTesting(); }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000064
Takashi Toyoshimad4f37cd2018-10-01 07:43:39 +000065 size_t GetPendingClientCount() { return GetPendingClientCountForTesting(); }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000066
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090067 bool IsInitialized() const { return initialized_; }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000068
69 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090070 bool initialized_ = false;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090071
Jeremy Roman9e1d1a72019-07-09 18:34:37 +000072 base::WeakPtrFactory<FakeMidiManager> weak_factory_{this};
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000073};
74
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000075class FakeMidiManagerFactory : public MidiService::ManagerFactory {
76 public:
Jeremy Roman9e1d1a72019-07-09 18:34:37 +000077 FakeMidiManagerFactory() {}
Peter Boström53634032021-09-22 20:24:34 +000078
79 FakeMidiManagerFactory(const FakeMidiManagerFactory&) = delete;
80 FakeMidiManagerFactory& operator=(const FakeMidiManagerFactory&) = delete;
81
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000082 ~FakeMidiManagerFactory() override = default;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090083
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000084 std::unique_ptr<MidiManager> Create(MidiService* service) override {
85 std::unique_ptr<FakeMidiManager> manager =
86 std::make_unique<FakeMidiManager>(service);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090087 manager_ = manager->GetWeakPtr();
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000088 return manager;
89 }
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090090
91 base::WeakPtr<FakeMidiManagerFactory> GetWeakPtr() {
92 return weak_factory_.GetWeakPtr();
93 }
94
95 base::WeakPtr<FakeMidiManager> manager() {
Xiaohan Wang77cc36d2022-01-15 06:19:37 +000096#if BUILDFLAG(IS_MAC)
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090097 // To avoid Core MIDI issues, MidiManager won't be destructed on macOS.
98 // See https://crbug.com/718140.
99 if (!manager_ ||
100 (!manager_->GetClientCount() && !manager_->GetPendingClientCount())) {
101 return nullptr;
102 }
103#endif
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000104 return manager_;
105 }
106
107 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900108 base::WeakPtr<FakeMidiManager> manager_ = nullptr;
Jeremy Roman9e1d1a72019-07-09 18:34:37 +0000109 base::WeakPtrFactory<FakeMidiManagerFactory> weak_factory_{this};
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000110};
111
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000112class FakeMidiManagerClient : public MidiManagerClient {
113 public:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900114 FakeMidiManagerClient() = default;
Peter Boström53634032021-09-22 20:24:34 +0000115
116 FakeMidiManagerClient(const FakeMidiManagerClient&) = delete;
117 FakeMidiManagerClient& operator=(const FakeMidiManagerClient&) = delete;
118
Chris Watkinsc6cbcf62017-12-01 03:08:01 +0000119 ~FakeMidiManagerClient() override = default;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000120
121 // MidiManagerClient implementation.
Adithya Srinivasan33252732018-10-17 15:59:40 +0000122 void AddInputPort(const mojom::PortInfo& info) override {}
123 void AddOutputPort(const mojom::PortInfo& info) override {}
toyoshimec2570a2016-10-21 02:15:27 -0700124 void SetInputPortState(uint32_t port_index, PortState state) override {}
125 void SetOutputPortState(uint32_t port_index, PortState state) override {}
toyoshimf1b88962015-07-09 14:14:51 -0700126 void CompleteStartSession(Result result) override {
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000127 EXPECT_TRUE(wait_for_result_);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000128 result_ = result;
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000129 wait_for_result_ = false;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000130 }
Avi Drissman3528fd02015-12-18 20:11:31 -0500131 void ReceiveMidiData(uint32_t port_index,
132 const uint8_t* data,
dcheng63ccbc32014-10-21 05:23:27 -0700133 size_t size,
tzik925e2c62018-02-02 07:39:45 +0000134 base::TimeTicks timestamp) override {}
dcheng63ccbc32014-10-21 05:23:27 -0700135 void AccumulateMidiBytesSent(size_t size) override {}
toyoshim7a809662015-10-06 00:54:21 -0700136 void Detach() override {}
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000137
toyoshimf1b88962015-07-09 14:14:51 -0700138 Result result() const { return result_; }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000139
toyoshimf1b88962015-07-09 14:14:51 -0700140 Result WaitForResult() {
toyoshim11f7d572014-10-20 02:37:10 -0700141 while (wait_for_result_) {
142 base::RunLoop run_loop;
143 run_loop.RunUntilIdle();
144 }
toyoshim@chromium.orga25e6832014-05-07 18:06:25 +0000145 return result();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000146 }
147
148 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900149 Result result_ = Result::NOT_SUPPORTED;
150 bool wait_for_result_ = true;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000151};
152
153class MidiManagerTest : public ::testing::Test {
154 public:
Sebastien Marchand812fdbf2018-11-22 12:08:44 +0000155 MidiManagerTest() {
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000156 std::unique_ptr<FakeMidiManagerFactory> factory =
157 std::make_unique<FakeMidiManagerFactory>();
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900158 factory_ = factory->GetWeakPtr();
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000159 service_ = std::make_unique<MidiService>(std::move(factory));
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000160 }
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900161
Peter Boström53634032021-09-22 20:24:34 +0000162 MidiManagerTest(const MidiManagerTest&) = delete;
163 MidiManagerTest& operator=(const MidiManagerTest&) = delete;
164
toyoshim7a809662015-10-06 00:54:21 -0700165 ~MidiManagerTest() override {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900166 service_->Shutdown();
toyoshim7a809662015-10-06 00:54:21 -0700167 base::RunLoop run_loop;
168 run_loop.RunUntilIdle();
toyoshim7a809662015-10-06 00:54:21 -0700169 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000170
171 protected:
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000172 void StartTheFirstSession(FakeMidiManagerClient* client) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900173 DCHECK(factory_);
174
175 EXPECT_FALSE(factory_->manager());
176 service_->StartSession(client);
177 ASSERT_TRUE(factory_->manager());
178 EXPECT_TRUE(factory_->manager()->IsInitialized());
179 EXPECT_EQ(0U, factory_->manager()->GetClientCount());
180 EXPECT_EQ(1U, factory_->manager()->GetPendingClientCount());
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000181 }
182
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000183 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900184 DCHECK(factory_);
185 DCHECK_NE(1U, nth);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000186
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900187 ASSERT_TRUE(factory_->manager());
188 EXPECT_TRUE(factory_->manager()->IsInitialized());
189 EXPECT_EQ(0U, factory_->manager()->GetClientCount());
190 EXPECT_EQ(nth - 1U, factory_->manager()->GetPendingClientCount());
191 service_->StartSession(client);
192 EXPECT_EQ(nth, factory_->manager()->GetPendingClientCount());
193 }
194
195 void StartSession(FakeMidiManagerClient* client) {
196 service_->StartSession(client);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000197 }
198
199 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900200 DCHECK(factory_);
201
202 ASSERT_TRUE(factory_->manager());
203 EXPECT_EQ(before, factory_->manager()->GetClientCount());
204 EXPECT_TRUE(service_->EndSession(client));
205 if (after) {
206 ASSERT_TRUE(factory_->manager());
207 EXPECT_EQ(after, factory_->manager()->GetClientCount());
208 } else {
209 EXPECT_FALSE(factory_->manager());
210 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000211 }
212
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900213 bool CompleteInitialization(Result result) {
214 DCHECK(factory_);
215
216 if (!factory_->manager())
217 return false;
218
219 factory_->manager()->CallCompleteInitialization(result);
220 return true;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000221 }
222
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000223 void RunLoopUntilIdle() {
224 base::RunLoop run_loop;
225 run_loop.RunUntilIdle();
226 }
227
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900228 base::WeakPtr<FakeMidiManagerFactory> factory() { return factory_; }
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000229
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000230 private:
Gabriel Charettea7cc6672019-08-19 17:30:11 +0000231 base::test::TaskEnvironment env_;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900232 base::WeakPtr<FakeMidiManagerFactory> factory_;
233 std::unique_ptr<MidiService> service_;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000234};
235
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000236TEST_F(MidiManagerTest, StartAndEndSession) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900237 std::unique_ptr<FakeMidiManagerClient> client =
238 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000239
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000240 StartTheFirstSession(client.get());
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900241 EXPECT_TRUE(CompleteInitialization(Result::OK));
toyoshimf1b88962015-07-09 14:14:51 -0700242 EXPECT_EQ(Result::OK, client->WaitForResult());
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000243 EndSession(client.get(), 1U, 0U);
244}
245
246TEST_F(MidiManagerTest, StartAndEndSessionWithError) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900247 std::unique_ptr<FakeMidiManagerClient> client =
248 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000249
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000250 StartTheFirstSession(client.get());
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900251 EXPECT_TRUE(CompleteInitialization(Result::INITIALIZATION_ERROR));
toyoshimf1b88962015-07-09 14:14:51 -0700252 EXPECT_EQ(Result::INITIALIZATION_ERROR, client->WaitForResult());
Takashi Toyoshimaec05edf2017-11-28 11:21:20 +0000253 EndSession(client.get(), 1U, 0U);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000254}
255
256TEST_F(MidiManagerTest, StartMultipleSessions) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900257 std::unique_ptr<FakeMidiManagerClient> client1 =
258 std::make_unique<FakeMidiManagerClient>();
259 std::unique_ptr<FakeMidiManagerClient> client2 =
260 std::make_unique<FakeMidiManagerClient>();
261 std::unique_ptr<FakeMidiManagerClient> client3 =
262 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000263
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000264 StartTheFirstSession(client1.get());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000265 StartTheNthSession(client2.get(), 2);
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000266 StartTheNthSession(client3.get(), 3);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900267 EXPECT_TRUE(CompleteInitialization(Result::OK));
toyoshimf1b88962015-07-09 14:14:51 -0700268 EXPECT_EQ(Result::OK, client1->WaitForResult());
269 EXPECT_EQ(Result::OK, client2->WaitForResult());
270 EXPECT_EQ(Result::OK, client3->WaitForResult());
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000271 EndSession(client1.get(), 3U, 2U);
272 EndSession(client2.get(), 2U, 1U);
273 EndSession(client3.get(), 1U, 0U);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000274}
275
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000276TEST_F(MidiManagerTest, TooManyPendingSessions) {
277 // Push as many client requests for starting session as possible.
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700278 std::vector<std::unique_ptr<FakeMidiManagerClient>> many_existing_clients;
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000279 many_existing_clients.resize(MidiManager::kMaxPendingClientCount);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900280 many_existing_clients[0] = std::make_unique<FakeMidiManagerClient>();
281 StartTheFirstSession(many_existing_clients[0].get());
282 for (size_t i = 1; i < MidiManager::kMaxPendingClientCount; ++i) {
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000283 many_existing_clients[i] = std::make_unique<FakeMidiManagerClient>();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700284 StartTheNthSession(many_existing_clients[i].get(), i + 1);
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000285 }
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900286 ASSERT_TRUE(factory()->manager());
287 EXPECT_TRUE(factory()->manager()->IsInitialized());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000288
289 // Push the last client that should be rejected for too many pending requests.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900290 std::unique_ptr<FakeMidiManagerClient> additional_client =
291 std::make_unique<FakeMidiManagerClient>();
292 StartSession(additional_client.get());
toyoshimf1b88962015-07-09 14:14:51 -0700293 EXPECT_EQ(Result::INITIALIZATION_ERROR, additional_client->result());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000294
295 // Other clients still should not receive a result.
296 RunLoopUntilIdle();
297 for (size_t i = 0; i < many_existing_clients.size(); ++i)
toyoshimf1b88962015-07-09 14:14:51 -0700298 EXPECT_EQ(Result::NOT_SUPPORTED, many_existing_clients[i]->result());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000299
toyoshimf1b88962015-07-09 14:14:51 -0700300 // The Result::OK should be distributed to other clients.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900301 EXPECT_TRUE(CompleteInitialization(Result::OK));
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000302 for (size_t i = 0; i < many_existing_clients.size(); ++i)
toyoshimf1b88962015-07-09 14:14:51 -0700303 EXPECT_EQ(Result::OK, many_existing_clients[i]->WaitForResult());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000304
305 // Close all successful sessions in FIFO order.
306 size_t sessions = many_existing_clients.size();
307 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions)
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700308 EndSession(many_existing_clients[i].get(), sessions, sessions - 1);
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000309}
310
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000311TEST_F(MidiManagerTest, AbortSession) {
312 // A client starting a session can be destructed while an asynchronous
313 // initialization is performed.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900314 std::unique_ptr<FakeMidiManagerClient> client =
315 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000316
317 StartTheFirstSession(client.get());
318 EndSession(client.get(), 0, 0);
319 client.reset();
320
321 // Following function should not call the destructed |client| function.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900322 EXPECT_FALSE(CompleteInitialization(Result::OK));
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000323 base::RunLoop run_loop;
324 run_loop.RunUntilIdle();
325}
326
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000327class PlatformMidiManagerTest : public ::testing::Test {
328 public:
329 PlatformMidiManagerTest()
330 : client_(std::make_unique<FakeMidiManagerClient>()),
331 service_(std::make_unique<MidiService>()) {
332 //
333 }
334
Peter Boström53634032021-09-22 20:24:34 +0000335 PlatformMidiManagerTest(const PlatformMidiManagerTest&) = delete;
336 PlatformMidiManagerTest& operator=(const PlatformMidiManagerTest&) = delete;
337
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000338 ~PlatformMidiManagerTest() override {
339 service_->Shutdown();
340 base::RunLoop run_loop;
341 run_loop.RunUntilIdle();
342 }
343
344 MidiService* service() { return service_.get(); }
345
346 void StartSession() { service_->StartSession(client_.get()); }
347 void EndSession() { service_->EndSession(client_.get()); }
348 Result WaitForResult() { return client_->WaitForResult(); }
349
350 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
351 // Do not change the condition for disabling this test.
352 bool IsSupported() {
Xiaohan Wang77cc36d2022-01-15 06:19:37 +0000353#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_WIN) && \
354 !(defined(USE_ALSA) && defined(USE_UDEV)) && !BUILDFLAG(IS_ANDROID)
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000355 return false;
356#else
357 return true;
358#endif
359 }
360
361 private:
362 // SystemMonitor is needed on Windows.
363 base::SystemMonitor system_monitor;
364
Gabriel Charettea7cc6672019-08-19 17:30:11 +0000365 base::test::TaskEnvironment env_;
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000366
367 std::unique_ptr<FakeMidiManagerClient> client_;
368 std::unique_ptr<MidiService> service_;
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000369};
370
Xiaohan Wang77cc36d2022-01-15 06:19:37 +0000371#if BUILDFLAG(IS_ANDROID)
Hans Wennborg3b620e72018-05-17 16:58:16 +0000372// The test sometimes fails on Android. https://crbug.com/844027
373#define MAYBE_CreatePlatformMidiManager DISABLED_CreatePlatformMidiManager
374#else
375#define MAYBE_CreatePlatformMidiManager CreatePlatformMidiManager
376#endif
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000377TEST_F(PlatformMidiManagerTest, MAYBE_CreatePlatformMidiManager) {
378 StartSession();
379 Result result = WaitForResult();
toyoshim71818732015-04-07 04:15:44 -0700380
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000381#if defined(USE_ALSA)
agoode@chromium.org25227512014-06-08 05:12:05 +0000382 // Temporary until http://crbug.com/371230 is resolved.
toyoshimf1b88962015-07-09 14:14:51 -0700383 EXPECT_TRUE(result == Result::OK || result == Result::INITIALIZATION_ERROR);
dnicoara@chromium.orgc404df62014-05-06 22:56:00 +0000384#else
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000385 EXPECT_EQ(IsSupported() ? Result::OK : Result::NOT_SUPPORTED, result);
dnicoara@chromium.orgc404df62014-05-06 22:56:00 +0000386#endif
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000387}
toyoshim7a809662015-10-06 00:54:21 -0700388
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000389TEST_F(PlatformMidiManagerTest, InstanceIdOverflow) {
390 service()->task_service()->OverflowInstanceIdForTesting();
Xiaohan Wang77cc36d2022-01-15 06:19:37 +0000391#if BUILDFLAG(IS_WIN)
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000392 MidiManagerWin::OverflowInstanceIdForTesting();
Xiaohan Wang77cc36d2022-01-15 06:19:37 +0000393#endif // BUILDFLAG(IS_WIN)
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000394
395 StartSession();
396 EXPECT_EQ(
397 IsSupported() ? Result::INITIALIZATION_ERROR : Result::NOT_SUPPORTED,
398 WaitForResult());
399
400 EndSession();
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000401}
402
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000403} // namespace
404
toyoshime147c5e2015-05-07 21:58:31 -0700405} // namespace midi