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

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

Issue 2821203005: Add a mojo implementation of AudioOutputIPC. (Closed)
Patch Set: Death tests, Olga's comments Created 3 years, 7 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 2017 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/renderer/media/mojo_audio_output_ipc.h"
6
7 #include <algorithm>
8 #include <memory>
9 #include <string>
10 #include <utility>
11
12 #include "base/message_loop/message_loop.h"
13 #include "base/optional.h"
14 #include "base/run_loop.h"
15 #include "media/audio/audio_device_description.h"
16 #include "media/base/audio_parameters.h"
17 #include "mojo/public/cpp/bindings/binding.h"
18 #include "mojo/public/cpp/system/platform_handle.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/origin.h"
22
23 using testing::_;
24 using testing::AtLeast;
25 using testing::Mock;
26 using testing::StrictMock;
27
28 namespace content {
29
30 namespace {
31
32 const int kSessionId = 1234;
33 const size_t kMemoryLength = 4321;
34 const char kDeviceId[] = "device_id";
35 const char kReturnedDeviceId[] = "returned_device_id";
36 const double kNewVolume = 0.271828;
37
38 url::Origin Origin() {
39 return {};
40 }
41
42 media::AudioParameters Params() {
43 return media::AudioParameters::UnavailableDeviceParams();
44 }
45
46 MojoAudioOutputIPC::FactoryAccessor NullAccessor() {
47 return base::BindRepeating(
48 []() -> mojom::RendererAudioOutputStreamFactory* { return nullptr; });
49 }
50
51 class TestRemoteFactory : public mojom::RendererAudioOutputStreamFactory {
52 public:
53 TestRemoteFactory()
54 : expect_request_(false),
55 binding_(this, mojo::MakeRequest(&this_proxy_)) {}
56
57 ~TestRemoteFactory() override {}
58
59 void RequestDeviceAuthorization(
60 media::mojom::AudioOutputStreamProviderRequest stream_provider_request,
61 int64_t session_id,
62 const std::string& device_id,
63 RequestDeviceAuthorizationCallback callback) override {
64 EXPECT_EQ(session_id, expected_session_id_);
65 EXPECT_EQ(device_id, expected_device_id_);
66 EXPECT_TRUE(expect_request_);
67 if (provider_) {
68 std::move(callback).Run(
69 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK, Params(),
70 std::string(kReturnedDeviceId));
71 provider_binding_.emplace(provider_.get(),
72 std::move(stream_provider_request));
73 } else {
74 std::move(callback).Run(
75 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
76 Params(), std::string(""));
77 }
78 expect_request_ = false;
79 }
80
81 void PrepareProviderForAuthorization(
82 int64_t session_id,
83 const std::string& device_id,
84 std::unique_ptr<media::mojom::AudioOutputStreamProvider> provider) {
85 EXPECT_FALSE(expect_request_);
86 expect_request_ = true;
87 expected_session_id_ = session_id;
88 expected_device_id_ = device_id;
89 provider_binding_.reset();
90 std::swap(provider_, provider);
91 }
92
93 void RefuseNextRequest(int64_t session_id, const std::string& device_id) {
94 EXPECT_FALSE(expect_request_);
95 expect_request_ = true;
96 expected_session_id_ = session_id;
97 expected_device_id_ = device_id;
98 }
99
100 void Disconnect() {
101 binding_.Close();
102 this_proxy_.reset();
103 binding_.Bind(mojo::MakeRequest(&this_proxy_));
104 provider_binding_.reset();
105 provider_.reset();
106 expect_request_ = false;
107 }
108
109 MojoAudioOutputIPC::FactoryAccessor GetAccessor() {
110 return base::BindRepeating(&TestRemoteFactory::get, base::Unretained(this));
111 }
112
113 private:
114 mojom::RendererAudioOutputStreamFactory* get() { return this_proxy_.get(); }
115
116 bool expect_request_;
117 int64_t expected_session_id_;
118 std::string expected_device_id_;
119
120 mojom::RendererAudioOutputStreamFactoryPtr this_proxy_;
121 mojo::Binding<mojom::RendererAudioOutputStreamFactory> binding_;
122 std::unique_ptr<media::mojom::AudioOutputStreamProvider> provider_;
123 base::Optional<mojo::Binding<media::mojom::AudioOutputStreamProvider>>
124 provider_binding_;
125 };
126
127 class TestStreamProvider : public media::mojom::AudioOutputStreamProvider {
128 public:
129 explicit TestStreamProvider(media::mojom::AudioOutputStream* stream)
130 : stream_(stream) {}
131
132 ~TestStreamProvider() override {
133 // If we expected a stream to be acquired, make sure it is so.
134 if (stream_)
135 EXPECT_TRUE(binding_);
136 }
137
138 void Acquire(media::mojom::AudioOutputStreamRequest stream_request,
139 const media::AudioParameters& params,
140 const AcquireCallback& callback) override {
141 EXPECT_EQ(binding_, base::nullopt);
142 EXPECT_NE(stream_, nullptr);
143 binding_.emplace(stream_, std::move(stream_request));
144 base::CancelableSyncSocket foreign_socket;
145 EXPECT_TRUE(
146 base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
147 std::move(callback).Run(mojo::SharedBufferHandle::Create(kMemoryLength),
148 mojo::WrapPlatformFile(foreign_socket.Release()));
149 }
150
151 private:
152 media::mojom::AudioOutputStream* stream_;
153 base::Optional<mojo::Binding<media::mojom::AudioOutputStream>> binding_;
154 base::CancelableSyncSocket socket_;
155 };
156
157 class MockStream : public media::mojom::AudioOutputStream {
158 public:
159 MOCK_METHOD0(Play, void());
160 MOCK_METHOD0(Pause, void());
161 MOCK_METHOD1(SetVolume, void(double));
162 };
163
164 class MockDelegate : public media::AudioOutputIPCDelegate {
165 public:
166 MockDelegate() {}
167 ~MockDelegate() override {}
168
169 void OnStreamCreated(base::SharedMemoryHandle mem_handle,
170 base::SyncSocket::Handle socket_handle,
171 int length) {
172 base::SharedMemory sh_mem(
173 mem_handle, /*read_only*/ false); // Releases the shared memory handle.
174 base::SyncSocket socket(socket_handle); // Releases the socket descriptor.
175 GotOnStreamCreated(length);
176 }
177
178 MOCK_METHOD0(OnError, void());
179 MOCK_METHOD3(OnDeviceAuthorized,
180 void(media::OutputDeviceStatus device_status,
181 const media::AudioParameters& output_params,
182 const std::string& matched_device_id));
183 MOCK_METHOD1(GotOnStreamCreated, void(int length));
184 MOCK_METHOD0(OnIPCClosed, void());
185 };
186
187 } // namespace
188
189 TEST(MojoAudioOutputIPC, AuthorizeWithoutFactory_CallsOnIPCClosed) {
190 base::MessageLoopForIO message_loop;
191 StrictMock<MockDelegate> delegate;
192
193 const std::unique_ptr<media::AudioOutputIPC> ipc =
194 base::MakeUnique<MojoAudioOutputIPC>(NullAccessor());
195
196 EXPECT_CALL(delegate, OnIPCClosed());
197 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
198 base::RunLoop().RunUntilIdle();
199 }
200
201 TEST(MojoAudioOutputIPC, CreateWithoutFactoryOrAuthorization_CallsOnIPCClosed) {
202 base::MessageLoopForIO message_loop;
203 StrictMock<MockDelegate> delegate;
204
205 const std::unique_ptr<media::AudioOutputIPC> ipc =
206 base::MakeUnique<MojoAudioOutputIPC>(NullAccessor());
207
208 EXPECT_CALL(delegate, OnIPCClosed());
209 ipc->CreateStream(&delegate, Params());
210 base::RunLoop().RunUntilIdle();
211 }
212
213 TEST(MojoAudioOutputIPC, DeviceAuthorized_Propagates) {
214 base::MessageLoopForIO message_loop;
215 TestRemoteFactory stream_factory;
216 StrictMock<MockDelegate> delegate;
217
218 const std::unique_ptr<media::AudioOutputIPC> ipc =
219 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
220 stream_factory.PrepareProviderForAuthorization(
221 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
222
223 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
224
225 EXPECT_CALL(delegate, OnDeviceAuthorized(
226 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
227 _, std::string(kReturnedDeviceId)));
228 base::RunLoop().RunUntilIdle();
229
230 ipc->CloseStream();
231 base::RunLoop().RunUntilIdle();
232 }
233
234 TEST(MojoAudioOutputIPC, OnDeviceCreated_Propagates) {
235 base::MessageLoopForIO message_loop;
236 TestRemoteFactory stream_factory;
237 StrictMock<MockStream> stream;
238 StrictMock<MockDelegate> delegate;
239
240 const std::unique_ptr<media::AudioOutputIPC> ipc =
241 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
242 stream_factory.PrepareProviderForAuthorization(
243 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
244
245 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
246 ipc->CreateStream(&delegate, Params());
247
248 EXPECT_CALL(delegate, OnDeviceAuthorized(
249 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
250 _, std::string(kReturnedDeviceId)));
251 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
252 base::RunLoop().RunUntilIdle();
253
254 ipc->CloseStream();
255 base::RunLoop().RunUntilIdle();
256 }
257
258 TEST(MojoAudioOutputIPC,
259 CreateWithoutAuthorization_RequestsAuthorizationFirst) {
260 base::MessageLoopForIO message_loop;
261 TestRemoteFactory stream_factory;
262 StrictMock<MockStream> stream;
263 StrictMock<MockDelegate> delegate;
264 const std::unique_ptr<media::AudioOutputIPC> ipc =
265 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
266
267 // Note: This call implicitly EXPECTs that authorization is requested,
268 // and constructing the TestStreamProvider with a |&stream| EXPECTs that the
269 // stream is created. This implicit request should always be for the default
270 // device and no session id.
271 stream_factory.PrepareProviderForAuthorization(
272 0, std::string(media::AudioDeviceDescription::kDefaultDeviceId),
273 base::MakeUnique<TestStreamProvider>(&stream));
274
275 ipc->CreateStream(&delegate, Params());
276
277 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
278 base::RunLoop().RunUntilIdle();
279
280 ipc->CloseStream();
281 base::RunLoop().RunUntilIdle();
282 }
283
284 TEST(MojoAudioOutputIPC, IsReusable) {
285 base::MessageLoopForIO message_loop;
286 TestRemoteFactory stream_factory;
287 StrictMock<MockStream> stream;
288 StrictMock<MockDelegate> delegate;
289
290 const std::unique_ptr<media::AudioOutputIPC> ipc =
291 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
292
293 for (int i = 0; i < 5; ++i) {
294 stream_factory.PrepareProviderForAuthorization(
295 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
296
297 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
298 ipc->CreateStream(&delegate, Params());
299
300 EXPECT_CALL(
301 delegate,
302 OnDeviceAuthorized(media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
303 _, std::string(kReturnedDeviceId)));
304 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
305 base::RunLoop().RunUntilIdle();
306 Mock::VerifyAndClearExpectations(&delegate);
307
308 ipc->CloseStream();
309 base::RunLoop().RunUntilIdle();
310 }
311 }
312
313 TEST(MojoAudioOutputIPC, IsReusableAfterError) {
314 base::MessageLoopForIO message_loop;
315 TestRemoteFactory stream_factory;
316 StrictMock<MockStream> stream;
317 StrictMock<MockDelegate> delegate;
318
319 const std::unique_ptr<media::AudioOutputIPC> ipc =
320 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
321
322 stream_factory.PrepareProviderForAuthorization(
323 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
324 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
325
326 EXPECT_CALL(delegate, OnDeviceAuthorized(
327 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
328 _, std::string(kReturnedDeviceId)));
329 base::RunLoop().RunUntilIdle();
330 Mock::VerifyAndClearExpectations(&delegate);
331
332 EXPECT_CALL(delegate, OnError()).Times(AtLeast(1));
333 stream_factory.Disconnect();
334 base::RunLoop().RunUntilIdle();
335 Mock::VerifyAndClearExpectations(&delegate);
336
337 ipc->CloseStream();
338 base::RunLoop().RunUntilIdle();
339
340 for (int i = 0; i < 5; ++i) {
341 stream_factory.PrepareProviderForAuthorization(
342 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
343
344 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
345 ipc->CreateStream(&delegate, Params());
346
347 EXPECT_CALL(
348 delegate,
349 OnDeviceAuthorized(media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
350 _, std::string(kReturnedDeviceId)));
351 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
352 base::RunLoop().RunUntilIdle();
353 Mock::VerifyAndClearExpectations(&delegate);
354
355 ipc->CloseStream();
356 base::RunLoop().RunUntilIdle();
357 }
358 }
359
360 TEST(MojoAudioOutputIPC, DeviceNotAuthorized_Propagates) {
361 base::MessageLoopForIO message_loop;
362 TestRemoteFactory stream_factory;
363 StrictMock<MockDelegate> delegate;
364
365 const std::unique_ptr<media::AudioOutputIPC> ipc =
366 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
367 stream_factory.RefuseNextRequest(kSessionId, kDeviceId);
368
369 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
370
371 EXPECT_CALL(
372 delegate,
373 OnDeviceAuthorized(
374 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
375 _, std::string()));
376 EXPECT_CALL(delegate, OnError()).Times(AtLeast(0));
377 base::RunLoop().RunUntilIdle();
378
379 ipc->CloseStream();
380 base::RunLoop().RunUntilIdle();
381 }
382
383 TEST(MojoAudioOutputIPC,
384 FactoryDisconnectedBeforeAuthorizationReply_CallsAuthorizedAnyways) {
385 // The authorization IPC message might be aborted by the remote end
386 // disconnecting. In this case, the MojoAudioOutputIPC object must still
387 // send a notification to unblock the AudioOutputIPCDelegate.
388 base::MessageLoopForIO message_loop;
389 TestRemoteFactory stream_factory;
390 StrictMock<MockDelegate> delegate;
391
392 const std::unique_ptr<media::AudioOutputIPC> ipc =
393 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
394
395 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
396
397 EXPECT_CALL(
398 delegate,
399 OnDeviceAuthorized(
400 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL, _,
401 std::string()));
402 stream_factory.Disconnect();
403 EXPECT_CALL(delegate, OnError());
404 base::RunLoop().RunUntilIdle();
405
406 ipc->CloseStream();
407 base::RunLoop().RunUntilIdle();
408 }
409
410 TEST(MojoAudioOutputIPC,
411 FactoryDisconnectedAfterAuthorizationReply_CallsAuthorizedOnlyOnce) {
412 // This test makes sure that the MojoAudioOutputIPC doesn't callback for
413 // authorization when the factory disconnects if it already got a callback
414 // for authorization.
415 base::MessageLoopForIO message_loop;
416 TestRemoteFactory stream_factory;
417 stream_factory.PrepareProviderForAuthorization(
418 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
419 StrictMock<MockDelegate> delegate;
420
421 const std::unique_ptr<media::AudioOutputIPC> ipc =
422 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
423
424 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
425
426 EXPECT_CALL(delegate, OnDeviceAuthorized(
427 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
428 _, std::string(kReturnedDeviceId)));
429 base::RunLoop().RunUntilIdle();
430
431 stream_factory.Disconnect();
432 EXPECT_CALL(delegate, OnError());
433 base::RunLoop().RunUntilIdle();
434
435 ipc->CloseStream();
436 base::RunLoop().RunUntilIdle();
437 }
438
439 #if DCHECK_IS_ON()
DaleCurtis 2017/05/24 01:36:55 There's EXPECT_DCHECK_DEATH().
Max Morin 2017/05/30 14:17:11 Done.
440 TEST(MojoAudioOutputIPC, AuthorizeNoClose_DCHECKs) {
441 base::MessageLoopForIO message_loop;
442 TestRemoteFactory stream_factory;
443 StrictMock<MockDelegate> delegate;
444
445 stream_factory.PrepareProviderForAuthorization(
446 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(nullptr));
447
448 std::unique_ptr<media::AudioOutputIPC> ipc =
449 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
450
451 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
452 EXPECT_DEATH(
453 ipc.reset(),
454 ".*CloseStream must be called before destructing the AudioOutputIPC.*");
455 ipc->CloseStream();
456 ipc.reset();
457 base::RunLoop().RunUntilIdle();
458 }
459
460 TEST(MojoAudioOutputIPC, CreateNoClose_DCHECKs) {
461 base::MessageLoopForIO message_loop;
462 TestRemoteFactory stream_factory;
463 StrictMock<MockDelegate> delegate;
464 StrictMock<MockStream> stream;
465
466 stream_factory.PrepareProviderForAuthorization(
467 0, std::string(media::AudioDeviceDescription::kDefaultDeviceId),
468 base::MakeUnique<TestStreamProvider>(&stream));
469
470 std::unique_ptr<media::AudioOutputIPC> ipc =
471 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
472
473 ipc->CreateStream(&delegate, Params());
474 EXPECT_DEATH(
475 ipc.reset(),
476 ".*CloseStream must be called before destructing the AudioOutputIPC.*");
477 ipc->CloseStream();
478 ipc.reset();
479 base::RunLoop().RunUntilIdle();
480 }
481 #endif // DCHECK_IS_ON()
482
483 TEST(MojoAudioOutputIPC, Play_Plays) {
484 base::MessageLoopForIO message_loop;
485 TestRemoteFactory stream_factory;
486 StrictMock<MockStream> stream;
487 StrictMock<MockDelegate> delegate;
488
489 const std::unique_ptr<media::AudioOutputIPC> ipc =
490 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
491 stream_factory.PrepareProviderForAuthorization(
492 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
493
494 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
495 ipc->CreateStream(&delegate, Params());
496 ipc->PlayStream();
497
498 EXPECT_CALL(delegate, OnDeviceAuthorized(
499 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
500 _, std::string(kReturnedDeviceId)));
501 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
502 EXPECT_CALL(stream, Play());
503 base::RunLoop().RunUntilIdle();
504
505 ipc->CloseStream();
506 base::RunLoop().RunUntilIdle();
507 }
508
509 TEST(MojoAudioOutputIPC, Pause_Pauses) {
510 base::MessageLoopForIO message_loop;
511 TestRemoteFactory stream_factory;
512 StrictMock<MockStream> stream;
513 StrictMock<MockDelegate> delegate;
514
515 const std::unique_ptr<media::AudioOutputIPC> ipc =
516 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
517 stream_factory.PrepareProviderForAuthorization(
518 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
519
520 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
521 ipc->CreateStream(&delegate, Params());
522 ipc->PauseStream();
523
524 EXPECT_CALL(delegate, OnDeviceAuthorized(
525 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
526 _, std::string(kReturnedDeviceId)));
527 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
528 EXPECT_CALL(stream, Pause());
529 base::RunLoop().RunUntilIdle();
530
531 ipc->CloseStream();
532 base::RunLoop().RunUntilIdle();
533 }
534
535 TEST(MojoAudioOutputIPC, SetVolume_SetsVolume) {
536 base::MessageLoopForIO message_loop;
537 TestRemoteFactory stream_factory;
538 StrictMock<MockStream> stream;
539 StrictMock<MockDelegate> delegate;
540
541 const std::unique_ptr<media::AudioOutputIPC> ipc =
542 base::MakeUnique<MojoAudioOutputIPC>(stream_factory.GetAccessor());
543 stream_factory.PrepareProviderForAuthorization(
544 kSessionId, kDeviceId, base::MakeUnique<TestStreamProvider>(&stream));
545
546 ipc->RequestDeviceAuthorization(&delegate, kSessionId, kDeviceId, Origin());
547 ipc->CreateStream(&delegate, Params());
548 ipc->SetVolume(kNewVolume);
549
550 EXPECT_CALL(delegate, OnDeviceAuthorized(
551 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_OK,
552 _, std::string(kReturnedDeviceId)));
553 EXPECT_CALL(delegate, GotOnStreamCreated(kMemoryLength));
554 EXPECT_CALL(stream, SetVolume(kNewVolume));
555 base::RunLoop().RunUntilIdle();
556
557 ipc->CloseStream();
558 base::RunLoop().RunUntilIdle();
559 }
560
561 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698