blob: 1fe89a49c868b01bfdd7f69b8398dbe861887e30 [file] [log] [blame]
// Copyright (c) 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 "chrome/browser/media/webrtc/webrtc_event_log_manager.h"
#include "base/command_line.h"
#include "base/optional.h"
#include "base/task_scheduler/post_task.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
namespace {
using BrowserContext = content::BrowserContext;
using BrowserThread = content::BrowserThread;
using RenderProcessHost = content::RenderProcessHost;
using BrowserContextId = WebRtcEventLogManager::BrowserContextId;
class PeerConnectionTrackerProxyImpl
: public WebRtcEventLogManager::PeerConnectionTrackerProxy {
public:
~PeerConnectionTrackerProxyImpl() override = default;
void SetWebRtcEventLoggingState(const WebRtcEventLogPeerConnectionKey& key,
bool event_logging_enabled) override {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(
&PeerConnectionTrackerProxyImpl::SetWebRtcEventLoggingStateInternal,
key, event_logging_enabled));
}
private:
static void SetWebRtcEventLoggingStateInternal(
WebRtcEventLogPeerConnectionKey key,
bool event_logging_enabled) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* host = RenderProcessHost::FromID(key.render_process_id);
if (!host) {
return; // The host has been asynchronously removed; not a problem.
}
host->SetWebRtcEventLogOutput(key.lid, event_logging_enabled);
}
};
const BrowserContext* GetBrowserContext(int render_process_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHost* const host = RenderProcessHost::FromID(render_process_id);
return host ? host->GetBrowserContext() : nullptr;
}
} // namespace
const size_t kWebRtcEventLogManagerUnlimitedFileSize = 0;
WebRtcEventLogManager* WebRtcEventLogManager::g_webrtc_event_log_manager =
nullptr;
std::unique_ptr<WebRtcEventLogManager>
WebRtcEventLogManager::CreateSingletonInstance() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!g_webrtc_event_log_manager);
g_webrtc_event_log_manager = new WebRtcEventLogManager;
return base::WrapUnique<WebRtcEventLogManager>(g_webrtc_event_log_manager);
}
WebRtcEventLogManager* WebRtcEventLogManager::GetInstance() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return g_webrtc_event_log_manager;
}
WebRtcEventLogManager::WebRtcEventLogManager()
: local_logs_observer_(nullptr),
remote_logs_observer_(nullptr),
local_logs_manager_(this),
pc_tracker_proxy_(new PeerConnectionTrackerProxyImpl),
url_request_context_getter_was_set_(false),
task_runner_(base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BACKGROUND,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (IsRemoteLoggingEnabled()) {
remote_logs_manager_ = std::make_unique<WebRtcRemoteEventLogManager>(this);
}
DCHECK(!g_webrtc_event_log_manager);
g_webrtc_event_log_manager = this;
}
WebRtcEventLogManager::~WebRtcEventLogManager() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
for (RenderProcessHost* host : observed_render_process_hosts_) {
host->RemoveObserver(this);
}
DCHECK(g_webrtc_event_log_manager);
g_webrtc_event_log_manager = nullptr;
}
void WebRtcEventLogManager::EnableForBrowserContext(
const BrowserContext* browser_context,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(browser_context);
CHECK(!browser_context->IsOffTheRecord());
// system_request_context() not available during instantiation; we get it
// when the first profile is loaded, which is also the earliest time when
// it could be needed.
net::URLRequestContextGetter* url_request_context_getter;
if (remote_logs_manager_ && !url_request_context_getter_was_set_) {
url_request_context_getter = g_browser_process->system_request_context();
DCHECK(url_request_context_getter);
url_request_context_getter_was_set_ = true;
} else {
url_request_context_getter = nullptr;
}
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
// |url_request_context_getter| is owned by IOThread. The internal task runner
// that uses it (|task_runner_|) stops before IOThread dies, so we can trust
// that |url_request_context_getter| will not be used after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&WebRtcEventLogManager::EnableForBrowserContextInternal,
base::Unretained(this), GetBrowserContextId(browser_context),
browser_context->GetPath(),
base::Unretained(url_request_context_getter), std::move(reply)));
}
void WebRtcEventLogManager::DisableForBrowserContext(
const content::BrowserContext* browser_context,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(browser_context);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::DisableForBrowserContextInternal,
base::Unretained(this),
GetBrowserContextId(browser_context), std::move(reply)));
}
void WebRtcEventLogManager::PeerConnectionAdded(
int render_process_id,
int lid,
const std::string& peer_connection_id,
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!peer_connection_id.empty());
RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
if (!rph) {
// RPH died before processing of this notification.
MaybeReply(std::move(reply), false);
return;
}
auto it = observed_render_process_hosts_.find(rph);
if (it == observed_render_process_hosts_.end()) {
// This is the first PeerConnection which we see that's associated
// with this RPH.
rph->AddObserver(this);
observed_render_process_hosts_.insert(rph);
}
const auto browser_context_id = GetBrowserContextId(rph->GetBrowserContext());
DCHECK_NE(browser_context_id, kNullBrowserContextId);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&WebRtcEventLogManager::PeerConnectionAddedInternal,
base::Unretained(this),
PeerConnectionKey(render_process_id, lid, browser_context_id),
peer_connection_id, std::move(reply)));
}
void WebRtcEventLogManager::PeerConnectionRemoved(
int render_process_id,
int lid,
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const auto browser_context_id = GetBrowserContextId(render_process_id);
if (browser_context_id == kNullBrowserContextId) {
// RPH died before processing of this notification. This is handled by
// RenderProcessExited() / RenderProcessHostDestroyed.
MaybeReply(std::move(reply), false);
return;
}
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&WebRtcEventLogManager::PeerConnectionRemovedInternal,
base::Unretained(this),
PeerConnectionKey(render_process_id, lid, browser_context_id),
std::move(reply)));
}
void WebRtcEventLogManager::PeerConnectionStopped(
int render_process_id,
int lid,
base::OnceCallback<void(bool)> reply) {
return PeerConnectionRemoved(render_process_id, lid, std::move(reply));
}
void WebRtcEventLogManager::EnableLocalLogging(
const base::FilePath& base_path,
base::OnceCallback<void(bool)> reply) {
EnableLocalLogging(base_path, kDefaultMaxLocalLogFileSizeBytes,
std::move(reply));
}
void WebRtcEventLogManager::EnableLocalLogging(
const base::FilePath& base_path,
size_t max_file_size_bytes,
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(!base_path.empty());
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::EnableLocalLoggingInternal,
base::Unretained(this), base_path, max_file_size_bytes,
std::move(reply)));
}
void WebRtcEventLogManager::DisableLocalLogging(
base::OnceCallback<void(bool)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::DisableLocalLoggingInternal,
base::Unretained(this), std::move(reply)));
}
void WebRtcEventLogManager::OnWebRtcEventLogWrite(
int render_process_id,
int lid,
const std::string& message,
base::OnceCallback<void(std::pair<bool, bool>)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const BrowserContext* browser_context = GetBrowserContext(render_process_id);
if (!browser_context) {
// RPH died before processing of this notification.
MaybeReply(std::move(reply), false, false);
return;
}
const auto browser_context_id = GetBrowserContextId(browser_context);
DCHECK_NE(browser_context_id, kNullBrowserContextId);
const bool remote_logging_allowed = !browser_context->IsOffTheRecord();
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&WebRtcEventLogManager::OnWebRtcEventLogWriteInternal,
base::Unretained(this),
PeerConnectionKey(render_process_id, lid, browser_context_id),
remote_logging_allowed, message, std::move(reply)));
}
void WebRtcEventLogManager::StartRemoteLogging(
int render_process_id,
const std::string& peer_connection_id,
size_t max_file_size_bytes,
const std::string& metadata,
base::OnceCallback<void(bool, const std::string&)> reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!remote_logs_manager_) {
MaybeReply(std::move(reply), false,
std::string(kStartRemoteLoggingFailureFeatureDisabled));
return;
}
const BrowserContext* browser_context = GetBrowserContext(render_process_id);
if (!browser_context || browser_context->IsOffTheRecord()) {
// RPH died before processing of this notification, or is incognito.
// In the former case, there's no one to report to anyway.
// In the latter case, we don't want to expose incognito state to the
// JS application, so we give an error message that must be shared with
// other common events.
MaybeReply(std::move(reply), false,
std::string(kStartRemoteLoggingFailureGeneric));
return;
}
const auto browser_context_id = GetBrowserContextId(browser_context);
DCHECK_NE(browser_context_id, kNullBrowserContextId);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::StartRemoteLoggingInternal,
base::Unretained(this), render_process_id,
browser_context_id, peer_connection_id,
browser_context->GetPath(), max_file_size_bytes, metadata,
std::move(reply)));
}
void WebRtcEventLogManager::ClearCacheForBrowserContext(
const BrowserContext* browser_context,
const base::Time& delete_begin,
const base::Time& delete_end,
base::OnceClosure reply) {
const auto browser_context_id = GetBrowserContextId(browser_context);
DCHECK_NE(browser_context_id, kNullBrowserContextId);
// The object outlives the task queue - base::Unretained(this) is safe.
task_runner_->PostTaskAndReply(
FROM_HERE,
base::BindOnce(
&WebRtcEventLogManager::ClearCacheForBrowserContextInternal,
base::Unretained(this), browser_context_id, delete_begin, delete_end),
std::move(reply));
}
void WebRtcEventLogManager::SetLocalLogsObserver(
WebRtcLocalEventLogsObserver* observer,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::SetLocalLogsObserverInternal,
base::Unretained(this), observer, std::move(reply)));
}
void WebRtcEventLogManager::SetRemoteLogsObserver(
WebRtcRemoteEventLogsObserver* observer,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::SetRemoteLogsObserverInternal,
base::Unretained(this), observer, std::move(reply)));
}
bool WebRtcEventLogManager::IsRemoteLoggingEnabled() const {
base::Optional<bool> enabled;
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kWebRtcRemoteEventLog)) {
const std::string switch_value =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kWebRtcRemoteEventLog);
if (switch_value == "disable" || switch_value == "disabled") {
enabled = false;
} else if (switch_value == "enable" || switch_value == "enabled") {
enabled = true;
} else {
LOG(WARNING) << "Unrecognized value given for "
<< switches::kWebRtcRemoteEventLog
<< "; ignoring. (Use enabled/disabled.)";
}
}
if (!enabled.has_value()) {
// TODO(crbug.com/775415): Enable for non-mobile builds where the users
// have given appropriate consent.
enabled = false;
}
VLOG(1) << "WebRTC remote-bound event logging "
<< (enabled.value() ? "enabled" : "disabled") << ".";
return enabled.value();
}
void WebRtcEventLogManager::RenderProcessExited(
RenderProcessHost* host,
const content::ChildProcessTerminationInfo& info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHostExitedDestroyed(host);
}
void WebRtcEventLogManager::RenderProcessHostDestroyed(
RenderProcessHost* host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderProcessHostExitedDestroyed(host);
}
void WebRtcEventLogManager::RenderProcessHostExitedDestroyed(
RenderProcessHost* host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(host);
auto it = observed_render_process_hosts_.find(host);
if (it == observed_render_process_hosts_.end()) {
return; // We've never seen PeerConnections associated with this RPH.
}
host->RemoveObserver(this);
observed_render_process_hosts_.erase(host);
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebRtcEventLogManager::RenderProcessExitedInternal,
base::Unretained(this), host->GetID()));
}
void WebRtcEventLogManager::OnLocalLogStarted(PeerConnectionKey peer_connection,
const base::FilePath& file_path) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
OnLoggingTargetStarted(LoggingTarget::kLocalLogging, peer_connection);
if (local_logs_observer_) {
local_logs_observer_->OnLocalLogStarted(peer_connection, file_path);
}
}
void WebRtcEventLogManager::OnLocalLogStopped(
PeerConnectionKey peer_connection) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
OnLoggingTargetStopped(LoggingTarget::kLocalLogging, peer_connection);
if (local_logs_observer_) {
local_logs_observer_->OnLocalLogStopped(peer_connection);
}
}
void WebRtcEventLogManager::OnRemoteLogStarted(
PeerConnectionKey key,
const base::FilePath& file_path) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
OnLoggingTargetStarted(LoggingTarget::kRemoteLogging, key);
if (remote_logs_observer_) {
remote_logs_observer_->OnRemoteLogStarted(key, file_path);
}
}
void WebRtcEventLogManager::OnRemoteLogStopped(
WebRtcEventLogPeerConnectionKey key) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
OnLoggingTargetStopped(LoggingTarget::kRemoteLogging, key);
if (remote_logs_observer_) {
remote_logs_observer_->OnRemoteLogStopped(key);
}
}
void WebRtcEventLogManager::OnLoggingTargetStarted(LoggingTarget target,
PeerConnectionKey key) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
auto it = peer_connections_with_event_logging_enabled_.find(key);
if (it != peer_connections_with_event_logging_enabled_.end()) {
DCHECK_EQ((it->second & target), 0u);
it->second |= target;
} else {
// This is the first client for WebRTC event logging - let WebRTC know
// that it should start informing us of events.
peer_connections_with_event_logging_enabled_.emplace(key, target);
pc_tracker_proxy_->SetWebRtcEventLoggingState(key, true);
}
}
void WebRtcEventLogManager::OnLoggingTargetStopped(LoggingTarget target,
PeerConnectionKey key) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
// Record that we're no longer performing this type of logging for this PC.
auto it = peer_connections_with_event_logging_enabled_.find(key);
CHECK(it != peer_connections_with_event_logging_enabled_.end());
DCHECK_NE(it->second, 0u);
it->second &= ~target;
// If we're not doing any other type of logging for this peer connection,
// it's time to stop receiving notifications for it from WebRTC.
if (it->second == 0u) {
peer_connections_with_event_logging_enabled_.erase(it);
pc_tracker_proxy_->SetWebRtcEventLoggingState(key, false);
}
}
void WebRtcEventLogManager::EnableForBrowserContextInternal(
BrowserContextId browser_context_id,
const base::FilePath& browser_context_dir,
net::URLRequestContextGetter* context_getter,
base::OnceClosure reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK_NE(browser_context_id, kNullBrowserContextId);
if (remote_logs_manager_) {
if (context_getter) {
remote_logs_manager_->SetUrlRequestContextGetter(context_getter);
}
remote_logs_manager_->EnableForBrowserContext(browser_context_id,
browser_context_dir);
}
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
}
void WebRtcEventLogManager::DisableForBrowserContextInternal(
BrowserContextId browser_context_id,
base::OnceClosure reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (remote_logs_manager_) {
remote_logs_manager_->DisableForBrowserContext(browser_context_id);
}
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
}
void WebRtcEventLogManager::PeerConnectionAddedInternal(
PeerConnectionKey key,
const std::string& peer_connection_id,
base::OnceCallback<void(bool)> reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
const bool local_result = local_logs_manager_.PeerConnectionAdded(key);
if (remote_logs_manager_) {
const bool remote_result =
remote_logs_manager_->PeerConnectionAdded(key, peer_connection_id);
DCHECK_EQ(local_result, remote_result);
}
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), local_result));
}
}
void WebRtcEventLogManager::PeerConnectionRemovedInternal(
PeerConnectionKey key,
base::OnceCallback<void(bool)> reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
const bool local_result = local_logs_manager_.PeerConnectionRemoved(key);
if (remote_logs_manager_) {
const bool remote_result = remote_logs_manager_->PeerConnectionRemoved(key);
DCHECK_EQ(local_result, remote_result);
}
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), local_result));
}
}
void WebRtcEventLogManager::EnableLocalLoggingInternal(
const base::FilePath& base_path,
size_t max_file_size_bytes,
base::OnceCallback<void(bool)> reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
const bool result =
local_logs_manager_.EnableLogging(base_path, max_file_size_bytes);
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), result));
}
}
void WebRtcEventLogManager::DisableLocalLoggingInternal(
base::OnceCallback<void(bool)> reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
const bool result = local_logs_manager_.DisableLogging();
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), result));
}
}
void WebRtcEventLogManager::OnWebRtcEventLogWriteInternal(
PeerConnectionKey key,
bool remote_logging_allowed,
const std::string& message,
base::OnceCallback<void(std::pair<bool, bool>)> reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
const bool local_result = local_logs_manager_.EventLogWrite(key, message);
const bool remote_result =
(remote_logging_allowed && remote_logs_manager_)
? remote_logs_manager_->EventLogWrite(key, message)
: false;
if (reply) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply),
std::make_pair(local_result, remote_result)));
}
}
void WebRtcEventLogManager::StartRemoteLoggingInternal(
int render_process_id,
BrowserContextId browser_context_id,
const std::string& peer_connection_id,
const base::FilePath& browser_context_dir,
size_t max_file_size_bytes,
const std::string& metadata,
base::OnceCallback<void(bool, const std::string&)> reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
std::string error_message;
const bool result = remote_logs_manager_->StartRemoteLogging(
render_process_id, browser_context_id, peer_connection_id,
browser_context_dir, max_file_size_bytes, metadata, &error_message);
DCHECK_EQ(result, error_message.empty()); // Error set iff has failed.
if (reply) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), result, error_message));
}
}
void WebRtcEventLogManager::ClearCacheForBrowserContextInternal(
BrowserContextId browser_context_id,
const base::Time& delete_begin,
const base::Time& delete_end) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (remote_logs_manager_) {
remote_logs_manager_->ClearCacheForBrowserContext(browser_context_id,
delete_begin, delete_end);
}
}
void WebRtcEventLogManager::RenderProcessExitedInternal(int render_process_id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
local_logs_manager_.RenderProcessHostExitedDestroyed(render_process_id);
if (remote_logs_manager_) {
remote_logs_manager_->RenderProcessHostExitedDestroyed(render_process_id);
}
}
void WebRtcEventLogManager::SetLocalLogsObserverInternal(
WebRtcLocalEventLogsObserver* observer,
base::OnceClosure reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
local_logs_observer_ = observer;
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
}
void WebRtcEventLogManager::SetRemoteLogsObserverInternal(
WebRtcRemoteEventLogsObserver* observer,
base::OnceClosure reply) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
remote_logs_observer_ = observer;
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
}
void WebRtcEventLogManager::MaybeReply(base::OnceClosure reply) {
if (!reply) {
return;
}
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
void WebRtcEventLogManager::MaybeReply(base::OnceCallback<void(bool)> reply,
bool value) {
if (!reply) {
return;
}
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), value));
}
void WebRtcEventLogManager::MaybeReply(
base::OnceCallback<void(bool, const std::string&)> reply,
bool bool_val,
const std::string& str_val) {
if (!reply) {
return;
}
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), bool_val, str_val));
}
void WebRtcEventLogManager::MaybeReply(
base::OnceCallback<void(std::pair<bool, bool>)> reply,
bool first,
bool second) {
if (!reply) {
return;
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(reply), std::make_pair(first, second)));
}
void WebRtcEventLogManager::SetClockForTesting(base::Clock* clock,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto task = [](WebRtcEventLogManager* manager, base::Clock* clock,
base::OnceClosure reply) {
manager->local_logs_manager_.SetClockForTesting(clock);
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
};
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(FROM_HERE, base::BindOnce(task, base::Unretained(this),
clock, std::move(reply)));
}
void WebRtcEventLogManager::SetPeerConnectionTrackerProxyForTesting(
std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto task = [](WebRtcEventLogManager* manager,
std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy,
base::OnceClosure reply) {
manager->pc_tracker_proxy_ = std::move(pc_tracker_proxy);
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(reply));
}
};
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE, base::BindOnce(task, base::Unretained(this),
std::move(pc_tracker_proxy), std::move(reply)));
}
void WebRtcEventLogManager::SetWebRtcEventLogUploaderFactoryForTesting(
std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
base::OnceClosure reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(remote_logs_manager_); // The test would otherwise be meaningless.
auto task =
[](WebRtcEventLogManager* manager,
std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory,
base::OnceClosure reply) {
auto* remote_logs_manager = manager->remote_logs_manager_.get();
remote_logs_manager->SetWebRtcEventLogUploaderFactoryForTesting(
std::move(uploader_factory));
if (reply) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
std::move(reply));
}
};
// The object is destroyed by ~BrowserProcessImpl(), so base::Unretained(this)
// will not be dereferenced after destruction.
task_runner_->PostTask(
FROM_HERE, base::BindOnce(task, base::Unretained(this),
std::move(uploader_factory), std::move(reply)));
}
scoped_refptr<base::SequencedTaskRunner>&
WebRtcEventLogManager::GetTaskRunnerForTesting() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return task_runner_;
}
void WebRtcEventLogManager::PostNullTaskForTesting(base::OnceClosure reply) {
task_runner_->PostTask(FROM_HERE, std::move(reply));
}