Commit 539d243b authored by Max Morin's avatar Max Morin Committed by Commit Bot

Add a new RenderFrameAudioInputStreamFactory

It checks that the stream is allowed and forwards the request to the
relevant ForwardingAudioStreamFactory if so. This will cause
the stream to be served by the audio service.
The old RenderFrameAudioInputStreamFactory which creates streams
living in content/ is renamed to
OldRenderFrameAudioInputStreamFactory. Since the class was renamed,
the files were moved (by adding "old_" to the beginning). No need to
review those files. Also note that replacement is diffed against
the previous implementation. It's probably best to just ignore the diff
and review render_frame_audio_input_stream_factory{.cc,.h,_unittest.cc}
as new files.

The same flag as for output is used to switch between the old factory
and the new one.

Approximate diagram of stuff:
https://docs.google.com/drawings/d/1_ZIKj6lihGKRjq4Mflduitmkn_REqpHFeqVNelBGHHk/edit

Bug: 830493, 836226
Change-Id: Ib0f58a52d849a48ba79405f0d499444c66029b58
Reviewed-on: https://chromium-review.googlesource.com/1050245
Commit-Queue: Max Morin <maxmorin@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557832}
parent 2108740c
...@@ -1364,6 +1364,8 @@ jumbo_source_set("browser") { ...@@ -1364,6 +1364,8 @@ jumbo_source_set("browser") {
"renderer_host/media/media_stream_track_metrics_host.h", "renderer_host/media/media_stream_track_metrics_host.h",
"renderer_host/media/media_stream_ui_proxy.cc", "renderer_host/media/media_stream_ui_proxy.cc",
"renderer_host/media/media_stream_ui_proxy.h", "renderer_host/media/media_stream_ui_proxy.h",
"renderer_host/media/old_render_frame_audio_input_stream_factory.cc",
"renderer_host/media/old_render_frame_audio_input_stream_factory.h",
"renderer_host/media/old_render_frame_audio_output_stream_factory.cc", "renderer_host/media/old_render_frame_audio_output_stream_factory.cc",
"renderer_host/media/old_render_frame_audio_output_stream_factory.h", "renderer_host/media/old_render_frame_audio_output_stream_factory.h",
"renderer_host/media/peer_connection_tracker_host.cc", "renderer_host/media/peer_connection_tracker_host.cc",
......
...@@ -4447,15 +4447,22 @@ void RenderFrameHostImpl::CreateAudioInputStreamFactory( ...@@ -4447,15 +4447,22 @@ void RenderFrameHostImpl::CreateAudioInputStreamFactory(
mojom::RendererAudioInputStreamFactoryRequest request) { mojom::RendererAudioInputStreamFactoryRequest request) {
BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance();
DCHECK(browser_main_loop); DCHECK(browser_main_loop);
audio_input_stream_factory_ = if (base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams)) {
RenderFrameAudioInputStreamFactoryHandle::CreateFactory( scoped_refptr<AudioInputDeviceManager> aidm =
base::BindRepeating(&AudioInputDelegateImpl::Create, browser_main_loop->media_stream_manager()->audio_input_device_manager();
media::AudioManager::Get(), audio_service_audio_input_stream_factory_.emplace(std::move(request),
AudioMirroringManager::GetInstance(), std::move(aidm), this);
browser_main_loop->user_input_monitor(), } else {
GetProcess()->GetID(), GetRoutingID()), in_content_audio_input_stream_factory_ =
browser_main_loop->media_stream_manager(), GetProcess()->GetID(), RenderFrameAudioInputStreamFactoryHandle::CreateFactory(
GetRoutingID(), std::move(request)); base::BindRepeating(&AudioInputDelegateImpl::Create,
media::AudioManager::Get(),
AudioMirroringManager::GetInstance(),
browser_main_loop->user_input_monitor(),
GetProcess()->GetID(), GetRoutingID()),
browser_main_loop->media_stream_manager(), GetProcess()->GetID(),
GetRoutingID(), std::move(request));
}
} }
void RenderFrameHostImpl::CreateAudioOutputStreamFactory( void RenderFrameHostImpl::CreateAudioOutputStreamFactory(
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/bad_message.h" #include "content/browser/bad_message.h"
#include "content/browser/loader/global_routing_id.h" #include "content/browser/loader/global_routing_id.h"
#include "content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.h"
#include "content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.h" #include "content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.h"
#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h" #include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h"
#include "content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h" #include "content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h"
...@@ -1419,8 +1420,6 @@ class CONTENT_EXPORT RenderFrameHostImpl ...@@ -1419,8 +1420,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
// |FrameHostMsg_TextSurroundingSelectionResponse| message comes. // |FrameHostMsg_TextSurroundingSelectionResponse| message comes.
TextSurroundingSelectionCallback text_surrounding_selection_callback_; TextSurroundingSelectionCallback text_surrounding_selection_callback_;
UniqueAudioInputStreamFactoryPtr audio_input_stream_factory_;
// We switch between |audio_service_audio_output_stream_factory_| and // We switch between |audio_service_audio_output_stream_factory_| and
// |in_content_audio_output_stream_factory_| based on // |in_content_audio_output_stream_factory_| based on
// features::kAudioServiceAudioStreams status. // features::kAudioServiceAudioStreams status.
...@@ -1428,6 +1427,13 @@ class CONTENT_EXPORT RenderFrameHostImpl ...@@ -1428,6 +1427,13 @@ class CONTENT_EXPORT RenderFrameHostImpl
audio_service_audio_output_stream_factory_; audio_service_audio_output_stream_factory_;
UniqueAudioOutputStreamFactoryPtr in_content_audio_output_stream_factory_; UniqueAudioOutputStreamFactoryPtr in_content_audio_output_stream_factory_;
// We switch between |audio_service_audio_input_stream_factory_| and
// |in_content_audio_input_stream_factory_| based on
// features::kAudioServiceAudioStreams status.
base::Optional<RenderFrameAudioInputStreamFactory>
audio_service_audio_input_stream_factory_;
UniqueAudioInputStreamFactoryPtr in_content_audio_input_stream_factory_;
#if BUILDFLAG(ENABLE_WEBRTC) #if BUILDFLAG(ENABLE_WEBRTC)
std::unique_ptr<MediaStreamDispatcherHost, BrowserThread::DeleteOnIOThread> std::unique_ptr<MediaStreamDispatcherHost, BrowserThread::DeleteOnIOThread>
media_stream_dispatcher_host_; media_stream_dispatcher_host_;
......
...@@ -542,7 +542,7 @@ VideoCaptureManager* MediaStreamManager::video_capture_manager() { ...@@ -542,7 +542,7 @@ VideoCaptureManager* MediaStreamManager::video_capture_manager() {
} }
AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() {
DCHECK_CURRENTLY_ON(BrowserThread::IO); // May be called on any thread, provided that we are not in shutdown.
DCHECK(audio_input_device_manager_.get()); DCHECK(audio_input_device_manager_.get());
return audio_input_device_manager_.get(); return audio_input_device_manager_.get();
} }
......
// Copyright 2017 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 "content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.h"
#include <utility>
#include "base/feature_list.h"
#include "base/task_runner_util.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/public/common/content_features.h"
#include "media/base/audio_parameters.h"
namespace content {
// static
std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
RenderFrameAudioInputStreamFactoryHandle::CreateFactory(
OldRenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
content::MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id,
mojom::RendererAudioInputStreamFactoryRequest request) {
std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
handle(new RenderFrameAudioInputStreamFactoryHandle(
std::move(create_delegate_callback), media_stream_manager,
render_process_id, render_frame_id));
// Unretained is safe since |*handle| must be posted to the IO thread prior to
// deletion.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&RenderFrameAudioInputStreamFactoryHandle::Init,
base::Unretained(handle.get()), std::move(request)));
return handle;
}
RenderFrameAudioInputStreamFactoryHandle::
~RenderFrameAudioInputStreamFactoryHandle() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
RenderFrameAudioInputStreamFactoryHandle::
RenderFrameAudioInputStreamFactoryHandle(
OldRenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id)
: impl_(std::move(create_delegate_callback),
media_stream_manager,
render_process_id,
render_frame_id),
binding_(&impl_) {}
void RenderFrameAudioInputStreamFactoryHandle::Init(
mojom::RendererAudioInputStreamFactoryRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
binding_.Bind(std::move(request));
}
OldRenderFrameAudioInputStreamFactory::OldRenderFrameAudioInputStreamFactory(
CreateDelegateCallback create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id)
: create_delegate_callback_(std::move(create_delegate_callback)),
media_stream_manager_(media_stream_manager),
render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
weak_ptr_factory_(this) {
DCHECK(create_delegate_callback_);
// No thread-hostile state has been initialized yet, so we don't have to bind
// to this specific thread.
}
OldRenderFrameAudioInputStreamFactory::
~OldRenderFrameAudioInputStreamFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
void OldRenderFrameAudioInputStreamFactory::CreateStream(
mojom::RendererAudioInputStreamFactoryClientPtr client,
int32_t session_id,
const media::AudioParameters& audio_params,
bool automatic_gain_control,
uint32_t shared_memory_count) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
#if defined(OS_CHROMEOS)
if (audio_params.channel_layout() ==
media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
media_stream_manager_->audio_input_device_manager()
->RegisterKeyboardMicStream(base::BindOnce(
&OldRenderFrameAudioInputStreamFactory::DoCreateStream,
weak_ptr_factory_.GetWeakPtr(), std::move(client), session_id,
audio_params, automatic_gain_control, shared_memory_count));
return;
}
#endif
DoCreateStream(std::move(client), session_id, audio_params,
automatic_gain_control, shared_memory_count,
AudioInputDeviceManager::KeyboardMicRegistration());
}
void OldRenderFrameAudioInputStreamFactory::DoCreateStream(
mojom::RendererAudioInputStreamFactoryClientPtr client,
int session_id,
const media::AudioParameters& audio_params,
bool automatic_gain_control,
uint32_t shared_memory_count,
AudioInputDeviceManager::KeyboardMicRegistration
keyboard_mic_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
int stream_id = ++next_stream_id_;
media::mojom::AudioLogPtr audio_log_ptr =
MediaInternals::GetInstance()->CreateMojoAudioLog(
media::AudioLogFactory::AUDIO_INPUT_CONTROLLER, stream_id,
render_process_id_, render_frame_id_);
// Unretained is safe since |this| owns |streams_|.
streams_.insert(std::make_unique<AudioInputStreamHandle>(
std::move(client),
base::BindOnce(
create_delegate_callback_,
base::Unretained(media_stream_manager_->audio_input_device_manager()),
std::move(audio_log_ptr), std::move(keyboard_mic_registration),
shared_memory_count, stream_id, session_id, automatic_gain_control,
audio_params),
base::BindOnce(&OldRenderFrameAudioInputStreamFactory::RemoveStream,
weak_ptr_factory_.GetWeakPtr())));
}
void OldRenderFrameAudioInputStreamFactory::RemoveStream(
AudioInputStreamHandle* stream) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
streams_.erase(stream);
}
} // namespace content
// Copyright 2017 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 CONTENT_BROWSER_RENDERER_HOST_MEDIA_OLD_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_OLD_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
#include <cstdint>
#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/memory/weak_ptr.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/audio_input_stream_handle.h"
#include "content/common/content_export.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "media/audio/audio_input_delegate.h"
#include "media/mojo/interfaces/audio_logging.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace media {
class AudioParameters;
} // namespace media
namespace content {
class MediaStreamManager;
// Handles a RendererAudioInputStreamFactory request for a render frame host,
// using the provided RendererAudioInputStreamFactoryContext. This class may
// be constructed on any thread, but must be used on the IO thread after that,
// and also destructed on the IO thread. It is being
// replaced by RenderFrameAudioInputStreamFactory, which forwards stream
// requests to the audio service (https://crbug.com/830493).
class CONTENT_EXPORT OldRenderFrameAudioInputStreamFactory
: public mojom::RendererAudioInputStreamFactory {
public:
using CreateDelegateCallback =
base::RepeatingCallback<std::unique_ptr<media::AudioInputDelegate>(
AudioInputDeviceManager* audio_input_device_manager,
media::mojom::AudioLogPtr audio_log,
AudioInputDeviceManager::KeyboardMicRegistration
keyboard_mic_registration,
uint32_t shared_memory_count,
int stream_id,
int session_id,
bool automatic_gain_control,
const media::AudioParameters& parameters,
media::AudioInputDelegate::EventHandler* event_handler)>;
OldRenderFrameAudioInputStreamFactory(
CreateDelegateCallback create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id);
~OldRenderFrameAudioInputStreamFactory() override;
private:
using InputStreamSet = base::flat_set<std::unique_ptr<AudioInputStreamHandle>,
base::UniquePtrComparator>;
// mojom::RendererAudioInputStreamFactory implementation.
void CreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client,
int32_t session_id,
const media::AudioParameters& audio_params,
bool automatic_gain_control,
uint32_t shared_memory_count) override;
void DoCreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client,
int session_id,
const media::AudioParameters& audio_params,
bool automatic_gain_control,
uint32_t shared_memory_count,
AudioInputDeviceManager::KeyboardMicRegistration
keyboard_mic_registration);
void RemoveStream(AudioInputStreamHandle* input_stream);
const CreateDelegateCallback create_delegate_callback_;
MediaStreamManager* media_stream_manager_;
const int render_process_id_;
const int render_frame_id_;
InputStreamSet streams_;
int next_stream_id_ = 0;
base::WeakPtrFactory<OldRenderFrameAudioInputStreamFactory> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(OldRenderFrameAudioInputStreamFactory);
};
// This class is a convenient bundle of factory and binding.
// It can be created on any thread, but should be destroyed on the IO thread
// (hence the DeleteOnIOThread pointer).
class CONTENT_EXPORT RenderFrameAudioInputStreamFactoryHandle {
public:
static std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
CreateFactory(OldRenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id,
mojom::RendererAudioInputStreamFactoryRequest request);
~RenderFrameAudioInputStreamFactoryHandle();
private:
RenderFrameAudioInputStreamFactoryHandle(
OldRenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id);
void Init(mojom::RendererAudioInputStreamFactoryRequest request);
OldRenderFrameAudioInputStreamFactory impl_;
mojo::Binding<mojom::RendererAudioInputStreamFactory> binding_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactoryHandle);
};
using UniqueAudioInputStreamFactoryPtr =
std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>;
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_OLD_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
// Copyright 2017 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 "content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.h"
#include <limits>
#include <utility>
#include "base/bind.h"
#include "base/memory/shared_memory.h"
#include "base/memory/shared_memory_handle.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/sync_socket.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/audio/audio_system_impl.h"
#include "media/audio/mock_audio_manager.h"
#include "media/audio/test_audio_thread.h"
#include "media/base/audio_parameters.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
using testing::Test;
const size_t kShmemSize = 1234;
const int kSessionId = 234;
const bool kAGC = false;
const uint32_t kSharedMemoryCount = 345;
const int kSampleFrequency = 44100;
const int kSamplesPerBuffer = kSampleFrequency / 100;
const bool kInitiallyMuted = false;
const int kRenderProcessID = -1;
const int kRenderFrameID = MSG_ROUTING_NONE;
media::AudioParameters GetTestAudioParameters() {
return media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::CHANNEL_LAYOUT_MONO, kSampleFrequency,
kSamplesPerBuffer);
}
class FakeAudioInputDelegate : public media::AudioInputDelegate {
public:
FakeAudioInputDelegate() {}
~FakeAudioInputDelegate() override {}
int GetStreamId() override { return 0; };
void OnRecordStream() override{};
void OnSetVolume(double volume) override{};
private:
DISALLOW_COPY_AND_ASSIGN(FakeAudioInputDelegate);
};
class FakeAudioInputStreamClient : public media::mojom::AudioInputStreamClient {
public:
void OnMutedStateChanged(bool is_muted) override {}
void OnError() override {}
};
class MockRendererAudioInputStreamFactoryClient
: public mojom::RendererAudioInputStreamFactoryClient {
public:
MOCK_METHOD0(Created, void());
void StreamCreated(media::mojom::AudioInputStreamPtr input_stream,
media::mojom::AudioInputStreamClientRequest client_request,
media::mojom::AudioDataPipePtr data_pipe,
bool initially_muted) override {
Created();
}
};
// Creates a fake delegate and saves the provided event handler in
// |event_handler_out|.
std::unique_ptr<media::AudioInputDelegate> CreateFakeDelegate(
media::AudioInputDelegate::EventHandler** event_handler_out,
AudioInputDeviceManager* audio_input_device_manager,
media::mojom::AudioLogPtr audio_log,
AudioInputDeviceManager::KeyboardMicRegistration keyboard_mic_registration,
uint32_t shared_memory_count,
int stream_id,
int session_id,
bool automatic_gain_control,
const media::AudioParameters& parameters,
media::AudioInputDelegate::EventHandler* event_handler) {
*event_handler_out = event_handler;
return std::make_unique<FakeAudioInputDelegate>();
}
} // namespace
class OldOldRenderFrameAudioInputStreamFactoryTest : public testing::Test {
public:
OldOldRenderFrameAudioInputStreamFactoryTest()
: thread_bundle_(base::in_place),
audio_manager_(std::make_unique<media::TestAudioThread>()),
audio_system_(&audio_manager_),
media_stream_manager_(&audio_system_, audio_manager_.GetTaskRunner()),
client_binding_(&client_, mojo::MakeRequest(&client_ptr_)),
factory_handle_(RenderFrameAudioInputStreamFactoryHandle::CreateFactory(
base::BindRepeating(&CreateFakeDelegate, &event_handler_),
&media_stream_manager_,
kRenderProcessID,
kRenderFrameID,
mojo::MakeRequest(&factory_ptr_))) {}
~OldOldRenderFrameAudioInputStreamFactoryTest() override {
audio_manager_.Shutdown();
// UniqueAudioInputStreamFactoryPtr uses DeleteOnIOThread and must run
// before |thread_bundle_| tear down.
factory_handle_.reset();
// Shutdown BrowserThread::IO before tearing down members.
thread_bundle_.reset();
}
// |thread_bundle_| needs to be up before the members below (as they use
// BrowserThreads for their initialization) but then needs to be torn down
// before them as some verify they're town down in a single-threaded
// environment (while
// !BrowserThread::IsThreadInitiaslized(BrowserThread::IO)).
base::Optional<TestBrowserThreadBundle> thread_bundle_;
// These members need to be torn down after |thread_bundle_|.
media::MockAudioManager audio_manager_;
media::AudioSystemImpl audio_system_;
MediaStreamManager media_stream_manager_;
mojom::RendererAudioInputStreamFactoryPtr factory_ptr_;
media::mojom::AudioInputStreamPtr stream_ptr_;
MockRendererAudioInputStreamFactoryClient client_;
mojom::RendererAudioInputStreamFactoryClientPtr client_ptr_;
media::AudioInputDelegate::EventHandler* event_handler_ = nullptr;
mojo::Binding<mojom::RendererAudioInputStreamFactoryClient> client_binding_;
UniqueAudioInputStreamFactoryPtr factory_handle_;
};
TEST_F(OldOldRenderFrameAudioInputStreamFactoryTest, CreateStream) {
factory_ptr_->CreateStream(std::move(client_ptr_), kSessionId,
GetTestAudioParameters(), kAGC,
kSharedMemoryCount);
// Wait for delegate to be created and |event_handler| set.
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(event_handler_);
base::SharedMemoryCreateOptions shmem_options;
shmem_options.size = kShmemSize;
shmem_options.share_read_only = true;
base::SharedMemory shared_memory;
shared_memory.Create(shmem_options);
shared_memory.Map(kShmemSize);
auto local = std::make_unique<base::CancelableSyncSocket>();
auto remote = std::make_unique<base::CancelableSyncSocket>();
ASSERT_TRUE(
base::CancelableSyncSocket::CreatePair(local.get(), remote.get()));
event_handler_->OnStreamCreated(/*stream_id, irrelevant*/ 0, &shared_memory,
std::move(remote), kInitiallyMuted);
EXPECT_CALL(client_, Created());
base::RunLoop().RunUntilIdle();
}
} // namespace content
// Copyright 2017 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -6,80 +6,48 @@ ...@@ -6,80 +6,48 @@
#include <utility> #include <utility>
#include "base/feature_list.h" #include "content/browser/media/capture/desktop_capture_device_uma_types.h"
#include "base/task_runner_util.h" #include "content/browser/media/forwarding_audio_stream_factory.h"
#include "content/browser/media/media_internals.h" #include "content/public/browser/browser_thread.h"
#include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/public/browser/web_contents_media_capture_id.h"
#include "content/public/common/content_features.h" #include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_input_device.h"
#include "media/base/audio_parameters.h" #include "media/base/audio_parameters.h"
namespace content { namespace content {
// static namespace {
std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
RenderFrameAudioInputStreamFactoryHandle::CreateFactory(
RenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
content::MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id,
mojom::RendererAudioInputStreamFactoryRequest request) {
std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
handle(new RenderFrameAudioInputStreamFactoryHandle(
std::move(create_delegate_callback), media_stream_manager,
render_process_id, render_frame_id));
// Unretained is safe since |*handle| must be posted to the IO thread prior to
// deletion.
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&RenderFrameAudioInputStreamFactoryHandle::Init,
base::Unretained(handle.get()), std::move(request)));
return handle;
}
RenderFrameAudioInputStreamFactoryHandle:: void LookUpDeviceAndRespondIfFound(
~RenderFrameAudioInputStreamFactoryHandle() { scoped_refptr<AudioInputDeviceManager> audio_input_device_manager,
int32_t session_id,
base::OnceCallback<void(const MediaStreamDevice&)> response) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
const MediaStreamDevice* device =
audio_input_device_manager->GetOpenedDeviceById(session_id);
if (device) {
// Copies device.
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(response), *device));
}
} }
RenderFrameAudioInputStreamFactoryHandle:: } // namespace
RenderFrameAudioInputStreamFactoryHandle(
RenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id)
: impl_(std::move(create_delegate_callback),
media_stream_manager,
render_process_id,
render_frame_id),
binding_(&impl_) {}
void RenderFrameAudioInputStreamFactoryHandle::Init(
mojom::RendererAudioInputStreamFactoryRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
binding_.Bind(std::move(request));
}
RenderFrameAudioInputStreamFactory::RenderFrameAudioInputStreamFactory( RenderFrameAudioInputStreamFactory::RenderFrameAudioInputStreamFactory(
CreateDelegateCallback create_delegate_callback, mojom::RendererAudioInputStreamFactoryRequest request,
MediaStreamManager* media_stream_manager, scoped_refptr<AudioInputDeviceManager> audio_input_device_manager,
int render_process_id, RenderFrameHost* render_frame_host)
int render_frame_id) : binding_(this, std::move(request)),
: create_delegate_callback_(std::move(create_delegate_callback)), audio_input_device_manager_(std::move(audio_input_device_manager)),
media_stream_manager_(media_stream_manager), render_frame_host_(render_frame_host),
render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(create_delegate_callback_); DCHECK_CURRENTLY_ON(BrowserThread::UI);
// No thread-hostile state has been initialized yet, so we don't have to bind
// to this specific thread.
} }
RenderFrameAudioInputStreamFactory::~RenderFrameAudioInputStreamFactory() { RenderFrameAudioInputStreamFactory::~RenderFrameAudioInputStreamFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::UI);
} }
void RenderFrameAudioInputStreamFactory::CreateStream( void RenderFrameAudioInputStreamFactory::CreateStream(
...@@ -88,58 +56,48 @@ void RenderFrameAudioInputStreamFactory::CreateStream( ...@@ -88,58 +56,48 @@ void RenderFrameAudioInputStreamFactory::CreateStream(
const media::AudioParameters& audio_params, const media::AudioParameters& audio_params,
bool automatic_gain_control, bool automatic_gain_control,
uint32_t shared_memory_count) { uint32_t shared_memory_count) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
#if defined(OS_CHROMEOS) BrowserThread::IO, FROM_HERE,
if (audio_params.channel_layout() == base::BindOnce(
media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { &LookUpDeviceAndRespondIfFound, audio_input_device_manager_,
media_stream_manager_->audio_input_device_manager() session_id,
->RegisterKeyboardMicStream(base::BindOnce( base::BindOnce(&RenderFrameAudioInputStreamFactory::
&RenderFrameAudioInputStreamFactory::DoCreateStream, CreateStreamAfterLookingUpDevice,
weak_ptr_factory_.GetWeakPtr(), std::move(client), session_id, weak_ptr_factory_.GetWeakPtr(), std::move(client),
audio_params, automatic_gain_control, shared_memory_count)); audio_params, automatic_gain_control,
return; shared_memory_count)));
}
#endif
DoCreateStream(std::move(client), session_id, audio_params,
automatic_gain_control, shared_memory_count,
AudioInputDeviceManager::KeyboardMicRegistration());
} }
void RenderFrameAudioInputStreamFactory::DoCreateStream( void RenderFrameAudioInputStreamFactory::CreateStreamAfterLookingUpDevice(
mojom::RendererAudioInputStreamFactoryClientPtr client, mojom::RendererAudioInputStreamFactoryClientPtr client,
int session_id,
const media::AudioParameters& audio_params, const media::AudioParameters& audio_params,
bool automatic_gain_control, bool automatic_gain_control,
uint32_t shared_memory_count, uint32_t shared_memory_count,
AudioInputDeviceManager::KeyboardMicRegistration const MediaStreamDevice& device) {
keyboard_mic_registration) { DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK_CURRENTLY_ON(BrowserThread::IO); ForwardingAudioStreamFactory* factory =
int stream_id = ++next_stream_id_; ForwardingAudioStreamFactory::ForFrame(render_frame_host_);
if (!factory)
media::mojom::AudioLogPtr audio_log_ptr = return;
MediaInternals::GetInstance()->CreateMojoAudioLog(
media::AudioLogFactory::AUDIO_INPUT_CONTROLLER, stream_id,
render_process_id_, render_frame_id_);
// Unretained is safe since |this| owns |streams_|.
streams_.insert(std::make_unique<AudioInputStreamHandle>(
std::move(client),
base::BindOnce(
create_delegate_callback_,
base::Unretained(media_stream_manager_->audio_input_device_manager()),
std::move(audio_log_ptr), std::move(keyboard_mic_registration),
shared_memory_count, stream_id, session_id, automatic_gain_control,
audio_params),
base::BindOnce(&RenderFrameAudioInputStreamFactory::RemoveStream,
weak_ptr_factory_.GetWeakPtr())));
}
void RenderFrameAudioInputStreamFactory::RemoveStream(
AudioInputStreamHandle* stream) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
streams_.erase(stream); if (WebContentsMediaCaptureId::Parse(device.id, nullptr)) {
CHECK(false) << "TODO(https://crbug.com/824019) not implemented.";
if (device.type == MEDIA_DESKTOP_AUDIO_CAPTURE)
IncrementDesktopCaptureCounter(SYSTEM_LOOPBACK_AUDIO_CAPTURER_CREATED);
} else {
factory->CreateInputStream(render_frame_host_, device.id, audio_params,
shared_memory_count, automatic_gain_control,
std::move(client));
// Only count for captures from desktop media picker dialog and system loop
// back audio.
if (device.type == MEDIA_DESKTOP_AUDIO_CAPTURE &&
(media::AudioDeviceDescription::IsLoopbackDevice(device.id))) {
IncrementDesktopCaptureCounter(SYSTEM_LOOPBACK_AUDIO_CAPTURER_CREATED);
}
}
} }
} // namespace content } // namespace content
// Copyright 2017 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -6,22 +6,13 @@ ...@@ -6,22 +6,13 @@
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_ #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
#include <cstdint> #include <cstdint>
#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/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/scoped_refptr.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h" #include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/audio_input_stream_handle.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 "content/common/media/renderer_audio_input_stream_factory.mojom.h"
#include "content/public/browser/browser_thread.h" #include "content/public/common/media_stream_request.h"
#include "media/audio/audio_input_delegate.h"
#include "media/mojo/interfaces/audio_logging.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
namespace media { namespace media {
...@@ -30,7 +21,8 @@ class AudioParameters; ...@@ -30,7 +21,8 @@ class AudioParameters;
namespace content { namespace content {
class MediaStreamManager; class AudioInputDeviceManager;
class RenderFrameHost;
// Handles a RendererAudioInputStreamFactory request for a render frame host, // Handles a RendererAudioInputStreamFactory request for a render frame host,
// using the provided RendererAudioInputStreamFactoryContext. This class may // using the provided RendererAudioInputStreamFactoryContext. This class may
...@@ -39,31 +31,14 @@ class MediaStreamManager; ...@@ -39,31 +31,14 @@ class MediaStreamManager;
class CONTENT_EXPORT RenderFrameAudioInputStreamFactory class CONTENT_EXPORT RenderFrameAudioInputStreamFactory
: public mojom::RendererAudioInputStreamFactory { : public mojom::RendererAudioInputStreamFactory {
public: public:
using CreateDelegateCallback =
base::RepeatingCallback<std::unique_ptr<media::AudioInputDelegate>(
AudioInputDeviceManager* audio_input_device_manager,
media::mojom::AudioLogPtr audio_log,
AudioInputDeviceManager::KeyboardMicRegistration
keyboard_mic_registration,
uint32_t shared_memory_count,
int stream_id,
int session_id,
bool automatic_gain_control,
const media::AudioParameters& parameters,
media::AudioInputDelegate::EventHandler* event_handler)>;
RenderFrameAudioInputStreamFactory( RenderFrameAudioInputStreamFactory(
CreateDelegateCallback create_delegate_callback, mojom::RendererAudioInputStreamFactoryRequest request,
MediaStreamManager* media_stream_manager, scoped_refptr<AudioInputDeviceManager> audio_input_device_manager,
int render_process_id, RenderFrameHost* render_frame_host);
int render_frame_id);
~RenderFrameAudioInputStreamFactory() override; ~RenderFrameAudioInputStreamFactory() override;
private: private:
using InputStreamSet = base::flat_set<std::unique_ptr<AudioInputStreamHandle>,
base::UniquePtrComparator>;
// mojom::RendererAudioInputStreamFactory implementation. // mojom::RendererAudioInputStreamFactory implementation.
void CreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client, void CreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client,
int32_t session_id, int32_t session_id,
...@@ -71,65 +46,22 @@ class CONTENT_EXPORT RenderFrameAudioInputStreamFactory ...@@ -71,65 +46,22 @@ class CONTENT_EXPORT RenderFrameAudioInputStreamFactory
bool automatic_gain_control, bool automatic_gain_control,
uint32_t shared_memory_count) override; uint32_t shared_memory_count) override;
void DoCreateStream(mojom::RendererAudioInputStreamFactoryClientPtr client, void CreateStreamAfterLookingUpDevice(
int session_id, mojom::RendererAudioInputStreamFactoryClientPtr client,
const media::AudioParameters& audio_params, const media::AudioParameters& audio_params,
bool automatic_gain_control, bool automatic_gain_control,
uint32_t shared_memory_count, uint32_t shared_memory_count,
AudioInputDeviceManager::KeyboardMicRegistration const MediaStreamDevice& device);
keyboard_mic_registration);
void RemoveStream(AudioInputStreamHandle* input_stream);
const CreateDelegateCallback create_delegate_callback_;
MediaStreamManager* media_stream_manager_;
const int render_process_id_;
const int render_frame_id_;
InputStreamSet streams_; const mojo::Binding<RendererAudioInputStreamFactory> binding_;
int next_stream_id_ = 0; const scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
RenderFrameHost* const render_frame_host_;
base::WeakPtrFactory<RenderFrameAudioInputStreamFactory> weak_ptr_factory_; base::WeakPtrFactory<RenderFrameAudioInputStreamFactory> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactory); DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactory);
}; };
// This class is a convenient bundle of factory and binding.
// It can be created on any thread, but should be destroyed on the IO thread
// (hence the DeleteOnIOThread pointer).
class CONTENT_EXPORT RenderFrameAudioInputStreamFactoryHandle {
public:
static std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>
CreateFactory(RenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id,
mojom::RendererAudioInputStreamFactoryRequest request);
~RenderFrameAudioInputStreamFactoryHandle();
private:
RenderFrameAudioInputStreamFactoryHandle(
RenderFrameAudioInputStreamFactory::CreateDelegateCallback
create_delegate_callback,
MediaStreamManager* media_stream_manager,
int render_process_id,
int render_frame_id);
void Init(mojom::RendererAudioInputStreamFactoryRequest request);
RenderFrameAudioInputStreamFactory impl_;
mojo::Binding<mojom::RendererAudioInputStreamFactory> binding_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactoryHandle);
};
using UniqueAudioInputStreamFactoryPtr =
std::unique_ptr<RenderFrameAudioInputStreamFactoryHandle,
BrowserThread::DeleteOnIOThread>;
} // namespace content } // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_ #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
...@@ -112,7 +112,6 @@ ...@@ -112,7 +112,6 @@
#include "content/browser/renderer_host/file_utilities_host_impl.h" #include "content/browser/renderer_host/file_utilities_host_impl.h"
#include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/peer_connection_tracker_host.h" #include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h"
#include "content/browser/renderer_host/media/video_capture_host.h" #include "content/browser/renderer_host/media/video_capture_host.h"
#include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_message_filter.h"
#include "content/browser/renderer_host/pepper/pepper_renderer_connection.h" #include "content/browser/renderer_host/pepper/pepper_renderer_connection.h"
......
...@@ -1435,6 +1435,7 @@ test("content_unittests") { ...@@ -1435,6 +1435,7 @@ test("content_unittests") {
"../browser/renderer_host/media/media_stream_ui_proxy_unittest.cc", "../browser/renderer_host/media/media_stream_ui_proxy_unittest.cc",
"../browser/renderer_host/media/mock_video_capture_provider.cc", "../browser/renderer_host/media/mock_video_capture_provider.cc",
"../browser/renderer_host/media/mock_video_capture_provider.h", "../browser/renderer_host/media/mock_video_capture_provider.h",
"../browser/renderer_host/media/old_render_frame_audio_input_stream_factory_unittest.cc",
"../browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc", "../browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc",
"../browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc", "../browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc",
"../browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc", "../browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc",
......
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