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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/audio/audio_input_device.cc ('k') | media/media.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/audio_input_device_unittest.cc
diff --git a/media/audio/audio_input_device_unittest.cc b/media/audio/audio_input_device_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bebc1a18c742e1324442e800cd2c1ca530c0aaf0
--- /dev/null
+++ b/media/audio/audio_input_device_unittest.cc
@@ -0,0 +1,215 @@
+// Copyright 2014 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 "base/memory/shared_memory.h"
+#include "base/message_loop/message_loop.h"
+#include "base/process/process_handle.h"
+#include "base/sync_socket.h"
+#include "base/test/test_timeouts.h"
+#include "media/audio/audio_device_thread.h"
+#include "media/audio/audio_input_device.h"
+#include "media/audio/audio_input_ipc.h"
+#include "media/base/audio_capturer_source.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::CancelableSyncSocket;
+using base::SharedMemory;
+using base::SyncSocket;
+using testing::_;
+using testing::StrictMock;
+
+namespace media {
+
+namespace {
+
+// The number of shared memory buffers used by AudioInputDevice.
+static const int kNumOfSharedMemoriesInAID = 10;
+
+int CalculateMemorySize(const AudioParameters& params) {
+ return sizeof(AudioInputBufferParameters) +
+ AudioBus::CalculateMemorySize(params);
+}
+
+// Creates a copy of a SyncSocket handle that we can give to AudioInputDevice.
+// On Windows this means duplicating the pipe handle so that AudioInputDevice
+// can call CloseHandle() (since ownership has been transferred), but on other
+// platforms, we just copy the same socket handle since AudioInputDevice on
+// those platforms won't actually own the socket (FileDescriptor.auto_close is
+// false).
+bool DuplicateSocketHandle(SyncSocket::Handle socket_handle,
+ SyncSocket::Handle* copy) {
+#if defined(OS_WIN)
+ HANDLE process = GetCurrentProcess();
+ ::DuplicateHandle(process, socket_handle, process, copy,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ return *copy != NULL;
+#else
+ *copy = socket_handle;
+ return *copy != -1;
+#endif
+}
+
+class MockCaptureCallback : public AudioCapturerSource::CaptureCallback {
+ public:
+ MockCaptureCallback() {}
+ virtual ~MockCaptureCallback() {}
+
+ MOCK_METHOD4(Capture, void(const AudioBus* audio_source,
+ int audio_delay_milliseconds,
+ double volume,
+ bool key_pressed));
+ MOCK_METHOD0(OnCaptureError, void());
+};
+
+class MockAudioInputIPC : public AudioInputIPC {
+ public:
+ MockAudioInputIPC() {}
+ virtual ~MockAudioInputIPC() {}
+
+ MOCK_METHOD5(CreateStream, void(AudioInputIPCDelegate* delegate,
+ int session_id,
+ const AudioParameters& params,
+ bool automatic_gain_control,
+ uint32 total_segments));
+ MOCK_METHOD0(RecordStream, void());
+ MOCK_METHOD1(SetVolume, void(double volume));
+ MOCK_METHOD0(CloseStream, void());
+};
+
+// Used to terminate a loop from a different thread than the loop belongs to.
+// |loop| should be a SingleThreadTaskRunner.
+ACTION_P(QuitLoop, task_runner) {
+ task_runner->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
+}
+
+} // namespace.
+
+class AudioInputDeviceTest : public testing::Test {
+ protected:
+ AudioInputDeviceTest()
+ : audio_parameters_(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ CHANNEL_LAYOUT_STEREO,
+ 44100,
+ 16,
+ 441),
tommi (sloooow) - chröme 2014/09/02 12:03:34 Did you get a chance to run tests with very small
+ io_loop_(new base::MessageLoopForIO),
+ mock_ipc_(new MockAudioInputIPC()),
+ audio_input_device_(
+ new AudioInputDevice(scoped_ptr<AudioInputIPC>(mock_ipc_),
+ io_loop_->message_loop_proxy())) {
+ audio_input_device_->Initialize(audio_parameters_, &callback_, 1);
+ io_loop_->RunUntilIdle();
+ }
+
+ virtual ~AudioInputDeviceTest() {}
+
+ void StartAudioInputDevice() {
+ audio_input_device_->Start();
+ EXPECT_CALL(
+ *mock_ipc_,
+ CreateStream(
+ audio_input_device_.get(), 1, _, false, kNumOfSharedMemoriesInAID));
+ io_loop_->RunUntilIdle();
+ }
+
+ void CreateInputStream() {
+ const int kMemorySize =
+ CalculateMemorySize(audio_parameters_) * kNumOfSharedMemoriesInAID;
+
+ ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
+ memset(shared_memory_.memory(), 0xff, kMemorySize);
+
+ ASSERT_TRUE(
+ CancelableSyncSocket::CreatePair(&browser_socket_, &renderer_socket_));
+
+ SyncSocket::Handle socket = SyncSocket::kInvalidHandle;
+ ASSERT_TRUE(DuplicateSocketHandle(renderer_socket_.handle(),
+ &socket));
+ base::SharedMemoryHandle duplicated_memory_handle;
+ ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(),
+ &duplicated_memory_handle));
+
+ EXPECT_CALL(*mock_ipc_, RecordStream());
+ audio_input_device_->OnStreamCreated(duplicated_memory_handle,
+ socket,
+ shared_memory_.requested_size(),
+ kNumOfSharedMemoriesInAID);
+ io_loop_->RunUntilIdle();
+ }
+
+ void WriteToSharedMemory() {
+ const size_t kSegmentSize = CalculateMemorySize(audio_parameters_);
+ uint8* ptr = static_cast<uint8*>(shared_memory_.memory());
+ for (int i = 0; i < kNumOfSharedMemoriesInAID; ++i) {
+ AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr);
+ buffer->params.volume = 0;
+ buffer->params.size = kSegmentSize;
+ buffer->params.key_pressed = false;
+ ptr += kSegmentSize;
+ }
+ }
+
+ void ConsumeAndVerifySharedMemory() {
+ const size_t kSegmentSize = CalculateMemorySize(audio_parameters_);
+ uint8* ptr = static_cast<uint8*>(shared_memory_.memory());
+ EXPECT_CALL(callback_, Capture(_, _, _, _))
+ .WillRepeatedly(QuitLoop(io_loop_->task_runner()));
+ for (int i = 0; i < kNumOfSharedMemoriesInAID; ++i) {
+ AudioInputBuffer* buffer = reinterpret_cast<AudioInputBuffer*>(ptr);
+ EXPECT_EQ(kSegmentSize, buffer->params.size);
+
+ // Send a socket from the browser to trigger processing the shared memory
+ // in AudioInputDevice.
+ int pending_bytes = 0;
+ browser_socket_.Send(&pending_bytes, sizeof(pending_bytes));
+ WaitForCaptureCallback();
+
+ // Verify the |size| of the buffer has been reset to 0;
+ EXPECT_EQ(0u, buffer->params.size);
+
+ // Iterate the next segment of shared memory.
+ ptr += kSegmentSize;
+ }
+ }
+
+ void StopAudioInputDevice() {
+ audio_input_device_->Stop();
+ EXPECT_CALL(*mock_ipc_, CloseStream());
+ io_loop_->RunUntilIdle();
+ }
+
+ void WaitForCaptureCallback() {
+ io_loop_->PostDelayedTask(FROM_HERE,
+ base::MessageLoop::QuitClosure(),
+ TestTimeouts::action_timeout());
+ io_loop_->Run();
+ }
+
+ protected:
+ AudioParameters audio_parameters_;
+ scoped_ptr<base::MessageLoopForIO> io_loop_;
+ MockAudioInputIPC* mock_ipc_; // owned by |audio_input_device_|.
+ scoped_refptr<AudioInputDevice> audio_input_device_;
+ StrictMock<MockCaptureCallback> callback_;
+
+ private:
+ SharedMemory shared_memory_;
+ CancelableSyncSocket browser_socket_;
+ CancelableSyncSocket renderer_socket_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioInputDeviceTest);
+};
+
+// Sets up shared memory and AudioInputDevice, and verify the shared memory
+// is correctly written and consumed.
+TEST_F(AudioInputDeviceTest, VerifySharedMemory) {
+ StartAudioInputDevice();
+ CreateInputStream();
+ WriteToSharedMemory();
+ ConsumeAndVerifySharedMemory();
+ StopAudioInputDevice();
+}
+
+} // namespace media.
« 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