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

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

Issue 8477037: Simplify AudioRendererImpl by using AudioDevice. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/bind.h" 5 #include "base/bind.h"
6 #include "base/message_loop.h" 6 #include "base/message_loop.h"
7 #include "base/process_util.h" 7 #include "base/process_util.h"
8 #include "base/synchronization/waitable_event.h" 8 #include "base/synchronization/waitable_event.h"
9 #include "base/test/test_timeouts.h" 9 #include "base/test/test_timeouts.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "content/common/child_process.h" 11 #include "content/common/child_process.h"
12 #include "content/common/child_thread.h" 12 #include "content/common/child_thread.h"
13 #include "content/common/media/audio_messages.h"
14 #include "content/renderer/media/audio_renderer_impl.h" 13 #include "content/renderer/media/audio_renderer_impl.h"
15 #include "content/renderer/mock_content_renderer_client.h" 14 #include "content/renderer/mock_content_renderer_client.h"
16 #include "content/renderer/render_process.h" 15 #include "content/renderer/render_process.h"
17 #include "content/renderer/render_thread_impl.h" 16 #include "content/renderer/render_thread_impl.h"
18 #include "ipc/ipc_channel.h" 17 #include "ipc/ipc_channel.h"
19 #include "media/base/data_buffer.h" 18 #include "media/base/data_buffer.h"
20 #include "media/base/mock_callback.h" 19 #include "media/base/mock_callback.h"
21 #include "media/base/mock_filter_host.h" 20 #include "media/base/mock_filter_host.h"
22 #include "media/base/mock_filters.h" 21 #include "media/base/mock_filters.h"
23 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
(...skipping 15 matching lines...) Expand all
39 virtual bool UseInProcessPlugins() const { return false; } 38 virtual bool UseInProcessPlugins() const { return false; }
40 virtual bool HasInitializedMediaLibrary() const { return false; } 39 virtual bool HasInitializedMediaLibrary() const { return false; }
41 40
42 private: 41 private:
43 DISALLOW_COPY_AND_ASSIGN(MockRenderProcess); 42 DISALLOW_COPY_AND_ASSIGN(MockRenderProcess);
44 }; 43 };
45 } 44 }
46 45
47 // This class defines a set of methods which will be used in combination 46 // This class defines a set of methods which will be used in combination
48 // with NewRunnableMethod to form tasks which will be posted on the 47 // with NewRunnableMethod to form tasks which will be posted on the
49 // IO thread. All methods emulate AudioMessageFilter::Delegate calls. 48 // IO thread. This emulates MessageLoop::DestructionObserver.
50 class DelegateCaller : public base::RefCountedThreadSafe<DelegateCaller> { 49 class DelegateCaller : public base::RefCountedThreadSafe<DelegateCaller> {
51 public: 50 public:
52 explicit DelegateCaller(AudioRendererImpl* renderer) 51 explicit DelegateCaller(AudioRendererImpl* renderer)
53 : renderer_(renderer) {} 52 : renderer_(renderer) {}
54 53
55 void OnCreated(base::SharedMemoryHandle handle, uint32 length) { 54 void DestroyCurrentMessageLoop() {}
56 if (renderer_->latency_type() == AudioRendererImpl::kHighLatency) {
57 renderer_->OnCreated(handle, length);
58 } else {
59 renderer_->OnLowLatencyCreated(handle, 0, length);
60 }
61 }
62 void OnStateChanged(AudioStreamState state) {
63 renderer_->OnStateChanged(state);
64 }
65 void OnRequestPacket(AudioBuffersState buffers_state) {
66 renderer_->OnRequestPacket(buffers_state);
67 }
68 void OnVolume(double volume) {
69 renderer_->OnVolume(volume);
70 }
71 void DestroyCurrentMessageLoop() {
72 renderer_->WillDestroyCurrentMessageLoop();
73 }
74 private: 55 private:
75 friend class base::RefCountedThreadSafe<DelegateCaller>; 56 friend class base::RefCountedThreadSafe<DelegateCaller>;
76 virtual ~DelegateCaller() {} 57 virtual ~DelegateCaller() {}
77 58
78 scoped_refptr<AudioRendererImpl> renderer_; 59 scoped_refptr<AudioRendererImpl> renderer_;
79 DISALLOW_COPY_AND_ASSIGN(DelegateCaller); 60 DISALLOW_COPY_AND_ASSIGN(DelegateCaller);
80 }; 61 };
81 62
82 // This task can be posted on the IO thread and will signal an event when 63 // This task can be posted on the IO thread and will signal an event when
83 // done. The caller can then wait for this signal to ensure that no 64 // done. The caller can then wait for this signal to ensure that no
84 // additional tasks remain in the task queue. 65 // additional tasks remain in the task queue.
85 class WaitTask : public Task { 66 class WaitTask : public Task {
86 public: 67 public:
87 explicit WaitTask(base::WaitableEvent* event) 68 explicit WaitTask(base::WaitableEvent* event)
88 : event_(event) {} 69 : event_(event) {}
89 virtual ~WaitTask() {} 70 virtual ~WaitTask() {}
90 virtual void Run() { 71 virtual void Run() {
91 event_->Signal(); 72 event_->Signal();
92 } 73 }
93 74
94 private: 75 private:
95 base::WaitableEvent* event_; 76 base::WaitableEvent* event_;
96 DISALLOW_COPY_AND_ASSIGN(WaitTask); 77 DISALLOW_COPY_AND_ASSIGN(WaitTask);
97 }; 78 };
98 79
99 // Class we would be testing. The only difference between it and "real" one 80 // Class we would be testing.
100 // is that test class does not open sockets and launch audio thread.
101 class TestAudioRendererImpl : public AudioRendererImpl { 81 class TestAudioRendererImpl : public AudioRendererImpl {
102 public: 82 public:
103 explicit TestAudioRendererImpl() 83 explicit TestAudioRendererImpl()
104 : AudioRendererImpl() { 84 : AudioRendererImpl() {
105 } 85 }
106 private:
107 virtual void CreateSocket(base::SyncSocket::Handle socket_handle) {}
108 virtual void CreateAudioThread() {}
109 }; 86 };
110 87
111 class AudioRendererImplTest 88 class AudioRendererImplTest
112 : public ::testing::Test, 89 : public ::testing::Test,
113 public IPC::Channel::Listener { 90 public IPC::Channel::Listener {
114 public: 91 public:
115 static void SetUpTestCase() { 92 static void SetUpTestCase() {}
116 // Set low latency mode, as it soon would be on by default.
117 if (AudioRendererImpl::latency_type() ==
118 AudioRendererImpl::kUninitializedLatency) {
119 AudioRendererImpl::set_latency_type(AudioRendererImpl::kLowLatency);
120 }
121 DCHECK_EQ(AudioRendererImpl::kLowLatency,
122 AudioRendererImpl::latency_type());
123 }
124 93
125 // IPC::Channel::Listener implementation. 94 // IPC::Channel::Listener implementation.
126 virtual bool OnMessageReceived(const IPC::Message& message) { 95 virtual bool OnMessageReceived(const IPC::Message& message) {
127 NOTIMPLEMENTED(); 96 NOTIMPLEMENTED();
128 return true; 97 return true;
129 } 98 }
130 99
131 static const int kSize; 100 static const int kSize;
132 101
133 AudioRendererImplTest() {} 102 AudioRendererImplTest() {}
134 virtual ~AudioRendererImplTest() {} 103 virtual ~AudioRendererImplTest() {}
135 104
136 virtual void SetUp() { 105 virtual void SetUp() {
137 // This part sets up a RenderThread environment to ensure that 106 // This part sets up a RenderThread environment to ensure that
138 // RenderThread::current() (<=> TLS pointer) is valid. 107 // RenderThread::current() (<=> TLS pointer) is valid.
139 // Main parts are inspired by the RenderViewFakeResourcesTest. 108 // Main parts are inspired by the RenderViewFakeResourcesTest.
140 // Note that, the IPC part is not utilized in this test. 109 // Note that, the IPC part is not utilized in this test.
141 content::GetContentClient()->set_renderer(&mock_content_renderer_client_); 110 content::GetContentClient()->set_renderer(&mock_content_renderer_client_);
142 111
143 static const char kThreadName[] = "RenderThread"; 112 static const char kThreadName[] = "RenderThread";
144 channel_.reset(new IPC::Channel(kThreadName, 113 channel_.reset(new IPC::Channel(kThreadName,
145 IPC::Channel::MODE_SERVER, this)); 114 IPC::Channel::MODE_SERVER, this));
146 ASSERT_TRUE(channel_->Connect()); 115 ASSERT_TRUE(channel_->Connect());
147 116
148 mock_process_.reset(new MockRenderProcess); 117 mock_process_.reset(new MockRenderProcess);
149 render_thread_ = new RenderThreadImpl(kThreadName); 118 render_thread_ = new RenderThreadImpl(kThreadName);
150 mock_process_->set_main_thread(render_thread_); 119 mock_process_->set_main_thread(render_thread_);
151 120
152 // Create temporary shared memory.
153 CHECK(shared_mem_.CreateAnonymous(kSize));
154
155 // Setup expectations for initialization. 121 // Setup expectations for initialization.
156 decoder_ = new media::MockAudioDecoder(); 122 decoder_ = new media::MockAudioDecoder();
157 123
158 EXPECT_CALL(*decoder_, bits_per_channel()) 124 EXPECT_CALL(*decoder_, bits_per_channel())
159 .WillRepeatedly(Return(16)); 125 .WillRepeatedly(Return(16));
160 EXPECT_CALL(*decoder_, channel_layout()) 126 EXPECT_CALL(*decoder_, channel_layout())
161 .WillRepeatedly(Return(CHANNEL_LAYOUT_MONO)); 127 .WillRepeatedly(Return(CHANNEL_LAYOUT_MONO));
162 EXPECT_CALL(*decoder_, samples_per_second()) 128 EXPECT_CALL(*decoder_, samples_per_second())
163 .WillRepeatedly(Return(44100)); 129 .WillRepeatedly(Return(44100));
164 130
165 // Create and initialize the audio renderer. 131 // Create and initialize the audio renderer.
166 renderer_ = new TestAudioRendererImpl(); 132 renderer_ = new TestAudioRendererImpl();
167 renderer_->set_host(&host_);
168 renderer_->Initialize(decoder_, media::NewExpectedClosure(), 133 renderer_->Initialize(decoder_, media::NewExpectedClosure(),
169 NewUnderflowClosure()); 134 NewUnderflowClosure());
170 135
171 // Wraps delegate calls into tasks. 136 // Wraps delegate calls into tasks.
172 delegate_caller_ = new DelegateCaller(renderer_); 137 delegate_caller_ = new DelegateCaller(renderer_);
173 138
174 // We need an event to verify that all tasks are done before leaving 139 // We need an event to verify that all tasks are done before leaving
175 // our tests. 140 // our tests.
176 event_.reset(new base::WaitableEvent(false, false)); 141 event_.reset(new base::WaitableEvent(false, false));
177
178 // Duplicate the shared memory handle so both the test and the callee can
179 // close their copy.
180 base::SharedMemoryHandle duplicated_handle;
181 EXPECT_TRUE(shared_mem_.ShareToProcess(base::GetCurrentProcessHandle(),
182 &duplicated_handle));
183
184 // Set things up and ensure that the call comes from the IO thread
185 // as all AudioMessageFilter::Delegate methods.
186 ChildProcess::current()->io_message_loop()->PostTask(
187 FROM_HERE,
188 base::Bind(&DelegateCaller::OnCreated, delegate_caller_.get(),
189 duplicated_handle, kSize));
190 WaitForIOThreadCompletion();
191 } 142 }
192 143
193 virtual void TearDown() { 144 virtual void TearDown() {
194 mock_process_.reset(); 145 mock_process_.reset();
195 } 146 }
196 147
197 MOCK_METHOD0(OnUnderflow, void()); 148 MOCK_METHOD0(OnUnderflow, void());
198 149
199 base::Closure NewUnderflowClosure() { 150 base::Closure NewUnderflowClosure() {
200 return base::Bind(&AudioRendererImplTest::OnUnderflow, 151 return base::Bind(&AudioRendererImplTest::OnUnderflow,
201 base::Unretained(this)); 152 base::Unretained(this));
202 } 153 }
203 154
204 protected: 155 protected:
205 // Posts a final task to the IO message loop and waits for completion. 156 // Posts a final task to the IO message loop and waits for completion.
206 void WaitForIOThreadCompletion() { 157 void WaitForIOThreadCompletion() {
207 ChildProcess::current()->io_message_loop()->PostTask( 158 ChildProcess::current()->io_message_loop()->PostTask(
208 FROM_HERE, new WaitTask(event_.get())); 159 FROM_HERE, new WaitTask(event_.get()));
209 EXPECT_TRUE(event_->TimedWait( 160 EXPECT_TRUE(event_->TimedWait(
210 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms()))); 161 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
211 } 162 }
212 163
213 MessageLoopForIO message_loop_; 164 MessageLoopForIO message_loop_;
214 content::MockContentRendererClient mock_content_renderer_client_; 165 content::MockContentRendererClient mock_content_renderer_client_;
215 scoped_ptr<IPC::Channel> channel_; 166 scoped_ptr<IPC::Channel> channel_;
216 RenderThreadImpl* render_thread_; // owned by mock_process_ 167 RenderThreadImpl* render_thread_; // owned by mock_process_
217 scoped_ptr<MockRenderProcess> mock_process_; 168 scoped_ptr<MockRenderProcess> mock_process_;
218 base::SharedMemory shared_mem_;
219 media::MockFilterHost host_;
220 scoped_refptr<media::MockAudioDecoder> decoder_; 169 scoped_refptr<media::MockAudioDecoder> decoder_;
221 scoped_refptr<AudioRendererImpl> renderer_; 170 scoped_refptr<AudioRendererImpl> renderer_;
222 scoped_ptr<base::WaitableEvent> event_; 171 scoped_ptr<base::WaitableEvent> event_;
223 scoped_refptr<DelegateCaller> delegate_caller_; 172 scoped_refptr<DelegateCaller> delegate_caller_;
224 173
225 private: 174 private:
226 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest); 175 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
227 }; 176 };
228 177
229 const int AudioRendererImplTest::kSize = 1024; 178 const int AudioRendererImplTest::kSize = 1024;
(...skipping 19 matching lines...) Expand all
249 198
250 renderer_->Stop(media::NewExpectedClosure()); 199 renderer_->Stop(media::NewExpectedClosure());
251 WaitForIOThreadCompletion(); 200 WaitForIOThreadCompletion();
252 } 201 }
253 202
254 TEST_F(AudioRendererImplTest, Stop) { 203 TEST_F(AudioRendererImplTest, Stop) {
255 // Execute Stop() codepath. 204 // Execute Stop() codepath.
256 // Tasks will be posted internally on the IO thread. 205 // Tasks will be posted internally on the IO thread.
257 renderer_->Stop(media::NewExpectedClosure()); 206 renderer_->Stop(media::NewExpectedClosure());
258 207
259 // Run AudioMessageFilter::Delegate methods, which can be executed after being
260 // stopped. AudioRendererImpl shouldn't create any messages in this state.
261 // All delegate method calls are posted on the IO thread since it is
262 // a requirement.
263 if (renderer_->latency_type() == AudioRendererImpl::kHighLatency) {
264 ChildProcess::current()->io_message_loop()->PostTask(
265 FROM_HERE,
266 base::Bind(&DelegateCaller::OnRequestPacket,
267 delegate_caller_.get(), AudioBuffersState(kSize, 0)));
268 }
269 ChildProcess::current()->io_message_loop()->PostTask(
270 FROM_HERE,
271 base::Bind(&DelegateCaller::OnStateChanged,
272 delegate_caller_.get(), kAudioStreamError));
273 ChildProcess::current()->io_message_loop()->PostTask(
274 FROM_HERE,
275 base::Bind(&DelegateCaller::OnStateChanged,
276 delegate_caller_.get(), kAudioStreamPlaying));
277 ChildProcess::current()->io_message_loop()->PostTask(
278 FROM_HERE,
279 base::Bind(&DelegateCaller::OnStateChanged,
280 delegate_caller_.get(), kAudioStreamPaused));
281 ChildProcess::current()->io_message_loop()->PostTask(
282 FROM_HERE,
283 base::Bind(&DelegateCaller::OnCreated,
284 delegate_caller_.get(), shared_mem_.handle(), kSize));
285 ChildProcess::current()->io_message_loop()->PostTask(
286 FROM_HERE,
287 base::Bind(&DelegateCaller::OnVolume,
288 delegate_caller_.get(), 0.5));
289
290 WaitForIOThreadCompletion(); 208 WaitForIOThreadCompletion();
291 209
292 // It's possible that the upstream decoder replies right after being stopped. 210 // It's possible that the upstream decoder replies right after being stopped.
293 scoped_refptr<media::Buffer> buffer(new media::DataBuffer(kSize)); 211 scoped_refptr<media::Buffer> buffer(new media::DataBuffer(kSize));
294 renderer_->ConsumeAudioSamples(buffer); 212 renderer_->ConsumeAudioSamples(buffer);
295 } 213 }
296 214
297 TEST_F(AudioRendererImplTest, DestroyedMessageLoop_SetPlaybackRate) { 215 TEST_F(AudioRendererImplTest, DestroyedMessageLoop_SetPlaybackRate) {
298 // Emulate "killing the message loop" and verify that SetPlaybackRate() 216 // Emulate "killing the message loop" and verify that SetPlaybackRate()
299 // still works. 217 // still works.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 base::Time time_now = base::Time(); // Null time by default. 266 base::Time time_now = base::Time(); // Null time by default.
349 renderer_->set_earliest_end_time(time_now); 267 renderer_->set_earliest_end_time(time_now);
350 renderer_->UpdateEarliestEndTime(renderer_->bytes_per_second(), 268 renderer_->UpdateEarliestEndTime(renderer_->bytes_per_second(),
351 base::TimeDelta::FromMilliseconds(100), 269 base::TimeDelta::FromMilliseconds(100),
352 time_now); 270 time_now);
353 int time_delta = (renderer_->earliest_end_time() - time_now).InMilliseconds(); 271 int time_delta = (renderer_->earliest_end_time() - time_now).InMilliseconds();
354 EXPECT_EQ(1100, time_delta); 272 EXPECT_EQ(1100, time_delta);
355 renderer_->Stop(media::NewExpectedClosure()); 273 renderer_->Stop(media::NewExpectedClosure());
356 WaitForIOThreadCompletion(); 274 WaitForIOThreadCompletion();
357 } 275 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698