blob: 59cc375f3ab101d2b557d875c2e41fc21c2cd1fb [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"
avi793390d2015-12-22 22:22:36 -080015#include "base/macros.h"
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090016#include "base/memory/weak_ptr.h"
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +000017#include "base/run_loop.h"
Sebastien Marchand21848772018-10-05 15:29:27 +000018#include "base/system/system_monitor.h"
Gabriel Charette69901582019-08-23 03:31:40 +000019#include "base/test/task_environment.h"
avi793390d2015-12-22 22:22:36 -080020#include "build/build_config.h"
toyoshimf4d61522017-02-10 02:03:32 -080021#include "media/midi/midi_service.h"
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +000022#include "media/midi/task_service.h"
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000023#include "testing/gtest/include/gtest/gtest.h"
24
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +000025#if defined(OS_WIN)
26#include "media/midi/midi_manager_win.h"
27#endif // defined(OS_WIN)
28
toyoshime147c5e2015-05-07 21:58:31 -070029namespace midi {
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000030
31namespace {
32
toyoshimec2570a2016-10-21 02:15:27 -070033using mojom::PortState;
toyoshim2f3a48f2016-10-17 01:54:13 -070034using mojom::Result;
35
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000036class FakeMidiManager : public MidiManager {
37 public:
Jeremy Roman9e1d1a72019-07-09 18:34:37 +000038 explicit FakeMidiManager(MidiService* service) : MidiManager(service) {}
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090039
Peter Boström53634032021-09-22 20:24:34 +000040 FakeMidiManager(const FakeMidiManager&) = delete;
41 FakeMidiManager& operator=(const FakeMidiManager&) = delete;
42
Takashi Toyoshimae8240ab2018-10-03 09:30:11 +000043 ~FakeMidiManager() override = default;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090044
45 base::WeakPtr<FakeMidiManager> GetWeakPtr() {
46 return weak_factory_.GetWeakPtr();
47 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000048
49 // MidiManager implementation.
dcheng63ccbc32014-10-21 05:23:27 -070050 void StartInitialization() override {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090051 DCHECK(!initialized_);
52 initialized_ = true;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000053 }
dcheng63ccbc32014-10-21 05:23:27 -070054 void DispatchSendMidiData(MidiManagerClient* client,
Avi Drissman3528fd02015-12-18 20:11:31 -050055 uint32_t port_index,
56 const std::vector<uint8_t>& data,
tzik925e2c62018-02-02 07:39:45 +000057 base::TimeTicks timestamp) override {}
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000058
59 // Utility functions for testing.
toyoshimf1b88962015-07-09 14:14:51 -070060 void CallCompleteInitialization(Result result) {
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000061 CompleteInitialization(result);
62 }
63
Takashi Toyoshimad4f37cd2018-10-01 07:43:39 +000064 size_t GetClientCount() { return GetClientCountForTesting(); }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000065
Takashi Toyoshimad4f37cd2018-10-01 07:43:39 +000066 size_t GetPendingClientCount() { return GetPendingClientCountForTesting(); }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000067
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090068 bool IsInitialized() const { return initialized_; }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000069
70 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090071 bool initialized_ = false;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090072
Jeremy Roman9e1d1a72019-07-09 18:34:37 +000073 base::WeakPtrFactory<FakeMidiManager> weak_factory_{this};
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +000074};
75
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000076class FakeMidiManagerFactory : public MidiService::ManagerFactory {
77 public:
Jeremy Roman9e1d1a72019-07-09 18:34:37 +000078 FakeMidiManagerFactory() {}
Peter Boström53634032021-09-22 20:24:34 +000079
80 FakeMidiManagerFactory(const FakeMidiManagerFactory&) = delete;
81 FakeMidiManagerFactory& operator=(const FakeMidiManagerFactory&) = delete;
82
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000083 ~FakeMidiManagerFactory() override = default;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090084
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000085 std::unique_ptr<MidiManager> Create(MidiService* service) override {
86 std::unique_ptr<FakeMidiManager> manager =
87 std::make_unique<FakeMidiManager>(service);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090088 manager_ = manager->GetWeakPtr();
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +000089 return manager;
90 }
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090091
92 base::WeakPtr<FakeMidiManagerFactory> GetWeakPtr() {
93 return weak_factory_.GetWeakPtr();
94 }
95
96 base::WeakPtr<FakeMidiManager> manager() {
Avi Drissman56d38b62020-07-29 19:29:27 +000097#if defined(OS_MAC)
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +090098 // To avoid Core MIDI issues, MidiManager won't be destructed on macOS.
99 // See https://crbug.com/718140.
100 if (!manager_ ||
101 (!manager_->GetClientCount() && !manager_->GetPendingClientCount())) {
102 return nullptr;
103 }
104#endif
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000105 return manager_;
106 }
107
108 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900109 base::WeakPtr<FakeMidiManager> manager_ = nullptr;
Jeremy Roman9e1d1a72019-07-09 18:34:37 +0000110 base::WeakPtrFactory<FakeMidiManagerFactory> weak_factory_{this};
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000111};
112
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000113class FakeMidiManagerClient : public MidiManagerClient {
114 public:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900115 FakeMidiManagerClient() = default;
Peter Boström53634032021-09-22 20:24:34 +0000116
117 FakeMidiManagerClient(const FakeMidiManagerClient&) = delete;
118 FakeMidiManagerClient& operator=(const FakeMidiManagerClient&) = delete;
119
Chris Watkinsc6cbcf62017-12-01 03:08:01 +0000120 ~FakeMidiManagerClient() override = default;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000121
122 // MidiManagerClient implementation.
Adithya Srinivasan33252732018-10-17 15:59:40 +0000123 void AddInputPort(const mojom::PortInfo& info) override {}
124 void AddOutputPort(const mojom::PortInfo& info) override {}
toyoshimec2570a2016-10-21 02:15:27 -0700125 void SetInputPortState(uint32_t port_index, PortState state) override {}
126 void SetOutputPortState(uint32_t port_index, PortState state) override {}
toyoshimf1b88962015-07-09 14:14:51 -0700127 void CompleteStartSession(Result result) override {
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000128 EXPECT_TRUE(wait_for_result_);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000129 result_ = result;
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000130 wait_for_result_ = false;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000131 }
Avi Drissman3528fd02015-12-18 20:11:31 -0500132 void ReceiveMidiData(uint32_t port_index,
133 const uint8_t* data,
dcheng63ccbc32014-10-21 05:23:27 -0700134 size_t size,
tzik925e2c62018-02-02 07:39:45 +0000135 base::TimeTicks timestamp) override {}
dcheng63ccbc32014-10-21 05:23:27 -0700136 void AccumulateMidiBytesSent(size_t size) override {}
toyoshim7a809662015-10-06 00:54:21 -0700137 void Detach() override {}
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000138
toyoshimf1b88962015-07-09 14:14:51 -0700139 Result result() const { return result_; }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000140
toyoshimf1b88962015-07-09 14:14:51 -0700141 Result WaitForResult() {
toyoshim11f7d572014-10-20 02:37:10 -0700142 while (wait_for_result_) {
143 base::RunLoop run_loop;
144 run_loop.RunUntilIdle();
145 }
toyoshim@chromium.orga25e6832014-05-07 18:06:25 +0000146 return result();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000147 }
148
149 private:
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900150 Result result_ = Result::NOT_SUPPORTED;
151 bool wait_for_result_ = true;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000152};
153
154class MidiManagerTest : public ::testing::Test {
155 public:
Sebastien Marchand812fdbf2018-11-22 12:08:44 +0000156 MidiManagerTest() {
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000157 std::unique_ptr<FakeMidiManagerFactory> factory =
158 std::make_unique<FakeMidiManagerFactory>();
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900159 factory_ = factory->GetWeakPtr();
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000160 service_ = std::make_unique<MidiService>(std::move(factory));
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000161 }
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900162
Peter Boström53634032021-09-22 20:24:34 +0000163 MidiManagerTest(const MidiManagerTest&) = delete;
164 MidiManagerTest& operator=(const MidiManagerTest&) = delete;
165
toyoshim7a809662015-10-06 00:54:21 -0700166 ~MidiManagerTest() override {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900167 service_->Shutdown();
toyoshim7a809662015-10-06 00:54:21 -0700168 base::RunLoop run_loop;
169 run_loop.RunUntilIdle();
toyoshim7a809662015-10-06 00:54:21 -0700170 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000171
172 protected:
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000173 void StartTheFirstSession(FakeMidiManagerClient* client) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900174 DCHECK(factory_);
175
176 EXPECT_FALSE(factory_->manager());
177 service_->StartSession(client);
178 ASSERT_TRUE(factory_->manager());
179 EXPECT_TRUE(factory_->manager()->IsInitialized());
180 EXPECT_EQ(0U, factory_->manager()->GetClientCount());
181 EXPECT_EQ(1U, factory_->manager()->GetPendingClientCount());
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000182 }
183
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000184 void StartTheNthSession(FakeMidiManagerClient* client, size_t nth) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900185 DCHECK(factory_);
186 DCHECK_NE(1U, nth);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000187
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900188 ASSERT_TRUE(factory_->manager());
189 EXPECT_TRUE(factory_->manager()->IsInitialized());
190 EXPECT_EQ(0U, factory_->manager()->GetClientCount());
191 EXPECT_EQ(nth - 1U, factory_->manager()->GetPendingClientCount());
192 service_->StartSession(client);
193 EXPECT_EQ(nth, factory_->manager()->GetPendingClientCount());
194 }
195
196 void StartSession(FakeMidiManagerClient* client) {
197 service_->StartSession(client);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000198 }
199
200 void EndSession(FakeMidiManagerClient* client, size_t before, size_t after) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900201 DCHECK(factory_);
202
203 ASSERT_TRUE(factory_->manager());
204 EXPECT_EQ(before, factory_->manager()->GetClientCount());
205 EXPECT_TRUE(service_->EndSession(client));
206 if (after) {
207 ASSERT_TRUE(factory_->manager());
208 EXPECT_EQ(after, factory_->manager()->GetClientCount());
209 } else {
210 EXPECT_FALSE(factory_->manager());
211 }
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000212 }
213
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900214 bool CompleteInitialization(Result result) {
215 DCHECK(factory_);
216
217 if (!factory_->manager())
218 return false;
219
220 factory_->manager()->CallCompleteInitialization(result);
221 return true;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000222 }
223
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000224 void RunLoopUntilIdle() {
225 base::RunLoop run_loop;
226 run_loop.RunUntilIdle();
227 }
228
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900229 base::WeakPtr<FakeMidiManagerFactory> factory() { return factory_; }
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000230
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000231 private:
Gabriel Charettea7cc6672019-08-19 17:30:11 +0000232 base::test::TaskEnvironment env_;
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900233 base::WeakPtr<FakeMidiManagerFactory> factory_;
234 std::unique_ptr<MidiService> service_;
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000235};
236
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000237TEST_F(MidiManagerTest, StartAndEndSession) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900238 std::unique_ptr<FakeMidiManagerClient> client =
239 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000240
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000241 StartTheFirstSession(client.get());
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900242 EXPECT_TRUE(CompleteInitialization(Result::OK));
toyoshimf1b88962015-07-09 14:14:51 -0700243 EXPECT_EQ(Result::OK, client->WaitForResult());
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000244 EndSession(client.get(), 1U, 0U);
245}
246
247TEST_F(MidiManagerTest, StartAndEndSessionWithError) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900248 std::unique_ptr<FakeMidiManagerClient> client =
249 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000250
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000251 StartTheFirstSession(client.get());
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900252 EXPECT_TRUE(CompleteInitialization(Result::INITIALIZATION_ERROR));
toyoshimf1b88962015-07-09 14:14:51 -0700253 EXPECT_EQ(Result::INITIALIZATION_ERROR, client->WaitForResult());
Takashi Toyoshimaec05edf2017-11-28 11:21:20 +0000254 EndSession(client.get(), 1U, 0U);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000255}
256
257TEST_F(MidiManagerTest, StartMultipleSessions) {
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900258 std::unique_ptr<FakeMidiManagerClient> client1 =
259 std::make_unique<FakeMidiManagerClient>();
260 std::unique_ptr<FakeMidiManagerClient> client2 =
261 std::make_unique<FakeMidiManagerClient>();
262 std::unique_ptr<FakeMidiManagerClient> client3 =
263 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000264
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000265 StartTheFirstSession(client1.get());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000266 StartTheNthSession(client2.get(), 2);
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000267 StartTheNthSession(client3.get(), 3);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900268 EXPECT_TRUE(CompleteInitialization(Result::OK));
toyoshimf1b88962015-07-09 14:14:51 -0700269 EXPECT_EQ(Result::OK, client1->WaitForResult());
270 EXPECT_EQ(Result::OK, client2->WaitForResult());
271 EXPECT_EQ(Result::OK, client3->WaitForResult());
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000272 EndSession(client1.get(), 3U, 2U);
273 EndSession(client2.get(), 2U, 1U);
274 EndSession(client3.get(), 1U, 0U);
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000275}
276
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000277TEST_F(MidiManagerTest, TooManyPendingSessions) {
278 // Push as many client requests for starting session as possible.
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700279 std::vector<std::unique_ptr<FakeMidiManagerClient>> many_existing_clients;
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000280 many_existing_clients.resize(MidiManager::kMaxPendingClientCount);
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900281 many_existing_clients[0] = std::make_unique<FakeMidiManagerClient>();
282 StartTheFirstSession(many_existing_clients[0].get());
283 for (size_t i = 1; i < MidiManager::kMaxPendingClientCount; ++i) {
Takashi Toyoshimaa88997d2017-09-07 08:30:18 +0000284 many_existing_clients[i] = std::make_unique<FakeMidiManagerClient>();
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700285 StartTheNthSession(many_existing_clients[i].get(), i + 1);
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000286 }
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900287 ASSERT_TRUE(factory()->manager());
288 EXPECT_TRUE(factory()->manager()->IsInitialized());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000289
290 // Push the last client that should be rejected for too many pending requests.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900291 std::unique_ptr<FakeMidiManagerClient> additional_client =
292 std::make_unique<FakeMidiManagerClient>();
293 StartSession(additional_client.get());
toyoshimf1b88962015-07-09 14:14:51 -0700294 EXPECT_EQ(Result::INITIALIZATION_ERROR, additional_client->result());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000295
296 // Other clients still should not receive a result.
297 RunLoopUntilIdle();
298 for (size_t i = 0; i < many_existing_clients.size(); ++i)
toyoshimf1b88962015-07-09 14:14:51 -0700299 EXPECT_EQ(Result::NOT_SUPPORTED, many_existing_clients[i]->result());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000300
toyoshimf1b88962015-07-09 14:14:51 -0700301 // The Result::OK should be distributed to other clients.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900302 EXPECT_TRUE(CompleteInitialization(Result::OK));
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000303 for (size_t i = 0; i < many_existing_clients.size(); ++i)
toyoshimf1b88962015-07-09 14:14:51 -0700304 EXPECT_EQ(Result::OK, many_existing_clients[i]->WaitForResult());
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000305
306 // Close all successful sessions in FIFO order.
307 size_t sessions = many_existing_clients.size();
308 for (size_t i = 0; i < many_existing_clients.size(); ++i, --sessions)
xiaofeng.zhang06152d82017-05-21 04:39:34 -0700309 EndSession(many_existing_clients[i].get(), sessions, sessions - 1);
toyoshim@chromium.orgfc2002e2014-05-07 08:10:34 +0000310}
311
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000312TEST_F(MidiManagerTest, AbortSession) {
313 // A client starting a session can be destructed while an asynchronous
314 // initialization is performed.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900315 std::unique_ptr<FakeMidiManagerClient> client =
316 std::make_unique<FakeMidiManagerClient>();
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000317
318 StartTheFirstSession(client.get());
319 EndSession(client.get(), 0, 0);
320 client.reset();
321
322 // Following function should not call the destructed |client| function.
Takashi Toyoshimabc959ee2018-01-09 16:04:04 +0900323 EXPECT_FALSE(CompleteInitialization(Result::OK));
toyoshim@chromium.org1fa678a2014-06-13 09:40:33 +0000324 base::RunLoop run_loop;
325 run_loop.RunUntilIdle();
326}
327
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000328class PlatformMidiManagerTest : public ::testing::Test {
329 public:
330 PlatformMidiManagerTest()
331 : client_(std::make_unique<FakeMidiManagerClient>()),
332 service_(std::make_unique<MidiService>()) {
333 //
334 }
335
Peter Boström53634032021-09-22 20:24:34 +0000336 PlatformMidiManagerTest(const PlatformMidiManagerTest&) = delete;
337 PlatformMidiManagerTest& operator=(const PlatformMidiManagerTest&) = delete;
338
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000339 ~PlatformMidiManagerTest() override {
340 service_->Shutdown();
341 base::RunLoop run_loop;
342 run_loop.RunUntilIdle();
343 }
344
345 MidiService* service() { return service_.get(); }
346
347 void StartSession() { service_->StartSession(client_.get()); }
348 void EndSession() { service_->EndSession(client_.get()); }
349 Result WaitForResult() { return client_->WaitForResult(); }
350
351 // This #ifdef needs to be identical to the one in media/midi/midi_manager.cc.
352 // Do not change the condition for disabling this test.
353 bool IsSupported() {
Avi Drissman56d38b62020-07-29 19:29:27 +0000354#if !defined(OS_MAC) && !defined(OS_WIN) && \
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000355 !(defined(USE_ALSA) && defined(USE_UDEV)) && !defined(OS_ANDROID)
356 return false;
357#else
358 return true;
359#endif
360 }
361
362 private:
363 // SystemMonitor is needed on Windows.
364 base::SystemMonitor system_monitor;
365
Gabriel Charettea7cc6672019-08-19 17:30:11 +0000366 base::test::TaskEnvironment env_;
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000367
368 std::unique_ptr<FakeMidiManagerClient> client_;
369 std::unique_ptr<MidiService> service_;
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000370};
371
Hans Wennborg3b620e72018-05-17 16:58:16 +0000372#if defined(OS_ANDROID)
373// The test sometimes fails on Android. https://crbug.com/844027
374#define MAYBE_CreatePlatformMidiManager DISABLED_CreatePlatformMidiManager
375#else
376#define MAYBE_CreatePlatformMidiManager CreatePlatformMidiManager
377#endif
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000378TEST_F(PlatformMidiManagerTest, MAYBE_CreatePlatformMidiManager) {
379 StartSession();
380 Result result = WaitForResult();
toyoshim71818732015-04-07 04:15:44 -0700381
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000382#if defined(USE_ALSA)
agoode@chromium.org25227512014-06-08 05:12:05 +0000383 // Temporary until http://crbug.com/371230 is resolved.
toyoshimf1b88962015-07-09 14:14:51 -0700384 EXPECT_TRUE(result == Result::OK || result == Result::INITIALIZATION_ERROR);
dnicoara@chromium.orgc404df62014-05-06 22:56:00 +0000385#else
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000386 EXPECT_EQ(IsSupported() ? Result::OK : Result::NOT_SUPPORTED, result);
dnicoara@chromium.orgc404df62014-05-06 22:56:00 +0000387#endif
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000388}
toyoshim7a809662015-10-06 00:54:21 -0700389
Takashi Toyoshima88b4ac02019-02-12 11:25:56 +0000390TEST_F(PlatformMidiManagerTest, InstanceIdOverflow) {
391 service()->task_service()->OverflowInstanceIdForTesting();
392#if defined(OS_WIN)
393 MidiManagerWin::OverflowInstanceIdForTesting();
394#endif // defined(OS_WIN)
395
396 StartSession();
397 EXPECT_EQ(
398 IsSupported() ? Result::INITIALIZATION_ERROR : Result::NOT_SUPPORTED,
399 WaitForResult());
400
401 EndSession();
toyoshim@chromium.orgc1e05fb2014-05-06 16:39:20 +0000402}
403
toyoshim@chromium.org51c7f532014-05-01 17:17:32 +0000404} // namespace
405
toyoshime147c5e2015-05-07 21:58:31 -0700406} // namespace midi