| Index: content/browser/renderer_host/media/audio_output_service_impl_unittest.cc
|
| diff --git a/content/browser/renderer_host/media/audio_output_service_impl_unittest.cc b/content/browser/renderer_host/media/audio_output_service_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7c4c501362c32df7d095d39835ac93342ebb9798
|
| --- /dev/null
|
| +++ b/content/browser/renderer_host/media/audio_output_service_impl_unittest.cc
|
| @@ -0,0 +1,177 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "content/browser/renderer_host/media/audio_output_service_impl.h"
|
| +
|
| +#include <utility>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/command_line.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/run_loop.h"
|
| +#include "content/browser/audio_manager_thread.h"
|
| +#include "content/browser/media/capture/audio_mirroring_manager.h"
|
| +#include "content/browser/renderer_host/media/audio_output_service_context.h"
|
| +#include "content/browser/renderer_host/media/media_stream_manager.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/media_observer.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "media/audio/fake_audio_log_factory.h"
|
| +#include "media/audio/fake_audio_manager.h"
|
| +#include "media/base/media_switches.h"
|
| +#include "media/mojo/interfaces/audio_output.mojom.h"
|
| +#include "mojo/public/cpp/bindings/binding.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace {
|
| +int kRenderProcessId = 42;
|
| +int kRenderFrameId = 24;
|
| +const char kSecurityOrigin[] = "http://localhost";
|
| +const char kSalt[] = "salt";
|
| +}
|
| +
|
| +namespace content {
|
| +
|
| +class AudioOutputServiceImplTest : public testing::Test {
|
| + public:
|
| + using AudioOutputService = media::mojom::AudioOutputService;
|
| + using AudioOutputServicePtr = mojo::InterfacePtr<AudioOutputService>;
|
| + using AudioOutputServiceRequest = mojo::InterfaceRequest<AudioOutputService>;
|
| + using AudioOutput = media::mojom::AudioOutput;
|
| + using AudioOutputPtr = mojo::InterfacePtr<AudioOutput>;
|
| + using AudioOutputRequest = mojo::InterfaceRequest<AudioOutput>;
|
| +
|
| + AudioOutputServiceImplTest()
|
| + : media_stream_manager_(),
|
| + thread_bundle_(TestBrowserThreadBundle::Options::REAL_IO_THREAD),
|
| + audio_thread_(),
|
| + log_factory_(),
|
| + audio_manager_(
|
| + new media::FakeAudioManager(audio_thread_.task_runner(),
|
| + audio_thread_.worker_task_runner(),
|
| + &log_factory_)) {
|
| + media_stream_manager_ =
|
| + base::MakeUnique<MediaStreamManager>(audio_manager_.get());
|
| + }
|
| +
|
| + ~AudioOutputServiceImplTest() override { SyncWithAllThreads(); }
|
| +
|
| + void SyncWithAllThreads() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + // New tasks might be posted while we are syncing, but in every iteration at
|
| + // least one task will be run. 20 iterations should be enough for our code.
|
| + for (int i = 0; i < 20; ++i) {
|
| + {
|
| + base::MessageLoop::ScopedNestableTaskAllower allower(
|
| + base::MessageLoop::current());
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
| + SyncWith(BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
|
| + SyncWith(audio_manager_->GetWorkerTaskRunner());
|
| + }
|
| + }
|
| +
|
| + void SyncWith(scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
| + CHECK(task_runner);
|
| + CHECK(!task_runner->BelongsToCurrentThread());
|
| + base::WaitableEvent e = {base::WaitableEvent::ResetPolicy::MANUAL,
|
| + base::WaitableEvent::InitialState::NOT_SIGNALED};
|
| + task_runner->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal,
|
| + base::Unretained(&e)));
|
| + e.Wait();
|
| + }
|
| +
|
| + void CreateAndBindService(AudioOutputServiceRequest request) {
|
| + service_context_.reset(new AudioOutputServiceContext(
|
| + kRenderProcessId, audio_manager_.get(), media_stream_manager_.get(),
|
| + AudioMirroringManager::GetInstance(), kSalt));
|
| + service_context_->CreateService(kRenderFrameId, std::move(request));
|
| + }
|
| +
|
| + std::unique_ptr<MediaStreamManager> media_stream_manager_;
|
| + TestBrowserThreadBundle thread_bundle_;
|
| + AudioManagerThread audio_thread_;
|
| + media::FakeAudioLogFactory log_factory_;
|
| + media::ScopedAudioManagerPtr audio_manager_;
|
| + std::unique_ptr<AudioOutputServiceContext, BrowserThread::DeleteOnIOThread>
|
| + service_context_;
|
| +};
|
| +
|
| +void AuthCallback(base::OnceClosure sync_closure,
|
| + media::OutputDeviceStatus* status_out,
|
| + media::AudioParameters* params_out,
|
| + std::string* id_out,
|
| + media::OutputDeviceStatus status,
|
| + const media::AudioParameters& params,
|
| + const std::string& id) {
|
| + *status_out = status;
|
| + *params_out = params;
|
| + *id_out = id;
|
| + std::move(sync_closure).Run();
|
| +}
|
| +
|
| +TEST_F(AudioOutputServiceImplTest, AuthWithoutStreamRequest) {
|
| + AudioOutputServicePtr service_ptr;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&AudioOutputServiceImplTest::CreateAndBindService,
|
| + base::Unretained(this),
|
| + base::Passed(mojo::MakeRequest(&service_ptr))));
|
| + SyncWithAllThreads();
|
| +
|
| + base::RunLoop loop;
|
| + media::OutputDeviceStatus status;
|
| + media::AudioParameters params;
|
| + std::string id;
|
| + service_ptr->RequestDeviceAuthorization(
|
| + /*session_id*/ 0, "default", nullptr, url::Origin(GURL(kSecurityOrigin)),
|
| + base::Bind(&AuthCallback, base::Passed(loop.QuitWhenIdleClosure()),
|
| + base::Unretained(&status), base::Unretained(¶ms),
|
| + base::Unretained(&id)));
|
| + loop.Run();
|
| + EXPECT_EQ(status, media::OUTPUT_DEVICE_STATUS_OK);
|
| + EXPECT_TRUE(params.IsValid());
|
| + EXPECT_TRUE(id.empty());
|
| +}
|
| +
|
| +TEST_F(AudioOutputServiceImplTest, AuthWithStreamRequest) {
|
| + AudioOutputServicePtr service_ptr;
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + base::Bind(&AudioOutputServiceImplTest::CreateAndBindService,
|
| + base::Unretained(this),
|
| + base::Passed(mojo::MakeRequest(&service_ptr))));
|
| + SyncWithAllThreads();
|
| +
|
| + AudioOutputPtr output_ptr;
|
| +
|
| + base::RunLoop loop;
|
| + media::OutputDeviceStatus status;
|
| + media::AudioParameters params;
|
| + std::string id;
|
| + service_ptr->RequestDeviceAuthorization(
|
| + /*session_id*/ 0, "default", mojo::MakeRequest<AudioOutput>(&output_ptr),
|
| + url::Origin(GURL(kSecurityOrigin)),
|
| + base::Bind(&AuthCallback, base::Passed(loop.QuitWhenIdleClosure()),
|
| + base::Unretained(&status), base::Unretained(¶ms),
|
| + base::Unretained(&id)));
|
| + loop.Run();
|
| + EXPECT_EQ(status, media::OUTPUT_DEVICE_STATUS_OK);
|
| + EXPECT_TRUE(params.IsValid());
|
| + EXPECT_TRUE(id.empty());
|
| +
|
| + base::RunLoop loop2;
|
| +
|
| + output_ptr->Start(
|
| + params,
|
| + base::Bind([](base::Closure cl, mojo::ScopedSharedBufferHandle handle1,
|
| + mojo::ScopedHandle handle2) { cl.Run(); },
|
| + base::Passed(loop2.QuitWhenIdleClosure())));
|
| + loop2.Run();
|
| + output_ptr.reset();
|
| + SyncWithAllThreads();
|
| +}
|
| +
|
| +} // namespace content
|
|
|