captured_audio_input_unittest.cc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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 "components/mirroring/service/captured_audio_input.h"
  5. #include "base/bind.h"
  6. #include "base/memory/raw_ptr.h"
  7. #include "base/run_loop.h"
  8. #include "base/test/task_environment.h"
  9. #include "media/base/audio_capturer_source.h"
  10. #include "media/base/audio_parameters.h"
  11. #include "media/mojo/mojom/audio_data_pipe.mojom.h"
  12. #include "mojo/public/cpp/bindings/pending_remote.h"
  13. #include "mojo/public/cpp/bindings/remote.h"
  14. #include "mojo/public/cpp/bindings/self_owned_receiver.h"
  15. #include "mojo/public/cpp/system/buffer.h"
  16. #include "mojo/public/cpp/system/platform_handle.h"
  17. #include "testing/gmock/include/gmock/gmock.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "third_party/abseil-cpp/absl/utility/utility.h"
  20. using ::testing::InvokeWithoutArgs;
  21. namespace mirroring {
  22. using AudioSourceErrorCode = media::AudioCapturerSource::ErrorCode;
  23. namespace {
  24. class MockStream final : public media::mojom::AudioInputStream {
  25. public:
  26. MOCK_METHOD0(Record, void());
  27. MOCK_METHOD1(SetVolume, void(double));
  28. };
  29. class MockDelegate final : public media::AudioInputIPCDelegate {
  30. public:
  31. MockDelegate() {}
  32. ~MockDelegate() override {}
  33. MOCK_METHOD0(StreamCreated, void());
  34. MOCK_METHOD1(OnError, void(AudioSourceErrorCode code));
  35. MOCK_METHOD1(OnMuted, void(bool muted));
  36. MOCK_METHOD0(OnIPCClosed, void());
  37. void OnStreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
  38. base::SyncSocket::ScopedHandle socket_handle,
  39. bool initially_muted) override {
  40. StreamCreated();
  41. }
  42. };
  43. } // namespace
  44. class CapturedAudioInputTest : public ::testing::Test {
  45. public:
  46. CapturedAudioInputTest() {}
  47. CapturedAudioInputTest(const CapturedAudioInputTest&) = delete;
  48. CapturedAudioInputTest& operator=(const CapturedAudioInputTest&) = delete;
  49. ~CapturedAudioInputTest() override { task_environment_.RunUntilIdle(); }
  50. void CreateMockStream(
  51. mojo::PendingRemote<mojom::AudioStreamCreatorClient> client,
  52. const media::AudioParameters& params,
  53. uint32_t total_segments) {
  54. EXPECT_FALSE(socket_.IsValid());
  55. EXPECT_FALSE(stream_);
  56. mojo::PendingRemote<media::mojom::AudioInputStream> pending_stream;
  57. auto input_stream = std::make_unique<MockStream>();
  58. stream_ = input_stream.get();
  59. mojo::MakeSelfOwnedReceiver(
  60. std::move(input_stream),
  61. pending_stream.InitWithNewPipeAndPassReceiver());
  62. base::CancelableSyncSocket foreign_socket;
  63. EXPECT_TRUE(
  64. base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
  65. mojo::Remote<mojom::AudioStreamCreatorClient> audio_client(
  66. std::move(client));
  67. stream_client_.reset();
  68. audio_client->StreamCreated(
  69. std::move(pending_stream), stream_client_.BindNewPipeAndPassReceiver(),
  70. {absl::in_place, base::ReadOnlySharedMemoryRegion::Create(1024).region,
  71. mojo::PlatformHandle(foreign_socket.Take())});
  72. }
  73. protected:
  74. void CreateStream() {
  75. audio_input_ = std::make_unique<CapturedAudioInput>(base::BindRepeating(
  76. &CapturedAudioInputTest::CreateMockStream, base::Unretained(this)));
  77. base::RunLoop run_loop;
  78. EXPECT_CALL(delegate_, StreamCreated())
  79. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  80. audio_input_->CreateStream(&delegate_, media::AudioParameters(), false, 10);
  81. run_loop.Run();
  82. }
  83. void CloseStream() {
  84. EXPECT_TRUE(audio_input_);
  85. audio_input_->CloseStream();
  86. task_environment_.RunUntilIdle();
  87. socket_.Close();
  88. audio_input_.reset();
  89. stream_ = nullptr;
  90. }
  91. void SignalStreamError() {
  92. EXPECT_TRUE(stream_client_.is_bound());
  93. base::RunLoop run_loop;
  94. EXPECT_CALL(delegate_, OnError(AudioSourceErrorCode::kUnknown))
  95. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  96. stream_client_->OnError(media::mojom::InputStreamErrorCode::kUnknown);
  97. run_loop.Run();
  98. }
  99. void SignalStreamPermissionsError() {
  100. EXPECT_TRUE(stream_client_.is_bound());
  101. base::RunLoop run_loop;
  102. EXPECT_CALL(delegate_, OnError(AudioSourceErrorCode::kSystemPermissions))
  103. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  104. stream_client_->OnError(
  105. media::mojom::InputStreamErrorCode::kSystemPermissions);
  106. run_loop.Run();
  107. }
  108. void SignalMutedStateChanged(bool is_muted) {
  109. EXPECT_TRUE(stream_client_.is_bound());
  110. base::RunLoop run_loop;
  111. EXPECT_CALL(delegate_, OnMuted(true))
  112. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  113. stream_client_->OnMutedStateChanged(is_muted);
  114. run_loop.Run();
  115. }
  116. void SetVolume(double volume) {
  117. EXPECT_TRUE(audio_input_);
  118. base::RunLoop run_loop;
  119. EXPECT_CALL(*stream_, SetVolume(volume))
  120. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  121. audio_input_->SetVolume(volume);
  122. run_loop.Run();
  123. }
  124. void Record() {
  125. EXPECT_TRUE(audio_input_);
  126. base::RunLoop run_loop;
  127. EXPECT_CALL(*stream_, Record())
  128. .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  129. audio_input_->RecordStream();
  130. run_loop.Run();
  131. }
  132. private:
  133. base::test::TaskEnvironment task_environment_;
  134. std::unique_ptr<media::AudioInputIPC> audio_input_;
  135. MockDelegate delegate_;
  136. raw_ptr<MockStream> stream_ = nullptr;
  137. mojo::Remote<media::mojom::AudioInputStreamClient> stream_client_;
  138. base::CancelableSyncSocket socket_;
  139. };
  140. TEST_F(CapturedAudioInputTest, CreateStream) {
  141. // Test that |delegate_| runs OnStreamCreated().
  142. CreateStream();
  143. CloseStream();
  144. }
  145. TEST_F(CapturedAudioInputTest, PropagatesStreamError) {
  146. CreateStream();
  147. SignalStreamError();
  148. CloseStream();
  149. }
  150. TEST_F(CapturedAudioInputTest, PropagatesStreamPermissionsError) {
  151. CreateStream();
  152. SignalStreamPermissionsError();
  153. CloseStream();
  154. }
  155. TEST_F(CapturedAudioInputTest, PropagatesMutedStateChange) {
  156. CreateStream();
  157. SignalMutedStateChanged(true);
  158. CloseStream();
  159. }
  160. TEST_F(CapturedAudioInputTest, SetVolume) {
  161. CreateStream();
  162. SetVolume(0.8);
  163. CloseStream();
  164. }
  165. TEST_F(CapturedAudioInputTest, Record) {
  166. CreateStream();
  167. Record();
  168. CloseStream();
  169. }
  170. } // namespace mirroring