910e62b5创建于 1月15日历史提交
// 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