Commit 068c786e authored by Max Morin's avatar Max Morin Committed by Commit Bot

Make MojoAudioInputIPC a FactoryClient.

After https://chromium-review.googlesource.com/c/chromium/src/+/771196,
the interface MojoAudioInputIPC should conform to is slightly different
than originally expected. This CL updates it to fit the new interface.

Bug: 653871
Change-Id: Iea76d3033087742a93943fad94a8875c12459236
Reviewed-on: https://chromium-review.googlesource.com/806222
Commit-Queue: Max Morin <maxmorin@chromium.org>
Reviewed-by: default avatarOlga Sharonova <olka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524056}
parent 75b6ebb7
...@@ -14,8 +14,12 @@ namespace content { ...@@ -14,8 +14,12 @@ namespace content {
MojoAudioInputIPC::MojoAudioInputIPC(StreamCreatorCB stream_creator) MojoAudioInputIPC::MojoAudioInputIPC(StreamCreatorCB stream_creator)
: stream_creator_(std::move(stream_creator)), : stream_creator_(std::move(stream_creator)),
client_binding_(this), stream_client_binding_(this),
weak_factory_(this) {} factory_client_binding_(this),
weak_factory_(this) {
DETACH_FROM_SEQUENCE(sequence_checker_);
DCHECK(stream_creator_);
}
MojoAudioInputIPC::~MojoAudioInputIPC() = default; MojoAudioInputIPC::~MojoAudioInputIPC() = default;
...@@ -24,55 +28,57 @@ void MojoAudioInputIPC::CreateStream(media::AudioInputIPCDelegate* delegate, ...@@ -24,55 +28,57 @@ void MojoAudioInputIPC::CreateStream(media::AudioInputIPCDelegate* delegate,
const media::AudioParameters& params, const media::AudioParameters& params,
bool automatic_gain_control, bool automatic_gain_control,
uint32_t total_segments) { uint32_t total_segments) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(delegate); DCHECK(delegate);
DCHECK(!delegate_); DCHECK(!delegate_);
delegate_ = delegate; delegate_ = delegate;
media::mojom::AudioInputStreamClientPtr client; mojom::RendererAudioInputStreamFactoryClientPtr client;
client_binding_.Bind(mojo::MakeRequest(&client)); factory_client_binding_.Bind(mojo::MakeRequest(&client));
client_binding_.set_connection_error_handler(base::BindOnce( factory_client_binding_.set_connection_error_handler(base::BindOnce(
&media::AudioInputIPCDelegate::OnError, base::Unretained(delegate_))); &media::AudioInputIPCDelegate::OnError, base::Unretained(delegate_)));
stream_creator_.Run(mojo::MakeRequest(&stream_), session_id, params, stream_creator_.Run(std::move(client), session_id, params,
automatic_gain_control, total_segments, std::move(client), automatic_gain_control, total_segments);
base::BindOnce(&MojoAudioInputIPC::StreamCreated,
weak_factory_.GetWeakPtr()));
// Unretained is safe since |delegate_| is required to remain valid until
// CloseStream is called, which closes the binding.
stream_.set_connection_error_handler(base::BindOnce(
&media::AudioInputIPCDelegate::OnError, base::Unretained(delegate_)));
} }
void MojoAudioInputIPC::RecordStream() { void MojoAudioInputIPC::RecordStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (stream_.is_bound()) DCHECK(stream_.is_bound());
stream_->Record(); stream_->Record();
} }
void MojoAudioInputIPC::SetVolume(double volume) { void MojoAudioInputIPC::SetVolume(double volume) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (stream_.is_bound()) DCHECK(stream_.is_bound());
stream_->SetVolume(volume); stream_->SetVolume(volume);
} }
void MojoAudioInputIPC::CloseStream() { void MojoAudioInputIPC::CloseStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
client_binding_.Close();
stream_.reset();
delegate_ = nullptr; delegate_ = nullptr;
if (factory_client_binding_.is_bound())
factory_client_binding_.Unbind();
if (stream_client_binding_.is_bound())
stream_client_binding_.Unbind();
stream_.reset();
} }
void MojoAudioInputIPC::StreamCreated( void MojoAudioInputIPC::StreamCreated(
media::mojom::AudioInputStreamPtr stream,
media::mojom::AudioInputStreamClientRequest stream_client_request,
mojo::ScopedSharedBufferHandle shared_memory, mojo::ScopedSharedBufferHandle shared_memory,
mojo::ScopedHandle socket, mojo::ScopedHandle socket,
bool initially_muted) { bool initially_muted) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(delegate_); DCHECK(delegate_);
DCHECK(socket.is_valid()); DCHECK(socket.is_valid());
DCHECK(shared_memory.is_valid()); DCHECK(shared_memory.is_valid());
DCHECK(!stream_);
DCHECK(!stream_client_binding_.is_bound());
stream_ = std::move(stream);
stream_client_binding_.Bind(std::move(stream_client_request));
base::PlatformFile socket_handle; base::PlatformFile socket_handle;
auto result = mojo::UnwrapPlatformFile(std::move(socket), &socket_handle); auto result = mojo::UnwrapPlatformFile(std::move(socket), &socket_handle);
...@@ -89,13 +95,13 @@ void MojoAudioInputIPC::StreamCreated( ...@@ -89,13 +95,13 @@ void MojoAudioInputIPC::StreamCreated(
} }
void MojoAudioInputIPC::OnError() { void MojoAudioInputIPC::OnError() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(delegate_); DCHECK(delegate_);
delegate_->OnError(); delegate_->OnError();
} }
void MojoAudioInputIPC::OnMutedStateChanged(bool is_muted) { void MojoAudioInputIPC::OnMutedStateChanged(bool is_muted) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(delegate_); DCHECK(delegate_);
delegate_->OnMuted(is_muted); delegate_->OnMuted(is_muted);
} }
......
...@@ -10,8 +10,9 @@ ...@@ -10,8 +10,9 @@
#include "base/callback_helpers.h" #include "base/callback_helpers.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h" #include "base/sequence_checker.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
#include "media/audio/audio_input_ipc.h" #include "media/audio/audio_input_ipc.h"
#include "media/mojo/interfaces/audio_input_stream.mojom.h" #include "media/mojo/interfaces/audio_input_stream.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
...@@ -23,24 +24,19 @@ namespace content { ...@@ -23,24 +24,19 @@ namespace content {
// thread. // thread.
class CONTENT_EXPORT MojoAudioInputIPC class CONTENT_EXPORT MojoAudioInputIPC
: public media::AudioInputIPC, : public media::AudioInputIPC,
public mojom::RendererAudioInputStreamFactoryClient,
public media::mojom::AudioInputStreamClient { public media::mojom::AudioInputStreamClient {
public: public:
using StreamCreatedCB = // This callback is used by MojoAudioInputIPC to create streams.
base::OnceCallback<void(mojo::ScopedSharedBufferHandle shared_memory, // It is expected that after calling, either client->StreamCreated() is
mojo::ScopedHandle socket, // called or |client| is destructed.
bool initially_muted)>;
using StreamCreatorCB = base::RepeatingCallback<void( using StreamCreatorCB = base::RepeatingCallback<void(
media::mojom::AudioInputStreamRequest, mojom::RendererAudioInputStreamFactoryClientPtr client,
int64_t session_id, int32_t session_id,
media::AudioParameters params, const media::AudioParameters& params,
bool automatic_gain_control, bool automatic_gain_control,
uint32_t total_segments, uint32_t total_segments)>;
media::mojom::AudioInputStreamClientPtr client,
StreamCreatedCB on_stream_created)>;
// |stream_creator| is required to create a stream and call on_stream_created.
// It will get posted on the |main_task_runner| during CreateStream.
explicit MojoAudioInputIPC(StreamCreatorCB stream_creator); explicit MojoAudioInputIPC(StreamCreatorCB stream_creator);
~MojoAudioInputIPC() override; ~MojoAudioInputIPC() override;
...@@ -55,19 +51,22 @@ class CONTENT_EXPORT MojoAudioInputIPC ...@@ -55,19 +51,22 @@ class CONTENT_EXPORT MojoAudioInputIPC
void CloseStream() override; void CloseStream() override;
private: private:
void StreamCreated(mojo::ScopedSharedBufferHandle shared_memory, void StreamCreated(
mojo::ScopedHandle socket, media::mojom::AudioInputStreamPtr stream,
bool initially_muted); media::mojom::AudioInputStreamClientRequest stream_client_request,
mojo::ScopedSharedBufferHandle shared_memory,
mojo::ScopedHandle socket,
bool initially_muted) override;
void OnError() override; void OnError() override;
void OnMutedStateChanged(bool is_muted) override; void OnMutedStateChanged(bool is_muted) override;
StreamCreatorCB stream_creator_; StreamCreatorCB stream_creator_;
THREAD_CHECKER(thread_checker_); SEQUENCE_CHECKER(sequence_checker_);
media::mojom::AudioInputStreamPtr stream_; media::mojom::AudioInputStreamPtr stream_;
mojo::Binding<AudioInputStreamClient> client_binding_; mojo::Binding<AudioInputStreamClient> stream_client_binding_;
mojo::Binding<RendererAudioInputStreamFactoryClient> factory_client_binding_;
media::AudioInputIPCDelegate* delegate_ = nullptr; media::AudioInputIPCDelegate* delegate_ = nullptr;
base::WeakPtrFactory<MojoAudioInputIPC> weak_factory_; base::WeakPtrFactory<MojoAudioInputIPC> weak_factory_;
......
...@@ -71,27 +71,26 @@ class FakeStreamCreator { ...@@ -71,27 +71,26 @@ class FakeStreamCreator {
public: public:
FakeStreamCreator(media::mojom::AudioInputStream* stream, FakeStreamCreator(media::mojom::AudioInputStream* stream,
bool initially_muted) bool initially_muted)
: stream_(stream), initially_muted_(initially_muted) {} : stream_(stream), binding_(stream_), initially_muted_(initially_muted) {}
void Create(media::mojom::AudioInputStreamRequest stream_request, void Create(mojom::RendererAudioInputStreamFactoryClientPtr factory_client,
int64_t session_id, int32_t session_id,
media::AudioParameters params, const media::AudioParameters& params,
bool automatic_gain_control, bool automatic_gain_control,
uint32_t total_segments, uint32_t total_segments) {
media::mojom::AudioInputStreamClientPtr client, EXPECT_FALSE(binding_.is_bound());
MojoAudioInputIPC::StreamCreatedCB on_stream_created) {
EXPECT_EQ(binding_, base::nullopt);
EXPECT_NE(stream_, nullptr); EXPECT_NE(stream_, nullptr);
std::swap(client_, client); std::swap(factory_client_, factory_client);
binding_.emplace(stream_, std::move(stream_request)); media::mojom::AudioInputStreamPtr stream_ptr;
binding_.Bind(mojo::MakeRequest(&stream_ptr));
base::CancelableSyncSocket foreign_socket; base::CancelableSyncSocket foreign_socket;
EXPECT_TRUE( EXPECT_TRUE(
base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket)); base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
std::move(on_stream_created) factory_client_->StreamCreated(
.Run(mojo::SharedBufferHandle::Create(kMemoryLength) std::move(stream_ptr), mojo::MakeRequest(&stream_client_),
->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY), mojo::SharedBufferHandle::Create(kMemoryLength)
mojo::WrapPlatformFile(foreign_socket.Release()), ->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY),
initially_muted_); mojo::WrapPlatformFile(foreign_socket.Release()), initially_muted_);
} }
MojoAudioInputIPC::StreamCreatorCB GetCallback() { MojoAudioInputIPC::StreamCreatorCB GetCallback() {
...@@ -100,19 +99,21 @@ class FakeStreamCreator { ...@@ -100,19 +99,21 @@ class FakeStreamCreator {
} }
void Rearm() { void Rearm() {
binding_.reset(); if (binding_.is_bound())
binding_.Unbind();
socket_.Close(); socket_.Close();
} }
void SignalError() { void SignalError() {
ASSERT_TRUE(client_); ASSERT_TRUE(stream_client_);
client_->OnError(); stream_client_->OnError();
} }
private: private:
media::mojom::AudioInputStream* stream_; media::mojom::AudioInputStream* stream_;
media::mojom::AudioInputStreamClientPtr client_; media::mojom::AudioInputStreamClientPtr stream_client_;
base::Optional<mojo::Binding<media::mojom::AudioInputStream>> binding_; mojom::RendererAudioInputStreamFactoryClientPtr factory_client_;
mojo::Binding<media::mojom::AudioInputStream> binding_;
bool initially_muted_; bool initially_muted_;
base::CancelableSyncSocket socket_; base::CancelableSyncSocket socket_;
}; };
...@@ -137,6 +138,25 @@ TEST(MojoAudioInputIPC, OnStreamCreated_Propagates) { ...@@ -137,6 +138,25 @@ TEST(MojoAudioInputIPC, OnStreamCreated_Propagates) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
TEST(MojoAudioInputIPC, FactoryDisconnected_SendsError) {
base::MessageLoopForIO message_loop;
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioInputIPC> ipc =
std::make_unique<MojoAudioInputIPC>(base::BindRepeating(
[](mojom::RendererAudioInputStreamFactoryClientPtr factory_client,
int32_t session_id, const media::AudioParameters& params,
bool automatic_gain_control, uint32_t total_segments) {}));
EXPECT_CALL(delegate, OnError());
ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
base::RunLoop().RunUntilIdle();
ipc->CloseStream();
base::RunLoop().RunUntilIdle();
}
TEST(MojoAudioInputIPC, OnStreamCreated_PropagatesInitiallyMuted) { TEST(MojoAudioInputIPC, OnStreamCreated_PropagatesInitiallyMuted) {
base::MessageLoopForIO message_loop; base::MessageLoopForIO message_loop;
StrictMock<MockStream> stream; StrictMock<MockStream> stream;
...@@ -219,6 +239,7 @@ TEST(MojoAudioInputIPC, Record_Records) { ...@@ -219,6 +239,7 @@ TEST(MojoAudioInputIPC, Record_Records) {
EXPECT_CALL(stream, Record()); EXPECT_CALL(stream, Record());
ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments); ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
base::RunLoop().RunUntilIdle();
ipc->RecordStream(); ipc->RecordStream();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -239,6 +260,7 @@ TEST(MojoAudioInputIPC, SetVolume_SetsVolume) { ...@@ -239,6 +260,7 @@ TEST(MojoAudioInputIPC, SetVolume_SetsVolume) {
EXPECT_CALL(stream, SetVolume(kNewVolume)); EXPECT_CALL(stream, SetVolume(kNewVolume));
ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments); ipc->CreateStream(&delegate, kSessionId, Params(), false, kTotalSegments);
base::RunLoop().RunUntilIdle();
ipc->SetVolume(kNewVolume); ipc->SetVolume(kNewVolume);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
......
...@@ -96,14 +96,14 @@ void MojoAudioOutputIPC::CreateStream(media::AudioOutputIPCDelegate* delegate, ...@@ -96,14 +96,14 @@ void MojoAudioOutputIPC::CreateStream(media::AudioOutputIPCDelegate* delegate,
void MojoAudioOutputIPC::PlayStream() { void MojoAudioOutputIPC::PlayStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (stream_.is_bound()) DCHECK(stream_.is_bound());
stream_->Play(); stream_->Play();
} }
void MojoAudioOutputIPC::PauseStream() { void MojoAudioOutputIPC::PauseStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (stream_.is_bound()) DCHECK(stream_.is_bound());
stream_->Pause(); stream_->Pause();
} }
void MojoAudioOutputIPC::CloseStream() { void MojoAudioOutputIPC::CloseStream() {
...@@ -119,8 +119,8 @@ void MojoAudioOutputIPC::CloseStream() { ...@@ -119,8 +119,8 @@ void MojoAudioOutputIPC::CloseStream() {
void MojoAudioOutputIPC::SetVolume(double volume) { void MojoAudioOutputIPC::SetVolume(double volume) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (stream_.is_bound()) DCHECK(stream_.is_bound());
stream_->SetVolume(volume); stream_->SetVolume(volume);
} }
void MojoAudioOutputIPC::OnError() { void MojoAudioOutputIPC::OnError() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment