Commit b47670a1 authored by Darin Fisher's avatar Darin Fisher Committed by Commit Bot

Migrate aec_dump_messages.h to Mojo

A nice side-effect of this change is that it moves complexity out of
RenderProcessHostImpl.

Bug: 967834
Change-Id: I39e93344e1db84668ef11b535447160ee3ab54cd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1654238Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Commit-Queue: Darin Fisher <darin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#668864}
parent 8cc8d4b8
...@@ -1545,6 +1545,8 @@ jumbo_source_set("browser") { ...@@ -1545,6 +1545,8 @@ jumbo_source_set("browser") {
"renderer_host/input_event_shim.h", "renderer_host/input_event_shim.h",
"renderer_host/legacy_render_widget_host_win.cc", "renderer_host/legacy_render_widget_host_win.cc",
"renderer_host/legacy_render_widget_host_win.h", "renderer_host/legacy_render_widget_host_win.h",
"renderer_host/media/aec_dump_manager_impl.cc",
"renderer_host/media/aec_dump_manager_impl.h",
"renderer_host/media/audio_input_delegate_impl.cc", "renderer_host/media/audio_input_delegate_impl.cc",
"renderer_host/media/audio_input_delegate_impl.h", "renderer_host/media/audio_input_delegate_impl.h",
"renderer_host/media/audio_input_device_manager.cc", "renderer_host/media/audio_input_device_manager.cc",
......
// Copyright 2019 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/aec_dump_manager_impl.h"
#include "base/files/file.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "content/browser/webrtc/webrtc_internals.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/base/file_mojom_traits.h"
namespace content {
namespace {
constexpr char kAecDumpFileNameAddition[] = "aec_dump";
base::File CreateDumpFile(const base::FilePath& file_path) {
return base::File(file_path,
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
}
} // namespace
AecDumpManagerImpl::AecDumpManagerImpl() = default;
AecDumpManagerImpl::~AecDumpManagerImpl() = default;
void AecDumpManagerImpl::AddRequest(
mojo::InterfaceRequest<mojom::AecDumpManager> request) {
receiver_set_.Add(this, std::move(request));
}
void AecDumpManagerImpl::AutoStart(base::ProcessId pid) {
WebRTCInternals* webrtc_internals = WebRTCInternals::GetInstance();
if (webrtc_internals->IsAudioDebugRecordingsEnabled())
Start(pid, webrtc_internals->GetAudioDebugRecordingsFilePath());
}
void AecDumpManagerImpl::Start(base::ProcessId pid,
const base::FilePath& file_path) {
base::FilePath file_path_extended =
file_path.AddExtensionASCII(base::NumberToString(pid))
.AddExtensionASCII(kAecDumpFileNameAddition);
for (auto& it : agents_)
CreateFileAndStartDump(file_path_extended, it.first);
}
void AecDumpManagerImpl::Stop() {
for (auto& it : agents_)
it.second->Stop();
}
void AecDumpManagerImpl::Add(mojo::PendingRemote<mojom::AecDumpAgent> agent) {
int id = ++id_counter_;
agents_.emplace(std::make_pair(id, std::move(agent)));
agents_[id].set_disconnect_handler(
base::BindOnce(&AecDumpManagerImpl::OnAgentDisconnected,
weak_factory_.GetWeakPtr(), id));
WebRTCInternals* webrtc_internals = WebRTCInternals::GetInstance();
if (webrtc_internals->IsAudioDebugRecordingsEnabled()) {
CreateFileAndStartDump(webrtc_internals->GetAudioDebugRecordingsFilePath(),
id);
}
}
void AecDumpManagerImpl::CreateFileAndStartDump(const base::FilePath& file_path,
int id) {
base::PostTaskAndReplyWithResult(
FROM_HERE,
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
base::TaskPriority::USER_BLOCKING},
base::BindOnce(&CreateDumpFile,
file_path.AddExtensionASCII(base::NumberToString(id))),
base::BindOnce(&AecDumpManagerImpl::StartDump, weak_factory_.GetWeakPtr(),
id));
}
void AecDumpManagerImpl::StartDump(int id, base::File file) {
if (!file.IsValid()) {
VLOG(1) << "Could not open AEC dump file, error=" << file.error_details();
return;
}
auto it = agents_.find(id);
if (it == agents_.end()) {
// Post the file close to avoid blocking the current thread.
base::PostTaskWithTraits(
FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()},
base::BindOnce([](base::File) {}, std::move(file)));
return;
}
it->second->Start(std::move(file));
}
void AecDumpManagerImpl::OnAgentDisconnected(int id) {
agents_.erase(id);
}
} // namespace content
// Copyright 2019 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_AEC_DUMP_MANAGER_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_AEC_DUMP_MANAGER_IMPL_H_
#include <map>
#include <memory>
#include "base/process/process_handle.h"
#include "content/common/media/aec_dump.mojom.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
namespace base {
class File;
class FilePath;
} // namespace base
namespace content {
class AecDumpManagerImpl : public mojom::AecDumpManager {
public:
AecDumpManagerImpl();
~AecDumpManagerImpl() override;
void AddRequest(mojo::InterfaceRequest<mojom::AecDumpManager> request);
// Start generating AEC dumps using default settings.
void AutoStart(base::ProcessId pid);
// Start generating AEC dumps using a specific file path prefix.
void Start(base::ProcessId pid, const base::FilePath& file_path);
// Stop generating AEC dumps.
void Stop();
// mojom::AecDumpManager methods:
void Add(mojo::PendingRemote<mojom::AecDumpAgent> agent) override;
private:
void CreateFileAndStartDump(const base::FilePath& file_path, int id);
void StartDump(int id, base::File file);
void OnAgentDisconnected(int id);
std::map<int /* id */, mojo::Remote<mojom::AecDumpAgent>> agents_;
int id_counter_ = 0;
mojo::ReceiverSet<mojom::AecDumpManager> receiver_set_;
base::WeakPtrFactory<AecDumpManagerImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(AecDumpManagerImpl);
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_AEC_DUMP_MANAGER_IMPL_H_
...@@ -135,14 +135,12 @@ ...@@ -135,14 +135,12 @@
#include "content/browser/site_instance_impl.h" #include "content/browser/site_instance_impl.h"
#include "content/browser/storage_partition_impl.h" #include "content/browser/storage_partition_impl.h"
#include "content/browser/tracing/background_tracing_manager_impl.h" #include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/webrtc/webrtc_internals.h"
#include "content/browser/websockets/websocket_manager.h" #include "content/browser/websockets/websocket_manager.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/common/child_process_host_impl.h" #include "content/common/child_process_host_impl.h"
#include "content/common/content_switches_internal.h" #include "content/common/content_switches_internal.h"
#include "content/common/frame_messages.h" #include "content/common/frame_messages.h"
#include "content/common/in_process_child_thread_params.h" #include "content/common/in_process_child_thread_params.h"
#include "content/common/media/aec_dump_messages.h"
#include "content/common/media/peer_connection_tracker_messages.h" #include "content/common/media/peer_connection_tracker_messages.h"
#include "content/common/resource_messages.h" #include "content/common/resource_messages.h"
#include "content/common/service_manager/child_connection.h" #include "content/common/service_manager/child_connection.h"
...@@ -269,12 +267,6 @@ ...@@ -269,12 +267,6 @@
#include "services/service_manager/zygote/common/zygote_handle.h" // nogncheck #include "services/service_manager/zygote/common/zygote_handle.h" // nogncheck
#endif #endif
#if defined(OS_WIN)
#define NumberToStringType base::NumberToString16
#else
#define NumberToStringType base::NumberToString
#endif
namespace content { namespace content {
namespace { namespace {
...@@ -295,9 +287,6 @@ const char kSiteProcessMapKeyName[] = "content_site_process_map"; ...@@ -295,9 +287,6 @@ const char kSiteProcessMapKeyName[] = "content_site_process_map";
RenderProcessHost::AnalyzeHungRendererFunction g_analyze_hung_renderer = RenderProcessHost::AnalyzeHungRendererFunction g_analyze_hung_renderer =
nullptr; nullptr;
const base::FilePath::CharType kAecDumpFileNameAddition[] =
FILE_PATH_LITERAL("aec_dump");
void CacheShaderInfo(int32_t id, base::FilePath path) { void CacheShaderInfo(int32_t id, base::FilePath path) {
if (GetShaderCacheFactorySingleton()) if (GetShaderCacheFactorySingleton())
GetShaderCacheFactorySingleton()->SetCacheInfo(id, path); GetShaderCacheFactorySingleton()->SetCacheInfo(id, path);
...@@ -332,18 +321,6 @@ void GetContexts( ...@@ -332,18 +321,6 @@ void GetContexts(
GetRequestContext(request_context, media_request_context, resource_type); GetRequestContext(request_context, media_request_context, resource_type);
} }
// Creates a file used for handing over to the renderer.
IPC::PlatformFileForTransit CreateFileForProcess(base::FilePath file_path) {
base::File dump_file(file_path,
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_APPEND);
if (!dump_file.IsValid()) {
VLOG(1) << "Could not open AEC dump file, error="
<< dump_file.error_details();
return IPC::InvalidPlatformFileForTransit();
}
return IPC::TakePlatformFileForTransit(std::move(dump_file));
}
// Allow us to only run the trial in the first renderer. // Allow us to only run the trial in the first renderer.
bool has_done_stun_trials = false; bool has_done_stun_trials = false;
...@@ -2194,6 +2171,11 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() { ...@@ -2194,6 +2171,11 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::BindRepeating(&RenderProcessHostImpl::BindVideoDecoderService, base::BindRepeating(&RenderProcessHostImpl::BindVideoDecoderService,
base::Unretained(this))); base::Unretained(this)));
AddUIThreadInterface(
registry.get(),
base::BindRepeating(&AecDumpManagerImpl::AddRequest,
base::Unretained(&aec_dump_manager_)));
// ---- Please do not register interfaces below this line ------ // ---- Please do not register interfaces below this line ------
// //
// This call should be done after registering all interfaces above, so that // This call should be done after registering all interfaces above, so that
...@@ -3277,10 +3259,6 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) { ...@@ -3277,10 +3259,6 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction) OnUserMetricsRecordAction)
IPC_MESSAGE_HANDLER(WidgetHostMsg_Close_ACK, OnCloseACK) IPC_MESSAGE_HANDLER(WidgetHostMsg_Close_ACK, OnCloseACK)
IPC_MESSAGE_HANDLER(AecDumpMsg_RegisterAecDumpConsumer,
OnRegisterAecDumpConsumer)
IPC_MESSAGE_HANDLER(AecDumpMsg_UnregisterAecDumpConsumer,
OnUnregisterAecDumpConsumer)
// Adding single handlers for your service here is fine, but once your // Adding single handlers for your service here is fine, but once your
// service needs more than one handler, please extract them into a new // service needs more than one handler, please extract them into a new
// message filter and add that filter to CreateMessageFilters(). // message filter and add that filter to CreateMessageFilters().
...@@ -3547,26 +3525,16 @@ void RenderProcessHostImpl::FilterURL(bool empty_allowed, GURL* url) { ...@@ -3547,26 +3525,16 @@ void RenderProcessHostImpl::FilterURL(bool empty_allowed, GURL* url) {
} }
void RenderProcessHostImpl::EnableAudioDebugRecordings( void RenderProcessHostImpl::EnableAudioDebugRecordings(
const base::FilePath& file) { const base::FilePath& file_path) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Enable AEC dump for each registered consumer. aec_dump_manager_.Start(GetProcess().Pid(), file_path);
base::FilePath file_with_extensions = GetAecDumpFilePathWithExtensions(file);
for (int id : aec_dump_consumers_) {
EnableAecDumpForId(file_with_extensions, id);
}
} }
void RenderProcessHostImpl::DisableAudioDebugRecordings() { void RenderProcessHostImpl::DisableAudioDebugRecordings() {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Posting on the sequence and then replying back on the UI thread is only aec_dump_manager_.Stop();
// for avoiding races between enable and disable. Nothing is done on the
// sequence.
GetAecDumpFileTaskRunner().PostTaskAndReply(
FROM_HERE, base::DoNothing(),
base::BindOnce(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
weak_factory_.GetWeakPtr()));
} }
RenderProcessHostImpl::WebRtcStopRtpDumpCallback RenderProcessHostImpl::WebRtcStopRtpDumpCallback
...@@ -4472,11 +4440,7 @@ void RenderProcessHostImpl::OnProcessLaunched() { ...@@ -4472,11 +4440,7 @@ void RenderProcessHostImpl::OnProcessLaunched() {
observer.RenderProcessReady(this); observer.RenderProcessReady(this);
} }
WebRTCInternals* webrtc_internals = WebRTCInternals::GetInstance(); aec_dump_manager_.AutoStart(GetProcess().Pid());
if (webrtc_internals->IsAudioDebugRecordingsEnabled()) {
EnableAudioDebugRecordings(
webrtc_internals->GetAudioDebugRecordingsFilePath());
}
} }
void RenderProcessHostImpl::OnProcessLaunchFailed(int error_code) { void RenderProcessHostImpl::OnProcessLaunchFailed(int error_code) {
...@@ -4576,80 +4540,6 @@ void RenderProcessHostImpl::CreateMdnsResponder( ...@@ -4576,80 +4540,6 @@ void RenderProcessHostImpl::CreateMdnsResponder(
} }
#endif // BUILDFLAG(ENABLE_MDNS) #endif // BUILDFLAG(ENABLE_MDNS)
void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread,
weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread(int id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
aec_dump_consumers_.push_back(id);
WebRTCInternals* webrtc_internals = WebRTCInternals::GetInstance();
if (webrtc_internals->IsAudioDebugRecordingsEnabled()) {
base::FilePath file_with_extensions = GetAecDumpFilePathWithExtensions(
webrtc_internals->GetAudioDebugRecordingsFilePath());
EnableAecDumpForId(file_with_extensions, id);
}
}
void RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread(int id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto it =
std::find(aec_dump_consumers_.begin(), aec_dump_consumers_.end(), id);
if (it != aec_dump_consumers_.end())
aec_dump_consumers_.erase(it);
}
void RenderProcessHostImpl::EnableAecDumpForId(const base::FilePath& file,
int id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::PostTaskAndReplyWithResult(
&GetAecDumpFileTaskRunner(), FROM_HERE,
base::Bind(&CreateFileForProcess,
file.AddExtension(NumberToStringType(id))),
base::Bind(&RenderProcessHostImpl::SendAecDumpFileToRenderer,
weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::SendAecDumpFileToRenderer(
int id,
IPC::PlatformFileForTransit file_for_transit) {
if (file_for_transit == IPC::InvalidPlatformFileForTransit())
return;
Send(new AecDumpMsg_EnableAecDump(id, file_for_transit));
}
void RenderProcessHostImpl::SendDisableAecDumpToRenderer() {
Send(new AecDumpMsg_DisableAecDump());
}
base::FilePath RenderProcessHostImpl::GetAecDumpFilePathWithExtensions(
const base::FilePath& file) {
return file.AddExtension(NumberToStringType(GetProcess().Pid()))
.AddExtension(kAecDumpFileNameAddition);
}
base::SequencedTaskRunner& RenderProcessHostImpl::GetAecDumpFileTaskRunner() {
if (!audio_debug_recordings_file_task_runner_) {
audio_debug_recordings_file_task_runner_ =
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
base::TaskPriority::USER_BLOCKING});
}
return *audio_debug_recordings_file_task_runner_;
}
// static // static
void RenderProcessHostImpl::OnMojoError(int render_process_id, void RenderProcessHostImpl::OnMojoError(int render_process_id,
const std::string& error) { const std::string& error) {
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "content/browser/media/video_decoder_proxy.h" #include "content/browser/media/video_decoder_proxy.h"
#include "content/browser/renderer_host/embedded_frame_sink_provider_impl.h" #include "content/browser/renderer_host/embedded_frame_sink_provider_impl.h"
#include "content/browser/renderer_host/frame_sink_provider_impl.h" #include "content/browser/renderer_host/frame_sink_provider_impl.h"
#include "content/browser/renderer_host/media/aec_dump_manager_impl.h"
#include "content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h" #include "content/browser/renderer_host/media/renderer_audio_output_stream_factory_context_impl.h"
#include "content/common/associated_interfaces.mojom.h" #include "content/common/associated_interfaces.mojom.h"
#include "content/common/child_control.mojom.h" #include "content/common/child_control.mojom.h"
...@@ -636,17 +637,6 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -636,17 +637,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
void CreateMdnsResponder(network::mojom::MdnsResponderRequest request); void CreateMdnsResponder(network::mojom::MdnsResponderRequest request);
#endif // BUILDFLAG(ENABLE_MDNS) #endif // BUILDFLAG(ENABLE_MDNS)
void OnRegisterAecDumpConsumer(int id);
void OnUnregisterAecDumpConsumer(int id);
void RegisterAecDumpConsumerOnUIThread(int id);
void UnregisterAecDumpConsumerOnUIThread(int id);
void EnableAecDumpForId(const base::FilePath& file, int id);
// Sends |file_for_transit| to the render process.
void SendAecDumpFileToRenderer(int id,
IPC::PlatformFileForTransit file_for_transit);
void SendDisableAecDumpToRenderer();
base::FilePath GetAecDumpFilePathWithExtensions(const base::FilePath& file);
base::SequencedTaskRunner& GetAecDumpFileTaskRunner();
void NotifyRendererIfLockedToSite(); void NotifyRendererIfLockedToSite();
void PopulateTerminationInfoRendererFields(ChildProcessTerminationInfo* info); void PopulateTerminationInfoRendererFields(ChildProcessTerminationInfo* info);
...@@ -839,13 +829,10 @@ class CONTENT_EXPORT RenderProcessHostImpl ...@@ -839,13 +829,10 @@ class CONTENT_EXPORT RenderProcessHostImpl
std::unique_ptr<P2PSocketDispatcherHost> p2p_socket_dispatcher_host_; std::unique_ptr<P2PSocketDispatcherHost> p2p_socket_dispatcher_host_;
// Must be accessed on UI thread. // Must be accessed on UI thread.
std::vector<int> aec_dump_consumers_; AecDumpManagerImpl aec_dump_manager_;
WebRtcStopRtpDumpCallback stop_rtp_dump_callback_; WebRtcStopRtpDumpCallback stop_rtp_dump_callback_;
scoped_refptr<base::SequencedTaskRunner>
audio_debug_recordings_file_task_runner_;
std::unique_ptr<MediaStreamTrackMetricsHost, BrowserThread::DeleteOnIOThread> std::unique_ptr<MediaStreamTrackMetricsHost, BrowserThread::DeleteOnIOThread>
media_stream_track_metrics_host_; media_stream_track_metrics_host_;
......
...@@ -176,7 +176,6 @@ source_set("common") { ...@@ -176,7 +176,6 @@ source_set("common") {
"mac/attributed_string_coder.mm", "mac/attributed_string_coder.mm",
"mac/font_loader.h", "mac/font_loader.h",
"mac/font_loader.mm", "mac/font_loader.mm",
"media/aec_dump_messages.h",
"media/cdm_info.cc", "media/cdm_info.cc",
"media/media_player_delegate_messages.h", "media/media_player_delegate_messages.h",
"media/peer_connection_tracker_messages.h", "media/peer_connection_tracker_messages.h",
...@@ -476,6 +475,7 @@ mojom("mojo_bindings") { ...@@ -476,6 +475,7 @@ mojom("mojo_bindings") {
"input/input_handler.mojom", "input/input_handler.mojom",
"input/input_injector.mojom", "input/input_injector.mojom",
"input/synchronous_compositor.mojom", "input/synchronous_compositor.mojom",
"media/aec_dump.mojom",
"media/peer_connection_tracker.mojom", "media/peer_connection_tracker.mojom",
"media/renderer_audio_input_stream_factory.mojom", "media/renderer_audio_input_stream_factory.mojom",
"media/renderer_audio_output_stream_factory.mojom", "media/renderer_audio_output_stream_factory.mojom",
......
...@@ -41,11 +41,6 @@ ...@@ -41,11 +41,6 @@
#ifndef CONTENT_COMMON_INPUT_MESSAGES_H_ #ifndef CONTENT_COMMON_INPUT_MESSAGES_H_
#error "Failed to include content/common/input_messages.h" #error "Failed to include content/common/input_messages.h"
#endif #endif
#undef CONTENT_COMMON_MEDIA_AEC_DUMP_MESSAGES_H_
#include "content/common/media/aec_dump_messages.h"
#ifndef CONTENT_COMMON_MEDIA_AEC_DUMP_MESSAGES_H_
#error "Failed to include content/common/media/aec_dump_messages.h"
#endif
#undef CONTENT_COMMON_MEDIA_MEDIA_PLAYER_DELEGATE_MESSAGES_H_ #undef CONTENT_COMMON_MEDIA_MEDIA_PLAYER_DELEGATE_MESSAGES_H_
#include "content/common/media/media_player_delegate_messages.h" #include "content/common/media/media_player_delegate_messages.h"
#ifndef CONTENT_COMMON_MEDIA_MEDIA_PLAYER_DELEGATE_MESSAGES_H_ #ifndef CONTENT_COMMON_MEDIA_MEDIA_PLAYER_DELEGATE_MESSAGES_H_
......
// Copyright 2019 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.
module content.mojom;
import "mojo/public/mojom/base/file.mojom";
// Interface used to start / stop writing out an AEC dump from a child process.
interface AecDumpAgent {
Start(mojo_base.mojom.File file);
Stop();
};
// Interface used to register child processes that can generate AEC dump files.
interface AecDumpManager {
// Register the provided |agent| until disconnected.
Add(pending_remote<AecDumpAgent> agent);
};
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_COMMON_MEDIA_AEC_DUMP_MESSAGES_H_
#define CONTENT_COMMON_MEDIA_AEC_DUMP_MESSAGES_H_
// IPC messages for the AEC dump.
#include "content/common/content_export.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
#define IPC_MESSAGE_START AecDumpMsgStart
// Messages sent from the browser to the renderer.
// The browser hands over a file handle to the consumer in the renderer
// identified by |id| to use for AEC dump.
IPC_MESSAGE_CONTROL2(AecDumpMsg_EnableAecDump,
int /* id */,
IPC::PlatformFileForTransit /* file_handle */)
// Tell the renderer to disable AEC dump in all consumers.
IPC_MESSAGE_CONTROL0(AecDumpMsg_DisableAecDump)
// Messages sent from the renderer to the browser.
// Registers a consumer with the browser. The consumer will then get a file
// handle when the dump is enabled.
IPC_MESSAGE_CONTROL1(AecDumpMsg_RegisterAecDumpConsumer,
int /* id */)
// Unregisters a consumer with the browser.
IPC_MESSAGE_CONTROL1(AecDumpMsg_UnregisterAecDumpConsumer,
int /* id */)
#endif // CONTENT_COMMON_MEDIA_AEC_DUMP_MESSAGES_H_
...@@ -71,6 +71,7 @@ const service_manager::Manifest& GetContentBrowserManifest() { ...@@ -71,6 +71,7 @@ const service_manager::Manifest& GetContentBrowserManifest() {
"blink.mojom.ReportingServiceProxy", "blink.mojom.ReportingServiceProxy",
"blink.mojom.StoragePartitionService", "blink.mojom.StoragePartitionService",
"blink.mojom.WebDatabaseHost", "blink.mojom.WebDatabaseHost",
"content.mojom.AecDumpManager",
"content.mojom.ClipboardHost", "content.mojom.ClipboardHost",
"content.mojom.FieldTrialRecorder", "content.mojom.FieldTrialRecorder",
"content.mojom.FrameSinkProvider", "content.mojom.FrameSinkProvider",
......
...@@ -200,8 +200,8 @@ target(link_target_type, "renderer") { ...@@ -200,8 +200,8 @@ target(link_target_type, "renderer") {
"media/renderer_webaudiodevice_impl.h", "media/renderer_webaudiodevice_impl.h",
"media/renderer_webmediaplayer_delegate.cc", "media/renderer_webmediaplayer_delegate.cc",
"media/renderer_webmediaplayer_delegate.h", "media/renderer_webmediaplayer_delegate.h",
"media/stream/aec_dump_message_filter.cc", "media/stream/aec_dump_agent_impl.cc",
"media/stream/aec_dump_message_filter.h", "media/stream/aec_dump_agent_impl.h",
"media/stream/apply_constraints_processor.cc", "media/stream/apply_constraints_processor.cc",
"media/stream/apply_constraints_processor.h", "media/stream/apply_constraints_processor.h",
"media/stream/audio_service_audio_processor_proxy.cc", "media/stream/audio_service_audio_processor_proxy.cc",
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/media/stream/aec_dump_agent_impl.h"
#include "content/public/child/child_thread.h"
#include "content/public/common/service_names.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/service_manager/public/cpp/connector.h"
namespace content {
// static
std::unique_ptr<AecDumpAgentImpl> AecDumpAgentImpl::Create(Delegate* delegate) {
if (!ChildThread::Get()) // Can be true in unit tests.
return nullptr;
mojo::Remote<mojom::AecDumpManager> manager;
ChildThread::Get()->GetConnector()->Connect(
mojom::kBrowserServiceName, manager.BindNewPipeAndPassReceiver());
mojo::PendingRemote<AecDumpAgent> remote;
auto receiver = remote.InitWithNewPipeAndPassReceiver();
manager->Add(std::move(remote));
return base::WrapUnique(new AecDumpAgentImpl(delegate, std::move(receiver)));
}
AecDumpAgentImpl::AecDumpAgentImpl(
Delegate* delegate,
mojo::PendingReceiver<mojom::AecDumpAgent> receiver)
: delegate_(delegate), receiver_(this, std::move(receiver)) {}
AecDumpAgentImpl::~AecDumpAgentImpl() = default;
void AecDumpAgentImpl::Start(base::File dump_file) {
delegate_->OnStartDump(std::move(dump_file));
}
void AecDumpAgentImpl::Stop() {
delegate_->OnStopDump();
}
} // namespace content
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_MEDIA_STREAM_AEC_DUMP_AGENT_IMPL_H_
#define CONTENT_RENDERER_MEDIA_STREAM_AEC_DUMP_AGENT_IMPL_H_
#include "base/macros.h"
#include "content/common/media/aec_dump.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace content {
// An instance of this class connects to the browser process to register for
// notifications to start / stop writing to a dump file.
class AecDumpAgentImpl : public mojom::AecDumpAgent {
public:
class Delegate {
public:
virtual void OnStartDump(base::File file) = 0;
virtual void OnStopDump() = 0;
};
// This may fail in unit tests, in which case a null object is returned.
static std::unique_ptr<AecDumpAgentImpl> Create(Delegate* delegate);
~AecDumpAgentImpl() override;
// AecDumpAgent methods:
void Start(base::File dump_file) override;
void Stop() override;
private:
explicit AecDumpAgentImpl(
Delegate* delegate,
mojo::PendingReceiver<mojom::AecDumpAgent> receiver);
Delegate* delegate_;
mojo::Receiver<mojom::AecDumpAgent> receiver_{this};
DISALLOW_COPY_AND_ASSIGN(AecDumpAgentImpl);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_STREAM_AEC_DUMP_AGENT_IMPL_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/media/stream/aec_dump_message_filter.h"
#include "base/bind.h"
#include "base/single_thread_task_runner.h"
#include "content/common/media/aec_dump_messages.h"
#include "content/renderer/media/webrtc_logging.h"
#include "ipc/ipc_logging.h"
#include "ipc/ipc_sender.h"
namespace {
const int kInvalidDelegateId = -1;
}
namespace content {
AecDumpMessageFilter* AecDumpMessageFilter::g_filter = nullptr;
AecDumpMessageFilter::AecDumpMessageFilter(
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
: sender_(nullptr),
delegate_id_counter_(1),
io_task_runner_(io_task_runner),
main_task_runner_(main_task_runner) {
DCHECK(!g_filter);
g_filter = this;
}
AecDumpMessageFilter::~AecDumpMessageFilter() {
DCHECK_EQ(g_filter, this);
g_filter = nullptr;
}
// static
scoped_refptr<AecDumpMessageFilter> AecDumpMessageFilter::Get() {
return g_filter;
}
void AecDumpMessageFilter::AddDelegate(
AecDumpMessageFilter::AecDumpDelegate* delegate) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
DCHECK(delegate);
DCHECK_EQ(kInvalidDelegateId, GetIdForDelegate(delegate));
int id = delegate_id_counter_++;
delegates_[id] = delegate;
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AecDumpMessageFilter::RegisterAecDumpConsumer, this, id));
}
void AecDumpMessageFilter::RemoveDelegate(
AecDumpMessageFilter::AecDumpDelegate* delegate) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
DCHECK(delegate);
int id = GetIdForDelegate(delegate);
DCHECK_NE(kInvalidDelegateId, id);
delegates_.erase(id);
io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AecDumpMessageFilter::UnregisterAecDumpConsumer, this,
id));
}
void AecDumpMessageFilter::Send(IPC::Message* message) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (sender_)
sender_->Send(message);
else
delete message;
}
void AecDumpMessageFilter::RegisterAecDumpConsumer(int id) {
Send(new AecDumpMsg_RegisterAecDumpConsumer(id));
}
void AecDumpMessageFilter::UnregisterAecDumpConsumer(int id) {
Send(new AecDumpMsg_UnregisterAecDumpConsumer(id));
}
bool AecDumpMessageFilter::OnMessageReceived(const IPC::Message& message) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(AecDumpMessageFilter, message)
IPC_MESSAGE_HANDLER(AecDumpMsg_EnableAecDump, OnEnableAecDump)
IPC_MESSAGE_HANDLER(AecDumpMsg_DisableAecDump, OnDisableAecDump)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void AecDumpMessageFilter::OnFilterAdded(IPC::Channel* channel) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
sender_ = channel;
}
void AecDumpMessageFilter::OnFilterRemoved() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
// Once removed, a filter will not be used again. At this time the
// observer must be notified so it releases its reference.
OnChannelClosing();
}
void AecDumpMessageFilter::OnChannelClosing() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
sender_ = nullptr;
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AecDumpMessageFilter::DoChannelClosingOnDelegates, this));
}
void AecDumpMessageFilter::OnEnableAecDump(
int id,
IPC::PlatformFileForTransit file_handle) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
main_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&AecDumpMessageFilter::DoEnableAecDump, this,
id, file_handle));
}
void AecDumpMessageFilter::OnDisableAecDump() {
DCHECK(io_task_runner_->BelongsToCurrentThread());
main_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&AecDumpMessageFilter::DoDisableAecDump, this));
}
void AecDumpMessageFilter::DoEnableAecDump(
int id,
IPC::PlatformFileForTransit file_handle) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
auto it = delegates_.find(id);
if (it != delegates_.end()) {
it->second->OnAecDumpFile(file_handle);
} else {
// Delegate has been removed, we must close the file.
base::File file = IPC::PlatformFileForTransitToFile(file_handle);
DCHECK(file.IsValid());
file.Close();
}
}
void AecDumpMessageFilter::DoDisableAecDump() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
it->second->OnDisableAecDump();
}
}
void AecDumpMessageFilter::DoChannelClosingOnDelegates() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
it->second->OnIpcClosing();
}
delegates_.clear();
}
int AecDumpMessageFilter::GetIdForDelegate(
AecDumpMessageFilter::AecDumpDelegate* delegate) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
if (it->second == delegate)
return it->first;
}
return kInvalidDelegateId;
}
} // namespace content
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_MEDIA_STREAM_AEC_DUMP_MESSAGE_FILTER_H_
#define CONTENT_RENDERER_MEDIA_STREAM_AEC_DUMP_MESSAGE_FILTER_H_
#include <memory>
#include "base/macros.h"
#include "base/optional.h"
#include "content/common/content_export.h"
#include "content/renderer/render_thread_impl.h"
#include "ipc/ipc_platform_file.h"
#include "ipc/message_filter.h"
namespace base {
class SingleThreadTaskRunner;
}
namespace content {
// MessageFilter that handles AEC dump messages and forwards them to an
// observer.
class CONTENT_EXPORT AecDumpMessageFilter : public IPC::MessageFilter {
public:
class AecDumpDelegate {
public:
virtual void OnAecDumpFile(
const IPC::PlatformFileForTransit& file_handle) = 0;
virtual void OnDisableAecDump() = 0;
virtual void OnIpcClosing() = 0;
};
AecDumpMessageFilter(
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner);
// Getter for the one AecDumpMessageFilter object.
static scoped_refptr<AecDumpMessageFilter> Get();
// Adds a delegate that receives the enable and disable notifications. Must be
// called on the main task runner (|main_task_runner| in constructor). All
// calls on |delegate| are done on the main task runner.
void AddDelegate(AecDumpMessageFilter::AecDumpDelegate* delegate);
// Removes a delegate. Must be called on the main task runner
// (|main_task_runner| in constructor).
void RemoveDelegate(AecDumpMessageFilter::AecDumpDelegate* delegate);
// IO task runner associated with this message filter.
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() const {
return io_task_runner_;
}
protected:
~AecDumpMessageFilter() override;
private:
// Sends an IPC message using |sender_|.
void Send(IPC::Message* message);
// Registers a consumer of AEC dump in the browser process. This consumer will
// get a file handle when the AEC dump is enabled and a notification when it
// is disabled.
void RegisterAecDumpConsumer(int id);
// Unregisters a consumer of AEC dump in the browser process.
void UnregisterAecDumpConsumer(int id);
// IPC::MessageFilter override. Called on |io_task_runner|.
bool OnMessageReceived(const IPC::Message& message) override;
void OnFilterAdded(IPC::Channel* channel) override;
void OnFilterRemoved() override;
void OnChannelClosing() override;
// Accessed on |io_task_runner_|.
void OnEnableAecDump(int id, IPC::PlatformFileForTransit file_handle);
void OnDisableAecDump();
// Accessed on |main_task_runner_|.
void DoEnableAecDump(int id, IPC::PlatformFileForTransit file_handle);
void DoDisableAecDump();
void DoChannelClosingOnDelegates();
int GetIdForDelegate(AecDumpMessageFilter::AecDumpDelegate* delegate);
// Accessed on |io_task_runner_|.
IPC::Sender* sender_;
// The delgates for this filter. Must only be accessed on
// |main_task_runner_|.
using DelegateMap = std::map<int, AecDumpMessageFilter::AecDumpDelegate*>;
DelegateMap delegates_;
// Counter for generating unique IDs to delegates. Accessed on
// |main_task_runner_|.
int delegate_id_counter_;
// Task runner which IPC calls are executed.
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
// Main task runner.
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
// The singleton instance for this filter.
static AecDumpMessageFilter* g_filter;
DISALLOW_COPY_AND_ASSIGN(AecDumpMessageFilter);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_STREAM_AEC_DUMP_MESSAGE_FILTER_H_
...@@ -31,7 +31,6 @@ AudioServiceAudioProcessorProxy::AudioServiceAudioProcessorProxy( ...@@ -31,7 +31,6 @@ AudioServiceAudioProcessorProxy::AudioServiceAudioProcessorProxy(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
: main_thread_runner_(std::move(main_thread_task_runner)), : main_thread_runner_(std::move(main_thread_task_runner)),
target_stats_interval_(kMaxStatsInterval), target_stats_interval_(kMaxStatsInterval),
aec_dump_message_filter_(AecDumpMessageFilter::Get()),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
} }
...@@ -44,10 +43,7 @@ AudioServiceAudioProcessorProxy::~AudioServiceAudioProcessorProxy() { ...@@ -44,10 +43,7 @@ AudioServiceAudioProcessorProxy::~AudioServiceAudioProcessorProxy() {
void AudioServiceAudioProcessorProxy::Stop() { void AudioServiceAudioProcessorProxy::Stop() {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
if (aec_dump_message_filter_.get()) { aec_dump_agent_impl_.reset();
aec_dump_message_filter_->RemoveDelegate(this);
aec_dump_message_filter_ = nullptr;
}
if (processor_controls_) { if (processor_controls_) {
processor_controls_->StopEchoCancellationDump(); processor_controls_->StopEchoCancellationDump();
...@@ -57,33 +53,25 @@ void AudioServiceAudioProcessorProxy::Stop() { ...@@ -57,33 +53,25 @@ void AudioServiceAudioProcessorProxy::Stop() {
stats_update_timer_.Stop(); stats_update_timer_.Stop();
} }
void AudioServiceAudioProcessorProxy::OnAecDumpFile( void AudioServiceAudioProcessorProxy::OnStartDump(base::File dump_file) {
const IPC::PlatformFileForTransit& file_handle) {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
base::File file = IPC::PlatformFileForTransitToFile(file_handle); DCHECK(dump_file.IsValid());
DCHECK(file.IsValid());
if (processor_controls_) { if (processor_controls_) {
processor_controls_->StartEchoCancellationDump(std::move(file)); processor_controls_->StartEchoCancellationDump(std::move(dump_file));
} else { } else {
// Post the file close to avoid blocking the main thread. // Post the file close to avoid blocking the main thread.
base::PostTaskWithTraits( base::PostTaskWithTraits(
FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()}, FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()},
base::BindOnce([](base::File) {}, std::move(file))); base::BindOnce([](base::File) {}, std::move(dump_file)));
} }
} }
void AudioServiceAudioProcessorProxy::OnDisableAecDump() { void AudioServiceAudioProcessorProxy::OnStopDump() {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
if (processor_controls_) if (processor_controls_)
processor_controls_->StopEchoCancellationDump(); processor_controls_->StopEchoCancellationDump();
} }
void AudioServiceAudioProcessorProxy::OnIpcClosing() {
DCHECK(main_thread_runner_->BelongsToCurrentThread());
aec_dump_message_filter_->RemoveDelegate(this);
aec_dump_message_filter_ = nullptr;
}
void AudioServiceAudioProcessorProxy::SetControls( void AudioServiceAudioProcessorProxy::SetControls(
media::AudioProcessorControls* controls) { media::AudioProcessorControls* controls) {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
...@@ -96,11 +84,9 @@ void AudioServiceAudioProcessorProxy::SetControls( ...@@ -96,11 +84,9 @@ void AudioServiceAudioProcessorProxy::SetControls(
last_stats_request_time_ = base::TimeTicks::Now(); last_stats_request_time_ = base::TimeTicks::Now();
stats_update_timer_.SetTaskRunner(main_thread_runner_); stats_update_timer_.SetTaskRunner(main_thread_runner_);
RescheduleStatsUpdateTimer(target_stats_interval_); RescheduleStatsUpdateTimer(target_stats_interval_);
// In unit tests not creating a message filter, |aec_dump_message_filter_|
// will be null. We can just ignore that. Other unit tests and browser tests // Can be null in unit tests. That's okay.
// ensure that we do get the filter when we should. aec_dump_agent_impl_ = AecDumpAgentImpl::Create(this);
if (aec_dump_message_filter_)
aec_dump_message_filter_->AddDelegate(this);
} }
webrtc::AudioProcessorInterface::AudioProcessorStatistics webrtc::AudioProcessorInterface::AudioProcessorStatistics
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/renderer/media/stream/aec_dump_message_filter.h" #include "content/renderer/media/stream/aec_dump_agent_impl.h"
#include "media/base/audio_processing.h" #include "media/base/audio_processing.h"
#include "media/webrtc/audio_processor_controls.h" #include "media/webrtc/audio_processor_controls.h"
#include "third_party/webrtc/api/media_stream_interface.h" #include "third_party/webrtc/api/media_stream_interface.h"
...@@ -31,7 +31,7 @@ namespace content { ...@@ -31,7 +31,7 @@ namespace content {
// calculation code should be encapsulated in a class. // calculation code should be encapsulated in a class.
class CONTENT_EXPORT AudioServiceAudioProcessorProxy class CONTENT_EXPORT AudioServiceAudioProcessorProxy
: public webrtc::AudioProcessorInterface, : public webrtc::AudioProcessorInterface,
public AecDumpMessageFilter::AecDumpDelegate { public AecDumpAgentImpl::Delegate {
public: public:
// All methods (including constructor and destructor) must be called on the // All methods (including constructor and destructor) must be called on the
// main thread except for GetStats. // main thread except for GetStats.
...@@ -45,11 +45,10 @@ class CONTENT_EXPORT AudioServiceAudioProcessorProxy ...@@ -45,11 +45,10 @@ class CONTENT_EXPORT AudioServiceAudioProcessorProxy
// This method is called on the libjingle thread. // This method is called on the libjingle thread.
AudioProcessorStatistics GetStats(bool has_remote_tracks) override; AudioProcessorStatistics GetStats(bool has_remote_tracks) override;
// AecDumpMessageFilter::AecDumpDelegate implementation. // AecDumpAgentImpl::Delegate implementation.
// Called on the main render thread. // Called on the main render thread.
void OnAecDumpFile(const IPC::PlatformFileForTransit& file_handle) override; void OnStartDump(base::File file) override;
void OnDisableAecDump() override; void OnStopDump() override;
void OnIpcClosing() override;
// Set the AudioProcessorControls which to proxy to. Must only be called once // Set the AudioProcessorControls which to proxy to. Must only be called once
// and |controls| cannot be nullptr. // and |controls| cannot be nullptr.
...@@ -78,7 +77,7 @@ class CONTENT_EXPORT AudioServiceAudioProcessorProxy ...@@ -78,7 +77,7 @@ class CONTENT_EXPORT AudioServiceAudioProcessorProxy
AudioProcessorStatistics latest_stats_ = {}; AudioProcessorStatistics latest_stats_ = {};
// Communication with browser for AEC dump. // Communication with browser for AEC dump.
scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter_; std::unique_ptr<AecDumpAgentImpl> aec_dump_agent_impl_;
base::WeakPtrFactory<AudioServiceAudioProcessorProxy> weak_ptr_factory_; base::WeakPtrFactory<AudioServiceAudioProcessorProxy> weak_ptr_factory_;
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include "base/optional.h" #include "base/optional.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -276,19 +278,13 @@ MediaStreamAudioProcessor::MediaStreamAudioProcessor( ...@@ -276,19 +278,13 @@ MediaStreamAudioProcessor::MediaStreamAudioProcessor(
main_thread_runner_(base::ThreadTaskRunnerHandle::Get()), main_thread_runner_(base::ThreadTaskRunnerHandle::Get()),
audio_mirroring_(false), audio_mirroring_(false),
typing_detected_(false), typing_detected_(false),
aec_dump_message_filter_(AecDumpMessageFilter::Get()), aec_dump_agent_impl_(AecDumpAgentImpl::Create(this)),
stopped_(false) { stopped_(false) {
DCHECK(main_thread_runner_); DCHECK(main_thread_runner_);
DETACH_FROM_THREAD(capture_thread_checker_); DETACH_FROM_THREAD(capture_thread_checker_);
DETACH_FROM_THREAD(render_thread_checker_); DETACH_FROM_THREAD(render_thread_checker_);
InitializeAudioProcessingModule(properties); InitializeAudioProcessingModule(properties);
// In unit tests not creating a message filter, |aec_dump_message_filter_|
// will be null. We can just ignore that. Other unit tests and browser tests
// ensure that we do get the filter when we should.
if (aec_dump_message_filter_.get())
aec_dump_message_filter_->AddDelegate(this);
} }
MediaStreamAudioProcessor::~MediaStreamAudioProcessor() { MediaStreamAudioProcessor::~MediaStreamAudioProcessor() {
...@@ -369,10 +365,7 @@ void MediaStreamAudioProcessor::Stop() { ...@@ -369,10 +365,7 @@ void MediaStreamAudioProcessor::Stop() {
stopped_ = true; stopped_ = true;
if (aec_dump_message_filter_.get()) { aec_dump_agent_impl_.reset();
aec_dump_message_filter_->RemoveDelegate(this);
aec_dump_message_filter_ = nullptr;
}
if (!audio_processing_.get()) if (!audio_processing_.get())
return; return;
...@@ -394,12 +387,10 @@ const media::AudioParameters& MediaStreamAudioProcessor::OutputFormat() const { ...@@ -394,12 +387,10 @@ const media::AudioParameters& MediaStreamAudioProcessor::OutputFormat() const {
return output_format_; return output_format_;
} }
void MediaStreamAudioProcessor::OnAecDumpFile( void MediaStreamAudioProcessor::OnStartDump(base::File dump_file) {
const IPC::PlatformFileForTransit& file_handle) {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
base::File file = IPC::PlatformFileForTransitToFile(file_handle); DCHECK(dump_file.IsValid());
DCHECK(file.IsValid());
if (audio_processing_) { if (audio_processing_) {
if (!worker_queue_) { if (!worker_queue_) {
...@@ -409,14 +400,17 @@ void MediaStreamAudioProcessor::OnAecDumpFile( ...@@ -409,14 +400,17 @@ void MediaStreamAudioProcessor::OnAecDumpFile(
// Here tasks will be posted on the |worker_queue_|. It must be // Here tasks will be posted on the |worker_queue_|. It must be
// kept alive until StopEchoCancellationDump is called or the // kept alive until StopEchoCancellationDump is called or the
// webrtc::AudioProcessing instance is destroyed. // webrtc::AudioProcessing instance is destroyed.
blink::StartEchoCancellationDump(audio_processing_.get(), std::move(file), blink::StartEchoCancellationDump(audio_processing_.get(),
worker_queue_.get()); std::move(dump_file), worker_queue_.get());
} else { } else {
file.Close(); // Post the file close to avoid blocking the main thread.
base::PostTaskWithTraits(
FROM_HERE, {base::TaskPriority::LOWEST, base::MayBlock()},
base::BindOnce([](base::File) {}, std::move(dump_file)));
} }
} }
void MediaStreamAudioProcessor::OnDisableAecDump() { void MediaStreamAudioProcessor::OnStopDump() {
DCHECK(main_thread_runner_->BelongsToCurrentThread()); DCHECK(main_thread_runner_->BelongsToCurrentThread());
if (audio_processing_) if (audio_processing_)
blink::StopEchoCancellationDump(audio_processing_.get()); blink::StopEchoCancellationDump(audio_processing_.get());
...@@ -426,11 +420,6 @@ void MediaStreamAudioProcessor::OnDisableAecDump() { ...@@ -426,11 +420,6 @@ void MediaStreamAudioProcessor::OnDisableAecDump() {
worker_queue_.reset(nullptr); worker_queue_.reset(nullptr);
} }
void MediaStreamAudioProcessor::OnIpcClosing() {
DCHECK(main_thread_runner_->BelongsToCurrentThread());
aec_dump_message_filter_ = nullptr;
}
// static // static
bool MediaStreamAudioProcessor::WouldModifyAudio( bool MediaStreamAudioProcessor::WouldModifyAudio(
const blink::AudioProcessingProperties& properties) { const blink::AudioProcessingProperties& properties) {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/renderer/media/stream/aec_dump_message_filter.h" #include "content/renderer/media/stream/aec_dump_agent_impl.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.h" #include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
#include "media/base/audio_converter.h" #include "media/base/audio_converter.h"
#include "media/webrtc/audio_delay_stats_reporter.h" #include "media/webrtc/audio_delay_stats_reporter.h"
...@@ -51,7 +51,7 @@ using webrtc::AudioProcessorInterface; ...@@ -51,7 +51,7 @@ using webrtc::AudioProcessorInterface;
class CONTENT_EXPORT MediaStreamAudioProcessor class CONTENT_EXPORT MediaStreamAudioProcessor
: public WebRtcPlayoutDataSource::Sink, : public WebRtcPlayoutDataSource::Sink,
public AudioProcessorInterface, public AudioProcessorInterface,
public AecDumpMessageFilter::AecDumpDelegate { public AecDumpAgentImpl::Delegate {
public: public:
// |playout_data_source| is used to register this class as a sink to the // |playout_data_source| is used to register this class as a sink to the
// WebRtc playout data for processing AEC. If clients do not enable AEC, // WebRtc playout data for processing AEC. If clients do not enable AEC,
...@@ -105,11 +105,10 @@ class CONTENT_EXPORT MediaStreamAudioProcessor ...@@ -105,11 +105,10 @@ class CONTENT_EXPORT MediaStreamAudioProcessor
// Accessor to check if the audio processing is enabled or not. // Accessor to check if the audio processing is enabled or not.
bool has_audio_processing() const { return audio_processing_ != NULL; } bool has_audio_processing() const { return audio_processing_ != NULL; }
// AecDumpMessageFilter::AecDumpDelegate implementation. // AecDumpAgentImpl::Delegate implementation.
// Called on the main render thread. // Called on the main render thread.
void OnAecDumpFile(const IPC::PlatformFileForTransit& file_handle) override; void OnStartDump(base::File dump_file) override;
void OnDisableAecDump() override; void OnStopDump() override;
void OnIpcClosing() override;
// Returns true if MediaStreamAudioProcessor would modify the audio signal, // Returns true if MediaStreamAudioProcessor would modify the audio signal,
// based on |properties|. If the audio signal would not be modified, there is // based on |properties|. If the audio signal would not be modified, there is
...@@ -205,7 +204,7 @@ class CONTENT_EXPORT MediaStreamAudioProcessor ...@@ -205,7 +204,7 @@ class CONTENT_EXPORT MediaStreamAudioProcessor
base::subtle::Atomic32 typing_detected_; base::subtle::Atomic32 typing_detected_;
// Communication with browser for AEC dump. // Communication with browser for AEC dump.
scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter_; std::unique_ptr<AecDumpAgentImpl> aec_dump_agent_impl_;
// Flag to avoid executing Stop() more than once. // Flag to avoid executing Stop() more than once.
bool stopped_; bool stopped_;
......
...@@ -276,29 +276,6 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) { ...@@ -276,29 +276,6 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
audio_processor->Stop(); audio_processor->Stop();
} }
// Test that if we have an AEC dump message filter created, we are getting it
// correctly in MSAP. Any IPC messages will be deleted since no sender in the
// filter will be created.
TEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter_(
new AecDumpMessageFilter(
blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
blink::AudioProcessingProperties properties;
scoped_refptr<MediaStreamAudioProcessor> audio_processor(
new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_TRUE(audio_processor->aec_dump_message_filter_.get());
// Stop |audio_processor| so that it removes itself from
// |webrtc_audio_device| and clears its pointer to it.
audio_processor->Stop();
}
TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) { TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device( scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()); new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
...@@ -315,13 +292,13 @@ TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) { ...@@ -315,13 +292,13 @@ TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) {
properties, webrtc_audio_device.get())); properties, webrtc_audio_device.get()));
// Start and stop recording. // Start and stop recording.
audio_processor->OnAecDumpFile(IPC::TakePlatformFileForTransit(base::File( audio_processor->OnStartDump(base::File(
temp_file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN))); temp_file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN));
audio_processor->OnDisableAecDump(); audio_processor->OnStopDump();
// Start and wait for d-tor. // Start and wait for d-tor.
audio_processor->OnAecDumpFile(IPC::TakePlatformFileForTransit(base::File( audio_processor->OnStartDump(base::File(
temp_file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN))); temp_file_path, base::File::FLAG_WRITE | base::File::FLAG_OPEN));
} }
// Check that dump file is non-empty after audio processor has been // Check that dump file is non-empty after audio processor has been
......
...@@ -89,7 +89,6 @@ ...@@ -89,7 +89,6 @@
#include "content/renderer/media/audio/audio_renderer_mixer_manager.h" #include "content/renderer/media/audio/audio_renderer_mixer_manager.h"
#include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h" #include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h"
#include "content/renderer/media/render_media_client.h" #include "content/renderer/media/render_media_client.h"
#include "content/renderer/media/stream/aec_dump_message_filter.h"
#include "content/renderer/media/stream/media_stream_center.h" #include "content/renderer/media/stream/media_stream_center.h"
#include "content/renderer/media/video_capture/video_capture_impl_manager.h" #include "content/renderer/media/video_capture/video_capture_impl_manager.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
...@@ -756,11 +755,6 @@ void RenderThreadImpl::Init() { ...@@ -756,11 +755,6 @@ void RenderThreadImpl::Init() {
peer_connection_factory_.reset( peer_connection_factory_.reset(
new PeerConnectionDependencyFactory(p2p_socket_dispatcher_.get())); new PeerConnectionDependencyFactory(p2p_socket_dispatcher_.get()));
aec_dump_message_filter_ =
new AecDumpMessageFilter(GetIOTaskRunner(), main_thread_runner());
AddFilter(aec_dump_message_filter_.get());
unfreezable_message_filter_ = new UnfreezableMessageFilter(this); unfreezable_message_filter_ = new UnfreezableMessageFilter(this);
AddFilter(unfreezable_message_filter_.get()); AddFilter(unfreezable_message_filter_.get());
......
...@@ -112,7 +112,6 @@ class SyntheticBeginFrameSource; ...@@ -112,7 +112,6 @@ class SyntheticBeginFrameSource;
} // namespace viz } // namespace viz
namespace content { namespace content {
class AecDumpMessageFilter;
class AudioRendererMixerManager; class AudioRendererMixerManager;
class BrowserPluginManager; class BrowserPluginManager;
class CategorizedWorkerPool; class CategorizedWorkerPool;
...@@ -593,12 +592,6 @@ class CONTENT_EXPORT RenderThreadImpl ...@@ -593,12 +592,6 @@ class CONTENT_EXPORT RenderThreadImpl
// Dispatches all P2P sockets. // Dispatches all P2P sockets.
scoped_refptr<P2PSocketDispatcher> p2p_socket_dispatcher_; scoped_refptr<P2PSocketDispatcher> p2p_socket_dispatcher_;
// Used for communicating registering AEC dump consumers with the browser and
// receving AEC dump file handles when AEC dump is enabled. An AEC dump is
// diagnostic audio data for WebRTC stored locally when enabled by the user in
// chrome://webrtc-internals.
scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter_;
// Filter out unfreezable messages and pass it to unfreezable task runners. // Filter out unfreezable messages and pass it to unfreezable task runners.
scoped_refptr<UnfreezableMessageFilter> unfreezable_message_filter_; scoped_refptr<UnfreezableMessageFilter> unfreezable_message_filter_;
......
...@@ -51,7 +51,6 @@ enum IPCMessageStart { ...@@ -51,7 +51,6 @@ enum IPCMessageStart {
ChromeExtensionMsgStart, ChromeExtensionMsgStart,
GinJavaBridgeMsgStart, GinJavaBridgeMsgStart,
ChromeUtilityPrintingMsgStart, ChromeUtilityPrintingMsgStart,
AecDumpMsgStart,
OzoneGpuMsgStart, OzoneGpuMsgStart,
WebTestMsgStart, WebTestMsgStart,
NetworkHintsMsgStart, NetworkHintsMsgStart,
......
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