• 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 INCLUDE_PERFETTO_TRACING_CORE_TRACE_PACKET_H_
18 #define INCLUDE_PERFETTO_TRACING_CORE_TRACE_PACKET_H_
19 
20 #include <stddef.h>
21 
22 #include <memory>
23 #include <tuple>
24 
25 #include "google/protobuf/io/zero_copy_stream.h"
26 #include "perfetto/base/export.h"
27 #include "perfetto/base/logging.h"
28 #include "perfetto/tracing/core/slice.h"
29 
30 namespace perfetto {
31 
32 namespace protos {
33 class TracePacket;  // From protos/trace_packet.pb.h.
34 }  // namespace protos
35 
36 // A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
37 // (see trace_packet.proto). The TracePacket is decoded only if the Consumer
38 // requests that. This is to allow Consumer(s) to just stream the packet over
39 // the network or save it to a file without wasting time decoding it and without
40 // needing to depend on libprotobuf or the trace_packet.pb.h header.
41 // If the packets are saved / streamed and not just consumed locally, consumers
42 // should ensure to preserve the unknown fields in the proto. A consumer, in
43 // fact, might have an older version .proto which is newer on the producer.
44 class PERFETTO_EXPORT TracePacket {
45  public:
46   using const_iterator = Slices::const_iterator;
47   using ZeroCopyInputStream = ::google::protobuf::io::ZeroCopyInputStream;
48 
49   // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
50   static constexpr uint32_t kPacketFieldNumber = 1;
51 
52   TracePacket();
53   ~TracePacket();
54   TracePacket(TracePacket&&) noexcept;
55   TracePacket& operator=(TracePacket&&);
56 
57   // Accesses all the raw slices in the packet, for saving them to file/network.
slices()58   const Slices& slices() const { return slices_; }
59 
60   // Decodes the packet. This function requires that the caller:
61   // 1) Does #include "perfetto/trace/trace_packet.pb.h"
62   // 2) Links against the //protos/trace:lite target.
63   // The core service code deliberately doesn't link against that in order to
64   // avoid binary bloat. This is the reason why this is a templated function.
65   // It doesn't need to be (i.e. the caller should not specify the template
66   // argument) but doing so prevents the compiler trying to resolve the
67   // TracePacket type until it's needed, in which case the caller needs (1).
68   template <typename TracePacketType = protos::TracePacket>
Decode(TracePacketType * packet)69   bool Decode(TracePacketType* packet) const {
70     std::unique_ptr<ZeroCopyInputStream> istr = CreateSlicedInputStream();
71     return packet->ParseFromZeroCopyStream(istr.get());
72   }
73 
74   // Mutator, used only by the service and tests.
75   void AddSlice(Slice);
76 
77   // Does not copy / take ownership of the memory of the slice. The TracePacket
78   // will be valid only as long as the original buffer is valid.
79   void AddSlice(const void* start, size_t size);
80 
81   // Total size of all slices.
size()82   size_t size() const { return size_; }
83 
84   // Generates a protobuf preamble suitable to represent this packet as a
85   // repeated field within a root trace.proto message.
86   // Returns a pointer to a buffer, owned by this class, containing the preamble
87   // and its size.
88   std::tuple<char*, size_t> GetProtoPreamble();
89 
90  private:
91   TracePacket(const TracePacket&) = delete;
92   TracePacket& operator=(const TracePacket&) = delete;
93 
94   std::unique_ptr<ZeroCopyInputStream> CreateSlicedInputStream() const;
95 
96   Slices slices_;     // Not owned.
97   size_t size_ = 0;   // SUM(slice.size for slice in slices_).
98   char preamble_[8];  // Deliberately not initialized.
99 
100   // Remember to update the move operators and their unittest if adding new
101   // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
102   // std::move(TracePacket) to clear up the moved-from instance.
103 };
104 
105 }  // namespace perfetto
106 
107 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACE_PACKET_H_
108