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

Unified Diff: content/browser/media/audio_debug_recording_impl.cc

Issue 1246283003: Split out audio debug recording from RenderProcessHostImpl. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compile. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/media/audio_debug_recording_impl.cc
diff --git a/content/browser/media/audio_debug_recording_impl.cc b/content/browser/media/audio_debug_recording_impl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7af28019e671f86ce9f1d421e3164da9882a7610
--- /dev/null
+++ b/content/browser/media/audio_debug_recording_impl.cc
@@ -0,0 +1,214 @@
+// Copyright 2015 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/media/audio_debug_recording_impl.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/media/webrtc_internals.h"
+#include "content/browser/renderer_host/media/audio_input_renderer_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/common/child_process_host.h"
+#include "mojo/public/cpp/system/handle.h"
+#include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
+
+namespace content {
+
+namespace {
+
+const base::FilePath::CharType kAecDumpFileNameAddition[] =
+ FILE_PATH_LITERAL("aec_dump");
+
+// Creates a file used for diagnostic echo canceller recordings for handing
+// over to the renderer.
+mojo::ScopedHandle CreateAecDumpFile(base::FilePath file_path) {
+ DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+ 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 mojo::ScopedHandle();
+ }
+
+ mojo::embedder::PlatformHandle platform_handle_wrapper(
+ dump_file.TakePlatformFile());
+ mojo::embedder::ScopedPlatformHandle scoped_platform_handle(
+ platform_handle_wrapper);
+ MojoHandle mojo_handle = MOJO_HANDLE_INVALID;
+ MojoResult create_result = mojo::embedder::CreatePlatformHandleWrapper(
+ std::move(scoped_platform_handle), &mojo_handle);
+ if (create_result != MOJO_RESULT_OK)
+ return mojo::ScopedHandle();
+
+ return MakeScopedHandle(mojo::Handle(mojo_handle));
+}
+
+} // namespace
+
+class AudioDebugRecordingImpl::DumpObserver {
+ public:
+ DumpObserver(AudioDebugRecordingImpl* dump_impl,
+ int32_t id,
+ AudioDebugRecordingObserverPtr service)
+ : audio_debug_recording_impl_(dump_impl),
+ id_(id),
+ observer_service_(std::move(service)),
+ weak_factory_(this) {
+ observer_service_.set_connection_error_handler(
+ base::Bind(&DumpObserver::OnConnectionError, base::Unretained(this)));
+ }
+
+#if defined(OS_WIN)
+#define IntToStringType base::IntToString16
+#else
+#define IntToStringType base::IntToString
+#endif
+
+ void Enable(const base::FilePath& file) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ RenderProcessHost* rph =
+ RenderProcessHost::FromID(audio_debug_recording_impl_->render_host_id_);
+
+ // Process is dead. We're likely to receive a connection error soon.
+ if (!rph)
+ return;
+
+ base::FilePath unique_file =
+ file.AddExtension(IntToStringType(base::GetProcId(rph->GetHandle())))
+ .AddExtension(kAecDumpFileNameAddition)
+ .AddExtension(IntToStringType(id_));
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&CreateAecDumpFile, unique_file),
+ base::Bind(&DumpObserver::SendEnable, weak_factory_.GetWeakPtr()));
+ }
+
+#undef IntToStringType
+
+ void Disable() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // Posting on the FILE thread and then replying back on the UI thread is
+ // only for avoiding races between enable and disable. Nothing is done on
+ // the FILE thread.
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&base::DoNothing),
+ base::Bind(&DumpObserver::SendDisable, weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ void OnConnectionError() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // Deletes |this|.
+ audio_debug_recording_impl_->RemoveObserver(id_);
+ }
+
+ void SendEnable(mojo::ScopedHandle handle) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!handle.is_valid())
+ return;
+ observer_service_->Enable(std::move(handle));
+ }
+
+ void SendDisable() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ observer_service_->Disable();
+ }
+
+ AudioDebugRecordingImpl* audio_debug_recording_impl_;
+ const int32_t id_;
+ AudioDebugRecordingObserverPtr observer_service_;
+ base::ThreadChecker thread_checker_;
+
+ base::WeakPtrFactory<DumpObserver> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DumpObserver);
+};
+
+AudioDebugRecordingImpl::AudioDebugRecordingImpl(
+ int render_host_id,
+ const scoped_refptr<AudioInputRendererHost>& audio_input_renderer_host,
+ const DisconnectCallback& disconnect_cb,
+ mojo::InterfaceRequest<AudioDebugRecording> request)
+ : render_host_id_(render_host_id),
+ audio_input_renderer_host_(audio_input_renderer_host),
+ disconnect_cb_(disconnect_cb),
+ binding_(this) {
+ DCHECK_NE(render_host_id_, ChildProcessHost::kInvalidUniqueID);
+ DCHECK(!disconnect_cb_.is_null());
+ binding_.Bind(std::move(request));
+ binding_.set_connection_error_handler(base::Bind(
+ &AudioDebugRecordingImpl::OnConnectionError, base::Unretained(this)));
+}
+
+AudioDebugRecordingImpl::~AudioDebugRecordingImpl() {
+}
+
+void AudioDebugRecordingImpl::EnableAudioDebugRecording(
+ const base::FilePath& file) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // Enable AEC dumping for all registered obsevers.
+ for (auto& observer : observers_)
+ observer.second->Enable(file);
+
+ // Enable mic input recording. AudioInputRendererHost is reference counted,
+ // so its lifetime is guarantueed during the lifetime of the closure.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&AudioInputRendererHost::EnableDebugRecording,
+ audio_input_renderer_host_, file));
+}
+
+void AudioDebugRecordingImpl::DisableAudioDebugRecording() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // Disable AEC dumping for all registered obsevers.
+ for (auto& observer : observers_)
+ observer.second->Disable();
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&AudioInputRendererHost::DisableDebugRecording,
+ audio_input_renderer_host_));
+}
+
+void AudioDebugRecordingImpl::RegisterObserver(
+ int32_t id,
+ AudioDebugRecordingObserverPtr observer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ DumpObserver* dump_observer = new DumpObserver(this, id, std::move(observer));
+ bool inserted = observers_.insert(
+ std::make_pair(id, make_scoped_ptr(dump_observer))).second;
+ DCHECK(inserted);
+
+ if (WebRTCInternals::GetInstance()->IsAudioDebugRecordingsEnabled()) {
+ dump_observer->Enable(
+ WebRTCInternals::GetInstance()->GetAudioDebugRecordingsFilePath());
+ }
+}
+
+void AudioDebugRecordingImpl::OnConnectionError() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // May delete |this|.
+ disconnect_cb_.Run(this);
+}
+
+void AudioDebugRecordingImpl::RemoveObserver(int32_t observer_id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ auto it = observers_.find(observer_id);
+ DCHECK(it != observers_.end());
+ observers_.erase(it);
+}
+
+} // namespace content
« no previous file with comments | « content/browser/media/audio_debug_recording_impl.h ('k') | content/browser/media/audio_debug_recording_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698