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 INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_ 18 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_ 19 20 #include <stddef.h> 21 #include <memory> 22 #include <tuple> 23 24 #include "perfetto/base/export.h" 25 #include "perfetto/base/logging.h" 26 #include "perfetto/ext/tracing/core/slice.h" 27 28 namespace perfetto { 29 30 // A wrapper around a byte buffer that contains a protobuf-encoded TracePacket 31 // (see trace_packet.proto). The TracePacket is decoded only if the Consumer 32 // requests that. This is to allow Consumer(s) to just stream the packet over 33 // the network or save it to a file without wasting time decoding it and without 34 // needing to depend on libprotobuf or the trace_packet.pb.h header. 35 // If the packets are saved / streamed and not just consumed locally, consumers 36 // should ensure to preserve the unknown fields in the proto. A consumer, in 37 // fact, might have an older version .proto which is newer on the producer. 38 class PERFETTO_EXPORT TracePacket { 39 public: 40 using const_iterator = Slices::const_iterator; 41 42 // The field id of protos::Trace::packet, static_assert()-ed in the unittest. 43 static constexpr uint32_t kPacketFieldNumber = 1; 44 45 // Maximum size of the preamble returned by GetProtoPreamble(). 46 static constexpr size_t kMaxPreambleBytes = 8; 47 48 TracePacket(); 49 ~TracePacket(); 50 TracePacket(TracePacket&&) noexcept; 51 TracePacket& operator=(TracePacket&&); 52 53 // Accesses all the raw slices in the packet, for saving them to file/network. slices()54 const Slices& slices() const { return slices_; } 55 56 // Mutator, used only by the service and tests. 57 void AddSlice(Slice); 58 59 // Does not copy / take ownership of the memory of the slice. The TracePacket 60 // will be valid only as long as the original buffer is valid. 61 void AddSlice(const void* start, size_t size); 62 63 // Total size of all slices. size()64 size_t size() const { return size_; } 65 66 // Generates a protobuf preamble suitable to represent this packet as a 67 // repeated field within a root trace.proto message. 68 // Returns a pointer to a buffer, owned by this class, containing the preamble 69 // and its size. 70 std::tuple<char*, size_t> GetProtoPreamble(); 71 72 // Returns the raw protobuf bytes of the slices, all stitched together into 73 // a string. Only for testing. 74 std::string GetRawBytesForTesting(); 75 76 private: 77 TracePacket(const TracePacket&) = delete; 78 TracePacket& operator=(const TracePacket&) = delete; 79 80 Slices slices_; // Not owned. 81 size_t size_ = 0; // SUM(slice.size for slice in slices_). 82 char preamble_[kMaxPreambleBytes]; // Deliberately not initialized. 83 84 // Remember to update the move operators and their unittest if adding new 85 // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on 86 // std::move(TracePacket) to clear up the moved-from instance. 87 }; 88 89 } // namespace perfetto 90 91 #endif // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_ 92