xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/proto/proto_trace_reader.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2018 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_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <optional>
23 #include <utility>
24 #include <vector>
25 
26 #include "perfetto/base/status.h"
27 #include "perfetto/ext/base/flat_hash_map.h"
28 #include "src/trace_processor/importers/common/chunked_trace_reader.h"
29 #include "src/trace_processor/importers/proto/multi_machine_trace_manager.h"
30 #include "src/trace_processor/importers/proto/packet_sequence_state_builder.h"
31 #include "src/trace_processor/importers/proto/proto_trace_tokenizer.h"
32 #include "src/trace_processor/storage/trace_storage.h"
33 
34 namespace protozero {
35 struct ConstBytes;
36 }
37 
38 namespace perfetto {
39 
40 namespace protos::pbzero {
41 class TracePacket_Decoder;
42 class TraceConfig_Decoder;
43 }  // namespace protos::pbzero
44 
45 namespace trace_processor {
46 
47 class PacketSequenceState;
48 class TraceProcessorContext;
49 class TraceSorter;
50 class TraceStorage;
51 
52 // Implementation of ChunkedTraceReader for proto traces. Tokenizes a proto
53 // trace into packets, handles parsing of any packets which need to be
54 // handled in trace-order and passes the remainder to TraceSorter to sort
55 // into timestamp order.
56 class ProtoTraceReader : public ChunkedTraceReader {
57  public:
58   // |reader| is the abstract method of getting chunks of size |chunk_size_b|
59   // from a trace file with these chunks parsed into |trace|.
60   explicit ProtoTraceReader(TraceProcessorContext*);
61   ~ProtoTraceReader() override;
62 
63   // ChunkedTraceReader implementation.
64   base::Status Parse(TraceBlobView) override;
65   base::Status NotifyEndOfFile() override;
66 
67   using SyncClockSnapshots = base::FlatHashMap<
68       int64_t,
69       std::pair</*host ts*/ uint64_t, /*client ts*/ uint64_t>>;
70   static base::FlatHashMap<int64_t /*Clock Id*/, int64_t /*Offset*/>
CalculateClockOffsetsForTesting(std::vector<SyncClockSnapshots> & sync_clock_snapshots)71   CalculateClockOffsetsForTesting(
72       std::vector<SyncClockSnapshots>& sync_clock_snapshots) {
73     return CalculateClockOffsets(sync_clock_snapshots);
74   }
75 
76   std::optional<StringId> GetBuiltinClockNameOrNull(int64_t clock_id);
77 
78  private:
79   struct SequenceScopedState {
80     std::optional<PacketSequenceStateBuilder> sequence_state_builder;
81     uint32_t previous_packet_dropped_count = 0;
82     uint32_t needs_incremental_state_total = 0;
83     uint32_t needs_incremental_state_skipped = 0;
84   };
85 
86   using ConstBytes = protozero::ConstBytes;
87   base::Status ParsePacket(TraceBlobView);
88   base::Status ParseServiceEvent(int64_t ts, ConstBytes);
89   base::Status ParseClockSnapshot(ConstBytes blob, uint32_t seq_id);
90   base::Status ParseRemoteClockSync(ConstBytes blob);
91   void HandleIncrementalStateCleared(
92       const protos::pbzero::TracePacket_Decoder&);
93   void HandleFirstPacketOnSequence(uint32_t packet_sequence_id);
94   void HandlePreviousPacketDropped(const protos::pbzero::TracePacket_Decoder&);
95   void ParseTracePacketDefaults(const protos::pbzero::TracePacket_Decoder&,
96                                 TraceBlobView trace_packet_defaults);
97   void ParseInternedData(const protos::pbzero::TracePacket_Decoder&,
98                          TraceBlobView interned_data);
99   void ParseTraceConfig(ConstBytes);
100   void ParseTraceStats(ConstBytes);
101 
102   static base::FlatHashMap<int64_t /*Clock Id*/, int64_t /*Offset*/>
103   CalculateClockOffsets(std::vector<SyncClockSnapshots>&);
104 
GetIncrementalStateForPacketSequence(uint32_t sequence_id)105   PacketSequenceStateBuilder* GetIncrementalStateForPacketSequence(
106       uint32_t sequence_id) {
107     auto& builder = sequence_state_.Find(sequence_id)->sequence_state_builder;
108     if (!builder) {
109       builder = PacketSequenceStateBuilder(context_);
110     }
111     return &*builder;
112   }
113   base::Status ParseExtensionDescriptor(ConstBytes descriptor);
114 
115   TraceProcessorContext* context_;
116 
117   ProtoTraceTokenizer tokenizer_;
118 
119   // Temporary. Currently trace packets do not have a timestamp, so the
120   // timestamp given is latest_timestamp_.
121   int64_t latest_timestamp_ = 0;
122 
123   base::FlatHashMap<uint32_t, SequenceScopedState> sequence_state_;
124   StringId skipped_packet_key_id_;
125   StringId invalid_incremental_state_key_id_;
126 };
127 
128 }  // namespace trace_processor
129 }  // namespace perfetto
130 
131 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_
132