1 /* 2 * Copyright (C) 2019 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_IMPORTER_MODULE_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_IMPORTER_MODULE_H_ 19 20 #include <optional> 21 22 #include "perfetto/base/status.h" 23 #include "src/trace_processor/importers/common/trace_parser.h" 24 25 namespace perfetto { 26 27 namespace protos { 28 namespace pbzero { 29 class TraceConfig_Decoder; 30 class TracePacket_Decoder; 31 } // namespace pbzero 32 } // namespace protos 33 34 namespace trace_processor { 35 36 class PacketSequenceState; 37 class TraceBlobView; 38 class TraceProcessorContext; 39 40 // This file contains a base class for ProtoTraceReader/Parser modules. 41 // A module implements support for a subset of features of the TracePacket 42 // proto format. 43 // To add and integrate a new module: 44 // (1) Add MyModule as a subclass of ProtoImporterModule, 45 // overriding the TokenizePacket(), ParsePacket() and/or ParseTraceConfig() 46 // methods. 47 // (2) In the constructor call the RegisterForField method for every field 48 // that the module knows how to handle. 49 // (3) Create a module instance and add it to TraceProcessorContext's |modules| 50 // vector in either default_modules.cc or additional_modules.cc. 51 // See GraphicsEventModule for an example. 52 53 class ModuleResult { 54 public: 55 // Allow auto conversion from util::Status to Handled / Error result. ModuleResult(base::Status status)56 ModuleResult(base::Status status) 57 : ignored_(false), 58 error_(status.ok() ? std::nullopt 59 : std::make_optional(status.message())) {} 60 61 // Constructs a result that indicates the module ignored the packet and is 62 // deferring the handling of the packet to other modules. Ignored()63 static ModuleResult Ignored() { return ModuleResult(true); } 64 65 // Constructs a result that indicates the module handled the packet. Other 66 // modules will not be notified about the packet. Handled()67 static ModuleResult Handled() { return ModuleResult(false); } 68 69 // Constructs a result that indicates an error condition while handling the 70 // packet. Other modules will not be notified about the packet. Error(const std::string & message)71 static ModuleResult Error(const std::string& message) { 72 return ModuleResult(message); 73 } 74 ignored()75 bool ignored() const { return ignored_; } ok()76 bool ok() const { return !error_.has_value(); } message()77 const std::string& message() const { return *error_; } 78 ToStatus()79 base::Status ToStatus() const { 80 PERFETTO_DCHECK(!ignored_); 81 if (error_) 82 return base::Status(*error_); 83 return base::OkStatus(); 84 } 85 86 private: ModuleResult(bool ignored)87 explicit ModuleResult(bool ignored) : ignored_(ignored) {} ModuleResult(const std::string & error)88 explicit ModuleResult(const std::string& error) 89 : ignored_(false), error_(error) {} 90 91 bool ignored_; 92 std::optional<std::string> error_; 93 }; 94 95 // Base class for modules. 96 class ProtoImporterModule { 97 public: 98 ProtoImporterModule(); 99 100 virtual ~ProtoImporterModule(); 101 102 // Called by ProtoTraceReader during the tokenization stage, i.e. before 103 // sorting. It's called for each TracePacket that contains fields for which 104 // the module was registered. If this returns a result other than 105 // ModuleResult::Ignored(), tokenization of the packet will be aborted after 106 // the module. 107 virtual ModuleResult TokenizePacket( 108 const protos::pbzero::TracePacket_Decoder&, 109 TraceBlobView* packet, 110 int64_t packet_timestamp, 111 PacketSequenceState*, 112 uint32_t field_id); 113 114 // Called by ProtoTraceReader during the tokenization stage i.e. before 115 // sorting. Indicates that sequence with id |packet_sequence_id| has cleared 116 // its incremental state. This should be used to clear any cached state the 117 // tokenizer has built up while reading packets until this point for this 118 // packet sequence. OnIncrementalStateCleared(uint32_t)119 virtual void OnIncrementalStateCleared(uint32_t /* packet_sequence_id */) {} 120 121 // Called by ProtoTraceReader during the tokenization stage i.e. before 122 // sorting. Indicates that sequence with id |packet_sequence_id| has a packet 123 // with first_packet_on_sequence = true. This implies that there was no data 124 // loss, including ring buffer overwrittes, on this sequence. OnFirstPacketOnSequence(uint32_t)125 virtual void OnFirstPacketOnSequence(uint32_t /* packet_sequence_id */) {} 126 127 // ParsePacket functions are called by ProtoTraceParser after the sorting 128 // stage for each non-ftrace TracePacket that contains fields for which the 129 // module was registered. 130 virtual void ParseTracePacketData(const protos::pbzero::TracePacket_Decoder&, 131 int64_t ts, 132 const TracePacketData&, 133 uint32_t /*field_id*/); 134 135 // Called by ProtoTraceParser for trace config packets after the sorting 136 // stage, on all existing modules. 137 virtual void ParseTraceConfig(const protos::pbzero::TraceConfig_Decoder&); 138 NotifyEndOfFile()139 virtual void NotifyEndOfFile() {} 140 141 protected: 142 void RegisterForField(uint32_t field_id, TraceProcessorContext*); 143 // Primarily intended for special modules that need to get all TracePacket's, 144 // for example for trace proto content analysis. Most modules need to register 145 // for specific fields using the method above. 146 void RegisterForAllFields(TraceProcessorContext*); 147 }; 148 149 } // namespace trace_processor 150 } // namespace perfetto 151 152 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_IMPORTER_MODULE_H_ 153