Commit 4ab948cd authored by Max Morin's avatar Max Morin Committed by Commit Bot

Add factory for streams in audio service.

Just testing the factory is a bit tricky, so I test it as part of the
audio::OutputStream tests.

Doc: go/audio-service-streams-design

Bug: 803102

Change-Id: I463e7adbda7de1a8a5724fa23fc98015cb425a3c
Reviewed-on: https://chromium-review.googlesource.com/939179
Commit-Queue: Max Morin <maxmorin@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541785}
parent 505f0d3a
...@@ -25,6 +25,8 @@ source_set("lib") { ...@@ -25,6 +25,8 @@ source_set("lib") {
"service.h", "service.h",
"service_factory.cc", "service_factory.cc",
"service_factory.h", "service_factory.h",
"stream_factory.cc",
"stream_factory.h",
"system_info.cc", "system_info.cc",
"system_info.h", "system_info.h",
] ]
......
...@@ -8,11 +8,13 @@ ...@@ -8,11 +8,13 @@
#include "base/test/mock_callback.h" #include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h" #include "base/test/scoped_task_environment.h"
#include "base/unguessable_token.h"
#include "media/audio/audio_io.h" #include "media/audio/audio_io.h"
#include "media/audio/mock_audio_manager.h" #include "media/audio/mock_audio_manager.h"
#include "media/audio/test_audio_thread.h" #include "media/audio/test_audio_thread.h"
#include "mojo/edk/system/core.h" #include "mojo/edk/system/core.h"
#include "mojo/public/cpp/bindings/associated_binding.h" #include "mojo/public/cpp/bindings/associated_binding.h"
#include "services/audio/stream_factory.h"
#include "services/audio/test/mock_log.h" #include "services/audio/test/mock_log.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -74,12 +76,12 @@ class MockObserver : public media::mojom::AudioOutputStreamObserver { ...@@ -74,12 +76,12 @@ class MockObserver : public media::mojom::AudioOutputStreamObserver {
MockObserver() : binding_(this) {} MockObserver() : binding_(this) {}
// Should only be called once. // Should only be called once.
media::mojom::AudioOutputStreamObserverAssociatedPtr MakePtr() { media::mojom::AudioOutputStreamObserverAssociatedPtrInfo MakePtrInfo() {
media::mojom::AudioOutputStreamObserverAssociatedPtr ptr; media::mojom::AudioOutputStreamObserverAssociatedPtrInfo ptr_info;
binding_.Bind(mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr)); binding_.Bind(mojo::MakeRequest(&ptr_info));
binding_.set_connection_error_handler(base::BindOnce( binding_.set_connection_error_handler(base::BindOnce(
&MockObserver::BindingConnectionError, base::Unretained(this))); &MockObserver::BindingConnectionError, base::Unretained(this)));
return ptr; return ptr_info;
} }
void CloseBinding() { binding_.Close(); } void CloseBinding() { binding_.Close(); }
...@@ -124,7 +126,10 @@ class MockCreatedCallback { ...@@ -124,7 +126,10 @@ class MockCreatedCallback {
class TestEnvironment { class TestEnvironment {
public: public:
TestEnvironment() TestEnvironment()
: audio_manager_(std::make_unique<media::TestAudioThread>(false)) { : audio_manager_(std::make_unique<media::TestAudioThread>(false)),
stream_factory_(&audio_manager_),
stream_factory_binding_(&stream_factory_,
mojo::MakeRequest(&stream_factory_ptr_)) {
mojo::edk::SetDefaultProcessErrorCallback(bad_message_callback_.Get()); mojo::edk::SetDefaultProcessErrorCallback(bad_message_callback_.Get());
} }
...@@ -134,12 +139,14 @@ class TestEnvironment { ...@@ -134,12 +139,14 @@ class TestEnvironment {
using MockBadMessageCallback = using MockBadMessageCallback =
base::MockCallback<base::RepeatingCallback<void(const std::string&)>>; base::MockCallback<base::RepeatingCallback<void(const std::string&)>>;
std::unique_ptr<OutputStream> CreateStream( media::mojom::AudioOutputStreamPtr CreateStream() {
media::mojom::AudioOutputStreamRequest request) { media::mojom::AudioOutputStreamPtr stream_ptr;
return std::make_unique<OutputStream>( stream_factory_ptr_->CreateOutputStream(
created_callback_.Get(), delete_callback_.Get(), std::move(request), mojo::MakeRequest(&stream_ptr), client_.MakePtr(),
client_.MakePtr(), observer_.MakePtr(), log_.MakePtr(), &audio_manager_, observer_.MakePtrInfo(), log_.MakePtr(), "",
"", media::AudioParameters::UnavailableDeviceParams()); media::AudioParameters::UnavailableDeviceParams(),
base::UnguessableToken::Create(), created_callback_.Get());
return stream_ptr;
} }
media::MockAudioManager& audio_manager() { return audio_manager_; } media::MockAudioManager& audio_manager() { return audio_manager_; }
...@@ -152,8 +159,6 @@ class TestEnvironment { ...@@ -152,8 +159,6 @@ class TestEnvironment {
MockCreatedCallback& created_callback() { return created_callback_; } MockCreatedCallback& created_callback() { return created_callback_; }
MockDeleteCallback& delete_callback() { return delete_callback_; }
MockBadMessageCallback& bad_message_callback() { MockBadMessageCallback& bad_message_callback() {
return bad_message_callback_; return bad_message_callback_;
} }
...@@ -161,11 +166,13 @@ class TestEnvironment { ...@@ -161,11 +166,13 @@ class TestEnvironment {
private: private:
base::test::ScopedTaskEnvironment tasks_; base::test::ScopedTaskEnvironment tasks_;
media::MockAudioManager audio_manager_; media::MockAudioManager audio_manager_;
StreamFactory stream_factory_;
mojom::StreamFactoryPtr stream_factory_ptr_;
mojo::Binding<mojom::StreamFactory> stream_factory_binding_;
StrictMock<MockClient> client_; StrictMock<MockClient> client_;
StrictMock<MockObserver> observer_; StrictMock<MockObserver> observer_;
NiceMock<MockLog> log_; NiceMock<MockLog> log_;
StrictMock<MockCreatedCallback> created_callback_; StrictMock<MockCreatedCallback> created_callback_;
StrictMock<MockDeleteCallback> delete_callback_;
StrictMock<MockBadMessageCallback> bad_message_callback_; StrictMock<MockBadMessageCallback> bad_message_callback_;
DISALLOW_COPY_AND_ASSIGN(TestEnvironment); DISALLOW_COPY_AND_ASSIGN(TestEnvironment);
...@@ -184,9 +191,7 @@ TEST(OutputStreamTest, ConstructDestruct) { ...@@ -184,9 +191,7 @@ TEST(OutputStreamTest, ConstructDestruct) {
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
EXPECT_CALL(env.log(), OnCreated(_, _)); EXPECT_CALL(env.log(), OnCreated(_, _));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -195,6 +200,8 @@ TEST(OutputStreamTest, ConstructDestruct) { ...@@ -195,6 +200,8 @@ TEST(OutputStreamTest, ConstructDestruct) {
EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(mock_stream, Close());
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
stream_ptr.reset();
base::RunLoop().RunUntilIdle();
} }
TEST(OutputStreamTest, ConstructStreamAndDestructObserver_DestructsStream) { TEST(OutputStreamTest, ConstructStreamAndDestructObserver_DestructsStream) {
...@@ -209,22 +216,17 @@ TEST(OutputStreamTest, ConstructStreamAndDestructObserver_DestructsStream) { ...@@ -209,22 +216,17 @@ TEST(OutputStreamTest, ConstructStreamAndDestructObserver_DestructsStream) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(mock_stream, Close());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
EXPECT_CALL(env.delete_callback(), Run(stream.release()))
.WillOnce(DeleteArg<0>());
env.observer().CloseBinding(); env.observer().CloseBinding();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&env.delete_callback());
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.client());
} }
...@@ -241,22 +243,17 @@ TEST(OutputStreamTest, ConstructStreamAndDestructClient_DestructsStream) { ...@@ -241,22 +243,17 @@ TEST(OutputStreamTest, ConstructStreamAndDestructClient_DestructsStream) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(mock_stream, Close());
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.delete_callback(), Run(stream.release()))
.WillOnce(DeleteArg<0>());
env.client().CloseBinding(); env.client().CloseBinding();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&env.delete_callback());
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.observer()); Mock::VerifyAndClear(&env.observer());
} }
...@@ -273,9 +270,7 @@ TEST(OutputStreamTest, ConstructStreamAndReleaseStreamPtr_DestructsStream) { ...@@ -273,9 +270,7 @@ TEST(OutputStreamTest, ConstructStreamAndReleaseStreamPtr_DestructsStream) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -283,13 +278,10 @@ TEST(OutputStreamTest, ConstructStreamAndReleaseStreamPtr_DestructsStream) { ...@@ -283,13 +278,10 @@ TEST(OutputStreamTest, ConstructStreamAndReleaseStreamPtr_DestructsStream) {
EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(mock_stream, Close());
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
EXPECT_CALL(env.delete_callback(), Run(stream.release()))
.WillOnce(DeleteArg<0>());
stream_ptr.reset(); stream_ptr.reset();
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&env.delete_callback());
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.client());
Mock::VerifyAndClear(&env.observer()); Mock::VerifyAndClear(&env.observer());
...@@ -307,9 +299,7 @@ TEST(OutputStreamTest, Play_Plays) { ...@@ -307,9 +299,7 @@ TEST(OutputStreamTest, Play_Plays) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -331,6 +321,8 @@ TEST(OutputStreamTest, Play_Plays) { ...@@ -331,6 +321,8 @@ TEST(OutputStreamTest, Play_Plays) {
EXPECT_CALL(env.observer(), DidStopPlaying()).Times(AtMost(1)); EXPECT_CALL(env.observer(), DidStopPlaying()).Times(AtMost(1));
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
stream_ptr.reset();
base::RunLoop().RunUntilIdle();
} }
TEST(OutputStreamTest, PlayAndPause_PlaysAndStops) { TEST(OutputStreamTest, PlayAndPause_PlaysAndStops) {
...@@ -345,9 +337,7 @@ TEST(OutputStreamTest, PlayAndPause_PlaysAndStops) { ...@@ -345,9 +337,7 @@ TEST(OutputStreamTest, PlayAndPause_PlaysAndStops) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -374,6 +364,8 @@ TEST(OutputStreamTest, PlayAndPause_PlaysAndStops) { ...@@ -374,6 +364,8 @@ TEST(OutputStreamTest, PlayAndPause_PlaysAndStops) {
EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(mock_stream, Close());
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
stream_ptr.reset();
base::RunLoop().RunUntilIdle();
} }
TEST(OutputStreamTest, SetVolume_SetsVolume) { TEST(OutputStreamTest, SetVolume_SetsVolume) {
...@@ -389,9 +381,7 @@ TEST(OutputStreamTest, SetVolume_SetsVolume) { ...@@ -389,9 +381,7 @@ TEST(OutputStreamTest, SetVolume_SetsVolume) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -405,6 +395,8 @@ TEST(OutputStreamTest, SetVolume_SetsVolume) { ...@@ -405,6 +395,8 @@ TEST(OutputStreamTest, SetVolume_SetsVolume) {
EXPECT_CALL(mock_stream, Close()); EXPECT_CALL(mock_stream, Close());
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
stream_ptr.reset();
base::RunLoop().RunUntilIdle();
} }
TEST(OutputStreamTest, SetNegativeVolume_BadMessage) { TEST(OutputStreamTest, SetNegativeVolume_BadMessage) {
...@@ -419,9 +411,7 @@ TEST(OutputStreamTest, SetNegativeVolume_BadMessage) { ...@@ -419,9 +411,7 @@ TEST(OutputStreamTest, SetNegativeVolume_BadMessage) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -430,8 +420,6 @@ TEST(OutputStreamTest, SetNegativeVolume_BadMessage) { ...@@ -430,8 +420,6 @@ TEST(OutputStreamTest, SetNegativeVolume_BadMessage) {
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
EXPECT_CALL(env.bad_message_callback(), Run(_)); EXPECT_CALL(env.bad_message_callback(), Run(_));
EXPECT_CALL(env.delete_callback(), Run(stream.release()))
.WillOnce(DeleteArg<0>());
stream_ptr->SetVolume(-0.1); stream_ptr->SetVolume(-0.1);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
...@@ -448,9 +436,7 @@ TEST(OutputStreamTest, SetVolumeGreaterThanOne_BadMessage) { ...@@ -448,9 +436,7 @@ TEST(OutputStreamTest, SetVolumeGreaterThanOne_BadMessage) {
EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true)); EXPECT_CALL(mock_stream, Open()).WillOnce(Return(true));
EXPECT_CALL(mock_stream, SetVolume(1)); EXPECT_CALL(mock_stream, SetVolume(1));
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&mock_stream); Mock::VerifyAndClear(&mock_stream);
Mock::VerifyAndClear(&env.created_callback()); Mock::VerifyAndClear(&env.created_callback());
...@@ -459,8 +445,6 @@ TEST(OutputStreamTest, SetVolumeGreaterThanOne_BadMessage) { ...@@ -459,8 +445,6 @@ TEST(OutputStreamTest, SetVolumeGreaterThanOne_BadMessage) {
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
EXPECT_CALL(env.bad_message_callback(), Run(_)); EXPECT_CALL(env.bad_message_callback(), Run(_));
EXPECT_CALL(env.delete_callback(), Run(stream.release()))
.WillOnce(DeleteArg<0>());
stream_ptr->SetVolume(1.1); stream_ptr->SetVolume(1.1);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
...@@ -470,19 +454,14 @@ TEST(OutputStreamTest, ConstructWithStreamCreationFailure_SignalsError) { ...@@ -470,19 +454,14 @@ TEST(OutputStreamTest, ConstructWithStreamCreationFailure_SignalsError) {
// By default, the MockAudioManager fails to create a stream. // By default, the MockAudioManager fails to create a stream.
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
EXPECT_CALL(env.created_callback(), Created(unsuccessfully_)); EXPECT_CALL(env.created_callback(), Created(unsuccessfully_));
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.log(), OnError()); EXPECT_CALL(env.log(), OnError());
EXPECT_CALL(env.client(), OnError()); EXPECT_CALL(env.client(), OnError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
EXPECT_CALL(env.delete_callback(), Run(stream.release()))
.WillOnce(DeleteArg<0>());
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&env.delete_callback());
Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.client());
Mock::VerifyAndClear(&env.observer()); Mock::VerifyAndClear(&env.observer());
} }
...@@ -495,16 +474,12 @@ TEST(OutputStreamTest, ...@@ -495,16 +474,12 @@ TEST(OutputStreamTest,
// By default, the MockAudioManager fails to create a stream. // By default, the MockAudioManager fails to create a stream.
media::mojom::AudioOutputStreamPtr stream_ptr; media::mojom::AudioOutputStreamPtr stream_ptr = env.CreateStream();
{
EXPECT_CALL(env.created_callback(), Created(unsuccessfully_)); EXPECT_CALL(env.created_callback(), Created(unsuccessfully_));
std::unique_ptr<OutputStream> stream =
env.CreateStream(mojo::MakeRequest(&stream_ptr));
EXPECT_CALL(env.observer(), BindingConnectionError()); EXPECT_CALL(env.observer(), BindingConnectionError());
EXPECT_CALL(env.client(), OnError()); EXPECT_CALL(env.client(), OnError());
EXPECT_CALL(env.client(), BindingConnectionError()); EXPECT_CALL(env.client(), BindingConnectionError());
}
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
Mock::VerifyAndClear(&env.client()); Mock::VerifyAndClear(&env.client());
......
...@@ -8,6 +8,7 @@ mojom("mojom") { ...@@ -8,6 +8,7 @@ mojom("mojom") {
sources = [ sources = [
"audio_device_description.mojom", "audio_device_description.mojom",
"debug_recording.mojom", "debug_recording.mojom",
"stream_factory.mojom",
"system_info.mojom", "system_info.mojom",
] ]
......
module audio.mojom;
import "media/mojo/interfaces/audio_data_pipe.mojom";
import "media/mojo/interfaces/audio_logging.mojom";
import "media/mojo/interfaces/audio_output_stream.mojom";
import "media/mojo/interfaces/audio_parameters.mojom";
import "mojo/common/unguessable_token.mojom";
// This interface is exposed by the audio service to allow trusted clients
// (like the browser process) to create streams. Note that while the factory
// interface itself is only for trusted clients, the created streams and data
// pipes may be forwarded to untrusted clients.
// TODO(803102): Add other stream creation functionality to this interface.
interface StreamFactory {
// Creates an AudioOutputStream and returns the AudioDataPipe it reads data
// from. |data_pipe| is null in case stream creation failed.
// |device_id| is either the |unique_id| field from an AudioDeviceDescription
// obtained from the audio.mojom.SystemInfo interface, or "default".
// |stream_group_id| will later be used for muting streams or capturing them
// for loopback.
CreateOutputStream(
media.mojom.AudioOutputStream& stream,
media.mojom.AudioOutputStreamClient client,
associated media.mojom.AudioOutputStreamObserver observer,
media.mojom.AudioLog log,
string device_id, media.mojom.AudioParameters params,
mojo.common.mojom.UnguessableToken stream_group_id)
=> (media.mojom.AudioDataPipe? data_pipe);
};
// Copyright 2018 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 "services/audio/stream_factory.h"
#include <utility>
#include "services/audio/output_stream.h"
namespace audio {
StreamFactory::StreamFactory(media::AudioManager* audio_manager)
: audio_manager_(audio_manager) {}
StreamFactory::~StreamFactory() {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
}
void StreamFactory::BindRequest(mojom::StreamFactoryRequest request) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
bindings_.AddBinding(this, std::move(request));
}
void StreamFactory::CreateOutputStream(
media::mojom::AudioOutputStreamRequest stream_request,
media::mojom::AudioOutputStreamClientPtr client,
media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info,
media::mojom::AudioLogPtr log,
const std::string& output_device_id,
const media::AudioParameters& params,
const base::UnguessableToken& group_id,
CreateOutputStreamCallback created_callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
media::mojom::AudioOutputStreamObserverAssociatedPtr observer;
observer.Bind(std::move(observer_info));
// Unretained is safe since |this| indirectly owns the OutputStream.
auto deleter_callback = base::BindOnce(&StreamFactory::RemoveOutputStream,
base::Unretained(this));
output_streams_.insert(std::make_unique<OutputStream>(
std::move(created_callback), std::move(deleter_callback),
std::move(stream_request), std::move(client), std::move(observer),
std::move(log), audio_manager_, output_device_id, params));
}
void StreamFactory::RemoveOutputStream(OutputStream* stream) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
size_t erased = output_streams_.erase(stream);
DCHECK_EQ(1u, erased);
}
} // namespace audio
// Copyright 2018 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.
#ifndef SERVICES_AUDIO_STREAM_FACTORY_H_
#define SERVICES_AUDIO_STREAM_FACTORY_H_
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "media/mojo/interfaces/audio_logging.mojom.h"
#include "media/mojo/interfaces/audio_output_stream.mojom.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/audio/public/mojom/stream_factory.mojom.h"
namespace base {
class UnguessableToken;
}
namespace media {
class AudioManager;
class AudioParameters;
} // namespace media
namespace audio {
class OutputStream;
// This class is used to provide the StreamFactory interface. It will typically
// be instantiated when needed and remain for the lifetime of the service.
// Destructing the factory will also destroy all the streams it has created.
// |audio_manager| must outlive the factory.
class StreamFactory final : public mojom::StreamFactory {
public:
explicit StreamFactory(media::AudioManager* audio_manager);
~StreamFactory() final;
void BindRequest(mojom::StreamFactoryRequest request);
// StreamFactory implementation.
void CreateOutputStream(
media::mojom::AudioOutputStreamRequest stream_request,
media::mojom::AudioOutputStreamClientPtr client,
media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info,
media::mojom::AudioLogPtr log,
const std::string& output_device_id,
const media::AudioParameters& params,
const base::UnguessableToken& group_id,
CreateOutputStreamCallback created_callback) final;
private:
using OutputStreamSet =
base::flat_set<std::unique_ptr<OutputStream>, base::UniquePtrComparator>;
void RemoveOutputStream(OutputStream* stream);
SEQUENCE_CHECKER(owning_sequence_);
media::AudioManager* const audio_manager_;
mojo::BindingSet<mojom::StreamFactory> bindings_;
OutputStreamSet output_streams_;
DISALLOW_COPY_AND_ASSIGN(StreamFactory);
};
} // namespace audio
#endif // SERVICES_AUDIO_STREAM_FACTORY_H_
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