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

Unified Diff: content/renderer/media/audio_output_client_unittest.cc

Issue 1930393002: Switch stream creation and closing in Chrome audio rendering from IPC to Mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: unique_ptr for Binding Created 4 years, 7 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 | « content/renderer/media/audio_output_client.cc ('k') | content/renderer/render_frame_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/audio_output_client_unittest.cc
diff --git a/content/renderer/media/audio_output_client_unittest.cc b/content/renderer/media/audio_output_client_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..384763e65a9880239b151510c31439f3ac26e09d
--- /dev/null
+++ b/content/renderer/media/audio_output_client_unittest.cc
@@ -0,0 +1,354 @@
+// Copyright (c) 2016 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/bind.h"
+#include "base/memory/shared_memory.h"
+#include "base/run_loop.h"
+#include "base/sync_socket.h"
+#include "content/public/test/test_browser_thread.h"
+#include "content/renderer/media/audio_message_filter.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+/*
+using ::testing::_;
+
+namespace content {
+
+namespace {
+// const int kBufferSize1 = 30;
+const int kBufferSize2 = 40;
+const int kBufferSize3 = 50;
+// const int kRenderFrameId = 5;
+const int kStreamId1 = 9;
+const int kStreamId2 = 20;
+const int kStreamId3 = 3;
+}
+
+class MockAudioMessageFilter : public AudioMessageFilter {
+ public:
+ MockAudioMessageFilter(
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
+ : AudioMessageFilter(io_task_runner) {}
+ MOCK_METHOD4(OnStreamCreated,
+ void(int stream_id,
+ base::SharedMemoryHandle handle,
+ base::SyncSocket::TransitDescriptor socket_descriptor,
+ uint32_t length));
+ MOCK_METHOD2(OnStreamStateChanged,
+ void(int stream_id, media::AudioOutputIPCDelegateState state));
+ MOCK_METHOD1(CloseStream, void(int stream_id));
+
+ protected:
+ ~MockAudioMessageFilter() {}
+};
+
+class TestAudioOutputImpl;
+
+class AudioOutputClientTest : public testing::Test {
+ public:
+ AudioOutputClientTest() {
+ message_loop_.reset(new base::MessageLoopForUI());
+ io_thread_.reset(
+ new TestBrowserThread(BrowserThread::IO, message_loop_.get()));
+
+ audio_output_client_ =
+ new AudioOutputClient(NULL, message_loop_->task_runner());
+ audio_message_filter_ =
+ new MockAudioMessageFilter(message_loop_->task_runner());
+ }
+
+ void CreateStreamCallback(int stream_id,
+ media::mojom::AudioOutputStreamPtr stream,
+ mojo::ScopedSharedBufferHandle shared_buffer,
+ mojo::ScopedHandle socket_descriptor) {}
+ static mojo::ScopedSharedBufferHandle GenerateBuffer(int buffer_size) {
+ base::SharedMemory shared_memory;
+ shared_memory.CreateAnonymous(buffer_size);
+ base::SharedMemoryHandle shared_memory_handle = shared_memory.handle();
+
+ MojoHandle mojo_foreign_memory_handle;
+
+ MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
+ shared_memory_handle, shared_memory.requested_size(), false,
+ &mojo_foreign_memory_handle);
+
+ EXPECT_EQ(shared_buffer_result, MOJO_RESULT_OK);
+
+ mojo::ScopedSharedBufferHandle shared_buffer_handle =
+ mojo::ScopedSharedBufferHandle(
+ mojo::SharedBufferHandle(mojo_foreign_memory_handle));
+ return shared_buffer_handle;
+ }
+
+ static mojo::ScopedHandle GenerateSocket() {
+ base::SyncSocket::TransitDescriptor socket_descriptor;
+
+ MojoHandle socket_descriptor_handle;
+ MojoResult platform_handle_result;
+
+#if defined(OS_WIN)
+ platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
+ mojo::edk::ScopedPlatformHandle(
+ mojo::edk::PlatformHandle(socket_descriptor),
+ &socket_descriptor_handle);
+#else
+ platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
+ mojo::edk::ScopedPlatformHandle(
+ mojo::edk::PlatformHandle(socket_descriptor.fd)),
+ &socket_descriptor_handle);
+#endif
+
+ EXPECT_EQ(platform_handle_result, MOJO_RESULT_OK);
+
+ mojo::ScopedHandle socket_handle =
+ mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
+ return socket_handle;
+ }
+
+ protected:
+ scoped_refptr<AudioOutputClient> audio_output_client_;
+ std::unique_ptr<base::MessageLoop> message_loop_;
+ scoped_refptr<MockAudioMessageFilter> audio_message_filter_;
+ std::unique_ptr<TestAudioOutputImpl> audio_output_impl_;
+
+ private:
+ std::unique_ptr<TestBrowserThread> io_thread_;
+ DISALLOW_COPY_AND_ASSIGN(AudioOutputClientTest);
+};
+
+class TestAudioOutputStreamImpl : public media::mojom::AudioOutputStream {
+ public:
+ TestAudioOutputStreamImpl(media::mojom::AudioOutputStreamRequest request)
+ : binding_(this, std::move(request)) {}
+ ~TestAudioOutputStreamImpl() override {}
+
+ // AudioOutputStream implementation:
+ static base::RunLoop* run_loop_;
+ static int stream_count_;
+ void Close() override {
+ stream_count_--;
+ // The number of streams that will be closed is 2.
+ EXPECT_TRUE(stream_count_ > -1);
+ if (stream_count_ == 0)
+ run_loop_->Quit();
+ }
+
+ private:
+ mojo::Binding<media::mojom::AudioOutputStream> binding_;
+};
+
+class TestAudioOutputImpl : public media::mojom::AudioOutput {
+ public:
+ TestAudioOutputImpl(media::mojom::AudioOutputRequest request)
+ : binding_(this, std::move(request)) {}
+ ~TestAudioOutputImpl() override {}
+
+ // AudioOutput implementation:
+ void CreateStream(int stream_id,
+ const media::AudioParameters& params,
+ const CreateStreamCallback& callback) override {
+ media::mojom::AudioOutputStreamPtr stream_ptr =
+ media::mojom::AudioOutputStreamPtr();
+ std::unique_ptr<TestAudioOutputStreamImpl> stream(
+ new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr)));
+ mojo::ScopedSharedBufferHandle shared_buffer_handle =
+ mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
+
+ callback.Run(stream_id, std::move(stream_ptr),
+ std::move(shared_buffer_handle),
+ AudioOutputClientTest::GenerateSocket());
+ }
+
+ private:
+ mojo::Binding<media::mojom::AudioOutput> binding_;
+};
+
+base::RunLoop* TestAudioOutputStreamImpl::run_loop_;
+int TestAudioOutputStreamImpl::stream_count_ = 2;
+
+TEST_F(AudioOutputClientTest, CreateStream) {
+ base::RunLoop run_loop;
+ media::mojom::AudioOutputPtr audio_output_impl_ptr;
+ audio_output_impl_.reset(
+ new TestAudioOutputImpl(mojo::GetProxy(&audio_output_impl_ptr)));
+ media::AudioParameters params(
+ media::AudioParameters::AUDIO_FAKE, media::CHANNEL_LAYOUT_STEREO,
+ media::AudioParameters::kAudioCDSampleRate, 16,
+ media::AudioParameters::kAudioCDSampleRate / 10);
+ int stream_count = 2;
+ audio_output_client_->service_ = std::move(audio_output_impl_ptr);
+
+ audio_output_client_->CreateStream(
+ kStreamId1, params,
+ [&run_loop, &stream_count](int stream_id,
+ media::mojom::AudioOutputStreamPtr stream_ptr,
+ mojo::ScopedSharedBufferHandle shared_buffer,
+ mojo::ScopedHandle socket_descriptor) {
+ EXPECT_EQ(kStreamId1, stream_id);
+ EXPECT_TRUE(stream_ptr.is_bound());
+ stream_count--;
+ // The number of streams that will be closed is 2.
+ EXPECT_TRUE(stream_count > -1);
+ if (stream_count == 1)
+ run_loop.Quit();
+ });
+
+ audio_output_client_->CreateStream(
+ kStreamId2, params,
+ [&run_loop, &stream_count](int stream_id,
+ media::mojom::AudioOutputStreamPtr stream_ptr,
+ mojo::ScopedSharedBufferHandle shared_buffer,
+ mojo::ScopedHandle socket_descriptor) {
+ EXPECT_EQ(kStreamId2, stream_id);
+ EXPECT_TRUE(stream_ptr.is_bound());
+ stream_count--;
+ // The number of streams that will be closed is 2.
+ EXPECT_TRUE(stream_count > -1);
+ if (stream_count == 0)
+ run_loop.Quit();
+ });
+ run_loop.Run();
+}
+
+TEST_F(AudioOutputClientTest, CreateStreamCallback) {
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamStateChanged(
+ kStreamId2, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
+ .Times(0);
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamCreated(kStreamId2, _, _, kBufferSize2))
+ .Times(1);
+
+ media::mojom::AudioOutputStreamPtr stream_ptr2;
+ std::unique_ptr<TestAudioOutputStreamImpl> stream2(
+ new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr2)));
+
+ audio_output_client_->CreateStreamCallback(kStreamId2, std::move(stream_ptr2),
+ GenerateBuffer(kBufferSize2),
+ GenerateSocket());
+
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamStateChanged(
+ kStreamId3, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
+ .Times(0);
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamCreated(kStreamId3, _, _, kBufferSize3))
+ .Times(1);
+ media::mojom::AudioOutputStreamPtr stream_ptr3;
+
+ std::unique_ptr<TestAudioOutputStreamImpl> stream3(
+ new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr3)));
+
+ audio_output_client_->CreateStreamCallback(kStreamId3, std::move(stream_ptr3),
+ GenerateBuffer(kBufferSize3),
+ GenerateSocket());
+
+ message_loop_->RunUntilIdle();
+}
+
+TEST_F(AudioOutputClientTest, CreateStreamCallbackNotFound) {
+ media::mojom::AudioOutputStreamPtr stream_ptr1;
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamStateChanged(
+ kStreamId1, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
+ .Times(0);
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamStateChanged(
+ kStreamId1, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
+ .Times(1);
+
+ audio_output_client_->CreateStreamCallback(kStreamId1, std::move(stream_ptr1),
+ GenerateBuffer(kBufferSize1),
+ GenerateSocket());
+
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamStateChanged(
+ kStreamId2, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
+ .Times(0);
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamCreated(kStreamId2, _, _, kBufferSize2))
+ .Times(1);
+
+ media::mojom::AudioOutputStreamPtr stream_ptr2;
+ std::unique_ptr<AudioOutputStreamImpl> stream2(new AudioOutputStreamImpl(
+ mojo::GetProxy(&stream_ptr2), kStreamId2, kRenderFrameId, NULL));
+
+ audio_output_client_->CreateStreamCallback(kStreamId2, std::move(stream_ptr2),
+ GenerateBuffer(kBufferSize2),
+ GenerateSocket());
+
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamStateChanged(
+ kStreamId3, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR))
+ .Times(0);
+ EXPECT_CALL(*audio_message_filter_,
+ OnStreamCreated(kStreamId3, _, _, kBufferSize3))
+ .Times(1);
+ media::mojom::AudioOutputStreamPtr stream_ptr3;
+
+ std::unique_ptr<AudioOutputStreamImpl> stream3(new AudioOutputStreamImpl(
+ mojo::GetProxy(&stream_ptr3), kStreamId3, kRenderFrameId, NULL));
+
+ audio_output_client_->CreateStreamCallback(kStreamId3, std::move(stream_ptr3),
+ GenerateBuffer(kBufferSize3),
+ GenerateSocket());
+
+ message_loop_->RunUntilIdle();
+}
+
+TEST_F(AudioOutputClientTest, CloseAuthorizedNotCreatedStream) {
+ base::RunLoop run_loop;
+ media::mojom::AudioOutputPtr audio_output_impl_ptr;
+ audio_output_impl_.reset(
+ new TestAudioOutputImpl(mojo::GetProxy(&audio_output_impl_ptr)));
+ audio_output_client_->service_ = std::move(audio_output_impl_ptr);
+
+ EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId1)).Times(1);
+
+ audio_output_client_->CloseStream(kStreamId1);
+
+ EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId2)).Times(1);
+ audio_output_client_->CloseStream(kStreamId2);
+}
+
+TEST_F(AudioOutputClientTest, CloseCreatedStream) {
+ TestAudioOutputStreamImpl::run_loop_ = new base::RunLoop();
+ media::mojom::AudioOutputPtr audio_output_impl_ptr;
+ audio_output_impl_.reset(
+ new TestAudioOutputImpl(mojo::GetProxy(&audio_output_impl_ptr)));
+ audio_output_client_->service_ = std::move(audio_output_impl_ptr);
+
+ media::mojom::AudioOutputStreamPtr stream_ptr1;
+ std::unique_ptr<TestAudioOutputStreamImpl> stream1(
+ new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr1)));
+ audio_output_client_->streams_.insert(
+ std::make_pair(kStreamId1, std::move(stream_ptr1)));
+
+ // Closing an authorized but ńot created stream should call
+ // AudioMessageFilter::CloseStream.
+ EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId3)).Times(1);
+
+ audio_output_client_->CloseStream(kStreamId3);
+
+ audio_output_client_->CloseStream(kStreamId1);
+
+ media::mojom::AudioOutputStreamPtr stream_ptr2;
+ std::unique_ptr<TestAudioOutputStreamImpl> stream2(
+ new TestAudioOutputStreamImpl(mojo::GetProxy(&stream_ptr2)));
+ audio_output_client_->streams_.insert(
+ std::make_pair(kStreamId2, std::move(stream_ptr2)));
+ audio_output_client_->CloseStream(kStreamId2);
+ TestAudioOutputStreamImpl::run_loop_->Run();
+
+ // |kStreamId1| is cllosed now. Closing it will call
+ // AudioMessageFilter::CloseStream. The same for |kStreamId2|
+ EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId1)).Times(1);
+ audio_output_client_->CloseStream(kStreamId1);
+
+ EXPECT_CALL(*audio_message_filter_, CloseStream(kStreamId2)).Times(1);
+ audio_output_client_->CloseStream(kStreamId2);
+}
+
+} // namespace content
+*/
« no previous file with comments | « content/renderer/media/audio_output_client.cc ('k') | content/renderer/render_frame_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698