• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
18 #define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
19 
20 #include <algorithm>
21 #include <functional>
22 #include <map>
23 #include <memory>
24 #include <mutex>
25 #include <random>
26 #include <set>
27 #include <utility>
28 #include <vector>
29 
30 #include "perfetto/base/logging.h"
31 #include "perfetto/base/status.h"
32 #include "perfetto/base/time.h"
33 #include "perfetto/ext/base/circular_queue.h"
34 #include "perfetto/ext/base/optional.h"
35 #include "perfetto/ext/base/periodic_task.h"
36 #include "perfetto/ext/base/weak_ptr.h"
37 #include "perfetto/ext/tracing/core/basic_types.h"
38 #include "perfetto/ext/tracing/core/commit_data_request.h"
39 #include "perfetto/ext/tracing/core/observable_events.h"
40 #include "perfetto/ext/tracing/core/shared_memory_abi.h"
41 #include "perfetto/ext/tracing/core/trace_stats.h"
42 #include "perfetto/ext/tracing/core/tracing_service.h"
43 #include "perfetto/tracing/core/data_source_config.h"
44 #include "perfetto/tracing/core/data_source_descriptor.h"
45 #include "perfetto/tracing/core/forward_decls.h"
46 #include "perfetto/tracing/core/trace_config.h"
47 #include "src/android_stats/perfetto_atoms.h"
48 #include "src/tracing/core/id_allocator.h"
49 
50 namespace protozero {
51 class MessageFilter;
52 }
53 
54 namespace perfetto {
55 
56 namespace base {
57 class TaskRunner;
58 }  // namespace base
59 
60 class Consumer;
61 class Producer;
62 class SharedMemory;
63 class SharedMemoryArbiterImpl;
64 class TraceBuffer;
65 class TracePacket;
66 
67 // The tracing service business logic.
68 class TracingServiceImpl : public TracingService {
69  private:
70   struct DataSourceInstance;
71 
72  public:
73   static constexpr size_t kDefaultShmPageSize = 4096ul;
74   static constexpr size_t kDefaultShmSize = 256 * 1024ul;
75   static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
76   static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
77   static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
78                                             0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
79                                             0x6d, 0x57, 0xa0, 0x79};
80 
81   // The implementation behind the service endpoint exposed to each producer.
82   class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
83    public:
84     ProducerEndpointImpl(ProducerID,
85                          uid_t uid,
86                          TracingServiceImpl*,
87                          base::TaskRunner*,
88                          Producer*,
89                          const std::string& producer_name,
90                          const std::string& sdk_version,
91                          bool in_process,
92                          bool smb_scraping_enabled);
93     ~ProducerEndpointImpl() override;
94 
95     // TracingService::ProducerEndpoint implementation.
96     void RegisterDataSource(const DataSourceDescriptor&) override;
97     void UnregisterDataSource(const std::string& name) override;
98     void RegisterTraceWriter(uint32_t writer_id,
99                              uint32_t target_buffer) override;
100     void UnregisterTraceWriter(uint32_t writer_id) override;
101     void CommitData(const CommitDataRequest&, CommitDataCallback) override;
102     void SetupSharedMemory(std::unique_ptr<SharedMemory>,
103                            size_t page_size_bytes,
104                            bool provided_by_producer);
105     std::unique_ptr<TraceWriter> CreateTraceWriter(
106         BufferID,
107         BufferExhaustedPolicy) override;
108     SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
109     bool IsShmemProvidedByProducer() const override;
110     void NotifyFlushComplete(FlushRequestID) override;
111     void NotifyDataSourceStarted(DataSourceInstanceID) override;
112     void NotifyDataSourceStopped(DataSourceInstanceID) override;
113     SharedMemory* shared_memory() const override;
114     size_t shared_buffer_page_size_kb() const override;
115     void ActivateTriggers(const std::vector<std::string>&) override;
116     void Sync(std::function<void()> callback) override;
117 
118     void OnTracingSetup();
119     void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
120     void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
121     void StopDataSource(DataSourceInstanceID);
122     void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
123     void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
124     void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
125 
is_allowed_target_buffer(BufferID buffer_id)126     bool is_allowed_target_buffer(BufferID buffer_id) const {
127       return allowed_target_buffers_.count(buffer_id);
128     }
129 
buffer_id_for_writer(WriterID writer_id)130     base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
131       const auto it = writers_.find(writer_id);
132       if (it != writers_.end())
133         return it->second;
134       return base::nullopt;
135     }
136 
uid()137     uid_t uid() const { return uid_; }
138 
139    private:
140     friend class TracingServiceImpl;
141     friend class TracingServiceImplTest;
142     friend class TracingIntegrationTest;
143     ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
144     ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
145 
146     ProducerID const id_;
147     const uid_t uid_;
148     TracingServiceImpl* const service_;
149     base::TaskRunner* const task_runner_;
150     Producer* producer_;
151     std::unique_ptr<SharedMemory> shared_memory_;
152     size_t shared_buffer_page_size_kb_ = 0;
153     SharedMemoryABI shmem_abi_;
154     size_t shmem_size_hint_bytes_ = 0;
155     size_t shmem_page_size_hint_bytes_ = 0;
156     bool is_shmem_provided_by_producer_ = false;
157     const std::string name_;
158     std::string sdk_version_;
159     bool in_process_;
160     bool smb_scraping_enabled_;
161 
162     // Set of the global target_buffer IDs that the producer is configured to
163     // write into in any active tracing session.
164     std::set<BufferID> allowed_target_buffers_;
165 
166     // Maps registered TraceWriter IDs to their target buffers as registered by
167     // the producer. Note that producers aren't required to register their
168     // writers, so we may see commits of chunks with WriterIDs that aren't
169     // contained in this map. However, if a producer does register a writer, the
170     // service will prevent the writer from writing into any other buffer than
171     // the one associated with it here. The BufferIDs stored in this map are
172     // untrusted, so need to be verified against |allowed_target_buffers_|
173     // before use.
174     std::map<WriterID, BufferID> writers_;
175 
176     // This is used only in in-process configurations.
177     // SharedMemoryArbiterImpl methods themselves are thread-safe.
178     std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
179 
180     PERFETTO_THREAD_CHECKER(thread_checker_)
181     base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
182   };
183 
184   // The implementation behind the service endpoint exposed to each consumer.
185   class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
186    public:
187     ConsumerEndpointImpl(TracingServiceImpl*,
188                          base::TaskRunner*,
189                          Consumer*,
190                          uid_t uid);
191     ~ConsumerEndpointImpl() override;
192 
193     void NotifyOnTracingDisabled(const std::string& error);
194 
195     // TracingService::ConsumerEndpoint implementation.
196     void EnableTracing(const TraceConfig&, base::ScopedFile) override;
197     void ChangeTraceConfig(const TraceConfig& cfg) override;
198     void StartTracing() override;
199     void DisableTracing() override;
200     void ReadBuffers() override;
201     void FreeBuffers() override;
202     void Flush(uint32_t timeout_ms, FlushCallback) override;
203     void Detach(const std::string& key) override;
204     void Attach(const std::string& key) override;
205     void GetTraceStats() override;
206     void ObserveEvents(uint32_t enabled_event_types) override;
207     void QueryServiceState(QueryServiceStateCallback) override;
208     void QueryCapabilities(QueryCapabilitiesCallback) override;
209     void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
210 
211     // Will queue a task to notify the consumer about the state change.
212     void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
213                                          const DataSourceInstance&);
214     void OnAllDataSourcesStarted();
215 
216    private:
217     friend class TracingServiceImpl;
218     ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
219     ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
220 
221     // Returns a pointer to an ObservableEvents object that the caller can fill
222     // and schedules a task to send the ObservableEvents to the consumer.
223     ObservableEvents* AddObservableEvents();
224 
225     base::TaskRunner* const task_runner_;
226     TracingServiceImpl* const service_;
227     Consumer* const consumer_;
228     uid_t const uid_;
229     TracingSessionID tracing_session_id_ = 0;
230 
231     // Whether the consumer is interested in DataSourceInstance state change
232     // events.
233     uint32_t observable_events_mask_ = 0;
234 
235     // ObservableEvents that will be sent to the consumer. If set, a task to
236     // flush the events to the consumer has been queued.
237     std::unique_ptr<ObservableEvents> observable_events_;
238 
239     PERFETTO_THREAD_CHECKER(thread_checker_)
240     base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
241   };
242 
243   explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
244                               base::TaskRunner*);
245   ~TracingServiceImpl() override;
246 
247   // Called by ProducerEndpointImpl.
248   void DisconnectProducer(ProducerID);
249   void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
250   void UnregisterDataSource(ProducerID, const std::string& name);
251   void CopyProducerPageIntoLogBuffer(ProducerID,
252                                      uid_t,
253                                      WriterID,
254                                      ChunkID,
255                                      BufferID,
256                                      uint16_t num_fragments,
257                                      uint8_t chunk_flags,
258                                      bool chunk_complete,
259                                      const uint8_t* src,
260                                      size_t size);
261   void ApplyChunkPatches(ProducerID,
262                          const std::vector<CommitDataRequest::ChunkToPatch>&);
263   void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
264   void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID);
265   void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
266   void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
267 
268   // Called by ConsumerEndpointImpl.
269   bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
270   bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
271   void DisconnectConsumer(ConsumerEndpointImpl*);
272   base::Status EnableTracing(ConsumerEndpointImpl*,
273                              const TraceConfig&,
274                              base::ScopedFile);
275   void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
276 
277   base::Status StartTracing(TracingSessionID);
278   void DisableTracing(TracingSessionID, bool disable_immediately = false);
279   void Flush(TracingSessionID tsid,
280              uint32_t timeout_ms,
281              ConsumerEndpoint::FlushCallback);
282   void FlushAndDisableTracing(TracingSessionID);
283   bool ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
284   void FreeBuffers(TracingSessionID);
285 
286   // Service implementation.
287   std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
288       Producer*,
289       uid_t uid,
290       const std::string& producer_name,
291       size_t shared_memory_size_hint_bytes = 0,
292       bool in_process = false,
293       ProducerSMBScrapingMode smb_scraping_mode =
294           ProducerSMBScrapingMode::kDefault,
295       size_t shared_memory_page_size_hint_bytes = 0,
296       std::unique_ptr<SharedMemory> shm = nullptr,
297       const std::string& sdk_version = {}) override;
298 
299   std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
300       Consumer*,
301       uid_t) override;
302 
303   // Set whether SMB scraping should be enabled by default or not. Producers can
304   // override this setting for their own SMBs.
SetSMBScrapingEnabled(bool enabled)305   void SetSMBScrapingEnabled(bool enabled) override {
306     smb_scraping_enabled_ = enabled;
307   }
308 
309   // Exposed mainly for testing.
num_producers()310   size_t num_producers() const { return producers_.size(); }
311   ProducerEndpointImpl* GetProducer(ProducerID) const;
312 
313  private:
314   friend class TracingServiceImplTest;
315   friend class TracingIntegrationTest;
316 
317   static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000;
318 
319   struct TriggerHistory {
320     int64_t timestamp_ns;
321     uint64_t name_hash;
322 
323     bool operator<(const TriggerHistory& other) const {
324       return timestamp_ns < other.timestamp_ns;
325     }
326   };
327 
328   struct RegisteredDataSource {
329     ProducerID producer_id;
330     DataSourceDescriptor descriptor;
331   };
332 
333   // Represents an active data source for a tracing session.
334   struct DataSourceInstance {
DataSourceInstanceDataSourceInstance335     DataSourceInstance(DataSourceInstanceID id,
336                        const DataSourceConfig& cfg,
337                        const std::string& ds_name,
338                        bool notify_on_start,
339                        bool notify_on_stop,
340                        bool handles_incremental_state_invalidation)
341         : instance_id(id),
342           config(cfg),
343           data_source_name(ds_name),
344           will_notify_on_start(notify_on_start),
345           will_notify_on_stop(notify_on_stop),
346           handles_incremental_state_clear(
347               handles_incremental_state_invalidation) {}
348     DataSourceInstance(const DataSourceInstance&) = delete;
349     DataSourceInstance& operator=(const DataSourceInstance&) = delete;
350 
351     DataSourceInstanceID instance_id;
352     DataSourceConfig config;
353     std::string data_source_name;
354     bool will_notify_on_start;
355     bool will_notify_on_stop;
356     bool handles_incremental_state_clear;
357 
358     enum DataSourceInstanceState {
359       CONFIGURED,
360       STARTING,
361       STARTED,
362       STOPPING,
363       STOPPED
364     };
365     DataSourceInstanceState state = CONFIGURED;
366   };
367 
368   struct PendingFlush {
369     std::set<ProducerID> producers;
370     ConsumerEndpoint::FlushCallback callback;
PendingFlushPendingFlush371     explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
372   };
373 
374   // Holds the state of a tracing session. A tracing session is uniquely bound
375   // a specific Consumer. Each Consumer can own one or more sessions.
376   struct TracingSession {
377     enum State {
378       DISABLED = 0,
379       CONFIGURED,
380       STARTED,
381       DISABLING_WAITING_STOP_ACKS
382     };
383 
384     TracingSession(TracingSessionID,
385                    ConsumerEndpointImpl*,
386                    const TraceConfig&,
387                    base::TaskRunner*);
388     TracingSession(TracingSession&&) = delete;
389     TracingSession& operator=(TracingSession&&) = delete;
390 
num_buffersTracingSession391     size_t num_buffers() const { return buffers_index.size(); }
392 
delay_to_next_write_period_msTracingSession393     uint32_t delay_to_next_write_period_ms() const {
394       PERFETTO_DCHECK(write_period_ms > 0);
395       return write_period_ms -
396              static_cast<uint32_t>(base::GetWallTimeMs().count() %
397                                    write_period_ms);
398     }
399 
flush_timeout_msTracingSession400     uint32_t flush_timeout_ms() {
401       uint32_t timeout_ms = config.flush_timeout_ms();
402       return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
403     }
404 
data_source_stop_timeout_msTracingSession405     uint32_t data_source_stop_timeout_ms() {
406       uint32_t timeout_ms = config.data_source_stop_timeout_ms();
407       return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
408     }
409 
GetPacketSequenceIDTracingSession410     PacketSequenceID GetPacketSequenceID(ProducerID producer_id,
411                                          WriterID writer_id) {
412       auto key = std::make_pair(producer_id, writer_id);
413       auto it = packet_sequence_ids.find(key);
414       if (it != packet_sequence_ids.end())
415         return it->second;
416       // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
417       // are limited to 1024).
418       static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
419                     "PacketSequenceID value space doesn't cover service "
420                     "sequence ID and all producer/writer ID combinations!");
421       PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
422       PacketSequenceID sequence_id = ++last_packet_sequence_id;
423       packet_sequence_ids[key] = sequence_id;
424       return sequence_id;
425     }
426 
GetDataSourceInstanceTracingSession427     DataSourceInstance* GetDataSourceInstance(
428         ProducerID producer_id,
429         DataSourceInstanceID instance_id) {
430       for (auto& inst_kv : data_source_instances) {
431         if (inst_kv.first != producer_id ||
432             inst_kv.second.instance_id != instance_id) {
433           continue;
434         }
435         return &inst_kv.second;
436       }
437       return nullptr;
438     }
439 
AllDataSourceInstancesStartedTracingSession440     bool AllDataSourceInstancesStarted() {
441       return std::all_of(
442           data_source_instances.begin(), data_source_instances.end(),
443           [](decltype(data_source_instances)::const_reference x) {
444             return x.second.state == DataSourceInstance::STARTED;
445           });
446     }
447 
AllDataSourceInstancesStoppedTracingSession448     bool AllDataSourceInstancesStopped() {
449       return std::all_of(
450           data_source_instances.begin(), data_source_instances.end(),
451           [](decltype(data_source_instances)::const_reference x) {
452             return x.second.state == DataSourceInstance::STOPPED;
453           });
454     }
455 
456     const TracingSessionID id;
457 
458     // The consumer that started the session.
459     // Can be nullptr if the consumer detached from the session.
460     ConsumerEndpointImpl* consumer_maybe_null;
461 
462     // Unix uid of the consumer. This is valid even after the consumer detaches
463     // and does not change for the entire duration of the session. It is used to
464     // prevent that a consumer re-attaches to a session from a different uid.
465     uid_t const consumer_uid;
466 
467     // The list of triggers this session received while alive and the time they
468     // were received at. This is used to insert 'fake' packets back to the
469     // consumer so they can tell when some event happened. The order matches the
470     // order they were received.
471     struct TriggerInfo {
472       uint64_t boot_time_ns;
473       std::string trigger_name;
474       std::string producer_name;
475       uid_t producer_uid;
476     };
477     std::vector<TriggerInfo> received_triggers;
478 
479     // The trace config provided by the Consumer when calling
480     // EnableTracing(), plus any updates performed by ChangeTraceConfig.
481     TraceConfig config;
482 
483     // List of data source instances that have been enabled on the various
484     // producers for this tracing session.
485     // TODO(rsavitski): at the time of writing, the map structure is unused
486     // (even when the calling code has a key). This is also an opportunity to
487     // consider an alternative data type, e.g. a map of vectors.
488     std::multimap<ProducerID, DataSourceInstance> data_source_instances;
489 
490     // For each Flush(N) request, keeps track of the set of producers for which
491     // we are still awaiting a NotifyFlushComplete(N) ack.
492     std::map<FlushRequestID, PendingFlush> pending_flushes;
493 
494     // Maps a per-trace-session buffer index into the corresponding global
495     // BufferID (shared namespace amongst all consumers). This vector has as
496     // many entries as |config.buffers_size()|.
497     std::vector<BufferID> buffers_index;
498 
499     std::map<std::pair<ProducerID, WriterID>, PacketSequenceID>
500         packet_sequence_ids;
501     PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
502 
503     // Whether we should emit the trace stats next time we reach EOF while
504     // performing ReadBuffers.
505     bool should_emit_stats = false;
506 
507     // Whether we should emit the sync marker the next time ReadBuffers() is
508     // called.
509     bool should_emit_sync_marker = false;
510 
511     // Whether we mirrored the trace config back to the trace output yet.
512     bool did_emit_config = false;
513 
514     // Whether we put the system info into the trace output yet.
515     bool did_emit_system_info = false;
516 
517     // The number of received triggers we've emitted into the trace output.
518     size_t num_triggers_emitted_into_trace = 0;
519 
520     // Packets that failed validation of the TrustedPacket.
521     uint64_t invalid_packets = 0;
522 
523     // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
524     bool did_notify_all_data_source_started = false;
525 
526     // Stores all lifecycle events of a particular type (i.e. associated with a
527     // single field id in the TracingServiceEvent proto).
528     struct LifecycleEvent {
529       LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
field_idTracingSession::LifecycleEvent530           : field_id(f_id), max_size(m_size), timestamps(m_size) {}
531 
532       // The field id of the event in the TracingServiceEvent proto.
533       uint32_t field_id;
534 
535       // Stores the max size of |timestamps|. Set to 1 by default (in
536       // the constructor) but can be overriden in TraceSession constructor
537       // if a larger size is required.
538       uint32_t max_size;
539 
540       // Stores the timestamps emitted for each event type (in nanoseconds).
541       // Emitted into the trace and cleared when the consumer next calls
542       // ReadBuffers.
543       base::CircularQueue<int64_t> timestamps;
544     };
545     std::vector<LifecycleEvent> lifecycle_events;
546 
547     using ClockSnapshotData =
548         std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>;
549 
550     // Initial clock snapshot, captured at trace start time (when state goes to
551     // TracingSession::STARTED). Emitted into the trace when the consumer first
552     // calls ReadBuffers().
553     ClockSnapshotData initial_clock_snapshot;
554 
555     // Stores clock snapshots to emit into the trace as a ring buffer. This
556     // buffer is populated both periodically and when lifecycle events happen
557     // but only when significant clock drift is detected. Emitted into the trace
558     // and cleared when the consumer next calls ReadBuffers().
559     base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;
560 
561     State state = DISABLED;
562 
563     // If the consumer detached the session, this variable defines the key used
564     // for identifying the session later when reattaching.
565     std::string detach_key;
566 
567     // This is set when the Consumer calls sets |write_into_file| == true in the
568     // TraceConfig. In this case this represents the file we should stream the
569     // trace packets into, rather than returning it to the consumer via
570     // OnTraceData().
571     base::ScopedFile write_into_file;
572     uint32_t write_period_ms = 0;
573     uint64_t max_file_size_bytes = 0;
574     uint64_t bytes_written_into_file = 0;
575 
576     // Set when using SaveTraceForBugreport(). This callback will be called
577     // when the tracing session ends and the data has been saved into the file.
578     std::function<void()> on_disable_callback_for_bugreport;
579     bool seized_for_bugreport = false;
580 
581     // Periodic task for snapshotting service events (e.g. clocks, sync markers
582     // etc)
583     base::PeriodicTask snapshot_periodic_task;
584 
585     // When non-NULL the packets should be post-processed using the filter.
586     std::unique_ptr<protozero::MessageFilter> trace_filter;
587     uint64_t filter_input_packets = 0;
588     uint64_t filter_input_bytes = 0;
589     uint64_t filter_output_bytes = 0;
590     uint64_t filter_errors = 0;
591   };
592 
593   TracingServiceImpl(const TracingServiceImpl&) = delete;
594   TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
595 
596   DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
597                                       const TraceConfig::ProducerConfig&,
598                                       const RegisteredDataSource&,
599                                       TracingSession*);
600 
601   // Returns the next available ProducerID that is not in |producers_|.
602   ProducerID GetNextProducerID();
603 
604   // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
605   // session doesn't exists.
606   TracingSession* GetTracingSession(TracingSessionID);
607 
608   // Returns a pointer to the |tracing_sessions_| entry, matching the given
609   // uid and detach key, or nullptr if no such session exists.
610   TracingSession* GetDetachedSession(uid_t, const std::string& key);
611 
612   // Update the memory guard rail by using the latest information from the
613   // shared memory and trace buffers.
614   void UpdateMemoryGuardrail();
615 
616   void StartDataSourceInstance(ProducerEndpointImpl*,
617                                TracingSession*,
618                                DataSourceInstance*);
619   void StopDataSourceInstance(ProducerEndpointImpl*,
620                               TracingSession*,
621                               DataSourceInstance*,
622                               bool disable_immediately);
623   void PeriodicSnapshotTask(TracingSessionID);
624   void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
625   bool SnapshotClocks(TracingSession::ClockSnapshotData*);
626   void SnapshotLifecyleEvent(TracingSession*,
627                              uint32_t field_id,
628                              bool snapshot_clocks);
629   void EmitClockSnapshot(TracingSession*,
630                          TracingSession::ClockSnapshotData,
631                          std::vector<TracePacket>*);
632   void EmitSyncMarker(std::vector<TracePacket>*);
633   void EmitStats(TracingSession*, std::vector<TracePacket>*);
634   TraceStats GetTraceStats(TracingSession*);
635   void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
636   void EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket>*);
637   void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
638   void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
639   void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
640   void MaybeNotifyAllDataSourcesStarted(TracingSession*);
641   bool MaybeSaveTraceForBugreport(std::function<void()> callback);
642   void OnFlushTimeout(TracingSessionID, FlushRequestID);
643   void OnDisableTracingTimeout(TracingSessionID);
644   void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
645   void PeriodicFlushTask(TracingSessionID, bool post_next_only);
646   void CompleteFlush(TracingSessionID tsid,
647                      ConsumerEndpoint::FlushCallback callback,
648                      bool success);
649   void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
650   void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
651   TraceBuffer* GetBufferByID(BufferID);
652   void OnStartTriggersTimeout(TracingSessionID tsid);
653   void MaybeLogUploadEvent(const TraceConfig&,
654                            PerfettoStatsdAtom atom,
655                            const std::string& trigger_name = "");
656   void MaybeLogTriggerEvent(const TraceConfig&,
657                             PerfettoTriggerAtom atom,
658                             const std::string& trigger_name);
659   size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,
660                                              uint64_t trigger_name_hash);
661 
662   base::TaskRunner* const task_runner_;
663   std::unique_ptr<SharedMemory::Factory> shm_factory_;
664   ProducerID last_producer_id_ = 0;
665   DataSourceInstanceID last_data_source_instance_id_ = 0;
666   TracingSessionID last_tracing_session_id_ = 0;
667   FlushRequestID last_flush_request_id_ = 0;
668   uid_t uid_ = 0;
669 
670   // Buffer IDs are global across all consumers (because a Producer can produce
671   // data for more than one trace session, hence more than one consumer).
672   IdAllocator<BufferID> buffer_ids_;
673 
674   std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
675   std::map<ProducerID, ProducerEndpointImpl*> producers_;
676   std::set<ConsumerEndpointImpl*> consumers_;
677   std::map<TracingSessionID, TracingSession> tracing_sessions_;
678   std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
679   std::map<std::string, int64_t> session_to_last_trace_s_;
680 
681   // Contains timestamps of triggers.
682   // The queue is sorted by timestamp and invocations older than
683   // |trigger_window_ns_| are purged when a trigger happens.
684   base::CircularQueue<TriggerHistory> trigger_history_;
685 
686   bool smb_scraping_enabled_ = false;
687   bool lockdown_mode_ = false;
688   uint32_t min_write_period_ms_ = 100;       // Overridable for testing.
689   int64_t trigger_window_ns_ = kOneDayInNs;  // Overridable for testing.
690 
691   std::minstd_rand trigger_probability_rand_;
692   std::uniform_real_distribution<> trigger_probability_dist_;
693   double trigger_rnd_override_for_testing_ = 0;  // Overridable for testing.
694 
695   uint8_t sync_marker_packet_[32];  // Lazily initialized.
696   size_t sync_marker_packet_size_ = 0;
697 
698   // Stats.
699   uint64_t chunks_discarded_ = 0;
700   uint64_t patches_discarded_ = 0;
701 
702   PERFETTO_THREAD_CHECKER(thread_checker_)
703 
704   base::WeakPtrFactory<TracingServiceImpl>
705       weak_ptr_factory_;  // Keep at the end.
706 };
707 
708 }  // namespace perfetto
709 
710 #endif  // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
711