Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: content/browser/renderer_host/media/audio_output_impl_unittest.cc

Issue 2319493002: Add mojo interface for audio rendering. (Closed)
Patch Set: ++docs Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "content/browser/renderer_host/media/audio_output_impl.h"
6
7 #include <utility>
8
9 #include "base/memory/shared_memory.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/sync_socket.h"
13 #include "content/common/media/audio_output.mojom.h"
14 #include "media/audio/audio_output_controller.h"
15 #include "mojo/public/cpp/system/platform_handle.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace content {
20
21 namespace {
22
23 const double kNewVolume = 0.618;
24 // Not actually used, but sent from the AudioOutputDelegate.
25 const int kStreamId = 0;
26
27 using testing::_;
28 using testing::Mock;
29 using testing::NotNull;
30 using testing::Return;
31 using testing::SaveArg;
32 using testing::StrictMock;
33 using testing::Test;
34 using AudioOutput = mojom::AudioOutput;
35 using AudioOutputPtr = mojo::InterfacePtr<AudioOutput>;
36
37 class MockDelegate : public AudioOutputDelegate {
38 public:
39 MOCK_CONST_METHOD0(GetController,
40 scoped_refptr<media::AudioOutputController>());
41 MOCK_CONST_METHOD0(GetStreamId, int());
42 MOCK_METHOD0(OnPlayStream, void());
43 MOCK_METHOD0(OnPauseStream, void());
44 MOCK_METHOD1(OnSetVolume, void(double));
45 };
46
47 class MockDelegateFactory {
48 public:
49 void PrepareDelegateForCreation(
50 std::unique_ptr<AudioOutputDelegate> delegate) {
51 ASSERT_EQ(nullptr, delegate_);
52 delegate_.swap(delegate);
53 }
54
55 std::unique_ptr<AudioOutputDelegate> CreateDelegate(
56 AudioOutputDelegate::EventHandler* handler,
57 const media::AudioParameters& params) {
58 MockCreateDelegate(handler, params);
59 EXPECT_NE(nullptr, delegate_);
60 return std::move(delegate_);
61 }
62
63 MOCK_METHOD2(MockCreateDelegate,
64 void(AudioOutputDelegate::EventHandler*,
65 const media::AudioParameters&));
66
67 private:
68 std::unique_ptr<AudioOutputDelegate> delegate_;
69 };
70
71 class MockFinishedListener {
72 public:
73 MOCK_METHOD1(Finished, void(AudioOutput*));
74 };
75
76 class MockClient {
77 public:
78 MockClient() {}
79
80 void Started(mojo::ScopedSharedBufferHandle shared_buffer,
81 mojo::ScopedHandle socket_handle) {
82 ASSERT_TRUE(shared_buffer.is_valid());
83 ASSERT_TRUE(socket_handle.is_valid());
84
85 base::PlatformFile fd;
86 mojo::UnwrapPlatformFile(std::move(socket_handle), &fd);
87 socket_ = base::MakeUnique<base::CancelableSyncSocket>(fd);
88 EXPECT_NE(socket_->handle(), base::CancelableSyncSocket::kInvalidHandle);
89
90 size_t memory_length;
91 base::SharedMemoryHandle shmem_handle;
92 bool read_only;
93 EXPECT_EQ(
94 mojo::UnwrapSharedMemoryHandle(std::move(shared_buffer), &shmem_handle,
95 &memory_length, &read_only),
96 MOJO_RESULT_OK);
97 EXPECT_FALSE(read_only);
98 buffer_ = base::MakeUnique<base::SharedMemory>(shmem_handle, read_only);
99
100 GotNotification();
101 }
102
103 MOCK_METHOD0(GotNotification, void());
104
105 private:
106 std::unique_ptr<base::SharedMemory> buffer_;
107 std::unique_ptr<base::CancelableSyncSocket> socket_;
108 };
109 } // namespace
110
111 class AudioOutputImplTest : public Test {
112 public:
113 AudioOutputImplTest()
114 : impl_(base::MakeUnique<AudioOutputImpl>(
115 mojo::MakeRequest(&audio_output_ptr_),
116 base::BindOnce(&MockDelegateFactory::CreateDelegate,
117 base::Unretained(&mock_delegate_factory_)),
118 base::BindOnce(&MockFinishedListener::Finished,
119 base::Unretained(&listener_)))) {}
120
121 void ExpectDelegateCreation() {
122 delegate_ = new StrictMock<MockDelegate>();
123 mock_delegate_factory_.PrepareDelegateForCreation(
124 base::WrapUnique(delegate_));
125 EXPECT_TRUE(
126 base::CancelableSyncSocket::CreatePair(&local_, &foreign_socket_));
127 EXPECT_TRUE(mem_.CreateAnonymous(100));
128 EXPECT_CALL(mock_delegate_factory_, MockCreateDelegate(NotNull(), _))
129 .WillOnce(SaveArg<0>(&delegate_event_handler_));
130 }
131
132 base::MessageLoop loop_;
133 base::CancelableSyncSocket local_, foreign_socket_;
134 base::SharedMemory mem_;
135 StrictMock<MockDelegate>* delegate_ = nullptr;
136 AudioOutputDelegate::EventHandler* delegate_event_handler_ = nullptr;
137 StrictMock<MockDelegateFactory> mock_delegate_factory_;
138 StrictMock<MockFinishedListener> listener_;
139 AudioOutputPtr audio_output_ptr_;
140 std::unique_ptr<AudioOutputImpl> impl_;
141 };
142
143 TEST_F(AudioOutputImplTest, Play_Plays) {
144 ExpectDelegateCreation();
145 MockClient client;
146 audio_output_ptr_->Start(
147 media::AudioParameters::UnavailableDeviceParams(),
148 base::Bind(&MockClient::Started, base::Unretained(&client)));
149 audio_output_ptr_->Play();
150 base::RunLoop().RunUntilIdle();
151
152 // AudioOutputImpl has to wait with playing until it has been constructed.
153 // Same for other operations.
154 EXPECT_CALL(*delegate_, OnPlayStream());
155 ASSERT_NE(nullptr, delegate_event_handler_);
156 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
157 base::RunLoop().RunUntilIdle();
158 }
159
160 TEST_F(AudioOutputImplTest, Pause_Pauses) {
161 ExpectDelegateCreation();
162 MockClient client;
163 audio_output_ptr_->Start(
164 media::AudioParameters::UnavailableDeviceParams(),
165 base::Bind(&MockClient::Started, base::Unretained(&client)));
166 audio_output_ptr_->Pause();
167 base::RunLoop().RunUntilIdle();
168
169 EXPECT_CALL(*delegate_, OnPauseStream());
170 ASSERT_NE(nullptr, delegate_event_handler_);
171 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
172 base::RunLoop().RunUntilIdle();
173 }
174
175 TEST_F(AudioOutputImplTest, SetVolume_SetsVolume) {
176 ExpectDelegateCreation();
177 MockClient client;
178 audio_output_ptr_->Start(
179 media::AudioParameters::UnavailableDeviceParams(),
180 base::Bind(&MockClient::Started, base::Unretained(&client)));
181 audio_output_ptr_->SetVolume(kNewVolume);
182 base::RunLoop().RunUntilIdle();
183
184 EXPECT_CALL(*delegate_, OnSetVolume(kNewVolume));
185 ASSERT_NE(nullptr, delegate_event_handler_);
186 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
187 base::RunLoop().RunUntilIdle();
188 }
189
190 TEST_F(AudioOutputImplTest, DestructWithCallPending_CancelsCall) {
191 ExpectDelegateCreation();
192 MockClient client;
193 audio_output_ptr_->Start(
194 media::AudioParameters::UnavailableDeviceParams(),
195 base::Bind(&MockClient::Started, base::Unretained(&client)));
196 base::RunLoop().RunUntilIdle();
197 ASSERT_NE(nullptr, delegate_event_handler_);
198 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
199 audio_output_ptr_->Play();
200 impl_.reset();
201
202 base::RunLoop().RunUntilIdle();
203 }
204
205 TEST_F(AudioOutputImplTest, Start_NotifiesClient) {
206 ExpectDelegateCreation();
207 MockClient client;
208
209 audio_output_ptr_->Start(
210 media::AudioParameters::UnavailableDeviceParams(),
211 base::Bind(&MockClient::Started, base::Unretained(&client)));
212 base::RunLoop().RunUntilIdle();
213
214 EXPECT_CALL(client, GotNotification());
215
216 ASSERT_NE(nullptr, delegate_event_handler_);
217 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
218
219 base::RunLoop().RunUntilIdle();
220 }
221
222 TEST_F(AudioOutputImplTest, PlayBeforeStart_Error) {
223 EXPECT_CALL(listener_, Finished(impl_.get()));
224 audio_output_ptr_->Play();
225 base::RunLoop().RunUntilIdle();
226 }
227
228 TEST_F(AudioOutputImplTest, PauseBeforeStart_Error) {
229 EXPECT_CALL(listener_, Finished(impl_.get()));
230 audio_output_ptr_->Pause();
231 base::RunLoop().RunUntilIdle();
232 }
233
234 TEST_F(AudioOutputImplTest, SetVolumeBeforeStart_Error) {
235 EXPECT_CALL(listener_, Finished(impl_.get()));
236 audio_output_ptr_->SetVolume(kNewVolume);
237 base::RunLoop().RunUntilIdle();
238 }
239
240 TEST_F(AudioOutputImplTest, SetVolumeTooLarge_Error) {
241 ExpectDelegateCreation();
242 EXPECT_CALL(listener_, Finished(impl_.get()));
243 MockClient client;
244 audio_output_ptr_->Start(
245 media::AudioParameters::UnavailableDeviceParams(),
246 base::Bind(&MockClient::Started, base::Unretained(&client)));
247 audio_output_ptr_->SetVolume(15);
248 base::RunLoop().RunUntilIdle();
249 ASSERT_NE(nullptr, delegate_event_handler_);
250 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
251
252 base::RunLoop().RunUntilIdle();
253 }
254
255 TEST_F(AudioOutputImplTest, SetVolumeNegative_Error) {
256 ExpectDelegateCreation();
257 EXPECT_CALL(listener_, Finished(impl_.get()));
258 MockClient client;
259 audio_output_ptr_->Start(
260 media::AudioParameters::UnavailableDeviceParams(),
261 base::Bind(&MockClient::Started, base::Unretained(&client)));
262 audio_output_ptr_->SetVolume(-0.5);
263 base::RunLoop().RunUntilIdle();
264 ASSERT_NE(nullptr, delegate_event_handler_);
265 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
266
267 base::RunLoop().RunUntilIdle();
268 }
269
270 TEST_F(AudioOutputImplTest, StartStart_Error) {
271 MockClient client;
272 ExpectDelegateCreation();
273 EXPECT_CALL(listener_, Finished(impl_.get()));
274 audio_output_ptr_->Start(
275 media::AudioParameters::UnavailableDeviceParams(),
276 base::Bind(&MockClient::Started, base::Unretained(&client)));
277 audio_output_ptr_->Start(
278 media::AudioParameters::UnavailableDeviceParams(),
279 base::Bind(&MockClient::Started, base::Unretained(&client)));
280 base::RunLoop().RunUntilIdle();
281 ASSERT_NE(nullptr, delegate_event_handler_);
282 delegate_event_handler_->OnStreamCreated(
283 kStreamId, &mem_, &foreign_socket_); // Should be enough to trigger the
284 // error, as the first Start call
285 // will finish and the next will be
286 // processed.
287 base::RunLoop().RunUntilIdle();
288 }
289
290 TEST_F(AudioOutputImplTest, DelegateErrorBeforeCreated_PropagatesError) {
291 ExpectDelegateCreation();
292 MockClient client;
293 EXPECT_CALL(listener_, Finished(impl_.get()));
294
295 audio_output_ptr_->Start(
296 media::AudioParameters::UnavailableDeviceParams(),
297 base::Bind(&MockClient::Started, base::Unretained(&client)));
298 base::RunLoop().RunUntilIdle();
299
300 ASSERT_NE(nullptr, delegate_event_handler_);
301 delegate_event_handler_->OnStreamError(kStreamId);
302
303 base::RunLoop().RunUntilIdle();
304 }
305
306 TEST_F(AudioOutputImplTest, DelegateErrorAfterCreated_PropagatesError) {
307 ExpectDelegateCreation();
308 MockClient client;
309 EXPECT_CALL(listener_, Finished(impl_.get()));
310
311 audio_output_ptr_->Start(
312 media::AudioParameters::UnavailableDeviceParams(),
313 base::Bind(&MockClient::Started, base::Unretained(&client)));
314 base::RunLoop().RunUntilIdle();
315
316 ASSERT_NE(nullptr, delegate_event_handler_);
317 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
318 delegate_event_handler_->OnStreamError(kStreamId);
319
320 base::RunLoop().RunUntilIdle();
321 }
322
323 TEST_F(AudioOutputImplTest, RemoteEndGone_Error) {
324 EXPECT_CALL(listener_, Finished(impl_.get()));
325 audio_output_ptr_.reset();
326 base::RunLoop().RunUntilIdle();
327 Mock::VerifyAndClear(&listener_);
328 }
329
330 TEST_F(AudioOutputImplTest,
331 RemoteEndGoneWhileWaitingForDelegateCreation_Error) {
332 ExpectDelegateCreation();
333 MockClient client;
334 EXPECT_CALL(listener_, Finished(impl_.get()));
335 audio_output_ptr_->Start(
336 media::AudioParameters::UnavailableDeviceParams(),
337 base::Bind(&MockClient::Started, base::Unretained(&client)));
338 base::RunLoop().RunUntilIdle();
339 audio_output_ptr_.reset();
340
341 ASSERT_NE(nullptr, delegate_event_handler_);
342 delegate_event_handler_->OnStreamCreated(kStreamId, &mem_, &foreign_socket_);
343 base::RunLoop().RunUntilIdle();
344 Mock::VerifyAndClear(&listener_);
345 }
346
347 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698