blob: 67df667a482f775407cea928c54852eb8aba23c6 [file] [log] [blame]
// Copyright 2020 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 "components/net_log/net_log_proxy_source.h"
namespace net_log {
NetLogProxySource::NetLogProxySource(
mojo::PendingReceiver<network::mojom::NetLogProxySource>
proxy_source_receiver,
mojo::Remote<network::mojom::NetLogProxySink> proxy_sink_remote)
: proxy_source_receiver_(this, std::move(proxy_source_receiver)),
proxy_sink_remote_(std::move(proxy_sink_remote)),
task_runner_(base::SequencedTaskRunnerHandle::Get()) {
// Initialize a WeakPtr instance that can be safely referred to from other
// threads when binding tasks posted back to this thread.
weak_this_ = weak_factory_.GetWeakPtr();
}
NetLogProxySource::~NetLogProxySource() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
// Just in case ShutDown() was not called, make sure observer is removed.
UpdateCaptureModes(0);
}
void NetLogProxySource::ShutDown() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
UpdateCaptureModes(0);
weak_factory_.InvalidateWeakPtrs();
proxy_source_receiver_.reset();
proxy_sink_remote_.reset();
}
void NetLogProxySource::OnAddEntry(const net::NetLogEntry& entry) {
if (task_runner_->RunsTasksInCurrentSequence()) {
SendNetLogEntry(entry.type, entry.source.type, entry.source.id,
entry.source.start_time, entry.phase, entry.time,
entry.params.Clone());
} else {
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&NetLogProxySource::SendNetLogEntry, weak_this_,
entry.type, entry.source.type, entry.source.id,
entry.source.start_time, entry.phase, entry.time,
entry.params.Clone()));
}
}
void NetLogProxySource::UpdateCaptureModes(
net::NetLogCaptureModeSet new_modes) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
// Not capturing, remove observer if necessary.
if (new_modes == 0) {
if (net_log())
net::NetLog::Get()->RemoveObserver(this);
return;
}
// NetLog allows multiple observers to be registered at once, and each might
// have a different capture mode. In the common case there would normally be
// at most one observer registered. To avoid the complication of sending
// different sets of params for each capture mode, if multiple capture modes
// are active, only one observer is registered in the source process, using
// the lowest common denominator capture mode. This handles the common case,
// and in the rare case where multiple capture modes active, is a safe
// fallback.
//
// Register observer for the lowest level that is set in |new_modes|.
for (int i = 0; i <= static_cast<int>(net::NetLogCaptureMode::kLast); ++i) {
net::NetLogCaptureMode mode = static_cast<net::NetLogCaptureMode>(i);
if (net::NetLogCaptureModeSetContains(mode, new_modes)) {
if (net_log() && capture_mode() == mode) {
// Already listening at the desired level.
return;
}
if (net_log()) {
// Listening at the wrong level, remove observer.
net::NetLog::Get()->RemoveObserver(this);
}
net::NetLog::Get()->AddObserver(this, mode);
return;
}
}
NOTREACHED();
}
void NetLogProxySource::SendNetLogEntry(net::NetLogEventType type,
net::NetLogSourceType source_type,
uint32_t source_id,
base::TimeTicks source_start_time,
net::NetLogEventPhase phase,
base::TimeTicks time,
base::Value params) {
proxy_sink_remote_->AddEntry(
static_cast<uint32_t>(type), static_cast<uint32_t>(source_type),
source_id, source_start_time, phase, time, std::move(params));
}
} // namespace net_log