output_stream_unittest.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. // Copyright 2018 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. #include "services/audio/output_stream.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/callback_helpers.h"
  8. #include "base/test/mock_callback.h"
  9. #include "base/test/task_environment.h"
  10. #include "base/unguessable_token.h"
  11. #include "media/audio/audio_io.h"
  12. #include "media/audio/mock_audio_manager.h"
  13. #include "media/audio/test_audio_thread.h"
  14. #include "mojo/public/cpp/bindings/associated_receiver.h"
  15. #include "mojo/public/cpp/bindings/receiver.h"
  16. #include "mojo/public/cpp/system/functions.h"
  17. #include "services/audio/stream_factory.h"
  18. #include "services/audio/test/mock_log.h"
  19. #include "testing/gmock/include/gmock/gmock.h"
  20. #include "testing/gtest/include/gtest/gtest.h"
  21. using testing::AtMost;
  22. using testing::DeleteArg;
  23. using testing::Mock;
  24. using testing::NiceMock;
  25. using testing::NotNull;
  26. using testing::Return;
  27. using testing::SaveArg;
  28. using testing::StrictMock;
  29. using testing::_;
  30. namespace audio {
  31. namespace {
  32. // Aliases for use with MockCreatedCallback::Created().
  33. const bool successfully_ = true;
  34. const bool unsuccessfully_ = false;
  35. class MockStream : public media::AudioOutputStream {
  36. public:
  37. MockStream() {}
  38. MockStream(const MockStream&) = delete;
  39. MockStream& operator=(const MockStream&) = delete;
  40. MOCK_METHOD0(Open, bool());
  41. MOCK_METHOD1(Start, void(AudioSourceCallback* callback));
  42. MOCK_METHOD0(Stop, void());
  43. MOCK_METHOD1(SetVolume, void(double volume));
  44. MOCK_METHOD1(GetVolume, void(double* volume));
  45. MOCK_METHOD0(Close, void());
  46. MOCK_METHOD0(Flush, void());
  47. };
  48. const uint32_t kPlatformErrorDisconnectReason = static_cast<uint32_t>(
  49. media::mojom::AudioOutputStreamObserver::DisconnectReason::kPlatformError);
  50. const uint32_t kTerminatedByClientDisconnectReason =
  51. static_cast<uint32_t>(media::mojom::AudioOutputStreamObserver::
  52. DisconnectReason::kTerminatedByClient);
  53. class MockObserver : public media::mojom::AudioOutputStreamObserver {
  54. public:
  55. MockObserver() = default;
  56. MockObserver(const MockObserver&) = delete;
  57. MockObserver& operator=(const MockObserver&) = delete;
  58. mojo::PendingAssociatedRemote<media::mojom::AudioOutputStreamObserver>
  59. MakeRemote() {
  60. DCHECK(!receiver_.is_bound());
  61. mojo::PendingAssociatedRemote<media::mojom::AudioOutputStreamObserver>
  62. remote;
  63. receiver_.Bind(remote.InitWithNewEndpointAndPassReceiver());
  64. receiver_.set_disconnect_with_reason_handler(base::BindOnce(
  65. &MockObserver::BindingConnectionError, base::Unretained(this)));
  66. return remote;
  67. }
  68. void CloseBinding() { receiver_.reset(); }
  69. MOCK_METHOD0(DidStartPlaying, void());
  70. MOCK_METHOD0(DidStopPlaying, void());
  71. MOCK_METHOD1(DidChangeAudibleState, void(bool));
  72. MOCK_METHOD2(BindingConnectionError,
  73. void(uint32_t /*disconnect_reason*/, const std::string&));
  74. private:
  75. mojo::AssociatedReceiver<media::mojom::AudioOutputStreamObserver> receiver_{
  76. this};
  77. };
  78. class MockCreatedCallback {
  79. public:
  80. MockCreatedCallback() {}
  81. MockCreatedCallback(const MockCreatedCallback&) = delete;
  82. MockCreatedCallback& operator=(const MockCreatedCallback&) = delete;
  83. MOCK_METHOD1(Created, void(bool /*valid*/));
  84. void OnCreated(media::mojom::ReadWriteAudioDataPipePtr ptr) {
  85. Created(!!ptr);
  86. }
  87. OutputStream::CreatedCallback Get() {
  88. return base::BindOnce(&MockCreatedCallback::OnCreated,
  89. base::Unretained(this));
  90. }
  91. };
  92. } // namespace
  93. // Instantiates various classes that we're going to want in most test cases.
  94. class TestEnvironment {
  95. public:
  96. TestEnvironment()
  97. : audio_manager_(std::make_unique<media::TestAudioThread>(false)),
  98. stream_factory_(&audio_manager_, /*aecdump_recording_manager=*/nullptr),
  99. stream_factory_receiver_(
  100. &stream_factory_,
  101. remote_stream_factory_.BindNewPipeAndPassReceiver()) {
  102. mojo::SetDefaultProcessErrorHandler(bad_message_callback_.Get());
  103. }
  104. TestEnvironment(const TestEnvironment&) = delete;
  105. TestEnvironment& operator=(const TestEnvironment&) = delete;
  106. ~TestEnvironment() {
  107. audio_manager_.Shutdown();
  108. mojo::SetDefaultProcessErrorHandler(base::NullCallback());
  109. }
  110. using MockDeleteCallback = base::MockCallback<OutputStream::DeleteCallback>;
  111. using MockBadMessageCallback =
  112. base::MockCallback<base::RepeatingCallback<void(const std::string&)>>;
  113. mojo::PendingRemote<media::mojom::AudioOutputStream> CreateStream() {
  114. mojo::PendingRemote<media::mojom::AudioOutputStream> remote_stream;
  115. remote_stream_factory_->CreateOutputStream(
  116. remote_stream.InitWithNewPipeAndPassReceiver(), observer_.MakeRemote(),
  117. log_.MakeRemote(), "",
  118. media::AudioParameters::UnavailableDeviceParams(),
  119. base::UnguessableToken::Create(), created_callback_.Get());
  120. return remote_stream;
  121. }
  122. mojo::PendingRemote<media::mojom::AudioOutputStream>
  123. CreateStreamWithNullptrObserver() {
  124. mojo::PendingRemote<media::mojom::AudioOutputStream> remote_stream;
  125. remote_stream_factory_->CreateOutputStream(
  126. remote_stream.InitWithNewPipeAndPassReceiver(),
  127. mojo::NullAssociatedRemote(), log_.MakeRemote(), "",
  128. media::AudioParameters::UnavailableDeviceParams(),
  129. base::UnguessableToken::Create(), created_callback_.Get());
  130. return remote_stream;
  131. }
  132. mojo::PendingRemote<media::mojom::AudioOutputStream>
  133. CreateStreamWithNullptrLog() {
  134. mojo::PendingRemote<media::mojom::AudioOutputStream> remote_stream;
  135. remote_stream_factory_->CreateOutputStream(
  136. remote_stream.InitWithNewPipeAndPassReceiver(), observer_.MakeRemote(),
  137. mojo::NullRemote(), "",
  138. media::AudioParameters::UnavailableDeviceParams(),
  139. base::UnguessableToken::Create(), created_callback_.Get());
  140. return remote_stream;
  141. }
  142. media::MockAudioManager& audio_manager() { return audio_manager_; }
  143. MockObserver& observer() { return observer_; }
  144. MockLog& log() { return log_; }
  145. MockCreatedCallback& created_callback() { return created_callback_; }
  146. MockBadMessageCallback& bad_message_callback() {
  147. return bad_message_callback_;
  148. }
  149. media::mojom::AudioStreamFactory* remote_stream_factory() {
  150. return remote_stream_factory_.get();
  151. }
  152. private:
  153. base::test::TaskEnvironment tasks_;
  154. media::MockAudioManager audio_manager_;
  155. StreamFactory stream_factory_;
  156. mojo::Remote<media::mojom::AudioStreamFactory> remote_stream_factory_;
  157. mojo::Receiver<media::mojom::AudioStreamFactory> stream_factory_receiver_;
  158. StrictMock<MockObserver> observer_;
  159. NiceMock<MockLog> log_;
  160. StrictMock<MockCreatedCallback> created_callback_;
  161. StrictMock<MockBadMessageCallback> bad_message_callback_;
  162. };
  163. TEST(AudioServiceOutputStreamTest, ConstructDestruct) {
  164. TestEnvironment env;
  165. MockStream mock_stream;
  166. EXPECT_CALL(env.created_callback(), Created(successfully_));
  167. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  168. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  169. const std::string& device_id) { return stream; },
  170. &mock_stream));
  171. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  172. EXPECT_CALL(mock_stream, SetVolume(1));
  173. EXPECT_CALL(env.log(), OnCreated(_, _));
  174. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  175. base::RunLoop().RunUntilIdle();
  176. Mock::VerifyAndClear(&mock_stream);
  177. Mock::VerifyAndClear(&env.created_callback());
  178. EXPECT_CALL(env.log(), OnClosed());
  179. EXPECT_CALL(mock_stream, Close());
  180. EXPECT_CALL(env.observer(),
  181. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  182. stream.reset();
  183. base::RunLoop().RunUntilIdle();
  184. }
  185. TEST(AudioServiceOutputStreamTest, ConstructDestructNullptrObserver) {
  186. TestEnvironment env;
  187. MockStream mock_stream;
  188. EXPECT_CALL(env.created_callback(), Created(successfully_));
  189. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  190. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  191. const std::string& device_id) { return stream; },
  192. &mock_stream));
  193. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  194. EXPECT_CALL(mock_stream, SetVolume(1));
  195. EXPECT_CALL(env.log(), OnCreated(_, _));
  196. mojo::Remote<media::mojom::AudioOutputStream> stream(
  197. env.CreateStreamWithNullptrObserver());
  198. base::RunLoop().RunUntilIdle();
  199. Mock::VerifyAndClear(&mock_stream);
  200. Mock::VerifyAndClear(&env.created_callback());
  201. EXPECT_CALL(env.log(), OnClosed());
  202. EXPECT_CALL(mock_stream, Close());
  203. stream.reset();
  204. base::RunLoop().RunUntilIdle();
  205. }
  206. TEST(AudioServiceOutputStreamTest, ConstructDestructNullptrLog) {
  207. TestEnvironment env;
  208. MockStream mock_stream;
  209. EXPECT_CALL(env.created_callback(), Created(successfully_));
  210. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  211. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  212. const std::string& device_id) { return stream; },
  213. &mock_stream));
  214. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  215. EXPECT_CALL(mock_stream, SetVolume(1));
  216. mojo::Remote<media::mojom::AudioOutputStream> stream(
  217. env.CreateStreamWithNullptrLog());
  218. base::RunLoop().RunUntilIdle();
  219. Mock::VerifyAndClear(&mock_stream);
  220. Mock::VerifyAndClear(&env.created_callback());
  221. EXPECT_CALL(mock_stream, Close());
  222. EXPECT_CALL(env.observer(),
  223. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  224. stream.reset();
  225. base::RunLoop().RunUntilIdle();
  226. }
  227. TEST(AudioServiceOutputStreamTest,
  228. ConstructStreamAndDestructObserver_DestructsStream) {
  229. TestEnvironment env;
  230. MockStream mock_stream;
  231. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  232. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  233. const std::string& device_id) { return stream; },
  234. &mock_stream));
  235. EXPECT_CALL(env.created_callback(), Created(successfully_));
  236. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  237. EXPECT_CALL(mock_stream, SetVolume(1));
  238. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  239. base::RunLoop().RunUntilIdle();
  240. Mock::VerifyAndClear(&mock_stream);
  241. Mock::VerifyAndClear(&env.created_callback());
  242. EXPECT_CALL(mock_stream, Close());
  243. env.observer().CloseBinding();
  244. base::RunLoop().RunUntilIdle();
  245. Mock::VerifyAndClear(&mock_stream);
  246. }
  247. TEST(AudioServiceOutputStreamTest,
  248. ConstructStreamAndReleaseStreamPtr_DestructsStream) {
  249. TestEnvironment env;
  250. MockStream mock_stream;
  251. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  252. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  253. const std::string& device_id) { return stream; },
  254. &mock_stream));
  255. EXPECT_CALL(env.created_callback(), Created(successfully_));
  256. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  257. EXPECT_CALL(mock_stream, SetVolume(1));
  258. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  259. base::RunLoop().RunUntilIdle();
  260. Mock::VerifyAndClear(&mock_stream);
  261. Mock::VerifyAndClear(&env.created_callback());
  262. EXPECT_CALL(mock_stream, Close());
  263. EXPECT_CALL(env.observer(),
  264. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  265. stream.reset();
  266. base::RunLoop().RunUntilIdle();
  267. Mock::VerifyAndClear(&mock_stream);
  268. Mock::VerifyAndClear(&env.observer());
  269. }
  270. TEST(AudioServiceOutputStreamTest, Play_Plays) {
  271. TestEnvironment env;
  272. MockStream mock_stream;
  273. EXPECT_CALL(env.created_callback(), Created(successfully_));
  274. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  275. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  276. const std::string& device_id) { return stream; },
  277. &mock_stream));
  278. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  279. EXPECT_CALL(mock_stream, SetVolume(1));
  280. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  281. base::RunLoop().RunUntilIdle();
  282. Mock::VerifyAndClear(&mock_stream);
  283. Mock::VerifyAndClear(&env.created_callback());
  284. EXPECT_CALL(mock_stream, Start(NotNull()));
  285. EXPECT_CALL(env.log(), OnStarted());
  286. EXPECT_CALL(env.observer(), DidStartPlaying());
  287. // May or may not get an audibility notification depending on if power
  288. // monitoring is enabled.
  289. EXPECT_CALL(env.observer(), DidChangeAudibleState(true)).Times(AtMost(1));
  290. stream->Play();
  291. base::RunLoop().RunUntilIdle();
  292. Mock::VerifyAndClear(&mock_stream);
  293. Mock::VerifyAndClear(&env.observer());
  294. EXPECT_CALL(mock_stream, Stop());
  295. EXPECT_CALL(mock_stream, Close());
  296. EXPECT_CALL(env.observer(), DidChangeAudibleState(false)).Times(AtMost(1));
  297. EXPECT_CALL(env.observer(), DidStopPlaying()).Times(AtMost(1));
  298. EXPECT_CALL(env.observer(),
  299. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  300. stream.reset();
  301. base::RunLoop().RunUntilIdle();
  302. }
  303. TEST(AudioServiceOutputStreamTest, PlayAndPause_PlaysAndStops) {
  304. TestEnvironment env;
  305. MockStream mock_stream;
  306. EXPECT_CALL(env.created_callback(), Created(successfully_));
  307. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  308. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  309. const std::string& device_id) { return stream; },
  310. &mock_stream));
  311. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  312. EXPECT_CALL(mock_stream, SetVolume(1));
  313. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  314. base::RunLoop().RunUntilIdle();
  315. Mock::VerifyAndClear(&mock_stream);
  316. Mock::VerifyAndClear(&env.created_callback());
  317. EXPECT_CALL(mock_stream, Start(NotNull()));
  318. EXPECT_CALL(env.observer(), DidStartPlaying());
  319. // May or may not get an audibility notification depending on if power
  320. // monitoring is enabled.
  321. EXPECT_CALL(env.observer(), DidChangeAudibleState(true)).Times(AtMost(1));
  322. stream->Play();
  323. base::RunLoop().RunUntilIdle();
  324. Mock::VerifyAndClear(&mock_stream);
  325. Mock::VerifyAndClear(&env.observer());
  326. EXPECT_CALL(mock_stream, Stop());
  327. EXPECT_CALL(env.log(), OnStopped());
  328. EXPECT_CALL(env.observer(), DidChangeAudibleState(false)).Times(AtMost(1));
  329. EXPECT_CALL(env.observer(), DidStopPlaying());
  330. stream->Pause();
  331. base::RunLoop().RunUntilIdle();
  332. Mock::VerifyAndClear(&mock_stream);
  333. Mock::VerifyAndClear(&env.observer());
  334. EXPECT_CALL(mock_stream, Close());
  335. EXPECT_CALL(env.observer(),
  336. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  337. stream.reset();
  338. base::RunLoop().RunUntilIdle();
  339. }
  340. TEST(AudioServiceOutputStreamTest, SetVolume_SetsVolume) {
  341. double new_volume = 0.618;
  342. TestEnvironment env;
  343. MockStream mock_stream;
  344. EXPECT_CALL(env.created_callback(), Created(successfully_));
  345. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  346. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  347. const std::string& device_id) { return stream; },
  348. &mock_stream));
  349. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  350. EXPECT_CALL(mock_stream, SetVolume(1));
  351. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  352. base::RunLoop().RunUntilIdle();
  353. Mock::VerifyAndClear(&mock_stream);
  354. Mock::VerifyAndClear(&env.created_callback());
  355. EXPECT_CALL(mock_stream, SetVolume(new_volume));
  356. EXPECT_CALL(env.log(), OnSetVolume(new_volume));
  357. stream->SetVolume(new_volume);
  358. base::RunLoop().RunUntilIdle();
  359. Mock::VerifyAndClear(&mock_stream);
  360. EXPECT_CALL(mock_stream, Close());
  361. EXPECT_CALL(env.observer(),
  362. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  363. stream.reset();
  364. base::RunLoop().RunUntilIdle();
  365. }
  366. TEST(AudioServiceOutputStreamTest, SetNegativeVolume_BadMessage) {
  367. TestEnvironment env;
  368. MockStream mock_stream;
  369. EXPECT_CALL(env.created_callback(), Created(successfully_));
  370. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  371. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  372. const std::string& device_id) { return stream; },
  373. &mock_stream));
  374. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  375. EXPECT_CALL(mock_stream, SetVolume(1));
  376. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  377. base::RunLoop().RunUntilIdle();
  378. Mock::VerifyAndClear(&mock_stream);
  379. Mock::VerifyAndClear(&env.created_callback());
  380. EXPECT_CALL(mock_stream, Close());
  381. EXPECT_CALL(env.observer(),
  382. BindingConnectionError(kPlatformErrorDisconnectReason, _));
  383. EXPECT_CALL(env.bad_message_callback(), Run(_));
  384. stream->SetVolume(-0.1);
  385. base::RunLoop().RunUntilIdle();
  386. }
  387. TEST(AudioServiceOutputStreamTest, SetVolumeGreaterThanOne_BadMessage) {
  388. TestEnvironment env;
  389. MockStream mock_stream;
  390. EXPECT_CALL(env.created_callback(), Created(successfully_));
  391. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  392. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  393. const std::string& device_id) { return stream; },
  394. &mock_stream));
  395. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  396. EXPECT_CALL(mock_stream, SetVolume(1));
  397. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  398. base::RunLoop().RunUntilIdle();
  399. Mock::VerifyAndClear(&mock_stream);
  400. Mock::VerifyAndClear(&env.created_callback());
  401. EXPECT_CALL(mock_stream, Close());
  402. EXPECT_CALL(env.observer(),
  403. BindingConnectionError(kPlatformErrorDisconnectReason, _));
  404. EXPECT_CALL(env.bad_message_callback(), Run(_));
  405. stream->SetVolume(1.1);
  406. base::RunLoop().RunUntilIdle();
  407. }
  408. TEST(AudioServiceOutputStreamTest,
  409. ConstructWithStreamCreationFailure_SignalsError) {
  410. TestEnvironment env;
  411. // By default, the MockAudioManager fails to create a stream.
  412. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  413. EXPECT_CALL(env.created_callback(), Created(unsuccessfully_));
  414. EXPECT_CALL(env.observer(),
  415. BindingConnectionError(kPlatformErrorDisconnectReason, _));
  416. EXPECT_CALL(env.log(), OnError());
  417. base::RunLoop().RunUntilIdle();
  418. Mock::VerifyAndClear(&env.observer());
  419. }
  420. TEST(AudioServiceOutputStreamTest,
  421. ConstructWithStreamCreationFailureAndDestructBeforeErrorFires_NoCrash) {
  422. // The main purpose of this test is to make sure that that delete callback
  423. // call is deferred, and that it is canceled in case of destruction.
  424. TestEnvironment env;
  425. // By default, the MockAudioManager fails to create a stream.
  426. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  427. EXPECT_CALL(env.created_callback(), Created(unsuccessfully_));
  428. EXPECT_CALL(env.observer(),
  429. BindingConnectionError(kPlatformErrorDisconnectReason, _));
  430. base::RunLoop().RunUntilIdle();
  431. Mock::VerifyAndClear(&env.observer());
  432. }
  433. TEST(AudioServiceOutputStreamTest, BindMuters) {
  434. // Set up the test environment.
  435. TestEnvironment env;
  436. MockStream mock_stream;
  437. EXPECT_CALL(env.created_callback(), Created(successfully_));
  438. env.audio_manager().SetMakeOutputStreamCB(base::BindRepeating(
  439. [](media::AudioOutputStream* stream, const media::AudioParameters& params,
  440. const std::string& device_id) { return stream; },
  441. &mock_stream));
  442. EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
  443. EXPECT_CALL(mock_stream, SetVolume(1));
  444. EXPECT_CALL(env.log(), OnCreated(_, _));
  445. mojo::Remote<media::mojom::AudioOutputStream> stream(env.CreateStream());
  446. base::RunLoop().RunUntilIdle();
  447. Mock::VerifyAndClear(&mock_stream);
  448. Mock::VerifyAndClear(&env.created_callback());
  449. // Bind the first muter.
  450. mojo::AssociatedRemote<media::mojom::LocalMuter> muter1;
  451. base::UnguessableToken group_id = base::UnguessableToken::Create();
  452. env.remote_stream_factory()->BindMuter(
  453. muter1.BindNewEndpointAndPassReceiver(), group_id);
  454. base::RunLoop().RunUntilIdle();
  455. // Unbind the first muter and immediately bind the second muter. The muter
  456. // should not be destroyed in this case.
  457. muter1.reset();
  458. mojo::AssociatedRemote<media::mojom::LocalMuter> muter2;
  459. env.remote_stream_factory()->BindMuter(
  460. muter2.BindNewEndpointAndPassReceiver(), group_id);
  461. base::RunLoop().RunUntilIdle();
  462. EXPECT_CALL(env.log(), OnClosed());
  463. EXPECT_CALL(mock_stream, Close());
  464. EXPECT_CALL(env.observer(),
  465. BindingConnectionError(kTerminatedByClientDisconnectReason, _));
  466. stream.reset();
  467. base::RunLoop().RunUntilIdle();
  468. }
  469. } // namespace audio