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

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

Issue 2890753003: Introduce AudioIPCFactory. (Closed)
Patch Set: Dale's comments. Created 3 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
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/audio_ipc_factory.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/message_loop/message_loop.h"
12 #include "base/threading/thread.h"
13 #include "content/renderer/media/audio_message_filter.h"
14 #include "mojo/public/cpp/bindings/binding.h"
15 #include "mojo/public/cpp/bindings/interface_request.h"
16 #include "mojo/public/cpp/system/message_pipe.h"
17 #include "services/service_manager/public/cpp/interface_provider.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using ::testing::_;
22
23 namespace content {
24
25 namespace {
26
27 const int kRenderFrameId = 0;
28
29 std::unique_ptr<base::Thread> MakeIOThread() {
30 auto io_thread = base::MakeUnique<base::Thread>("test IO thread");
31 base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0);
32 CHECK(io_thread->StartWithOptions(thread_options));
33 return io_thread;
34 }
35
36 class FakeRemoteFactory : public mojom::RendererAudioOutputStreamFactory {
37 public:
38 FakeRemoteFactory() : binding_(this) {}
39 ~FakeRemoteFactory() override {}
40
41 void RequestDeviceAuthorization(
42 media::mojom::AudioOutputStreamProviderRequest stream_provider,
43 int64_t session_id,
44 const std::string& device_id,
45 RequestDeviceAuthorizationCallback callback) override {
46 std::move(callback).Run(
47 media::OutputDeviceStatus::OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED,
48 media::AudioParameters::UnavailableDeviceParams(), std::string());
49 EXPECT_FALSE(on_called_.is_null());
50 std::move(on_called_).Run();
51 }
52
53 void SetOnCalledCallback(base::OnceClosure on_called) {
54 on_called_ = std::move(on_called);
55 }
56
57 void Bind(mojo::ScopedMessagePipeHandle handle) {
58 EXPECT_FALSE(binding_.is_bound());
59 binding_.Bind(
60 mojo::InterfaceRequest<mojom::RendererAudioOutputStreamFactory>(
61 std::move(handle)));
62 }
63
64 private:
65 mojo::Binding<mojom::RendererAudioOutputStreamFactory> binding_;
66 base::OnceClosure on_called_;
67 };
68
69 class FakeAudioIPCDelegate : public media::AudioOutputIPCDelegate {
70 void OnError() override {}
71 void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
72 const media::AudioParameters& output_params,
73 const std::string& matched_device_id) override {}
74 void OnStreamCreated(base::SharedMemoryHandle handle,
75 base::SyncSocket::Handle socket_handle,
76 int length) override {}
77 void OnIPCClosed() override {}
78 };
79
80 } // namespace
81
82 class AudioIPCFactoryTest : public testing::Test {
83 public:
84 AudioIPCFactoryTest() {}
85 ~AudioIPCFactoryTest() override {}
86
87 void RequestAuthorizationOnIOThread(
88 std::unique_ptr<media::AudioOutputIPC> output_ipc) {
89 output_ipc->RequestDeviceAuthorization(&fake_delegate, 0, "",
90 url::Origin());
91
92 output_ipc->CloseStream();
93 }
94
95 private:
96 FakeAudioIPCDelegate fake_delegate;
97 };
98
99 TEST_F(AudioIPCFactoryTest, CallFactoryFromIOThread) {
100 // This test makes sure that AudioIPCFactory correctly binds the
101 // RendererAudioOutputStreamFactoryPtr to the IO thread.
102 base::MessageLoop message_loop;
103 base::RunLoop run_loop;
104 auto io_thread = MakeIOThread();
105
106 FakeRemoteFactory remote_factory;
107 remote_factory.SetOnCalledCallback(run_loop.QuitWhenIdleClosure());
108
109 service_manager::InterfaceProvider interface_provider;
110 service_manager::InterfaceProvider::TestApi(&interface_provider)
111 .SetBinderForName(mojom::RendererAudioOutputStreamFactory::Name_,
112 base::BindRepeating(&FakeRemoteFactory::Bind,
113 base::Unretained(&remote_factory)));
114
115 AudioIPCFactory ipc_factory(nullptr, io_thread->task_runner());
116
117 ipc_factory.MaybeRegisterRemoteFactory(kRenderFrameId, &interface_provider);
118
119 // To make sure that the pointer stored in |ipc_factory| is connected to
120 // |remote_factory|, and also that it's bound to |io_thread|, we create an
121 // AudioOutputIPC object and request device authorization on the IO thread.
122 // This is supposed to call |remote_factory| on the main thread.
123 io_thread->task_runner()->PostTask(
124 FROM_HERE,
125 base::BindOnce(&AudioIPCFactoryTest::RequestAuthorizationOnIOThread,
126 base::Unretained(this),
127 ipc_factory.CreateAudioOutputIPC(kRenderFrameId)));
128
129 // Wait for call to |remote_factory|:
130 run_loop.Run();
131
132 ipc_factory.MaybeDeregisterRemoteFactory(0);
133
134 io_thread.reset();
135 base::RunLoop().RunUntilIdle();
136 }
137
138 TEST_F(AudioIPCFactoryTest, SeveralFactories) {
139 // This test simulates having several frames being created and destructed.
140 base::MessageLoop message_loop;
141 auto io_thread = MakeIOThread();
142 const int n_factories = 5;
143
144 std::vector<service_manager::InterfaceProvider> interface_providers(
145 n_factories);
146
147 std::vector<FakeRemoteFactory> remote_factories(n_factories);
148
149 for (size_t i = 0; i < n_factories; i++) {
150 service_manager::InterfaceProvider::TestApi(&interface_providers[i])
151 .SetBinderForName(
152 mojom::RendererAudioOutputStreamFactory::Name_,
153 base::BindRepeating(&FakeRemoteFactory::Bind,
154 base::Unretained(&remote_factories[i])));
155 }
156
157 base::RunLoop().RunUntilIdle();
158
159 AudioIPCFactory ipc_factory(nullptr, io_thread->task_runner());
160
161 for (size_t i = 0; i < n_factories; i++) {
162 ipc_factory.MaybeRegisterRemoteFactory(kRenderFrameId + i,
163 &interface_providers[i]);
164 }
165
166 base::RunLoop run_loop;
167 remote_factories[0].SetOnCalledCallback(run_loop.QuitWhenIdleClosure());
168 io_thread->task_runner()->PostTask(
169 FROM_HERE,
170 base::BindOnce(&AudioIPCFactoryTest::RequestAuthorizationOnIOThread,
171 base::Unretained(this),
172 ipc_factory.CreateAudioOutputIPC(kRenderFrameId)));
173 run_loop.Run();
174
175 // Do some operation and make sure the internal state isn't messed up:
176 ipc_factory.MaybeDeregisterRemoteFactory(1);
177
178 base::RunLoop run_loop2;
179 remote_factories[2].SetOnCalledCallback(run_loop2.QuitWhenIdleClosure());
180 io_thread->task_runner()->PostTask(
181 FROM_HERE,
182 base::BindOnce(&AudioIPCFactoryTest::RequestAuthorizationOnIOThread,
183 base::Unretained(this),
184 ipc_factory.CreateAudioOutputIPC(kRenderFrameId + 2)));
185 run_loop2.Run();
186
187 for (size_t i = 0; i < n_factories; i++) {
188 if (i == 1)
189 continue;
190 ipc_factory.MaybeDeregisterRemoteFactory(i);
191 }
192
193 io_thread.reset();
194 base::RunLoop().RunUntilIdle();
195 }
196
197 TEST_F(AudioIPCFactoryTest, RegisterDeregisterBackToBack_Deregisters) {
198 // This test makes sure that calling Register... followed by Deregister...
199 // correctly sequences the registration before the deregistration.
200 base::MessageLoop message_loop;
201 auto io_thread = MakeIOThread();
202
203 FakeRemoteFactory remote_factory;
204
205 service_manager::InterfaceProvider interface_provider;
206 service_manager::InterfaceProvider::TestApi(&interface_provider)
207 .SetBinderForName(mojom::RendererAudioOutputStreamFactory::Name_,
208 base::BindRepeating(&FakeRemoteFactory::Bind,
209 base::Unretained(&remote_factory)));
210
211 AudioIPCFactory ipc_factory(nullptr, io_thread->task_runner());
212
213 ipc_factory.MaybeRegisterRemoteFactory(kRenderFrameId, &interface_provider);
214 ipc_factory.MaybeDeregisterRemoteFactory(kRenderFrameId);
215 // That there is no factory remaining at destruction is DCHECKed in the
216 // AudioIPCFactory destructor.
217
218 base::RunLoop().RunUntilIdle();
219 io_thread.reset();
220 base::RunLoop().RunUntilIdle();
221 }
222
223 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/audio_ipc_factory.cc ('k') | content/renderer/pepper/pepper_platform_audio_output.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698