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

Side by Side Diff: media/audio/audio_input_device_unittest.cc

Issue 510913005: Add native log and uma stat when all input shared memory buffers are full (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added unittest and addressed comments. Created 6 years, 3 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
« no previous file with comments | « media/audio/audio_input_device.cc ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "base/memory/shared_memory.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/process/process_handle.h"
8 #include "base/sync_socket.h"
9 #include "base/test/test_timeouts.h"
10 #include "media/audio/audio_device_thread.h"
11 #include "media/audio/audio_input_device.h"
12 #include "media/audio/audio_input_ipc.h"
13 #include "media/base/audio_capturer_source.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 using base::CancelableSyncSocket;
18 using base::SharedMemory;
19 using base::SyncSocket;
20 using testing::_;
21 using testing::StrictMock;
22
23 namespace media {
24
25 namespace {
26
27 // The number of shared memory buffers used by AudioInputDevice.
28 static const int kNumOfSharedMemoriesInAID = 10;
29
30 int CalculateMemorySize(const AudioParameters& params) {
31 return sizeof(AudioInputBufferParameters) +
32 AudioBus::CalculateMemorySize(params);
33 }
34
35 // Creates a copy of a SyncSocket handle that we can give to AudioInputDevice.
36 // On Windows this means duplicating the pipe handle so that AudioInputDevice
37 // can call CloseHandle() (since ownership has been transferred), but on other
38 // platforms, we just copy the same socket handle since AudioInputDevice on
39 // those platforms won't actually own the socket (FileDescriptor.auto_close is
40 // false).
41 bool DuplicateSocketHandle(SyncSocket::Handle socket_handle,
42 SyncSocket::Handle* copy) {
43 #if defined(OS_WIN)
44 HANDLE process = GetCurrentProcess();
45 ::DuplicateHandle(process, socket_handle, process, copy,
46 0, FALSE, DUPLICATE_SAME_ACCESS);
47 return *copy != NULL;
48 #else
49 *copy = socket_handle;
50 return *copy != -1;
51 #endif
52 }
53
54 class MockCaptureCallback : public AudioCapturerSource::CaptureCallback {
55 public:
56 MockCaptureCallback() {}
57 virtual ~MockCaptureCallback() {}
58
59 MOCK_METHOD4(Capture, void(const AudioBus* audio_source,
60 int audio_delay_milliseconds,
61 double volume,
62 bool key_pressed));
63 MOCK_METHOD0(OnCaptureError, void());
64 };
65
66 class MockAudioInputIPC : public AudioInputIPC {
67 public:
68 MockAudioInputIPC() {}
69 virtual ~MockAudioInputIPC() {}
70
71 MOCK_METHOD5(CreateStream, void(AudioInputIPCDelegate* delegate,
72 int session_id,
73 const AudioParameters& params,
74 bool automatic_gain_control,
75 uint32 total_segments));
76 MOCK_METHOD0(RecordStream, void());
77 MOCK_METHOD1(SetVolume, void(double volume));
78 MOCK_METHOD0(CloseStream, void());
79 };
80
81 // Used to terminate a loop from a different thread than the loop belongs to.
82 // |loop| should be a SingleThreadTaskRunner.
83 ACTION_P(QuitLoop, task_runner) {
84 task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
85 }
86
87 } // namespace.
88
89 class AudioInputDeviceTest : public testing::Test {
90 protected:
91 AudioInputDeviceTest()
92 : audio_parameters_(AudioParameters::AUDIO_PCM_LOW_LATENCY,
93 CHANNEL_LAYOUT_STEREO,
94 44100,
95 16,
96 441),
tommi (sloooow) - chröme 2014/09/02 12:03:34 Did you get a chance to run tests with very small
97 io_loop_(new base::MessageLoopForIO),
98 mock_ipc_(new MockAudioInputIPC()),
99 audio_input_device_(
100 new AudioInputDevice(scoped_ptr<AudioInputIPC>(mock_ipc_),
101 io_loop_->message_loop_proxy())) {
102 audio_input_device_->Initialize(audio_parameters_, &callback_, 1);
103 io_loop_->RunUntilIdle();
104 }
105
106 virtual ~AudioInputDeviceTest() {}
107
108 void StartAudioInputDevice() {
109 audio_input_device_->Start();
110 EXPECT_CALL(
111 *mock_ipc_,
112 CreateStream(
113 audio_input_device_.get(), 1, _, false, kNumOfSharedMemoriesInAID));
114 io_loop_->RunUntilIdle();
115 }
116
117 void CreateInputStream() {
118 const int kMemorySize =
119 CalculateMemorySize(audio_parameters_) * kNumOfSharedMemoriesInAID;
120
121 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
122 memset(shared_memory_.memory(), 0xff, kMemorySize);
123
124 ASSERT_TRUE(
125 CancelableSyncSocket::CreatePair(&browser_socket_, &renderer_socket_));
126
127 SyncSocket::Handle socket = SyncSocket::kInvalidHandle;
128 ASSERT_TRUE(DuplicateSocketHandle(renderer_socket_.handle(),
129 &socket));
130 base::SharedMemoryHandle duplicated_memory_handle;
131 ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(),
132 &duplicated_memory_handle));
133
134 EXPECT_CALL(*mock_ipc_, RecordStream());
135 audio_input_device_->OnStreamCreated(duplicated_memory_handle,
136 socket,
137 shared_memory_.requested_size(),
138 kNumOfSharedMemoriesInAID);
139 io_loop_->RunUntilIdle();
140 }
141
142 void WriteToSharedMemory() {
143 const size_t kSegmentSize = CalculateMemorySize(audio_parameters_);
144 uint8* ptr = static_cast<uint8*>(shared_memory_.memory());
145 for (int i = 0; i < kNumOfSharedMemoriesInAID; ++i) {
146 AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr);
147 buffer->params.volume = 0;
148 buffer->params.size = kSegmentSize;
149 buffer->params.key_pressed = false;
150 ptr += kSegmentSize;
151 }
152 }
153
154 void ConsumeAndVerifySharedMemory() {
155 const size_t kSegmentSize = CalculateMemorySize(audio_parameters_);
156 uint8* ptr = static_cast<uint8*>(shared_memory_.memory());
157 EXPECT_CALL(callback_, Capture(_, _, _, _))
158 .WillRepeatedly(QuitLoop(io_loop_->task_runner()));
159 for (int i = 0; i < kNumOfSharedMemoriesInAID; ++i) {
160 AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr);
161 EXPECT_EQ(kSegmentSize, buffer->params.size);
162
163 // Send a socket from the browser to trigger processing the shared memory
164 // in AudioInputDevice.
165 int pending_bytes = 0;
166 browser_socket_.Send(&pending_bytes, sizeof(pending_bytes));
167 WaitForCaptureCallback();
168
169 // Verify the |size| of the buffer has been reset to 0;
170 EXPECT_EQ(0u, buffer->params.size);
171
172 // Iterate the next segment of shared memory.
173 ptr += kSegmentSize;
174 }
175 }
176
177 void StopAudioInputDevice() {
178 audio_input_device_->Stop();
179 EXPECT_CALL(*mock_ipc_, CloseStream());
180 io_loop_->RunUntilIdle();
181 }
182
183 void WaitForCaptureCallback() {
184 io_loop_->PostDelayedTask(FROM_HERE,
185 base::MessageLoop::QuitClosure(),
186 TestTimeouts::action_timeout());
187 io_loop_->Run();
188 }
189
190 protected:
191 AudioParameters audio_parameters_;
192 scoped_ptr<base::MessageLoopForIO> io_loop_;
193 MockAudioInputIPC* mock_ipc_; // owned by |audio_input_device_|.
194 scoped_refptr<AudioInputDevice> audio_input_device_;
195 StrictMock<MockCaptureCallback> callback_;
196
197 private:
198 SharedMemory shared_memory_;
199 CancelableSyncSocket browser_socket_;
200 CancelableSyncSocket renderer_socket_;
201
202 DISALLOW_COPY_AND_ASSIGN(AudioInputDeviceTest);
203 };
204
205 // Sets up shared memory and AudioInputDevice, and verify the shared memory
206 // is correctly written and consumed.
207 TEST_F(AudioInputDeviceTest, VerifySharedMemory) {
208 StartAudioInputDevice();
209 CreateInputStream();
210 WriteToSharedMemory();
211 ConsumeAndVerifySharedMemory();
212 StopAudioInputDevice();
213 }
214
215 } // namespace media.
OLDNEW
« no previous file with comments | « media/audio/audio_input_device.cc ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698