| // Copyright 2018 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. |
| |
| #ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PRODUCER_CLIENT_H_ |
| #define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PRODUCER_CLIENT_H_ |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/atomicops.h" |
| #include "base/component_export.h" |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "mojo/public/cpp/bindings/binding.h" |
| #include "services/tracing/public/cpp/perfetto/perfetto_producer.h" |
| #include "services/tracing/public/cpp/perfetto/task_runner.h" |
| #include "services/tracing/public/mojom/perfetto_service.mojom.h" |
| |
| namespace perfetto { |
| class SharedMemoryArbiter; |
| } // namespace perfetto |
| |
| namespace tracing { |
| |
| class MojoSharedMemory; |
| |
| // This class is the per-process client side of the Perfetto |
| // producer, and is responsible for creating specific kinds |
| // of DataSources (like ChromeTracing) on demand, and provide |
| // them with TraceWriters and a configuration to start logging. |
| class COMPONENT_EXPORT(TRACING_CPP) ProducerClient |
| : public PerfettoProducer, |
| public mojom::ProducerClient { |
| public: |
| ProducerClient(PerfettoTaskRunner* task_runner); |
| ~ProducerClient() override; |
| |
| void NewDataSourceAdded( |
| const PerfettoTracedProcess::DataSourceBase* const data_source) override; |
| |
| void Connect(mojom::PerfettoServicePtr perfetto_service); |
| |
| // Create the messagepipes that'll be used to connect |
| // to the service-side ProducerHost, on the correct |
| // sequence. The callback will be called on same sequence |
| // as CreateMojoMessagepipes() got called on. |
| using MessagepipesReadyCallback = |
| base::OnceCallback<void(mojom::ProducerClientPtr, |
| mojom::ProducerHostRequest)>; |
| void CreateMojoMessagepipes(MessagepipesReadyCallback); |
| |
| void set_in_process_shmem_arbiter(perfetto::SharedMemoryArbiter* arbiter) { |
| DCHECK(!in_process_arbiter_); |
| in_process_arbiter_ = arbiter; |
| } |
| |
| // mojom::ProducerClient implementation. |
| // Called through Mojo by the ProducerHost on the service-side to control |
| // tracing and toggle specific DataSources. |
| void OnTracingStart(mojo::ScopedSharedBufferHandle shared_memory) override; |
| void StartDataSource(uint64_t id, |
| const perfetto::DataSourceConfig& data_source_config, |
| StartDataSourceCallback callback) override; |
| |
| void StopDataSource(uint64_t id, StopDataSourceCallback callback) override; |
| void Flush(uint64_t flush_request_id, |
| const std::vector<uint64_t>& data_source_ids) override; |
| |
| // perfetto::TracingService::ProducerEndpoint implementation. |
| // Used by the TraceWriters |
| // to signal Perfetto that shared memory chunks are ready |
| // for consumption. |
| void CommitData(const perfetto::CommitDataRequest& commit, |
| CommitDataCallback callback) override; |
| // Used by the DataSource implementations to create TraceWriters |
| // for writing their protobufs, and respond to flushes. |
| void NotifyFlushComplete(perfetto::FlushRequestID) override; |
| perfetto::SharedMemory* shared_memory() const override; |
| void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override; |
| void UnregisterTraceWriter(uint32_t writer_id) override; |
| |
| // These ProducerEndpoint functions are only used on the service |
| // side and should not be called on the clients. |
| void RegisterDataSource(const perfetto::DataSourceDescriptor&) override; |
| void UnregisterDataSource(const std::string& name) override; |
| void NotifyDataSourceStopped(perfetto::DataSourceInstanceID) override; |
| void NotifyDataSourceStarted(perfetto::DataSourceInstanceID) override; |
| void ActivateTriggers(const std::vector<std::string>&) override; |
| size_t shared_buffer_page_size_kb() const override; |
| perfetto::SharedMemoryArbiter* GetInProcessShmemArbiter() override; |
| |
| protected: |
| perfetto::SharedMemoryArbiter* GetSharedMemoryArbiter() override; |
| |
| private: |
| friend class base::NoDestructor<ProducerClient>; |
| |
| void CommitDataOnSequence(const perfetto::CommitDataRequest& request); |
| |
| // The callback will be run on the |origin_task_runner|, meaning |
| // the same sequence as CreateMojoMessagePipes() got called on. |
| void CreateMojoMessagepipesOnSequence( |
| scoped_refptr<base::SequencedTaskRunner> origin_task_runner, |
| MessagepipesReadyCallback, |
| mojom::ProducerClientRequest, |
| mojom::ProducerClientPtr); |
| |
| std::unique_ptr<mojo::Binding<mojom::ProducerClient>> binding_; |
| mojom::ProducerHostPtr producer_host_; |
| std::unique_ptr<MojoSharedMemory> shared_memory_; |
| std::unique_ptr<perfetto::SharedMemoryArbiter> shared_memory_arbiter_; |
| perfetto::SharedMemoryArbiter* in_process_arbiter_ = nullptr; |
| // First value is the flush ID, the second is the number of |
| // replies we're still waiting for. |
| std::pair<uint64_t, size_t> pending_replies_for_latest_flush_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| // NOTE: Weak pointers must be invalidated before all other member variables. |
| base::WeakPtrFactory<ProducerClient> weak_ptr_factory_; |
| DISALLOW_COPY_AND_ASSIGN(ProducerClient); |
| }; |
| |
| } // namespace tracing |
| |
| #endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_PRODUCER_CLIENT_H_ |