blob: d3a149f20142e43a8ea5a186853bd41ee51a4dd4 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/tracing/public/cpp/traced_process_impl.h"
#include <utility>
#include "base/functional/bind.h"
#include "base/no_destructor.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
#include "services/tracing/public/mojom/constants.mojom.h"
namespace tracing {
// static
TracedProcessImpl* TracedProcessImpl::GetInstance() {
static base::NoDestructor<TracedProcessImpl> traced_process;
return traced_process.get();
}
TracedProcessImpl::TracedProcessImpl() {
DETACH_FROM_SEQUENCE(sequence_checker_);
}
TracedProcessImpl::~TracedProcessImpl() = default;
void TracedProcessImpl::ResetTracedProcessReceiver() {
if (task_runner_ && !task_runner_->RunsTasksInCurrentSequence()) {
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&TracedProcessImpl::ResetTracedProcessReceiver,
base::Unretained(this)));
return;
}
receiver_.reset();
}
void TracedProcessImpl::OnTracedProcessRequest(
mojo::PendingReceiver<mojom::TracedProcess> receiver) {
if (task_runner_ && !task_runner_->RunsTasksInCurrentSequence()) {
task_runner_->PostTask(
FROM_HERE, base::BindOnce(&TracedProcessImpl::OnTracedProcessRequest,
base::Unretained(this), std::move(receiver)));
return;
}
// We only need one binding per process. If a new binding request is made,
// ignore it.
if (receiver_.is_bound())
return;
receiver_.Bind(std::move(receiver));
}
mojo::Remote<mojom::SystemTracingService>&
TracedProcessImpl::system_tracing_service() {
// |system_tracing_service_| can only be used on the Perfetto task runner.
auto* task_runner = PerfettoTracedProcess::GetTaskRunner();
DCHECK(task_runner && task_runner->RunsTasksInCurrentSequence());
return system_tracing_service_;
}
void TracedProcessImpl::EnableSystemTracingService(
mojo::PendingRemote<mojom::SystemTracingService> remote) {
auto* task_runner = PerfettoTracedProcess::GetTaskRunner();
if (!task_runner->RunsTasksInCurrentSequence()) {
// |system_tracing_service_| is bound on the Perfetto task runner.
task_runner->PostTask(
FROM_HERE,
base::BindOnce(&TracedProcessImpl::EnableSystemTracingService,
base::Unretained(this), std::move(remote)));
return;
}
system_tracing_service_.Bind(std::move(remote), nullptr);
}
// SetTaskRunner must be called before we start receiving
// any OnTracedProcessRequest calls.
void TracedProcessImpl::SetTaskRunner(
scoped_refptr<base::SequencedTaskRunner> task_runner) {
DCHECK(!receiver_.is_bound());
DCHECK(!task_runner_);
task_runner_ = task_runner;
}
void TracedProcessImpl::ConnectToTracingService(
mojom::ConnectToTracingRequestPtr request,
ConnectToTracingServiceCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Acknowledge this message so the tracing service knows it was dispatched in
// this process.
std::move(callback).Run();
// Tracing requires a running ThreadPool; disable tracing
// for processes without it.
if (!base::ThreadPoolInstance::Get()) {
return;
}
PerfettoTracedProcess::Get().ConnectProducer(
std::move(request->perfetto_service));
}
} // namespace tracing