OLD | NEW |
(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_service_impl.h" |
| 6 |
| 7 #include <utility> |
| 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" |
| 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/run_loop.h" |
| 13 #include "content/browser/audio_manager_thread.h" |
| 14 #include "content/browser/media/capture/audio_mirroring_manager.h" |
| 15 #include "content/browser/renderer_host/media/audio_output_service_context.h" |
| 16 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "content/public/browser/media_observer.h" |
| 19 #include "content/public/test/test_browser_thread_bundle.h" |
| 20 #include "media/audio/fake_audio_log_factory.h" |
| 21 #include "media/audio/fake_audio_manager.h" |
| 22 #include "media/base/media_switches.h" |
| 23 #include "media/mojo/interfaces/audio_output.mojom.h" |
| 24 #include "mojo/public/cpp/bindings/binding.h" |
| 25 #include "testing/gmock/include/gmock/gmock.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 |
| 28 namespace { |
| 29 int kRenderProcessId = 42; |
| 30 int kRenderFrameId = 24; |
| 31 const char kSecurityOrigin[] = "http://localhost"; |
| 32 const char kSalt[] = "salt"; |
| 33 } |
| 34 |
| 35 namespace content { |
| 36 |
| 37 class AudioOutputServiceImplTest : public testing::Test { |
| 38 public: |
| 39 using AudioOutputService = media::mojom::AudioOutputService; |
| 40 using AudioOutputServicePtr = mojo::InterfacePtr<AudioOutputService>; |
| 41 using AudioOutputServiceRequest = mojo::InterfaceRequest<AudioOutputService>; |
| 42 using AudioOutput = media::mojom::AudioOutput; |
| 43 using AudioOutputPtr = mojo::InterfacePtr<AudioOutput>; |
| 44 using AudioOutputRequest = mojo::InterfaceRequest<AudioOutput>; |
| 45 |
| 46 AudioOutputServiceImplTest() |
| 47 : media_stream_manager_(), |
| 48 thread_bundle_(TestBrowserThreadBundle::Options::REAL_IO_THREAD), |
| 49 audio_thread_(), |
| 50 log_factory_(), |
| 51 audio_manager_( |
| 52 new media::FakeAudioManager(audio_thread_.task_runner(), |
| 53 audio_thread_.worker_task_runner(), |
| 54 &log_factory_)) { |
| 55 media_stream_manager_ = |
| 56 base::MakeUnique<MediaStreamManager>(audio_manager_.get()); |
| 57 } |
| 58 |
| 59 ~AudioOutputServiceImplTest() override { SyncWithAllThreads(); } |
| 60 |
| 61 void SyncWithAllThreads() { |
| 62 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 63 // New tasks might be posted while we are syncing, but in every iteration at |
| 64 // least one task will be run. 20 iterations should be enough for our code. |
| 65 for (int i = 0; i < 20; ++i) { |
| 66 { |
| 67 base::MessageLoop::ScopedNestableTaskAllower allower( |
| 68 base::MessageLoop::current()); |
| 69 base::RunLoop().RunUntilIdle(); |
| 70 } |
| 71 SyncWith(BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); |
| 72 SyncWith(audio_manager_->GetWorkerTaskRunner()); |
| 73 } |
| 74 } |
| 75 |
| 76 void SyncWith(scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 77 CHECK(task_runner); |
| 78 CHECK(!task_runner->BelongsToCurrentThread()); |
| 79 base::WaitableEvent e = {base::WaitableEvent::ResetPolicy::MANUAL, |
| 80 base::WaitableEvent::InitialState::NOT_SIGNALED}; |
| 81 task_runner->PostTask(FROM_HERE, base::Bind(&base::WaitableEvent::Signal, |
| 82 base::Unretained(&e))); |
| 83 e.Wait(); |
| 84 } |
| 85 |
| 86 void CreateAndBindService(AudioOutputServiceRequest request) { |
| 87 service_context_.reset(new AudioOutputServiceContext( |
| 88 kRenderProcessId, audio_manager_.get(), media_stream_manager_.get(), |
| 89 AudioMirroringManager::GetInstance(), kSalt)); |
| 90 service_context_->CreateService(kRenderFrameId, std::move(request)); |
| 91 } |
| 92 |
| 93 std::unique_ptr<MediaStreamManager> media_stream_manager_; |
| 94 TestBrowserThreadBundle thread_bundle_; |
| 95 AudioManagerThread audio_thread_; |
| 96 media::FakeAudioLogFactory log_factory_; |
| 97 media::ScopedAudioManagerPtr audio_manager_; |
| 98 std::unique_ptr<AudioOutputServiceContext, BrowserThread::DeleteOnIOThread> |
| 99 service_context_; |
| 100 }; |
| 101 |
| 102 void AuthCallback(base::OnceClosure sync_closure, |
| 103 media::OutputDeviceStatus* status_out, |
| 104 media::AudioParameters* params_out, |
| 105 std::string* id_out, |
| 106 media::OutputDeviceStatus status, |
| 107 const media::AudioParameters& params, |
| 108 const std::string& id) { |
| 109 *status_out = status; |
| 110 *params_out = params; |
| 111 *id_out = id; |
| 112 std::move(sync_closure).Run(); |
| 113 } |
| 114 |
| 115 TEST_F(AudioOutputServiceImplTest, AuthWithoutStreamRequest) { |
| 116 AudioOutputServicePtr service_ptr; |
| 117 BrowserThread::PostTask( |
| 118 BrowserThread::IO, FROM_HERE, |
| 119 base::Bind(&AudioOutputServiceImplTest::CreateAndBindService, |
| 120 base::Unretained(this), |
| 121 base::Passed(mojo::MakeRequest(&service_ptr)))); |
| 122 SyncWithAllThreads(); |
| 123 |
| 124 base::RunLoop loop; |
| 125 media::OutputDeviceStatus status; |
| 126 media::AudioParameters params; |
| 127 std::string id; |
| 128 service_ptr->RequestDeviceAuthorization( |
| 129 /*session_id*/ 0, "default", nullptr, url::Origin(GURL(kSecurityOrigin)), |
| 130 base::Bind(&AuthCallback, base::Passed(loop.QuitWhenIdleClosure()), |
| 131 base::Unretained(&status), base::Unretained(¶ms), |
| 132 base::Unretained(&id))); |
| 133 loop.Run(); |
| 134 EXPECT_EQ(status, media::OUTPUT_DEVICE_STATUS_OK); |
| 135 EXPECT_TRUE(params.IsValid()); |
| 136 EXPECT_TRUE(id.empty()); |
| 137 } |
| 138 |
| 139 TEST_F(AudioOutputServiceImplTest, AuthWithStreamRequest) { |
| 140 AudioOutputServicePtr service_ptr; |
| 141 BrowserThread::PostTask( |
| 142 BrowserThread::IO, FROM_HERE, |
| 143 base::Bind(&AudioOutputServiceImplTest::CreateAndBindService, |
| 144 base::Unretained(this), |
| 145 base::Passed(mojo::MakeRequest(&service_ptr)))); |
| 146 SyncWithAllThreads(); |
| 147 |
| 148 AudioOutputPtr output_ptr; |
| 149 |
| 150 base::RunLoop loop; |
| 151 media::OutputDeviceStatus status; |
| 152 media::AudioParameters params; |
| 153 std::string id; |
| 154 service_ptr->RequestDeviceAuthorization( |
| 155 /*session_id*/ 0, "default", mojo::MakeRequest<AudioOutput>(&output_ptr), |
| 156 url::Origin(GURL(kSecurityOrigin)), |
| 157 base::Bind(&AuthCallback, base::Passed(loop.QuitWhenIdleClosure()), |
| 158 base::Unretained(&status), base::Unretained(¶ms), |
| 159 base::Unretained(&id))); |
| 160 loop.Run(); |
| 161 EXPECT_EQ(status, media::OUTPUT_DEVICE_STATUS_OK); |
| 162 EXPECT_TRUE(params.IsValid()); |
| 163 EXPECT_TRUE(id.empty()); |
| 164 |
| 165 base::RunLoop loop2; |
| 166 |
| 167 output_ptr->Start( |
| 168 params, |
| 169 base::Bind([](base::Closure cl, mojo::ScopedSharedBufferHandle handle1, |
| 170 mojo::ScopedHandle handle2) { cl.Run(); }, |
| 171 base::Passed(loop2.QuitWhenIdleClosure()))); |
| 172 loop2.Run(); |
| 173 output_ptr.reset(); |
| 174 SyncWithAllThreads(); |
| 175 } |
| 176 |
| 177 } // namespace content |
OLD | NEW |