1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "services/tracing/public/cpp/traced_process_impl.h" 6 7 #include <utility> 8 9 #include "base/bind.h" 10 #include "base/no_destructor.h" 11 #include "base/task/thread_pool/thread_pool_instance.h" 12 #include "services/tracing/public/cpp/base_agent.h" 13 #include "services/tracing/public/cpp/perfetto/producer_client.h" 14 #include "services/tracing/public/cpp/trace_event_agent.h" 15 #include "services/tracing/public/mojom/constants.mojom.h" 16 17 namespace tracing { 18 19 // static GetInstance()20TracedProcessImpl* TracedProcessImpl::GetInstance() { 21 static base::NoDestructor<TracedProcessImpl> traced_process; 22 return traced_process.get(); 23 } 24 TracedProcessImpl()25TracedProcessImpl::TracedProcessImpl() { 26 DETACH_FROM_SEQUENCE(sequence_checker_); 27 } 28 29 TracedProcessImpl::~TracedProcessImpl() = default; 30 ResetTracedProcessReceiver()31void TracedProcessImpl::ResetTracedProcessReceiver() { 32 if (task_runner_ && !task_runner_->RunsTasksInCurrentSequence()) { 33 task_runner_->PostTask( 34 FROM_HERE, 35 base::BindOnce(&TracedProcessImpl::ResetTracedProcessReceiver, 36 base::Unretained(this))); 37 return; 38 } 39 40 receiver_.reset(); 41 } 42 OnTracedProcessRequest(mojo::PendingReceiver<mojom::TracedProcess> receiver)43void TracedProcessImpl::OnTracedProcessRequest( 44 mojo::PendingReceiver<mojom::TracedProcess> receiver) { 45 if (task_runner_ && !task_runner_->RunsTasksInCurrentSequence()) { 46 task_runner_->PostTask( 47 FROM_HERE, base::BindOnce(&TracedProcessImpl::OnTracedProcessRequest, 48 base::Unretained(this), std::move(receiver))); 49 return; 50 } 51 52 // We only need one binding per process. If a new binding request is made, 53 // ignore it. 54 if (receiver_.is_bound()) 55 return; 56 57 receiver_.Bind(std::move(receiver)); 58 } 59 60 // SetTaskRunner must be called before we start receiving 61 // any OnTracedProcessRequest calls. SetTaskRunner(scoped_refptr<base::SequencedTaskRunner> task_runner)62void TracedProcessImpl::SetTaskRunner( 63 scoped_refptr<base::SequencedTaskRunner> task_runner) { 64 DCHECK(!receiver_.is_bound()); 65 DCHECK(!task_runner_); 66 task_runner_ = task_runner; 67 } 68 RegisterAgent(BaseAgent * agent)69void TracedProcessImpl::RegisterAgent(BaseAgent* agent) { 70 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 71 72 agents_.insert(agent); 73 } 74 UnregisterAgent(BaseAgent * agent)75void TracedProcessImpl::UnregisterAgent(BaseAgent* agent) { 76 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 77 agents_.erase(agent); 78 } 79 ConnectToTracingService(mojom::ConnectToTracingRequestPtr request,ConnectToTracingServiceCallback callback)80void TracedProcessImpl::ConnectToTracingService( 81 mojom::ConnectToTracingRequestPtr request, 82 ConnectToTracingServiceCallback callback) { 83 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 84 85 // Acknowledge this message so the tracing service knows it was dispatched in 86 // this process. 87 std::move(callback).Run(); 88 89 // Tracing requires a running ThreadPool; disable tracing 90 // for processes without it. 91 if (!base::ThreadPoolInstance::Get()) { 92 return; 93 } 94 95 // Ensure the TraceEventAgent has been created. 96 TraceEventAgent::GetInstance(); 97 98 PerfettoTracedProcess::Get()->ConnectProducer( 99 std::move(request->perfetto_service)); 100 } 101 GetCategories(std::set<std::string> * category_set)102void TracedProcessImpl::GetCategories(std::set<std::string>* category_set) { 103 for (auto* agent : agents_) { 104 agent->GetCategories(category_set); 105 } 106 } 107 108 } // namespace tracing 109