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

Side by Side Diff: content/renderer/media/audio_output_client_unittest.cc

Issue 1930393002: Switch stream creation and closing in Chrome audio rendering from IPC to Mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unique_ptr for Binding Created 4 years, 6 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
« no previous file with comments | « content/renderer/media/audio_output_client.cc ('k') | content/renderer/render_frame_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 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 "base/bind.h"
6 #include "base/memory/shared_memory.h"
7 #include "base/run_loop.h"
8 #include "base/sync_socket.h"
9 #include "content/public/test/test_browser_thread.h"
10 #include "content/renderer/media/audio_message_filter.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 /*
14 using ::testing::_;
15
16 namespace content {
17
18 namespace {
19 // const int kBufferSize1 = 30;
20 const int kBufferSize2 = 40;
21 const int kBufferSize3 = 50;
22 // const int kRenderFrameId = 5;
23 const int kStreamId1 = 9;
24 const int kStreamId2 = 20;
25 const int kStreamId3 = 3;
26 }
27
28 class MockAudioMessageFilter : public AudioMessageFilter {
29 public:
30 MockAudioMessageFilter(
31 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
32 : AudioMessageFilter(io_task_runner) {}
33 MOCK_METHOD4(OnStreamCreated,
34 void(int stream_id,
35 base::SharedMemoryHandle handle,
36 base::SyncSocket::TransitDescriptor socket_descriptor,
37 uint32_t length));
38 MOCK_METHOD2(OnStreamStateChanged,
39 void(int stream_id, media::AudioOutputIPCDelegateState state));
40 MOCK_METHOD1(CloseStream, void(int stream_id));
41
42 protected:
43 ~MockAudioMessageFilter() {}
44 };
45
46 class TestAudioOutputImpl;
47
48 class AudioOutputClientTest : public testing::Test {
49 public:
50 AudioOutputClientTest() {
51 message_loop_.reset(new base::MessageLoopForUI());
52 io_thread_.reset(
53 new TestBrowserThread(BrowserThread::IO, message_loop_.get()));
54
55 audio_output_client_ =
56 new AudioOutputClient(NULL, message_loop_->task_runner());
57 audio_message_filter_ =
58 new MockAudioMessageFilter(message_loop_->task_runner());
59 }
60
61 void CreateStreamCallback(int stream_id,
62 media::mojom::AudioOutputStreamPtr stream,
63 mojo::ScopedSharedBufferHandle shared_buffer,
64 mojo::ScopedHandle socket_descriptor) {}
65 static mojo::ScopedSharedBufferHandle GenerateBuffer(int buffer_size) {
66 base::SharedMemory shared_memory;
67 shared_memory.CreateAnonymous(buffer_size);
68 base::SharedMemoryHandle shared_memory_handle = shared_memory.handle();
69
70 MojoHandle mojo_foreign_memory_handle;
71
72 MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
73 shared_memory_handle, shared_memory.requested_size(), false,
74 &mojo_foreign_memory_handle);
75
76 EXPECT_EQ(shared_buffer_result, MOJO_RESULT_OK);
77
78 mojo::ScopedSharedBufferHandle shared_buffer_handle =
79 mojo::ScopedSharedBufferHandle(
80 mojo::SharedBufferHandle(mojo_foreign_memory_handle));
81 return shared_buffer_handle;
82 }
83
84 static mojo::ScopedHandle GenerateSocket() {
85 base::SyncSocket::TransitDescriptor socket_descriptor;
86
87 MojoHandle socket_descriptor_handle;
88 MojoResult platform_handle_result;
89
90 #if defined(OS_WIN)
91 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
92 mojo::edk::ScopedPlatformHandle(
93 mojo::edk::PlatformHandle(socket_descriptor),
94 &socket_descriptor_handle);
95 #else
96 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
97 mojo::edk::ScopedPlatformHandle(
98 mojo::edk::PlatformHandle(socket_descriptor.fd)),
99 &socket_descriptor_handle);
100 #endif
101
102 EXPECT_EQ(platform_handle_result, MOJO_RESULT_OK);
103
104 mojo::ScopedHandle socket_handle =
105 mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
106 return socket_handle;
107 }
108
109 protected:
110 scoped_refptr<AudioOutputClient> audio_output_client_;
111 std::unique_ptr<base::MessageLoop> message_loop_;
112 scoped_refptr<MockAudioMessageFilter> audio_message_filter_;
113 std::unique_ptr<TestAudioOutputImpl> audio_output_impl_;
114
115 private:
116 std::unique_ptr<TestBrowserThread> io_thread_;
117 DISALLOW_COPY_AND_ASSIGN(AudioOutputClientTest);
118 };
119
120 class TestAudioOutputStreamImpl : public media::mojom::AudioOutputStream {
121 public:
122 TestAudioOutputStreamImpl(media::mojom::AudioOutputStreamRequest request)
123 : binding_(this, std::move(request)) {}
124 ~TestAudioOutputStreamImpl() override {}
125
126 // AudioOutputStream implementation:
127 static base::RunLoop* run_loop_;
128 static int stream_count_;
129 void Close() override {
130 stream_count_--;
131 // The number of streams that will be closed is 2.
132 EXPECT_TRUE(stream_count_ > -1);
133 if (stream_count_ == 0)
134 run_loop_->Quit();
135 }
136
137 private:
138 mojo::Binding<media::mojom::AudioOutputStream> binding_;
139 };
140
141 class TestAudioOutputImpl : public media::mojom::AudioOutput {
142 public:
143 TestAudioOutputImpl(media::mojom::AudioOutputRequest request)
144 : binding_(this, std::move(request)) {}
145 ~TestAudioOutputImpl() override {}
146
147 // AudioOutput implementation:
148 void CreateStream(int stream_id,
149 const media::AudioParameters& params,
150 const CreateStreamCallback& callback) override {
151 media::mojom::AudioOutputStreamPtr stream_ptr =
152 media::mojom::AudioOutputStreamPtr();
153 std::unique_ptr<TestAudioOutputStreamImpl> stream(
154 new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr)));
155 mojo::ScopedSharedBufferHandle shared_buffer_handle =
156 mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
157
158 callback.Run(stream_id, std::move(stream_ptr),
159 std::move(shared_buffer_handle),
160 AudioOutputClientTest::GenerateSocket());
161 }
162
163 private:
164 mojo::Binding<media::mojom::AudioOutput> binding_;
165 };
166
167 base::RunLoop* TestAudioOutputStreamImpl::run_loop_;
168 int TestAudioOutputStreamImpl::stream_count_ = 2;
169
170 TEST_F(AudioOutputClientTest, CreateStream) {
171 base::RunLoop run_loop;
172 media::mojom::AudioOutputPtr audio_output_impl_ptr;
173 audio_output_impl_.reset(
174 new TestAudioOutputImpl(mojo::GetProxy(&audio_output_impl_ptr)));
175 media::AudioParameters params(
176 media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
177 media::AudioParameters::kAudioCDSampleRate, 16,
178 media::AudioParameters::kAudioCDSampleRate / 10);
179 int stream_count = 2;
180 audio_output_client_->service_ = std::move(audio_output_impl_ptr);
181
182 audio_output_client_->CreateStream(
183 kStreamId1, params,
184 [&run_loop, &stream_count](int stream_id,
185 media::mojom::AudioOutputStreamPtr stream_ptr,
186 mojo::ScopedSharedBufferHandle shared_buffer,
187 mojo::ScopedHandle socket_descriptor) {
188 EXPECT_EQ(kStreamId1, stream_id);
189 EXPECT_TRUE(stream_ptr.is_bound());
190 stream_count--;
191 // The number of streams that will be closed is 2.
192 EXPECT_TRUE(stream_count > -1);
193 if (stream_count == 1)
194 run_loop.Quit();
195 });
196
197 audio_output_client_->CreateStream(
198 kStreamId2, params,
199 [&run_loop, &stream_count](int stream_id,
200 media::mojom::AudioOutputStreamPtr stream_ptr,
201 mojo::ScopedSharedBufferHandle shared_buffer,
202 mojo::ScopedHandle socket_descriptor) {
203 EXPECT_EQ(kStreamId2, stream_id);
204 EXPECT_TRUE(stream_ptr.is_bound());
205 stream_count--;
206 // The number of streams that will be closed is 2.
207 EXPECT_TRUE(stream_count > -1);
208 if (stream_count == 0)
209 run_loop.Quit();
210 });
211 run_loop.Run();
212 }
213
214 TEST_F(AudioOutputClientTest, CreateStreamCallback) {
215 EXPECT_CALL(*audio_message_filter_,
216 OnStreamStateChanged(
217 kStreamId2, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
218 .Times(0);
219 EXPECT_CALL(*audio_message_filter_,
220 OnStreamCreated(kStreamId2, _, _, kBufferSize2))
221 .Times(1);
222
223 media::mojom::AudioOutputStreamPtr stream_ptr2;
224 std::unique_ptr<TestAudioOutputStreamImpl> stream2(
225 new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr2)));
226
227 audio_output_client_->CreateStreamCallback(kStreamId2, std::move(stream_ptr2),
228 GenerateBuffer(kBufferSize2),
229 GenerateSocket());
230
231 EXPECT_CALL(*audio_message_filter_,
232 OnStreamStateChanged(
233 kStreamId3, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
234 .Times(0);
235 EXPECT_CALL(*audio_message_filter_,
236 OnStreamCreated(kStreamId3, _, _, kBufferSize3))
237 .Times(1);
238 media::mojom::AudioOutputStreamPtr stream_ptr3;
239
240 std::unique_ptr<TestAudioOutputStreamImpl> stream3(
241 new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr3)));
242
243 audio_output_client_->CreateStreamCallback(kStreamId3, std::move(stream_ptr3),
244 GenerateBuffer(kBufferSize3),
245 GenerateSocket());
246
247 message_loop_->RunUntilIdle();
248 }
249
250 TEST_F(AudioOutputClientTest, CreateStreamCallbackNotFound) {
251 media::mojom::AudioOutputStreamPtr stream_ptr1;
252 EXPECT_CALL(*audio_message_filter_,
253 OnStreamStateChanged(
254 kStreamId1, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
255 .Times(0);
256 EXPECT_CALL(*audio_message_filter_,
257 OnStreamStateChanged(
258 kStreamId1, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
259 .Times(1);
260
261 audio_output_client_->CreateStreamCallback(kStreamId1, std::move(stream_ptr1),
262 GenerateBuffer(kBufferSize1),
263 GenerateSocket());
264
265 EXPECT_CALL(*audio_message_filter_,
266 OnStreamStateChanged(
267 kStreamId2, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
268 .Times(0);
269 EXPECT_CALL(*audio_message_filter_,
270 OnStreamCreated(kStreamId2, _, _, kBufferSize2))
271 .Times(1);
272
273 media::mojom::AudioOutputStreamPtr stream_ptr2;
274 std::unique_ptr<AudioOutputStreamImpl> stream2(new AudioOutputStreamImpl(
275 mojo::GetProxy(&stream_ptr2), kStreamId2, kRenderFrameId, NULL));
276
277 audio_output_client_->CreateStreamCallback(kStreamId2, std::move(stream_ptr2),
278 GenerateBuffer(kBufferSize2),
279 GenerateSocket());
280
281 EXPECT_CALL(*audio_message_filter_,
282 OnStreamStateChanged(
283 kStreamId3, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
284 .Times(0);
285 EXPECT_CALL(*audio_message_filter_,
286 OnStreamCreated(kStreamId3, _, _, kBufferSize3))
287 .Times(1);
288 media::mojom::AudioOutputStreamPtr stream_ptr3;
289
290 std::unique_ptr<AudioOutputStreamImpl> stream3(new AudioOutputStreamImpl(
291 mojo::GetProxy(&stream_ptr3), kStreamId3, kRenderFrameId, NULL));
292
293 audio_output_client_->CreateStreamCallback(kStreamId3, std::move(stream_ptr3),
294 GenerateBuffer(kBufferSize3),
295 GenerateSocket());
296
297 message_loop_->RunUntilIdle();
298 }
299
300 TEST_F(AudioOutputClientTest, CloseAuthorizedNotCreatedStream) {
301 base::RunLoop run_loop;
302 media::mojom::AudioOutputPtr audio_output_impl_ptr;
303 audio_output_impl_.reset(
304 new TestAudioOutputImpl(mojo::GetProxy(&audio_output_impl_ptr)));
305 audio_output_client_->service_ = std::move(audio_output_impl_ptr);
306
307 EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId1)).Times(1);
308
309 audio_output_client_->CloseStream(kStreamId1);
310
311 EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId2)).Times(1);
312 audio_output_client_->CloseStream(kStreamId2);
313 }
314
315 TEST_F(AudioOutputClientTest, CloseCreatedStream) {
316 TestAudioOutputStreamImpl::run_loop_ = new base::RunLoop();
317 media::mojom::AudioOutputPtr audio_output_impl_ptr;
318 audio_output_impl_.reset(
319 new TestAudioOutputImpl(mojo::GetProxy(&audio_output_impl_ptr)));
320 audio_output_client_->service_ = std::move(audio_output_impl_ptr);
321
322 media::mojom::AudioOutputStreamPtr stream_ptr1;
323 std::unique_ptr<TestAudioOutputStreamImpl> stream1(
324 new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr1)));
325 audio_output_client_->streams_.insert(
326 std::make_pair(kStreamId1, std::move(stream_ptr1)));
327
328 // Closing an authorized but ńot created stream should call
329 // AudioMessageFilter::CloseStream.
330 EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId3)).Times(1);
331
332 audio_output_client_->CloseStream(kStreamId3);
333
334 audio_output_client_->CloseStream(kStreamId1);
335
336 media::mojom::AudioOutputStreamPtr stream_ptr2;
337 std::unique_ptr<TestAudioOutputStreamImpl> stream2(
338 new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr2)));
339 audio_output_client_->streams_.insert(
340 std::make_pair(kStreamId2, std::move(stream_ptr2)));
341 audio_output_client_->CloseStream(kStreamId2);
342 TestAudioOutputStreamImpl::run_loop_->Run();
343
344 // |kStreamId1| is cllosed now. Closing it will call
345 // AudioMessageFilter::CloseStream. The same for |kStreamId2|
346 EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId1)).Times(1);
347 audio_output_client_->CloseStream(kStreamId1);
348
349 EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId2)).Times(1);
350 audio_output_client_->CloseStream(kStreamId2);
351 }
352
353 } // namespace content
354 */
OLDNEW
« no previous file with comments | « content/renderer/media/audio_output_client.cc ('k') | content/renderer/render_frame_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698