• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // This file is automatically generated by gen_amalgamated. Do not edit.
16 
17 // gen_amalgamated: predefined macros
18 #if !defined(GOOGLE_PROTOBUF_NO_RTTI)
19 #define GOOGLE_PROTOBUF_NO_RTTI
20 #endif
21 #if !defined(PERFETTO_IMPLEMENTATION)
22 #define PERFETTO_IMPLEMENTATION
23 #endif
24 #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
25 #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
26 #endif
27 #include "perfetto.h"
28 // gen_amalgamated begin source: src/base/file_utils.cc
29 // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
30 // gen_amalgamated begin header: include/perfetto/ext/base/utils.h
31 /*
32  * Copyright (C) 2017 The Android Open Source Project
33  *
34  * Licensed under the Apache License, Version 2.0 (the "License");
35  * you may not use this file except in compliance with the License.
36  * You may obtain a copy of the License at
37  *
38  *      http://www.apache.org/licenses/LICENSE-2.0
39  *
40  * Unless required by applicable law or agreed to in writing, software
41  * distributed under the License is distributed on an "AS IS" BASIS,
42  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43  * See the License for the specific language governing permissions and
44  * limitations under the License.
45  */
46 
47 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
48 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
49 
50 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
51 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
52 
53 #include <errno.h>
54 #include <stddef.h>
55 #include <stdlib.h>
56 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
57 #include <sys/types.h>
58 #endif
59 
60 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
61     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
62 #include <unistd.h>  // For getpagesize().
63 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64 #include <mach/vm_page_size.h>
65 #endif
66 
67 #include <atomic>
68 
69 #define PERFETTO_EINTR(x)                                   \
70   ([&] {                                                    \
71     decltype(x) eintr_wrapper_result;                       \
72     do {                                                    \
73       eintr_wrapper_result = (x);                           \
74     } while (eintr_wrapper_result == -1 && errno == EINTR); \
75     return eintr_wrapper_result;                            \
76   }())
77 
78 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
79 // TODO(brucedawson) - create a ::perfetto::base::IOSize to replace this.
80 #if defined(_WIN64)
81 using ssize_t = __int64;
82 #else
83 using ssize_t = long;
84 #endif
85 #endif
86 
87 namespace perfetto {
88 namespace base {
89 
90 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
91 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
92 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
93 #endif
94 
95 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
96 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
97 // Strictly speaking, this constant is incorrect on some new devices where the
98 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
99 // ended up depending on kPageSize for purposes that are not strictly related
100 // with the kernel's mm subsystem.
101 constexpr size_t kPageSize = 4096;
102 
103 // Returns the system's page size. Use this when dealing with mmap, madvise and
104 // similar mm-related syscalls.
GetSysPageSize()105 inline uint32_t GetSysPageSize() {
106   ignore_result(kPageSize);  // Just to keep the amalgamated build happy.
107 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
108     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
109   static std::atomic<uint32_t> page_size{0};
110   // This function might be called in hot paths. Avoid calling getpagesize() all
111   // the times, in many implementations getpagesize() calls sysconf() which is
112   // not cheap.
113   uint32_t cached_value = page_size.load(std::memory_order_relaxed);
114   if (PERFETTO_UNLIKELY(cached_value == 0)) {
115     cached_value = static_cast<uint32_t>(getpagesize());
116     page_size.store(cached_value, std::memory_order_relaxed);
117   }
118   return cached_value;
119 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
120   return static_cast<uint32_t>(vm_page_size);
121 #else
122   return 4096;
123 #endif
124 }
125 
126 template <typename T>
ArraySize(const T & array)127 constexpr size_t ArraySize(const T& array) {
128   return sizeof(array) / sizeof(array[0]);
129 }
130 
131 // Function object which invokes 'free' on its parameter, which must be
132 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
133 //
134 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
135 //     static_cast<int*>(malloc(sizeof(int))));
136 struct FreeDeleter {
operator ()perfetto::base::FreeDeleter137   inline void operator()(void* ptr) const { free(ptr); }
138 };
139 
140 template <typename T>
AssumeLittleEndian(T value)141 constexpr T AssumeLittleEndian(T value) {
142   static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
143                 "Unimplemented on big-endian archs");
144   return value;
145 }
146 
147 // Round up |size| to a multiple of |alignment| (must be a power of two).
148 template <size_t alignment>
AlignUp(size_t size)149 constexpr size_t AlignUp(size_t size) {
150   static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
151   return (size + alignment - 1) & ~(alignment - 1);
152 }
153 
IsAgain(int err)154 inline bool IsAgain(int err) {
155   return err == EAGAIN || err == EWOULDBLOCK;
156 }
157 
158 }  // namespace base
159 }  // namespace perfetto
160 
161 #endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
162 /*
163  * Copyright (C) 2018 The Android Open Source Project
164  *
165  * Licensed under the Apache License, Version 2.0 (the "License");
166  * you may not use this file except in compliance with the License.
167  * You may obtain a copy of the License at
168  *
169  *      http://www.apache.org/licenses/LICENSE-2.0
170  *
171  * Unless required by applicable law or agreed to in writing, software
172  * distributed under the License is distributed on an "AS IS" BASIS,
173  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174  * See the License for the specific language governing permissions and
175  * limitations under the License.
176  */
177 
178 #ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
179 #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
180 
181 #include <stddef.h>
182 
183 #include <string>
184 
185 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
186 
187 namespace perfetto {
188 namespace base {
189 
190 bool ReadFileDescriptor(int fd, std::string* out);
191 bool ReadFileStream(FILE* f, std::string* out);
192 bool ReadFile(const std::string& path, std::string* out);
193 
194 // Call write until all data is written or an error is detected.
195 //
196 // man 2 write:
197 //   If a write() is interrupted by a signal handler before any bytes are
198 //   written, then the call fails with the error EINTR; if it is
199 //   interrupted after at least one byte has been written, the call
200 //   succeeds, and returns the number of bytes written.
201 ssize_t WriteAll(int fd, const void* buf, size_t count);
202 
203 bool FlushFile(int fd);
204 
205 }  // namespace base
206 }  // namespace perfetto
207 
208 #endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
209 // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
210 /*
211  * Copyright (C) 2017 The Android Open Source Project
212  *
213  * Licensed under the Apache License, Version 2.0 (the "License");
214  * you may not use this file except in compliance with the License.
215  * You may obtain a copy of the License at
216  *
217  *      http://www.apache.org/licenses/LICENSE-2.0
218  *
219  * Unless required by applicable law or agreed to in writing, software
220  * distributed under the License is distributed on an "AS IS" BASIS,
221  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
222  * See the License for the specific language governing permissions and
223  * limitations under the License.
224  */
225 
226 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
227 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
228 
229 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
230 
231 #include <fcntl.h>
232 #include <stdio.h>
233 
234 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
235     !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
236 #include <corecrt_io.h>
237 typedef int mode_t;
238 #else
239 #include <dirent.h>
240 #include <unistd.h>
241 #endif
242 
243 #include <string>
244 
245 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
246 
247 namespace perfetto {
248 namespace base {
249 
250 constexpr mode_t kInvalidMode = static_cast<mode_t>(-1);
251 
252 // RAII classes for auto-releasing fds and dirs.
253 template <typename T,
254           int (*CloseFunction)(T),
255           T InvalidValue,
256           bool CheckClose = true>
257 class ScopedResource {
258  public:
ScopedResource(T t=InvalidValue)259   explicit ScopedResource(T t = InvalidValue) : t_(t) {}
ScopedResource(ScopedResource && other)260   ScopedResource(ScopedResource&& other) noexcept {
261     t_ = other.t_;
262     other.t_ = InvalidValue;
263   }
operator =(ScopedResource && other)264   ScopedResource& operator=(ScopedResource&& other) {
265     reset(other.t_);
266     other.t_ = InvalidValue;
267     return *this;
268   }
get() const269   T get() const { return t_; }
operator *() const270   T operator*() const { return t_; }
operator bool() const271   explicit operator bool() const { return t_ != InvalidValue; }
reset(T r=InvalidValue)272   void reset(T r = InvalidValue) {
273     if (t_ != InvalidValue) {
274       int res = CloseFunction(t_);
275       if (CheckClose)
276         PERFETTO_CHECK(res == 0);
277     }
278     t_ = r;
279   }
release()280   T release() {
281     T t = t_;
282     t_ = InvalidValue;
283     return t;
284   }
~ScopedResource()285   ~ScopedResource() { reset(InvalidValue); }
286 
287  private:
288   ScopedResource(const ScopedResource&) = delete;
289   ScopedResource& operator=(const ScopedResource&) = delete;
290 
291   T t_;
292 };
293 
294 using ScopedFile = ScopedResource<int, close, -1>;
OpenFile(const std::string & path,int flags,mode_t mode=kInvalidMode)295 inline static ScopedFile OpenFile(const std::string& path,
296                                   int flags,
297                                   mode_t mode = kInvalidMode) {
298   PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kInvalidMode);
299 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
300   // Always use O_BINARY on Windows, to avoid silly EOL translations.
301   ScopedFile fd(open(path.c_str(), flags | O_BINARY, mode));
302 #else
303   // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
304   ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
305 #endif
306   return fd;
307 }
308 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
309 using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
310 #endif
311 
312 using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
313 
314 }  // namespace base
315 }  // namespace perfetto
316 
317 #endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
318 /*
319  * Copyright (C) 2018 The Android Open Source Project
320  *
321  * Licensed under the Apache License, Version 2.0 (the "License");
322  * you may not use this file except in compliance with the License.
323  * You may obtain a copy of the License at
324  *
325  *      http://www.apache.org/licenses/LICENSE-2.0
326  *
327  * Unless required by applicable law or agreed to in writing, software
328  * distributed under the License is distributed on an "AS IS" BASIS,
329  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
330  * See the License for the specific language governing permissions and
331  * limitations under the License.
332  */
333 
334 #include <sys/stat.h>
335 
336 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
337 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
338 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
339 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
340 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
341 
342 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || \
343     PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
344 #include <unistd.h>
345 #else
346 #include <corecrt_io.h>
347 #include <io.h>
348 #endif
349 
350 namespace perfetto {
351 namespace base {
352 namespace {
353 constexpr size_t kBufSize = 2048;
354 }
355 
ReadFileDescriptor(int fd,std::string * out)356 bool ReadFileDescriptor(int fd, std::string* out) {
357   // Do not override existing data in string.
358   size_t i = out->size();
359 
360   struct stat buf {};
361   if (fstat(fd, &buf) != -1) {
362     if (buf.st_size > 0)
363       out->resize(i + static_cast<size_t>(buf.st_size));
364   }
365 
366   ssize_t bytes_read;
367   for (;;) {
368     if (out->size() < i + kBufSize)
369       out->resize(out->size() + kBufSize);
370 
371     bytes_read = PERFETTO_EINTR(read(fd, &((*out)[i]), kBufSize));
372     if (bytes_read > 0) {
373       i += static_cast<size_t>(bytes_read);
374     } else {
375       out->resize(i);
376       return bytes_read == 0;
377     }
378   }
379 }
380 
ReadFileStream(FILE * f,std::string * out)381 bool ReadFileStream(FILE* f, std::string* out) {
382   return ReadFileDescriptor(fileno(f), out);
383 }
384 
ReadFile(const std::string & path,std::string * out)385 bool ReadFile(const std::string& path, std::string* out) {
386   base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
387   if (!fd)
388     return false;
389 
390   return ReadFileDescriptor(*fd, out);
391 }
392 
WriteAll(int fd,const void * buf,size_t count)393 ssize_t WriteAll(int fd, const void* buf, size_t count) {
394   size_t written = 0;
395   while (written < count) {
396     ssize_t wr = PERFETTO_EINTR(
397         write(fd, static_cast<const char*>(buf) + written, count - written));
398     if (wr == 0)
399       break;
400     if (wr < 0)
401       return wr;
402     written += static_cast<size_t>(wr);
403   }
404   return static_cast<ssize_t>(written);
405 }
406 
FlushFile(int fd)407 bool FlushFile(int fd) {
408   PERFETTO_DCHECK(fd != 0);
409 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
410     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
411   return !PERFETTO_EINTR(fdatasync(fd));
412 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
413   return !PERFETTO_EINTR(_commit(fd));
414 #else
415   return !PERFETTO_EINTR(fsync(fd));
416 #endif
417 }
418 
419 }  // namespace base
420 }  // namespace perfetto
421 // gen_amalgamated begin source: src/base/logging.cc
422 /*
423  * Copyright (C) 2019 The Android Open Source Project
424  *
425  * Licensed under the Apache License, Version 2.0 (the "License");
426  * you may not use this file except in compliance with the License.
427  * You may obtain a copy of the License at
428  *
429  *      http://www.apache.org/licenses/LICENSE-2.0
430  *
431  * Unless required by applicable law or agreed to in writing, software
432  * distributed under the License is distributed on an "AS IS" BASIS,
433  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
434  * See the License for the specific language governing permissions and
435  * limitations under the License.
436  */
437 
438 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
439 
440 #include <stdarg.h>
441 #include <stdio.h>
442 
443 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
444 #include <unistd.h>  // For isatty()
445 #endif
446 
447 #include <memory>
448 
449 // gen_amalgamated expanded: #include "perfetto/base/time.h"
450 
451 namespace perfetto {
452 namespace base {
453 
454 namespace {
455 const char kReset[] = "\x1b[0m";
456 const char kDefault[] = "\x1b[39m";
457 const char kDim[] = "\x1b[2m";
458 const char kRed[] = "\x1b[31m";
459 const char kBoldGreen[] = "\x1b[1m\x1b[32m";
460 const char kLightGray[] = "\x1b[90m";
461 
462 }  // namespace
463 
LogMessage(LogLev level,const char * fname,int line,const char * fmt,...)464 void LogMessage(LogLev level,
465                 const char* fname,
466                 int line,
467                 const char* fmt,
468                 ...) {
469   char stack_buf[512];
470   std::unique_ptr<char[]> large_buf;
471   char* log_msg = &stack_buf[0];
472 
473   // By default use a stack allocated buffer because most log messages are quite
474   // short. In rare cases they can be larger (e.g. --help). In those cases we
475   // pay the cost of allocating the buffer on the heap.
476   for (size_t max_len = sizeof(stack_buf);;) {
477     va_list args;
478     va_start(args, fmt);
479     int res = vsnprintf(log_msg, max_len, fmt, args);
480     va_end(args);
481 
482     // If for any reason the print fails, overwrite the message but still print
483     // it. The code below will attach the filename and line, which is still
484     // useful.
485     if (res < 0) {
486       strncpy(log_msg, "[printf format error]", max_len);
487       break;
488     }
489 
490     // if res == max_len, vsnprintf saturated the input buffer. Retry with a
491     // larger buffer in that case (within reasonable limits).
492     if (res < static_cast<int>(max_len) || max_len >= 128 * 1024)
493       break;
494     max_len *= 4;
495     large_buf.reset(new char[max_len]);
496     log_msg = &large_buf[0];
497   }
498 
499   const char* color = kDefault;
500   switch (level) {
501     case kLogDebug:
502       color = kDim;
503       break;
504     case kLogInfo:
505       color = kDefault;
506       break;
507     case kLogImportant:
508       color = kBoldGreen;
509       break;
510     case kLogError:
511       color = kRed;
512       break;
513   }
514 
515 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
516     !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
517   static const bool use_colors = isatty(STDERR_FILENO);
518 #else
519   static const bool use_colors = false;
520 #endif
521 
522   // Formats file.cc:line as a space-padded fixed width string. If the file name
523   // |fname| is too long, truncate it on the left-hand side.
524   char line_str[10];
525   size_t line_len =
526       static_cast<size_t>(snprintf(line_str, sizeof(line_str), "%d", line));
527 
528   // 24 will be the width of the file.cc:line column in the log event.
529   char file_and_line[24];
530   size_t fname_len = strlen(fname);
531   size_t fname_max = sizeof(file_and_line) - line_len - 2;  // 2 = ':' + '\0'.
532   size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
533   int len = snprintf(file_and_line, sizeof(file_and_line), "%s:%s",
534                      fname + fname_offset, line_str);
535   memset(&file_and_line[len], ' ', sizeof(file_and_line) - size_t(len));
536   file_and_line[sizeof(file_and_line) - 1] = '\0';
537 
538 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
539   // Logcat has already timestamping, don't re-emit it.
540   __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
541                       file_and_line, log_msg);
542 #endif
543 
544   // When printing on stderr, print also the timestamp. We don't really care
545   // about the actual time. We just need some reference clock that can be used
546   // to correlated events across differrent processses (e.g. traced and
547   // traced_probes). The wall time % 1000 is good enough.
548   char timestamp[32];
549   uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
550   uint32_t t_sec = t_ms / 1000;
551   t_ms -= t_sec * 1000;
552   t_sec = t_sec % 1000;
553   snprintf(timestamp, sizeof(timestamp), "[%03u.%03u] ", t_sec, t_ms);
554 
555   if (use_colors) {
556     fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp, file_and_line,
557             kReset, color, log_msg, kReset);
558   } else {
559     fprintf(stderr, "%s%s %s\n", timestamp, file_and_line, log_msg);
560   }
561 }
562 
563 }  // namespace base
564 }  // namespace perfetto
565 // gen_amalgamated begin source: src/base/metatrace.cc
566 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
567 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
568 /*
569  * Copyright (C) 2019 The Android Open Source Project
570  *
571  * Licensed under the Apache License, Version 2.0 (the "License");
572  * you may not use this file except in compliance with the License.
573  * You may obtain a copy of the License at
574  *
575  *      http://www.apache.org/licenses/LICENSE-2.0
576  *
577  * Unless required by applicable law or agreed to in writing, software
578  * distributed under the License is distributed on an "AS IS" BASIS,
579  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
580  * See the License for the specific language governing permissions and
581  * limitations under the License.
582  */
583 
584 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
585 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
586 
587 #include <stdint.h>
588 
589 namespace perfetto {
590 namespace metatrace {
591 
592 enum Tags : uint32_t {
593   TAG_NONE = 0,
594   TAG_ANY = uint32_t(-1),
595   TAG_FTRACE = 1 << 0,
596   TAG_PROC_POLLERS = 1 << 1,
597   TAG_TRACE_WRITER = 1 << 2,
598   TAG_TRACE_SERVICE = 1 << 3,
599   TAG_PRODUCER = 1 << 4,
600 };
601 
602 // The macros below generate matching enums and arrays of string literals.
603 // This is to avoid maintaining string maps manually.
604 
605 // clang-format off
606 
607 // DO NOT remove or reshuffle items in this list, only append. The ID of these
608 // events are an ABI, the trace processor relies on these to open old traces.
609 #define PERFETTO_METATRACE_EVENTS(F) \
610   F(EVENT_ZERO_UNUSED), \
611   F(FTRACE_CPU_READER_READ), /*unused*/ \
612   F(FTRACE_DRAIN_CPUS), /*unused*/ \
613   F(FTRACE_UNBLOCK_READERS), /*unused*/ \
614   F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
615   F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
616   F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
617   F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
618   F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
619   F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
620   F(FTRACE_CPU_FLUSH), \
621   F(FTRACE_CPU_DRAIN), /*unused*/ \
622   F(READ_SYS_STATS), \
623   F(PS_WRITE_ALL_PROCESSES), \
624   F(PS_ON_PIDS), \
625   F(PS_ON_RENAME_PIDS), \
626   F(PS_WRITE_ALL_PROCESS_STATS), \
627   F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
628   F(FTRACE_READ_TICK), \
629   F(FTRACE_CPU_READ_CYCLE), \
630   F(FTRACE_CPU_READ_BATCH), \
631   F(KALLSYMS_PARSE), \
632   F(PROFILER_READ_TICK), \
633   F(PROFILER_READ_CPU), \
634   F(PROFILER_UNWIND_TICK), \
635   F(PROFILER_UNWIND_SAMPLE), \
636   F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
637   F(PROFILER_UNWIND_ATTEMPT), \
638   F(PROFILER_MAPS_PARSE), \
639   F(PROFILER_MAPS_REPARSE), \
640   F(PROFILER_UNWIND_CACHE_CLEAR)
641 
642 // Append only, see above.
643 //
644 // Values that aren't used as counters:
645 // * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
646 //   tracing_service_impl.cc for the format.
647 // * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
648 //
649 #define PERFETTO_METATRACE_COUNTERS(F) \
650   F(COUNTER_ZERO_UNUSED),\
651   F(FTRACE_PAGES_DRAINED), \
652   F(PS_PIDS_SCANNED), \
653   F(TRACE_SERVICE_COMMIT_DATA), \
654   F(PROFILER_UNWIND_QUEUE_SZ), \
655   F(PROFILER_UNWIND_CURRENT_PID)
656 
657 // clang-format on
658 
659 #define PERFETTO_METATRACE_IDENTITY(name) name
660 #define PERFETTO_METATRACE_TOSTRING(name) #name
661 
662 enum Events : uint16_t {
663   PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
664   EVENTS_MAX
665 };
666 constexpr char const* kEventNames[] = {
667     PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
668 
669 enum Counters : uint16_t {
670   PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
671   COUNTERS_MAX
672 };
673 constexpr char const* kCounterNames[] = {
674     PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
675 
SuppressUnusedVarsInAmalgamatedBuild()676 inline void SuppressUnusedVarsInAmalgamatedBuild() {
677   (void)kCounterNames;
678   (void)kEventNames;
679 }
680 
681 }  // namespace metatrace
682 }  // namespace perfetto
683 
684 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
685 // gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
686 /*
687  * Copyright (C) 2019 The Android Open Source Project
688  *
689  * Licensed under the Apache License, Version 2.0 (the "License");
690  * you may not use this file except in compliance with the License.
691  * You may obtain a copy of the License at
692  *
693  *      http://www.apache.org/licenses/LICENSE-2.0
694  *
695  * Unless required by applicable law or agreed to in writing, software
696  * distributed under the License is distributed on an "AS IS" BASIS,
697  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
698  * See the License for the specific language governing permissions and
699  * limitations under the License.
700  */
701 
702 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
703 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
704 
705 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
706 
707 // Windows TSAN doesn't currently support these annotations.
708 #if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
709 extern "C" {
710 void AnnotateBenignRaceSized(const char* file,
711                              int line,
712                              unsigned long address,
713                              unsigned long size,
714                              const char* description);
715 }
716 
717 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)   \
718   AnnotateBenignRaceSized(__FILE__, __LINE__,                             \
719                           reinterpret_cast<unsigned long>(pointer), size, \
720                           description);
721 #else  // defined(ADDRESS_SANITIZER)
722 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
723 #endif  // defined(ADDRESS_SANITIZER)
724 
725 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
726 /*
727  * Copyright (C) 2019 The Android Open Source Project
728  *
729  * Licensed under the Apache License, Version 2.0 (the "License");
730  * you may not use this file except in compliance with the License.
731  * You may obtain a copy of the License at
732  *
733  *      http://www.apache.org/licenses/LICENSE-2.0
734  *
735  * Unless required by applicable law or agreed to in writing, software
736  * distributed under the License is distributed on an "AS IS" BASIS,
737  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
738  * See the License for the specific language governing permissions and
739  * limitations under the License.
740  */
741 
742 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
743 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
744 
745 #include <array>
746 #include <atomic>
747 #include <functional>
748 #include <string>
749 
750 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
751 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
752 // gen_amalgamated expanded: #include "perfetto/base/time.h"
753 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
754 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
755 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
756 
757 // A facility to trace execution of the perfetto codebase itself.
758 // The meta-tracing framework is organized into three layers:
759 //
760 // 1. A static ring-buffer in base/ (this file) that supports concurrent writes
761 //    and a single reader.
762 //    The responsibility of this layer is to store events and counters as
763 //    efficiently as possible without re-entering any tracing code.
764 //    This is really a static-storage-based ring-buffer based on a POD array.
765 //    This layer does NOT deal with serializing the meta-trace buffer.
766 //    It posts a task when it's half full and expects something outside of
767 //    base/ to drain the ring-buffer and serialize it, eventually writing it
768 //    into the trace itself, before it gets 100% full.
769 //
770 // 2. A class in tracing/core which takes care of serializing the meta-trace
771 //    buffer into the trace using a TraceWriter. See metatrace_writer.h .
772 //
773 // 3. A data source in traced_probes that, when be enabled via the trace config,
774 //    injects metatrace events into the trace. See metatrace_data_source.h .
775 //
776 // The available events and tags are defined in metatrace_events.h .
777 
778 namespace perfetto {
779 
780 namespace base {
781 class TaskRunner;
782 }  // namespace base
783 
784 namespace metatrace {
785 
786 // Meta-tracing is organized in "tags" that can be selectively enabled. This is
787 // to enable meta-tracing only of one sub-system. This word has one "enabled"
788 // bit for each tag. 0 -> meta-tracing off.
789 extern std::atomic<uint32_t> g_enabled_tags;
790 
791 // Time of the Enable() call. Used as a reference for keeping delta timestmaps
792 // in Record.
793 extern std::atomic<uint64_t> g_enabled_timestamp;
794 
795 // Enables meta-tracing for one or more tags. Once enabled it will discard any
796 // further Enable() calls and return false until disabled,
797 // |read_task| is a closure that will be called enqueued |task_runner| when the
798 // meta-tracing ring buffer is half full. The task is expected to read the ring
799 // buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
800 // file or into the trace itself.
801 // Must be called on the |task_runner| passed.
802 // |task_runner| must have static lifetime.
803 bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
804 
805 // Disables meta-tracing.
806 // Must be called on the same |task_runner| as Enable().
807 void Disable();
808 
TraceTimeNowNs()809 inline uint64_t TraceTimeNowNs() {
810   return static_cast<uint64_t>(base::GetBootTimeNs().count());
811 }
812 
813 // Returns a relaxed view of whether metatracing is enabled for the given tag.
814 // Useful for skipping unnecessary argument computation if metatracing is off.
IsEnabled(uint32_t tag)815 inline bool IsEnabled(uint32_t tag) {
816   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
817   if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
818     return false;
819   else
820     return true;
821 }
822 
823 // Holds the data for a metatrace event or counter.
824 struct Record {
825   static constexpr uint16_t kTypeMask = 0x8000;
826   static constexpr uint16_t kTypeCounter = 0x8000;
827   static constexpr uint16_t kTypeEvent = 0;
828 
timestamp_nsperfetto::metatrace::Record829   uint64_t timestamp_ns() const {
830     auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
831     PERFETTO_DCHECK(base_ns);
832     return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
833                       timestamp_ns_low);
834   }
835 
set_timestampperfetto::metatrace::Record836   void set_timestamp(uint64_t ts) {
837     auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
838     uint64_t diff = ts - t_start;
839     PERFETTO_DCHECK(diff < (1ull << 48));
840     timestamp_ns_low = static_cast<uint32_t>(diff);
841     timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
842   }
843 
844   // We can't just memset() this class because on MSVC std::atomic<> is not
845   // trivially constructible anymore. Also std::atomic<> has a deleted copy
846   // constructor so we cant just do "*this = Record()" either.
847   // See http://bit.ly/339Jlzd .
clearperfetto::metatrace::Record848   void clear() {
849     this->~Record();
850     new (this) Record();
851   }
852 
853   // This field holds the type (counter vs event) in the MSB and event ID (as
854   // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
855   // as a linearization point: this is always written after all the other
856   // fields with a release-store. This is so the reader can determine whether it
857   // can safely process the other event fields after a load-acquire.
858   std::atomic<uint16_t> type_and_id{};
859 
860   // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
861   // This gives us 78 hours from Enabled().
862   uint16_t timestamp_ns_high = 0;
863   uint32_t timestamp_ns_low = 0;
864 
865   uint32_t thread_id = 0;
866 
867   union {
868     // Only one of the two elements can be zero initialized, clang complains
869     // about "initializing multiple members of union" otherwise.
870     uint32_t duration_ns = 0;  // If type == event.
871     int32_t counter_value;  // If type == counter.
872   };
873 };
874 
875 // Hold the meta-tracing data into a statically allocated array.
876 // This class uses static storage (as opposite to being a singleton) to:
877 // - Have the guarantee of always valid storage, so that meta-tracing can be
878 //   safely used in any part of the codebase, including base/ itself.
879 // - Avoid barriers that thread-safe static locals would require.
880 class RingBuffer {
881  public:
882   static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.
883 
884   // This iterator is not idempotent and will bump the read index in the buffer
885   // at the end of the reads. There can be only one reader at any time.
886   // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
887   class ReadIterator {
888    public:
ReadIterator(ReadIterator && other)889     ReadIterator(ReadIterator&& other) {
890       PERFETTO_DCHECK(other.valid_);
891       cur_ = other.cur_;
892       end_ = other.end_;
893       valid_ = other.valid_;
894       other.valid_ = false;
895     }
896 
~ReadIterator()897     ~ReadIterator() {
898       if (!valid_)
899         return;
900       PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
901       PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
902       RingBuffer::rd_index_.store(cur_, std::memory_order_release);
903     }
904 
operator bool() const905     explicit operator bool() const { return cur_ < end_; }
operator ->() const906     const Record* operator->() const { return RingBuffer::At(cur_); }
operator *() const907     const Record& operator*() const { return *operator->(); }
908 
909     // This is for ++it. it++ is deliberately not supported.
operator ++()910     ReadIterator& operator++() {
911       PERFETTO_DCHECK(cur_ < end_);
912       // Once a record has been read, mark it as free clearing its type_and_id,
913       // so if we encounter it in another read iteration while being written
914       // we know it's not fully written yet.
915       // The memory_order_relaxed below is enough because:
916       // - The reader is single-threaded and doesn't re-read the same records.
917       // - Before starting a read batch, the reader has an acquire barrier on
918       //   |rd_index_|.
919       // - After terminating a read batch, the ~ReadIterator dtor updates the
920       //   |rd_index_| with a release-store.
921       // - Reader and writer are typically kCapacity/2 apart. So unless an
922       //   overrun happens a writer won't reuse a newly released record any time
923       //   soon. If an overrun happens, everything is busted regardless.
924       At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
925       ++cur_;
926       return *this;
927     }
928 
929    private:
930     friend class RingBuffer;
ReadIterator(uint64_t begin,uint64_t end)931     ReadIterator(uint64_t begin, uint64_t end)
932         : cur_(begin), end_(end), valid_(true) {}
933     ReadIterator& operator=(const ReadIterator&) = delete;
934     ReadIterator(const ReadIterator&) = delete;
935 
936     uint64_t cur_;
937     uint64_t end_;
938     bool valid_;
939   };
940 
At(uint64_t index)941   static Record* At(uint64_t index) {
942     // Doesn't really have to be pow2, but if not the compiler will emit
943     // arithmetic operations to compute the modulo instead of a bitwise AND.
944     static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
945     PERFETTO_DCHECK(index >= rd_index_);
946     PERFETTO_DCHECK(index <= wr_index_);
947     return &records_[index % kCapacity];
948   }
949 
950   // Must be called on the same task runner passed to Enable()
GetReadIterator()951   static ReadIterator GetReadIterator() {
952     PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
953     return ReadIterator(rd_index_.load(std::memory_order_acquire),
954                         wr_index_.load(std::memory_order_acquire));
955   }
956 
957   static Record* AppendNewRecord();
958   static void Reset();
959 
has_overruns()960   static bool has_overruns() {
961     return has_overruns_.load(std::memory_order_acquire);
962   }
963 
964   // Can temporarily return a value >= kCapacity but is eventually consistent.
965   // This would happen in case of overruns until threads hit the --wr_index_
966   // in AppendNewRecord().
GetSizeForTesting()967   static uint64_t GetSizeForTesting() {
968     auto wr_index = wr_index_.load(std::memory_order_relaxed);
969     auto rd_index = rd_index_.load(std::memory_order_relaxed);
970     PERFETTO_DCHECK(wr_index >= rd_index);
971     return wr_index - rd_index;
972   }
973 
974  private:
975   friend class ReadIterator;
976 
977   // Returns true if the caller is on the task runner passed to Enable().
978   // Used only for DCHECKs.
979   static bool IsOnValidTaskRunner();
980 
981   static std::array<Record, kCapacity> records_;
982   static std::atomic<bool> read_task_queued_;
983   static std::atomic<uint64_t> wr_index_;
984   static std::atomic<uint64_t> rd_index_;
985   static std::atomic<bool> has_overruns_;
986   static Record bankruptcy_record_;  // Used in case of overruns.
987 };
988 
TraceCounter(uint32_t tag,uint16_t id,int32_t value)989 inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
990   // memory_order_relaxed is okay because the storage has static lifetime.
991   // It is safe to accidentally log an event soon after disabling.
992   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
993   if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
994     return;
995   Record* record = RingBuffer::AppendNewRecord();
996   record->thread_id = static_cast<uint32_t>(base::GetThreadId());
997   record->set_timestamp(TraceTimeNowNs());
998   record->counter_value = value;
999   record->type_and_id.store(Record::kTypeCounter | id,
1000                             std::memory_order_release);
1001 }
1002 
1003 class ScopedEvent {
1004  public:
ScopedEvent(uint32_t tag,uint16_t event_id)1005   ScopedEvent(uint32_t tag, uint16_t event_id) {
1006     auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
1007     if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
1008       return;
1009     event_id_ = event_id;
1010     record_ = RingBuffer::AppendNewRecord();
1011     record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
1012     record_->set_timestamp(TraceTimeNowNs());
1013   }
1014 
~ScopedEvent()1015   ~ScopedEvent() {
1016     if (PERFETTO_LIKELY(!record_))
1017       return;
1018     auto now = TraceTimeNowNs();
1019     record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
1020     record_->type_and_id.store(Record::kTypeEvent | event_id_,
1021                                std::memory_order_release);
1022   }
1023 
1024  private:
1025   Record* record_ = nullptr;
1026   uint16_t event_id_ = 0;
1027   ScopedEvent(const ScopedEvent&) = delete;
1028   ScopedEvent& operator=(const ScopedEvent&) = delete;
1029 };
1030 
1031 // Boilerplate to derive a unique variable name for the event.
1032 #define PERFETTO_METATRACE_UID2(a, b) a##b
1033 #define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
1034 
1035 #define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
1036   ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
1037       ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
1038 
1039 #define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
1040   ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
1041                                       ::perfetto::metatrace::ID,  \
1042                                       static_cast<int32_t>(VALUE))
1043 
1044 }  // namespace metatrace
1045 }  // namespace perfetto
1046 
1047 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
1048 // gen_amalgamated begin header: include/perfetto/base/task_runner.h
1049 /*
1050  * Copyright (C) 2017 The Android Open Source Project
1051  *
1052  * Licensed under the Apache License, Version 2.0 (the "License");
1053  * you may not use this file except in compliance with the License.
1054  * You may obtain a copy of the License at
1055  *
1056  *      http://www.apache.org/licenses/LICENSE-2.0
1057  *
1058  * Unless required by applicable law or agreed to in writing, software
1059  * distributed under the License is distributed on an "AS IS" BASIS,
1060  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1061  * See the License for the specific language governing permissions and
1062  * limitations under the License.
1063  */
1064 
1065 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1066 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1067 
1068 #include <stdint.h>
1069 
1070 #include <functional>
1071 
1072 // gen_amalgamated expanded: #include "perfetto/base/export.h"
1073 
1074 namespace perfetto {
1075 namespace base {
1076 
1077 // A generic interface to allow the library clients to interleave the execution
1078 // of the tracing internals in their runtime environment.
1079 // The expectation is that all tasks, which are queued either via PostTask() or
1080 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
1081 // same thread, or on a thread pool that gives sequencing guarantees).
1082 //
1083 // Tasks are never executed synchronously inside PostTask and there is a full
1084 // memory barrier between tasks.
1085 //
1086 // All methods of this interface can be called from any thread.
1087 class PERFETTO_EXPORT TaskRunner {
1088  public:
1089   virtual ~TaskRunner();
1090 
1091   // Schedule a task for immediate execution. Immediate tasks are always
1092   // executed in the order they are posted. Can be called from any thread.
1093   virtual void PostTask(std::function<void()>) = 0;
1094 
1095   // Schedule a task for execution after |delay_ms|. Note that there is no
1096   // strict ordering guarantee between immediate and delayed tasks. Can be
1097   // called from any thread.
1098   virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
1099 
1100   // Schedule a task to run when |fd| becomes readable. The same |fd| can only
1101   // be monitored by one function. Note that this function only needs to be
1102   // implemented on platforms where the built-in ipc framework is used. Can be
1103   // called from any thread.
1104   // TODO(skyostil): Refactor this out of the shared interface.
1105   virtual void AddFileDescriptorWatch(int fd, std::function<void()>) = 0;
1106 
1107   // Remove a previously scheduled watch for |fd|. If this is run on the target
1108   // thread of this TaskRunner, guarantees that the task registered to this fd
1109   // will not be executed after this function call. Can be called from any
1110   // thread.
1111   virtual void RemoveFileDescriptorWatch(int fd) = 0;
1112 
1113   // Checks if the current thread is the same thread where the TaskRunner's task
1114   // run. This allows single threaded task runners (like the ones used in
1115   // perfetto) to inform the caller that anything posted will run on the same
1116   // thread/sequence. This can allow some callers to skip PostTask and instead
1117   // directly execute the code. Can be called from any thread.
1118   virtual bool RunsTasksOnCurrentThread() const = 0;
1119 };
1120 
1121 }  // namespace base
1122 }  // namespace perfetto
1123 
1124 #endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
1125 /*
1126  * Copyright (C) 2018 The Android Open Source Project
1127  *
1128  * Licensed under the Apache License, Version 2.0 (the "License");
1129  * you may not use this file except in compliance with the License.
1130  * You may obtain a copy of the License at
1131  *
1132  *      http://www.apache.org/licenses/LICENSE-2.0
1133  *
1134  * Unless required by applicable law or agreed to in writing, software
1135  * distributed under the License is distributed on an "AS IS" BASIS,
1136  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1137  * See the License for the specific language governing permissions and
1138  * limitations under the License.
1139  */
1140 
1141 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
1142 
1143 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
1144 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
1145 // gen_amalgamated expanded: #include "perfetto/base/time.h"
1146 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
1147 
1148 namespace perfetto {
1149 namespace metatrace {
1150 
1151 std::atomic<uint32_t> g_enabled_tags{0};
1152 std::atomic<uint64_t> g_enabled_timestamp{0};
1153 
1154 // static members
1155 constexpr size_t RingBuffer::kCapacity;
1156 std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
1157 std::atomic<bool> RingBuffer::read_task_queued_;
1158 std::atomic<uint64_t> RingBuffer::wr_index_;
1159 std::atomic<uint64_t> RingBuffer::rd_index_;
1160 std::atomic<bool> RingBuffer::has_overruns_;
1161 Record RingBuffer::bankruptcy_record_;
1162 
1163 constexpr uint16_t Record::kTypeMask;
1164 constexpr uint16_t Record::kTypeCounter;
1165 constexpr uint16_t Record::kTypeEvent;
1166 
1167 namespace {
1168 
1169 // std::function<> is not trivially de/constructible. This struct wraps it in a
1170 // heap-allocated struct to avoid static initializers.
1171 struct Delegate {
GetInstanceperfetto::metatrace::__anon7bab3a4f0411::Delegate1172   static Delegate* GetInstance() {
1173     static Delegate* instance = new Delegate();
1174     return instance;
1175   }
1176 
1177   base::TaskRunner* task_runner = nullptr;
1178   std::function<void()> read_task;
1179 };
1180 
1181 }  // namespace
1182 
Enable(std::function<void ()> read_task,base::TaskRunner * task_runner,uint32_t tags)1183 bool Enable(std::function<void()> read_task,
1184             base::TaskRunner* task_runner,
1185             uint32_t tags) {
1186   PERFETTO_DCHECK(read_task);
1187   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
1188   if (g_enabled_tags.load(std::memory_order_acquire))
1189     return false;
1190 
1191   Delegate* dg = Delegate::GetInstance();
1192   dg->task_runner = task_runner;
1193   dg->read_task = std::move(read_task);
1194   RingBuffer::Reset();
1195   g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
1196   g_enabled_tags.store(tags, std::memory_order_release);
1197   return true;
1198 }
1199 
Disable()1200 void Disable() {
1201   g_enabled_tags.store(0, std::memory_order_release);
1202   Delegate* dg = Delegate::GetInstance();
1203   PERFETTO_DCHECK(!dg->task_runner ||
1204                   dg->task_runner->RunsTasksOnCurrentThread());
1205   dg->task_runner = nullptr;
1206   dg->read_task = nullptr;
1207 }
1208 
1209 // static
Reset()1210 void RingBuffer::Reset() {
1211   bankruptcy_record_.clear();
1212   for (Record& record : records_)
1213     record.clear();
1214   wr_index_ = 0;
1215   rd_index_ = 0;
1216   has_overruns_ = false;
1217   read_task_queued_ = false;
1218 }
1219 
1220 // static
AppendNewRecord()1221 Record* RingBuffer::AppendNewRecord() {
1222   auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
1223 
1224   // rd_index can only monotonically increase, we don't care if we read an
1225   // older value, we'll just hit the slow-path a bit earlier if it happens.
1226   auto rd_index = rd_index_.load(std::memory_order_relaxed);
1227 
1228   PERFETTO_DCHECK(wr_index >= rd_index);
1229   auto size = wr_index - rd_index;
1230   if (PERFETTO_LIKELY(size < kCapacity / 2))
1231     return At(wr_index);
1232 
1233   // Slow-path: Enqueue the read task and handle overruns.
1234   bool expected = false;
1235   if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
1236     Delegate* dg = Delegate::GetInstance();
1237     if (dg->task_runner) {
1238       dg->task_runner->PostTask([] {
1239         // Meta-tracing might have been disabled in the meantime.
1240         auto read_task = Delegate::GetInstance()->read_task;
1241         if (read_task)
1242           read_task();
1243         RingBuffer::read_task_queued_ = false;
1244       });
1245     }
1246   }
1247 
1248   if (PERFETTO_LIKELY(size < kCapacity))
1249     return At(wr_index);
1250 
1251   has_overruns_.store(true, std::memory_order_release);
1252   wr_index_.fetch_sub(1, std::memory_order_acq_rel);
1253 
1254   // In the case of overflows, threads will race writing on the same memory
1255   // location and TSan will rightly complain. This is fine though because nobody
1256   // will read the bankruptcy record and it's designed to contain garbage.
1257   PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
1258                                       "nothing reads bankruptcy_record_")
1259   return &bankruptcy_record_;
1260 }
1261 
1262 // static
IsOnValidTaskRunner()1263 bool RingBuffer::IsOnValidTaskRunner() {
1264   auto* task_runner = Delegate::GetInstance()->task_runner;
1265   return task_runner && task_runner->RunsTasksOnCurrentThread();
1266 }
1267 
1268 }  // namespace metatrace
1269 }  // namespace perfetto
1270 // gen_amalgamated begin source: src/base/paged_memory.cc
1271 // gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
1272 // gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
1273 /*
1274  * Copyright (C) 2018 The Android Open Source Project
1275  *
1276  * Licensed under the Apache License, Version 2.0 (the "License");
1277  * you may not use this file except in compliance with the License.
1278  * You may obtain a copy of the License at
1279  *
1280  *      http://www.apache.org/licenses/LICENSE-2.0
1281  *
1282  * Unless required by applicable law or agreed to in writing, software
1283  * distributed under the License is distributed on an "AS IS" BASIS,
1284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1285  * See the License for the specific language governing permissions and
1286  * limitations under the License.
1287  */
1288 
1289 #ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
1290 #define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
1291 
1292 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1293 
1294 // Windows ASAN doesn't currently support these annotations.
1295 #if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
1296     !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
1297 
1298 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
1299   if (buffer) {                                                              \
1300     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
1301                                               (buffer) + (capacity),         \
1302                                               (buffer) + (new_size));        \
1303   }
1304 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
1305   if (buffer) {                                                              \
1306     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
1307                                               (buffer) + (old_size),         \
1308                                               (buffer) + (capacity));        \
1309   }
1310 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
1311   if (buffer) {                                                              \
1312     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
1313                                               (buffer) + (old_size),         \
1314                                               (buffer) + (new_size));        \
1315   }
1316 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
1317                                  new_capacity)                      \
1318   ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
1319   ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
1320 // Annotations require buffers to begin on an 8-byte boundary.
1321 #else  // defined(ADDRESS_SANITIZER)
1322 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
1323 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
1324 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
1325 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
1326                                  new_capacity)
1327 #endif  // defined(ADDRESS_SANITIZER)
1328 
1329 #endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
1330 /*
1331  * Copyright (C) 2017 The Android Open Source Project
1332  *
1333  * Licensed under the Apache License, Version 2.0 (the "License");
1334  * you may not use this file except in compliance with the License.
1335  * You may obtain a copy of the License at
1336  *
1337  *      http://www.apache.org/licenses/LICENSE-2.0
1338  *
1339  * Unless required by applicable law or agreed to in writing, software
1340  * distributed under the License is distributed on an "AS IS" BASIS,
1341  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1342  * See the License for the specific language governing permissions and
1343  * limitations under the License.
1344  */
1345 
1346 #ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
1347 #define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
1348 
1349 #include <memory>
1350 
1351 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1352 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
1353 
1354 // We need to track the committed size on windows and when ASAN is enabled.
1355 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
1356 #define TRACK_COMMITTED_SIZE() 1
1357 #else
1358 #define TRACK_COMMITTED_SIZE() 0
1359 #endif
1360 
1361 namespace perfetto {
1362 namespace base {
1363 
1364 class PagedMemory {
1365  public:
1366   // Initializes an invalid PagedMemory pointing to nullptr.
1367   PagedMemory();
1368 
1369   ~PagedMemory();
1370 
1371   PagedMemory(PagedMemory&& other) noexcept;
1372   PagedMemory& operator=(PagedMemory&& other);
1373 
1374   enum AllocationFlags {
1375     // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
1376     // of virtual address space). When this flag is provided, an invalid
1377     // PagedMemory pointing to nullptr is returned in this case instead.
1378     kMayFail = 1 << 0,
1379 
1380     // By default, Allocate() commits the allocated memory immediately. When
1381     // this flag is provided, the memory virtual address space may only be
1382     // reserved and the user should call EnsureCommitted() before writing to
1383     // memory addresses.
1384     kDontCommit = 1 << 1,
1385   };
1386 
1387   // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
1388   // guaranteed to be page-aligned and guaranteed to be zeroed.
1389   // For |flags|, see the AllocationFlags enum above.
1390   static PagedMemory Allocate(size_t size, int flags = 0);
1391 
1392   // Hint to the OS that the memory range is not needed and can be discarded.
1393   // The memory remains accessible and its contents may be retained, or they
1394   // may be zeroed. This function may be a NOP on some platforms. Returns true
1395   // if implemented.
1396   bool AdviseDontNeed(void* p, size_t size);
1397 
1398   // Ensures that at least the first |committed_size| bytes of the allocated
1399   // memory region are committed. The implementation may commit memory in larger
1400   // chunks above |committed_size|. Crashes if the memory couldn't be committed.
1401 #if TRACK_COMMITTED_SIZE()
1402   void EnsureCommitted(size_t committed_size);
1403 #else   // TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t)1404   void EnsureCommitted(size_t /*committed_size*/) {}
1405 #endif  // TRACK_COMMITTED_SIZE()
1406 
Get() const1407   inline void* Get() const noexcept { return p_; }
IsValid() const1408   inline bool IsValid() const noexcept { return !!p_; }
size() const1409   inline size_t size() const noexcept { return size_; }
1410 
1411  private:
1412   PagedMemory(char* p, size_t size);
1413 
1414   PagedMemory(const PagedMemory&) = delete;
1415   // Defaulted for implementation of move constructor + assignment.
1416   PagedMemory& operator=(const PagedMemory&) = default;
1417 
1418   char* p_ = nullptr;
1419 
1420   // The size originally passed to Allocate(). The actual virtual memory
1421   // reservation will be larger due to: (i) guard pages; (ii) rounding up to
1422   // the system page size.
1423   size_t size_ = 0;
1424 
1425 #if TRACK_COMMITTED_SIZE()
1426   size_t committed_size_ = 0u;
1427 #endif  // TRACK_COMMITTED_SIZE()
1428 };
1429 
1430 }  // namespace base
1431 }  // namespace perfetto
1432 
1433 #endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
1434 /*
1435  * Copyright (C) 2017 The Android Open Source Project
1436  *
1437  * Licensed under the Apache License, Version 2.0 (the "License");
1438  * you may not use this file except in compliance with the License.
1439  * You may obtain a copy of the License at
1440  *
1441  *      http://www.apache.org/licenses/LICENSE-2.0
1442  *
1443  * Unless required by applicable law or agreed to in writing, software
1444  * distributed under the License is distributed on an "AS IS" BASIS,
1445  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1446  * See the License for the specific language governing permissions and
1447  * limitations under the License.
1448  */
1449 
1450 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
1451 
1452 #include <algorithm>
1453 #include <cmath>
1454 
1455 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1456 #include <Windows.h>
1457 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1458 #include <sys/mman.h>
1459 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1460 
1461 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1462 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
1463 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
1464 
1465 namespace perfetto {
1466 namespace base {
1467 
1468 namespace {
1469 
1470 #if TRACK_COMMITTED_SIZE()
1471 constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
1472 #endif
1473 
RoundUpToSysPageSize(size_t req_size)1474 size_t RoundUpToSysPageSize(size_t req_size) {
1475   const size_t page_size = GetSysPageSize();
1476   return (req_size + page_size - 1) & ~(page_size - 1);
1477 }
1478 
GuardSize()1479 size_t GuardSize() {
1480   return GetSysPageSize();
1481 }
1482 
1483 }  // namespace
1484 
1485 // static
Allocate(size_t req_size,int flags)1486 PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
1487   size_t rounded_up_size = RoundUpToSysPageSize(req_size);
1488   PERFETTO_CHECK(rounded_up_size >= req_size);
1489   size_t outer_size = rounded_up_size + GuardSize() * 2;
1490 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1491   void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
1492   if (!ptr && (flags & kMayFail))
1493     return PagedMemory();
1494   PERFETTO_CHECK(ptr);
1495   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
1496 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1497   void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
1498                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1499   if (ptr == MAP_FAILED && (flags & kMayFail))
1500     return PagedMemory();
1501   PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
1502   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
1503   int res = mprotect(ptr, GuardSize(), PROT_NONE);
1504   res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
1505   PERFETTO_CHECK(res == 0);
1506 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1507 
1508   auto memory = PagedMemory(usable_region, req_size);
1509 #if TRACK_COMMITTED_SIZE()
1510   size_t initial_commit = req_size;
1511   if (flags & kDontCommit)
1512     initial_commit = std::min(initial_commit, kCommitChunkSize);
1513   memory.EnsureCommitted(initial_commit);
1514 #endif  // TRACK_COMMITTED_SIZE()
1515   return memory;
1516 }
1517 
PagedMemory()1518 PagedMemory::PagedMemory() {}
1519 
1520 // clang-format off
PagedMemory(char * p,size_t size)1521 PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
1522   ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
1523 }
1524 
PagedMemory(PagedMemory && other)1525 PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
1526   *this = other;
1527   other.p_ = nullptr;
1528 }
1529 // clang-format on
1530 
operator =(PagedMemory && other)1531 PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
1532   this->~PagedMemory();
1533   new (this) PagedMemory(std::move(other));
1534   return *this;
1535 }
1536 
~PagedMemory()1537 PagedMemory::~PagedMemory() {
1538   if (!p_)
1539     return;
1540   PERFETTO_CHECK(size_);
1541   char* start = p_ - GuardSize();
1542 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1543   BOOL res = VirtualFree(start, 0, MEM_RELEASE);
1544   PERFETTO_CHECK(res != 0);
1545 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1546   const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
1547   int res = munmap(start, outer_size);
1548   PERFETTO_CHECK(res == 0);
1549 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1550   ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
1551 }
1552 
AdviseDontNeed(void * p,size_t size)1553 bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
1554   PERFETTO_DCHECK(p_);
1555   PERFETTO_DCHECK(p >= p_);
1556   PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
1557 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
1558   // Discarding pages on Windows has more CPU cost than is justified for the
1559   // possible memory savings.
1560   return false;
1561 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
1562         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
1563   // http://man7.org/linux/man-pages/man2/madvise.2.html
1564   int res = madvise(p, size, MADV_DONTNEED);
1565   PERFETTO_DCHECK(res == 0);
1566   return true;
1567 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
1568         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
1569 }
1570 
1571 #if TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t committed_size)1572 void PagedMemory::EnsureCommitted(size_t committed_size) {
1573   PERFETTO_DCHECK(committed_size > 0u);
1574   PERFETTO_DCHECK(committed_size <= size_);
1575 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1576   if (committed_size_ >= committed_size)
1577     return;
1578   // Rounding up.
1579   size_t delta = committed_size - committed_size_;
1580   size_t num_additional_chunks =
1581       (delta + kCommitChunkSize - 1) / kCommitChunkSize;
1582   PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
1583   // Don't commit more than the total size.
1584   size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
1585                                 size_ - committed_size_);
1586   void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
1587                            PAGE_READWRITE);
1588   PERFETTO_CHECK(res);
1589   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
1590                        committed_size_ + commit_size)
1591   committed_size_ += commit_size;
1592 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1593   // mmap commits automatically as needed, so we only track here for ASAN.
1594   committed_size = std::max(committed_size_, committed_size);
1595   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
1596   committed_size_ = committed_size;
1597 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1598 }
1599 #endif  // TRACK_COMMITTED_SIZE()
1600 
1601 }  // namespace base
1602 }  // namespace perfetto
1603 // gen_amalgamated begin source: src/base/string_splitter.cc
1604 // gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
1605 /*
1606  * Copyright (C) 2018 The Android Open Source Project
1607  *
1608  * Licensed under the Apache License, Version 2.0 (the "License");
1609  * you may not use this file except in compliance with the License.
1610  * You may obtain a copy of the License at
1611  *
1612  *      http://www.apache.org/licenses/LICENSE-2.0
1613  *
1614  * Unless required by applicable law or agreed to in writing, software
1615  * distributed under the License is distributed on an "AS IS" BASIS,
1616  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1617  * See the License for the specific language governing permissions and
1618  * limitations under the License.
1619  */
1620 
1621 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
1622 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
1623 
1624 #include <string>
1625 
1626 namespace perfetto {
1627 namespace base {
1628 
1629 // C++ version of strtok(). Splits a string without making copies or any heap
1630 // allocations. Destructs the original string passed in input.
1631 // Supports the special case of using \0 as a delimiter.
1632 // The token returned in output are valid as long as the input string is valid.
1633 class StringSplitter {
1634  public:
1635   // Can take ownership of the string if passed via std::move(), e.g.:
1636   // StringSplitter(std::move(str), '\n');
1637   StringSplitter(std::string, char delimiter);
1638 
1639   // Splits a C-string. The input string will be forcefully null-terminated (so
1640   // str[size - 1] should be == '\0' or the last char will be truncated).
1641   StringSplitter(char* str, size_t size, char delimiter);
1642 
1643   // Splits the current token from an outer StringSplitter instance. This is to
1644   // chain splitters as follows:
1645   // for (base::StringSplitter lines(x, '\n'); ss.Next();)
1646   //   for (base::StringSplitter words(&lines, ' '); words.Next();)
1647   StringSplitter(StringSplitter*, char delimiter);
1648 
1649   // Returns true if a token is found (in which case it will be stored in
1650   // cur_token()), false if no more tokens are found.
1651   bool Next();
1652 
1653   // Returns the current token iff last call to Next() returned true. In this
1654   // case it guarantees that the returned string is always null terminated.
1655   // In all other cases (before the 1st call to Next() and after Next() returns
1656   // false) returns nullptr.
cur_token()1657   char* cur_token() { return cur_; }
1658 
1659   // Returns the length of the current token (excluding the null terminator).
cur_token_size() const1660   size_t cur_token_size() const { return cur_size_; }
1661 
1662  private:
1663   StringSplitter(const StringSplitter&) = delete;
1664   StringSplitter& operator=(const StringSplitter&) = delete;
1665   void Initialize(char* str, size_t size);
1666 
1667   std::string str_;
1668   char* cur_;
1669   size_t cur_size_;
1670   char* next_;
1671   char* end_;  // STL-style, points one past the last char.
1672   const char delimiter_;
1673 };
1674 
1675 }  // namespace base
1676 }  // namespace perfetto
1677 
1678 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
1679 /*
1680  * Copyright (C) 2018 The Android Open Source Project
1681  *
1682  * Licensed under the Apache License, Version 2.0 (the "License");
1683  * you may not use this file except in compliance with the License.
1684  * You may obtain a copy of the License at
1685  *
1686  *      http://www.apache.org/licenses/LICENSE-2.0
1687  *
1688  * Unless required by applicable law or agreed to in writing, software
1689  * distributed under the License is distributed on an "AS IS" BASIS,
1690  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1691  * See the License for the specific language governing permissions and
1692  * limitations under the License.
1693  */
1694 
1695 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
1696 
1697 #include <utility>
1698 
1699 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1700 
1701 namespace perfetto {
1702 namespace base {
1703 
StringSplitter(std::string str,char delimiter)1704 StringSplitter::StringSplitter(std::string str, char delimiter)
1705     : str_(std::move(str)), delimiter_(delimiter) {
1706   // It's legal to access str[str.size()] in C++11 (it always returns \0),
1707   // hence the +1 (which becomes just size() after the -1 in Initialize()).
1708   Initialize(&str_[0], str_.size() + 1);
1709 }
1710 
StringSplitter(char * str,size_t size,char delimiter)1711 StringSplitter::StringSplitter(char* str, size_t size, char delimiter)
1712     : delimiter_(delimiter) {
1713   Initialize(str, size);
1714 }
1715 
StringSplitter(StringSplitter * outer,char delimiter)1716 StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
1717     : delimiter_(delimiter) {
1718   Initialize(outer->cur_token(), outer->cur_token_size() + 1);
1719 }
1720 
Initialize(char * str,size_t size)1721 void StringSplitter::Initialize(char* str, size_t size) {
1722   PERFETTO_DCHECK(!size || str);
1723   next_ = str;
1724   end_ = str + size;
1725   cur_ = nullptr;
1726   cur_size_ = 0;
1727   if (size)
1728     next_[size - 1] = '\0';
1729 }
1730 
Next()1731 bool StringSplitter::Next() {
1732   for (; next_ < end_; next_++) {
1733     if (*next_ == delimiter_)
1734       continue;
1735     cur_ = next_;
1736     for (;; next_++) {
1737       if (*next_ == delimiter_) {
1738         cur_size_ = static_cast<size_t>(next_ - cur_);
1739         *(next_++) = '\0';
1740         break;
1741       }
1742       if (*next_ == '\0') {
1743         cur_size_ = static_cast<size_t>(next_ - cur_);
1744         next_ = end_;
1745         break;
1746       }
1747     }
1748     if (*cur_)
1749       return true;
1750     break;
1751   }
1752   cur_ = nullptr;
1753   cur_size_ = 0;
1754   return false;
1755 }
1756 
1757 }  // namespace base
1758 }  // namespace perfetto
1759 // gen_amalgamated begin source: src/base/string_utils.cc
1760 // gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
1761 // gen_amalgamated begin header: include/perfetto/ext/base/optional.h
1762 /*
1763  * Copyright (C) 2018 The Android Open Source Project
1764  *
1765  * Licensed under the Apache License, Version 2.0 (the "License");
1766  * you may not use this file except in compliance with the License.
1767  * You may obtain a copy of the License at
1768  *
1769  *      http://www.apache.org/licenses/LICENSE-2.0
1770  *
1771  * Unless required by applicable law or agreed to in writing, software
1772  * distributed under the License is distributed on an "AS IS" BASIS,
1773  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1774  * See the License for the specific language governing permissions and
1775  * limitations under the License.
1776  */
1777 
1778 #ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
1779 #define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
1780 
1781 #include <functional>
1782 #include <type_traits>
1783 #include <utility>
1784 
1785 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1786 
1787 namespace perfetto {
1788 namespace base {
1789 
1790 // Specification:
1791 // http://en.cppreference.com/w/cpp/utility/optional/in_place_t
1792 struct in_place_t {};
1793 
1794 // Specification:
1795 // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
1796 struct nullopt_t {
nullopt_tperfetto::base::nullopt_t1797   constexpr explicit nullopt_t(int) {}
1798 };
1799 
1800 // Specification:
1801 // http://en.cppreference.com/w/cpp/utility/optional/in_place
1802 constexpr in_place_t in_place = {};
1803 
1804 // Specification:
1805 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
1806 constexpr nullopt_t nullopt(0);
1807 
1808 // Forward declaration, which is referred by following helpers.
1809 template <typename T>
1810 class Optional;
1811 
1812 namespace internal {
1813 
1814 template <typename T, bool = std::is_trivially_destructible<T>::value>
1815 struct OptionalStorageBase {
1816   // Initializing |empty_| here instead of using default member initializing
1817   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1818   constexpr OptionalStorageBase() : empty_('\0') {}
1819 
1820   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1821   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
1822       : is_populated_(true), value_(std::forward<Args>(args)...) {}
1823 
1824   // When T is not trivially destructible we must call its
1825   // destructor before deallocating its memory.
1826   // Note that this hides the (implicitly declared) move constructor, which
1827   // would be used for constexpr move constructor in OptionalStorage<T>.
1828   // It is needed iff T is trivially move constructible. However, the current
1829   // is_trivially_{copy,move}_constructible implementation requires
1830   // is_trivially_destructible (which looks a bug, cf:
1831   // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
1832   // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
1833   // necessary for this case at the moment. Please see also the destructor
1834   // comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1835   ~OptionalStorageBase() {
1836     if (is_populated_)
1837       value_.~T();
1838   }
1839 
1840   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase1841   void Init(Args&&... args) {
1842     PERFETTO_DCHECK(!is_populated_);
1843     ::new (&value_) T(std::forward<Args>(args)...);
1844     is_populated_ = true;
1845   }
1846 
1847   bool is_populated_ = false;
1848   union {
1849     // |empty_| exists so that the union will always be initialized, even when
1850     // it doesn't contain a value. Union members must be initialized for the
1851     // constructor to be 'constexpr'.
1852     char empty_;
1853     T value_;
1854   };
1855 };
1856 
1857 template <typename T>
1858 struct OptionalStorageBase<T, true /* trivially destructible */> {
1859   // Initializing |empty_| here instead of using default member initializing
1860   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1861   constexpr OptionalStorageBase() : empty_('\0') {}
1862 
1863   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase1864   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
1865       : is_populated_(true), value_(std::forward<Args>(args)...) {}
1866 
1867   // When T is trivially destructible (i.e. its destructor does nothing) there
1868   // is no need to call it. Implicitly defined destructor is trivial, because
1869   // both members (bool and union containing only variants which are trivially
1870   // destructible) are trivially destructible.
1871   // Explicitly-defaulted destructor is also trivial, but do not use it here,
1872   // because it hides the implicit move constructor. It is needed to implement
1873   // constexpr move constructor in OptionalStorage iff T is trivially move
1874   // constructible. Note that, if T is trivially move constructible, the move
1875   // constructor of OptionalStorageBase<T> is also implicitly defined and it is
1876   // trivially move constructor. If T is not trivially move constructible,
1877   // "not declaring move constructor without destructor declaration" here means
1878   // "delete move constructor", which works because any move constructor of
1879   // OptionalStorage will not refer to it in that case.
1880 
1881   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase1882   void Init(Args&&... args) {
1883     PERFETTO_DCHECK(!is_populated_);
1884     ::new (&value_) T(std::forward<Args>(args)...);
1885     is_populated_ = true;
1886   }
1887 
1888   bool is_populated_ = false;
1889   union {
1890     // |empty_| exists so that the union will always be initialized, even when
1891     // it doesn't contain a value. Union members must be initialized for the
1892     // constructor to be 'constexpr'.
1893     char empty_;
1894     T value_;
1895   };
1896 };
1897 
1898 // Implement conditional constexpr copy and move constructors. These are
1899 // constexpr if is_trivially_{copy,move}_constructible<T>::value is true
1900 // respectively. If each is true, the corresponding constructor is defined as
1901 // "= default;", which generates a constexpr constructor (In this case,
1902 // the condition of constexpr-ness is satisfied because the base class also has
1903 // compiler generated constexpr {copy,move} constructors). Note that
1904 // placement-new is prohibited in constexpr.
1905 template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
1906 struct OptionalStorage : OptionalStorageBase<T> {
1907   // This is no trivially {copy,move} constructible case. Other cases are
1908   // defined below as specializations.
1909 
1910   // Accessing the members of template base class requires explicit
1911   // declaration.
1912   using OptionalStorageBase<T>::is_populated_;
1913   using OptionalStorageBase<T>::value_;
1914   using OptionalStorageBase<T>::Init;
1915 
1916   // Inherit constructors (specifically, the in_place constructor).
1917   using OptionalStorageBase<T>::OptionalStorageBase;
1918 
1919   // User defined constructor deletes the default constructor.
1920   // Define it explicitly.
1921   OptionalStorage() = default;
1922 
OptionalStorageperfetto::base::internal::OptionalStorage1923   OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
1924     if (other.is_populated_)
1925       Init(other.value_);
1926   }
1927 
OptionalStorageperfetto::base::internal::OptionalStorage1928   OptionalStorage(OptionalStorage&& other) noexcept(
1929       std::is_nothrow_move_constructible<T>::value) {
1930     if (other.is_populated_)
1931       Init(std::move(other.value_));
1932   }
1933 };
1934 
1935 template <typename T>
1936 struct OptionalStorage<T, true /* trivially copy constructible */>
1937     : OptionalStorageBase<T> {
1938   using OptionalStorageBase<T>::is_populated_;
1939   using OptionalStorageBase<T>::value_;
1940   using OptionalStorageBase<T>::Init;
1941   using OptionalStorageBase<T>::OptionalStorageBase;
1942 
1943   OptionalStorage() = default;
1944   OptionalStorage(const OptionalStorage& other) = default;
1945 
OptionalStorageperfetto::base::internal::OptionalStorage1946   OptionalStorage(OptionalStorage&& other) noexcept(
1947       std::is_nothrow_move_constructible<T>::value) {
1948     if (other.is_populated_)
1949       Init(std::move(other.value_));
1950   }
1951 };
1952 
1953 // Base class to support conditionally usable copy-/move- constructors
1954 // and assign operators.
1955 template <typename T>
1956 class OptionalBase {
1957   // This class provides implementation rather than public API, so everything
1958   // should be hidden. Often we use composition, but we cannot in this case
1959   // because of C++ language restriction.
1960  protected:
1961   constexpr OptionalBase() = default;
1962   constexpr OptionalBase(const OptionalBase& other) = default;
1963   constexpr OptionalBase(OptionalBase&& other) = default;
1964 
1965   template <class... Args>
OptionalBase(in_place_t,Args &&...args)1966   constexpr explicit OptionalBase(in_place_t, Args&&... args)
1967       : storage_(in_place, std::forward<Args>(args)...) {}
1968 
1969   // Implementation of converting constructors.
1970   template <typename U>
OptionalBase(const OptionalBase<U> & other)1971   explicit OptionalBase(const OptionalBase<U>& other) {
1972     if (other.storage_.is_populated_)
1973       storage_.Init(other.storage_.value_);
1974   }
1975 
1976   template <typename U>
OptionalBase(OptionalBase<U> && other)1977   explicit OptionalBase(OptionalBase<U>&& other) {
1978     if (other.storage_.is_populated_)
1979       storage_.Init(std::move(other.storage_.value_));
1980   }
1981 
1982   ~OptionalBase() = default;
1983 
operator =(const OptionalBase & other)1984   OptionalBase& operator=(const OptionalBase& other) {
1985     CopyAssign(other);
1986     return *this;
1987   }
1988 
operator =(OptionalBase && other)1989   OptionalBase& operator=(OptionalBase&& other) noexcept(
1990       std::is_nothrow_move_assignable<T>::value&&
1991           std::is_nothrow_move_constructible<T>::value) {
1992     MoveAssign(std::move(other));
1993     return *this;
1994   }
1995 
1996   template <typename U>
CopyAssign(const OptionalBase<U> & other)1997   void CopyAssign(const OptionalBase<U>& other) {
1998     if (other.storage_.is_populated_)
1999       InitOrAssign(other.storage_.value_);
2000     else
2001       FreeIfNeeded();
2002   }
2003 
2004   template <typename U>
MoveAssign(OptionalBase<U> && other)2005   void MoveAssign(OptionalBase<U>&& other) {
2006     if (other.storage_.is_populated_)
2007       InitOrAssign(std::move(other.storage_.value_));
2008     else
2009       FreeIfNeeded();
2010   }
2011 
2012   template <typename U>
InitOrAssign(U && value)2013   void InitOrAssign(U&& value) {
2014     if (storage_.is_populated_)
2015       storage_.value_ = std::forward<U>(value);
2016     else
2017       storage_.Init(std::forward<U>(value));
2018   }
2019 
FreeIfNeeded()2020   void FreeIfNeeded() {
2021     if (!storage_.is_populated_)
2022       return;
2023     storage_.value_.~T();
2024     storage_.is_populated_ = false;
2025   }
2026 
2027   // For implementing conversion, allow access to other typed OptionalBase
2028   // class.
2029   template <typename U>
2030   friend class OptionalBase;
2031 
2032   OptionalStorage<T> storage_;
2033 };
2034 
2035 // The following {Copy,Move}{Constructible,Assignable} structs are helpers to
2036 // implement constructor/assign-operator overloading. Specifically, if T is
2037 // is not movable but copyable, Optional<T>'s move constructor should not
2038 // participate in overload resolution. This inheritance trick implements that.
2039 template <bool is_copy_constructible>
2040 struct CopyConstructible {};
2041 
2042 template <>
2043 struct CopyConstructible<false> {
2044   constexpr CopyConstructible() = default;
2045   constexpr CopyConstructible(const CopyConstructible&) = delete;
2046   constexpr CopyConstructible(CopyConstructible&&) = default;
2047   CopyConstructible& operator=(const CopyConstructible&) = default;
2048   CopyConstructible& operator=(CopyConstructible&&) = default;
2049 };
2050 
2051 template <bool is_move_constructible>
2052 struct MoveConstructible {};
2053 
2054 template <>
2055 struct MoveConstructible<false> {
2056   constexpr MoveConstructible() = default;
2057   constexpr MoveConstructible(const MoveConstructible&) = default;
2058   constexpr MoveConstructible(MoveConstructible&&) = delete;
2059   MoveConstructible& operator=(const MoveConstructible&) = default;
2060   MoveConstructible& operator=(MoveConstructible&&) = default;
2061 };
2062 
2063 template <bool is_copy_assignable>
2064 struct CopyAssignable {};
2065 
2066 template <>
2067 struct CopyAssignable<false> {
2068   constexpr CopyAssignable() = default;
2069   constexpr CopyAssignable(const CopyAssignable&) = default;
2070   constexpr CopyAssignable(CopyAssignable&&) = default;
2071   CopyAssignable& operator=(const CopyAssignable&) = delete;
2072   CopyAssignable& operator=(CopyAssignable&&) = default;
2073 };
2074 
2075 template <bool is_move_assignable>
2076 struct MoveAssignable {};
2077 
2078 template <>
2079 struct MoveAssignable<false> {
2080   constexpr MoveAssignable() = default;
2081   constexpr MoveAssignable(const MoveAssignable&) = default;
2082   constexpr MoveAssignable(MoveAssignable&&) = default;
2083   MoveAssignable& operator=(const MoveAssignable&) = default;
2084   MoveAssignable& operator=(MoveAssignable&&) = delete;
2085 };
2086 
2087 // Helper to conditionally enable converting constructors and assign operators.
2088 template <typename T, typename U>
2089 struct IsConvertibleFromOptional
2090     : std::integral_constant<
2091           bool,
2092           std::is_constructible<T, Optional<U>&>::value ||
2093               std::is_constructible<T, const Optional<U>&>::value ||
2094               std::is_constructible<T, Optional<U>&&>::value ||
2095               std::is_constructible<T, const Optional<U>&&>::value ||
2096               std::is_convertible<Optional<U>&, T>::value ||
2097               std::is_convertible<const Optional<U>&, T>::value ||
2098               std::is_convertible<Optional<U>&&, T>::value ||
2099               std::is_convertible<const Optional<U>&&, T>::value> {};
2100 
2101 template <typename T, typename U>
2102 struct IsAssignableFromOptional
2103     : std::integral_constant<
2104           bool,
2105           IsConvertibleFromOptional<T, U>::value ||
2106               std::is_assignable<T&, Optional<U>&>::value ||
2107               std::is_assignable<T&, const Optional<U>&>::value ||
2108               std::is_assignable<T&, Optional<U>&&>::value ||
2109               std::is_assignable<T&, const Optional<U>&&>::value> {};
2110 
2111 // Forward compatibility for C++17.
2112 // Introduce one more deeper nested namespace to avoid leaking using std::swap.
2113 namespace swappable_impl {
2114 using std::swap;
2115 
2116 struct IsSwappableImpl {
2117   // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
2118   // available for T. Otherwise, Check's overload resolution falls back to
2119   // Check(...) declared below thanks to SFINAE, so returns false_type.
2120   template <typename T>
2121   static auto Check(int)
2122       -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
2123 
2124   template <typename T>
2125   static std::false_type Check(...);
2126 };
2127 }  // namespace swappable_impl
2128 
2129 template <typename T>
2130 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
2131 
2132 // Forward compatibility for C++20.
2133 template <typename T>
2134 using RemoveCvRefT =
2135     typename std::remove_cv<typename std::remove_reference<T>::type>::type;
2136 
2137 }  // namespace internal
2138 
2139 // On Windows, by default, empty-base class optimization does not work,
2140 // which means even if the base class is empty struct, it still consumes one
2141 // byte for its body. __declspec(empty_bases) enables the optimization.
2142 // cf)
2143 // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
2144 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
2145     !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
2146 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
2147 #else
2148 #define OPTIONAL_DECLSPEC_EMPTY_BASES
2149 #endif
2150 
2151 // base::Optional is a Chromium version of the C++17 optional class:
2152 // std::optional documentation:
2153 // http://en.cppreference.com/w/cpp/utility/optional
2154 // Chromium documentation:
2155 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
2156 //
2157 // These are the differences between the specification and the implementation:
2158 // - Constructors do not use 'constexpr' as it is a C++14 extension.
2159 // - 'constexpr' might be missing in some places for reasons specified locally.
2160 // - No exceptions are thrown, because they are banned from Chromium.
2161 //   Marked noexcept for only move constructor and move assign operators.
2162 // - All the non-members are in the 'base' namespace instead of 'std'.
2163 //
2164 // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
2165 // PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
2166 // and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
2167 // which is recursive so it does not work. As of Feb 2018, std::optional C++17
2168 // implementation in both clang and gcc has same limitation. MSVC SFINAE looks
2169 // to have different behavior, but anyway it reports an error, too.
2170 //
2171 // This file is a modified version of optional.h from Chromium at revision
2172 // 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
2173 // specific code and replace with C++11 counterparts.
2174 template <typename T>
2175 class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
2176     : public internal::OptionalBase<T>,
2177       public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
2178       public internal::MoveConstructible<std::is_move_constructible<T>::value>,
2179       public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
2180                                       std::is_copy_assignable<T>::value>,
2181       public internal::MoveAssignable<std::is_move_constructible<T>::value &&
2182                                       std::is_move_assignable<T>::value> {
2183  public:
2184 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
2185   using value_type = T;
2186 
2187   // Defer default/copy/move constructor implementation to OptionalBase.
2188   constexpr Optional() = default;
2189   constexpr Optional(const Optional& other) = default;
2190   constexpr Optional(Optional&& other) noexcept(
2191       std::is_nothrow_move_constructible<T>::value) = default;
2192 
Optional(nullopt_t)2193   constexpr Optional(nullopt_t) {}  // NOLINT(runtime/explicit)
2194 
2195   // Converting copy constructor. "explicit" only if
2196   // std::is_convertible<const U&, T>::value is false. It is implemented by
2197   // declaring two almost same constructors, but that condition in enable_if_t
2198   // is different, so that either one is chosen, thanks to SFINAE.
2199   template <typename U,
2200             typename std::enable_if<
2201                 std::is_constructible<T, const U&>::value &&
2202                     !internal::IsConvertibleFromOptional<T, U>::value &&
2203                     std::is_convertible<const U&, T>::value,
2204                 bool>::type = false>
Optional(const Optional<U> & other)2205   Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
2206 
2207   template <typename U,
2208             typename std::enable_if<
2209                 std::is_constructible<T, const U&>::value &&
2210                     !internal::IsConvertibleFromOptional<T, U>::value &&
2211                     !std::is_convertible<const U&, T>::value,
2212                 bool>::type = false>
Optional(const Optional<U> & other)2213   explicit Optional(const Optional<U>& other)
2214       : internal::OptionalBase<T>(other) {}
2215 
2216   // Converting move constructor. Similar to converting copy constructor,
2217   // declaring two (explicit and non-explicit) constructors.
2218   template <typename U,
2219             typename std::enable_if<
2220                 std::is_constructible<T, U&&>::value &&
2221                     !internal::IsConvertibleFromOptional<T, U>::value &&
2222                     std::is_convertible<U&&, T>::value,
2223                 bool>::type = false>
Optional(Optional<U> && other)2224   Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
2225 
2226   template <typename U,
2227             typename std::enable_if<
2228                 std::is_constructible<T, U&&>::value &&
2229                     !internal::IsConvertibleFromOptional<T, U>::value &&
2230                     !std::is_convertible<U&&, T>::value,
2231                 bool>::type = false>
Optional(Optional<U> && other)2232   explicit Optional(Optional<U>&& other)
2233       : internal::OptionalBase<T>(std::move(other)) {}
2234 
2235   template <class... Args>
Optional(in_place_t,Args &&...args)2236   constexpr explicit Optional(in_place_t, Args&&... args)
2237       : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
2238 
2239   template <class U,
2240             class... Args,
2241             class = typename std::enable_if<
2242                 std::is_constructible<value_type,
2243                                       std::initializer_list<U>&,
2244                                       Args...>::value>::type>
Optional(in_place_t,std::initializer_list<U> il,Args &&...args)2245   constexpr explicit Optional(in_place_t,
2246                               std::initializer_list<U> il,
2247                               Args&&... args)
2248       : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
2249 
2250   // Forward value constructor. Similar to converting constructors,
2251   // conditionally explicit.
2252   template <
2253       typename U = value_type,
2254       typename std::enable_if<
2255           std::is_constructible<T, U&&>::value &&
2256               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
2257               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
2258               std::is_convertible<U&&, T>::value,
2259           bool>::type = false>
Optional(U && value)2260   constexpr Optional(U&& value)
2261       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
2262 
2263   template <
2264       typename U = value_type,
2265       typename std::enable_if<
2266           std::is_constructible<T, U&&>::value &&
2267               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
2268               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
2269               !std::is_convertible<U&&, T>::value,
2270           bool>::type = false>
Optional(U && value)2271   constexpr explicit Optional(U&& value)
2272       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
2273 
2274   ~Optional() = default;
2275 
2276   // Defer copy-/move- assign operator implementation to OptionalBase.
2277   Optional& operator=(const Optional& other) = default;
2278   Optional& operator=(Optional&& other) noexcept(
2279       std::is_nothrow_move_assignable<T>::value&&
2280           std::is_nothrow_move_constructible<T>::value) = default;
2281 
operator =(nullopt_t)2282   Optional& operator=(nullopt_t) {
2283     FreeIfNeeded();
2284     return *this;
2285   }
2286 
2287   // Perfect-forwarded assignment.
2288   template <typename U>
2289   typename std::enable_if<
2290       !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
2291           std::is_constructible<T, U>::value &&
2292           std::is_assignable<T&, U>::value &&
2293           (!std::is_scalar<T>::value ||
2294            !std::is_same<typename std::decay<U>::type, T>::value),
2295       Optional&>::type
operator =(U && value)2296   operator=(U&& value) {
2297     InitOrAssign(std::forward<U>(value));
2298     return *this;
2299   }
2300 
2301   // Copy assign the state of other.
2302   template <typename U>
2303   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
2304                               std::is_constructible<T, const U&>::value &&
2305                               std::is_assignable<T&, const U&>::value,
2306                           Optional&>::type
operator =(const Optional<U> & other)2307   operator=(const Optional<U>& other) {
2308     CopyAssign(other);
2309     return *this;
2310   }
2311 
2312   // Move assign the state of other.
2313   template <typename U>
2314   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
2315                               std::is_constructible<T, U>::value &&
2316                               std::is_assignable<T&, U>::value,
2317                           Optional&>::type
operator =(Optional<U> && other)2318   operator=(Optional<U>&& other) {
2319     MoveAssign(std::move(other));
2320     return *this;
2321   }
2322 
operator ->() const2323   const T* operator->() const {
2324     PERFETTO_DCHECK(storage_.is_populated_);
2325     return &storage_.value_;
2326   }
2327 
operator ->()2328   T* operator->() {
2329     PERFETTO_DCHECK(storage_.is_populated_);
2330     return &storage_.value_;
2331   }
2332 
operator *() const2333   const T& operator*() const& {
2334     PERFETTO_DCHECK(storage_.is_populated_);
2335     return storage_.value_;
2336   }
2337 
operator *()2338   T& operator*() & {
2339     PERFETTO_DCHECK(storage_.is_populated_);
2340     return storage_.value_;
2341   }
2342 
operator *() const2343   const T&& operator*() const&& {
2344     PERFETTO_DCHECK(storage_.is_populated_);
2345     return std::move(storage_.value_);
2346   }
2347 
operator *()2348   T&& operator*() && {
2349     PERFETTO_DCHECK(storage_.is_populated_);
2350     return std::move(storage_.value_);
2351   }
2352 
operator bool() const2353   constexpr explicit operator bool() const { return storage_.is_populated_; }
2354 
has_value() const2355   constexpr bool has_value() const { return storage_.is_populated_; }
2356 
value()2357   T& value() & {
2358     PERFETTO_CHECK(storage_.is_populated_);
2359     return storage_.value_;
2360   }
2361 
value() const2362   const T& value() const& {
2363     PERFETTO_CHECK(storage_.is_populated_);
2364     return storage_.value_;
2365   }
2366 
value()2367   T&& value() && {
2368     PERFETTO_CHECK(storage_.is_populated_);
2369     return std::move(storage_.value_);
2370   }
2371 
value() const2372   const T&& value() const&& {
2373     PERFETTO_CHECK(storage_.is_populated_);
2374     return std::move(storage_.value_);
2375   }
2376 
2377   template <class U>
value_or(U && default_value) const2378   constexpr T value_or(U&& default_value) const& {
2379     static_assert(std::is_convertible<U, T>::value,
2380                   "U must be convertible to T");
2381     return storage_.is_populated_
2382                ? storage_.value_
2383                : static_cast<T>(std::forward<U>(default_value));
2384   }
2385 
2386   template <class U>
value_or(U && default_value)2387   T value_or(U&& default_value) && {
2388     static_assert(std::is_convertible<U, T>::value,
2389                   "U must be convertible to T");
2390     return storage_.is_populated_
2391                ? std::move(storage_.value_)
2392                : static_cast<T>(std::forward<U>(default_value));
2393   }
2394 
swap(Optional & other)2395   void swap(Optional& other) {
2396     if (!storage_.is_populated_ && !other.storage_.is_populated_)
2397       return;
2398 
2399     if (storage_.is_populated_ != other.storage_.is_populated_) {
2400       if (storage_.is_populated_) {
2401         other.storage_.Init(std::move(storage_.value_));
2402         FreeIfNeeded();
2403       } else {
2404         storage_.Init(std::move(other.storage_.value_));
2405         other.FreeIfNeeded();
2406       }
2407       return;
2408     }
2409 
2410     PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
2411     using std::swap;
2412     swap(**this, *other);
2413   }
2414 
reset()2415   void reset() { FreeIfNeeded(); }
2416 
2417   template <class... Args>
emplace(Args &&...args)2418   T& emplace(Args&&... args) {
2419     FreeIfNeeded();
2420     storage_.Init(std::forward<Args>(args)...);
2421     return storage_.value_;
2422   }
2423 
2424   template <class U, class... Args>
2425   typename std::enable_if<
2426       std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
2427       T&>::type
emplace(std::initializer_list<U> il,Args &&...args)2428   emplace(std::initializer_list<U> il, Args&&... args) {
2429     FreeIfNeeded();
2430     storage_.Init(il, std::forward<Args>(args)...);
2431     return storage_.value_;
2432   }
2433 
2434  private:
2435   // Accessing template base class's protected member needs explicit
2436   // declaration to do so.
2437   using internal::OptionalBase<T>::CopyAssign;
2438   using internal::OptionalBase<T>::FreeIfNeeded;
2439   using internal::OptionalBase<T>::InitOrAssign;
2440   using internal::OptionalBase<T>::MoveAssign;
2441   using internal::OptionalBase<T>::storage_;
2442 };
2443 
2444 // Here after defines comparation operators. The definition follows
2445 // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
2446 // while bool() casting is replaced by has_value() to meet the chromium
2447 // style guide.
2448 template <class T, class U>
operator ==(const Optional<T> & lhs,const Optional<U> & rhs)2449 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
2450   if (lhs.has_value() != rhs.has_value())
2451     return false;
2452   if (!lhs.has_value())
2453     return true;
2454   return *lhs == *rhs;
2455 }
2456 
2457 template <class T, class U>
operator !=(const Optional<T> & lhs,const Optional<U> & rhs)2458 bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
2459   if (lhs.has_value() != rhs.has_value())
2460     return true;
2461   if (!lhs.has_value())
2462     return false;
2463   return *lhs != *rhs;
2464 }
2465 
2466 template <class T, class U>
operator <(const Optional<T> & lhs,const Optional<U> & rhs)2467 bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
2468   if (!rhs.has_value())
2469     return false;
2470   if (!lhs.has_value())
2471     return true;
2472   return *lhs < *rhs;
2473 }
2474 
2475 template <class T, class U>
operator <=(const Optional<T> & lhs,const Optional<U> & rhs)2476 bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
2477   if (!lhs.has_value())
2478     return true;
2479   if (!rhs.has_value())
2480     return false;
2481   return *lhs <= *rhs;
2482 }
2483 
2484 template <class T, class U>
operator >(const Optional<T> & lhs,const Optional<U> & rhs)2485 bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
2486   if (!lhs.has_value())
2487     return false;
2488   if (!rhs.has_value())
2489     return true;
2490   return *lhs > *rhs;
2491 }
2492 
2493 template <class T, class U>
operator >=(const Optional<T> & lhs,const Optional<U> & rhs)2494 bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
2495   if (!rhs.has_value())
2496     return true;
2497   if (!lhs.has_value())
2498     return false;
2499   return *lhs >= *rhs;
2500 }
2501 
2502 template <class T>
operator ==(const Optional<T> & opt,nullopt_t)2503 constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
2504   return !opt;
2505 }
2506 
2507 template <class T>
operator ==(nullopt_t,const Optional<T> & opt)2508 constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
2509   return !opt;
2510 }
2511 
2512 template <class T>
operator !=(const Optional<T> & opt,nullopt_t)2513 constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
2514   return opt.has_value();
2515 }
2516 
2517 template <class T>
operator !=(nullopt_t,const Optional<T> & opt)2518 constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
2519   return opt.has_value();
2520 }
2521 
2522 template <class T>
operator <(const Optional<T> &,nullopt_t)2523 constexpr bool operator<(const Optional<T>&, nullopt_t) {
2524   return false;
2525 }
2526 
2527 template <class T>
operator <(nullopt_t,const Optional<T> & opt)2528 constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
2529   return opt.has_value();
2530 }
2531 
2532 template <class T>
operator <=(const Optional<T> & opt,nullopt_t)2533 constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
2534   return !opt;
2535 }
2536 
2537 template <class T>
operator <=(nullopt_t,const Optional<T> &)2538 constexpr bool operator<=(nullopt_t, const Optional<T>&) {
2539   return true;
2540 }
2541 
2542 template <class T>
operator >(const Optional<T> & opt,nullopt_t)2543 constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
2544   return opt.has_value();
2545 }
2546 
2547 template <class T>
operator >(nullopt_t,const Optional<T> &)2548 constexpr bool operator>(nullopt_t, const Optional<T>&) {
2549   return false;
2550 }
2551 
2552 template <class T>
operator >=(const Optional<T> &,nullopt_t)2553 constexpr bool operator>=(const Optional<T>&, nullopt_t) {
2554   return true;
2555 }
2556 
2557 template <class T>
operator >=(nullopt_t,const Optional<T> & opt)2558 constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
2559   return !opt;
2560 }
2561 
2562 template <class T, class U>
operator ==(const Optional<T> & opt,const U & value)2563 constexpr bool operator==(const Optional<T>& opt, const U& value) {
2564   return opt.has_value() ? *opt == value : false;
2565 }
2566 
2567 template <class T, class U>
operator ==(const U & value,const Optional<T> & opt)2568 constexpr bool operator==(const U& value, const Optional<T>& opt) {
2569   return opt.has_value() ? value == *opt : false;
2570 }
2571 
2572 template <class T, class U>
operator !=(const Optional<T> & opt,const U & value)2573 constexpr bool operator!=(const Optional<T>& opt, const U& value) {
2574   return opt.has_value() ? *opt != value : true;
2575 }
2576 
2577 template <class T, class U>
operator !=(const U & value,const Optional<T> & opt)2578 constexpr bool operator!=(const U& value, const Optional<T>& opt) {
2579   return opt.has_value() ? value != *opt : true;
2580 }
2581 
2582 template <class T, class U>
operator <(const Optional<T> & opt,const U & value)2583 constexpr bool operator<(const Optional<T>& opt, const U& value) {
2584   return opt.has_value() ? *opt < value : true;
2585 }
2586 
2587 template <class T, class U>
operator <(const U & value,const Optional<T> & opt)2588 constexpr bool operator<(const U& value, const Optional<T>& opt) {
2589   return opt.has_value() ? value < *opt : false;
2590 }
2591 
2592 template <class T, class U>
operator <=(const Optional<T> & opt,const U & value)2593 constexpr bool operator<=(const Optional<T>& opt, const U& value) {
2594   return opt.has_value() ? *opt <= value : true;
2595 }
2596 
2597 template <class T, class U>
operator <=(const U & value,const Optional<T> & opt)2598 constexpr bool operator<=(const U& value, const Optional<T>& opt) {
2599   return opt.has_value() ? value <= *opt : false;
2600 }
2601 
2602 template <class T, class U>
operator >(const Optional<T> & opt,const U & value)2603 constexpr bool operator>(const Optional<T>& opt, const U& value) {
2604   return opt.has_value() ? *opt > value : false;
2605 }
2606 
2607 template <class T, class U>
operator >(const U & value,const Optional<T> & opt)2608 constexpr bool operator>(const U& value, const Optional<T>& opt) {
2609   return opt.has_value() ? value > *opt : true;
2610 }
2611 
2612 template <class T, class U>
operator >=(const Optional<T> & opt,const U & value)2613 constexpr bool operator>=(const Optional<T>& opt, const U& value) {
2614   return opt.has_value() ? *opt >= value : false;
2615 }
2616 
2617 template <class T, class U>
operator >=(const U & value,const Optional<T> & opt)2618 constexpr bool operator>=(const U& value, const Optional<T>& opt) {
2619   return opt.has_value() ? value >= *opt : true;
2620 }
2621 
2622 template <class T>
make_optional(T && value)2623 constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
2624   return Optional<typename std::decay<T>::type>(std::forward<T>(value));
2625 }
2626 
2627 template <class T, class... Args>
make_optional(Args &&...args)2628 constexpr Optional<T> make_optional(Args&&... args) {
2629   return Optional<T>(in_place, std::forward<Args>(args)...);
2630 }
2631 
2632 template <class T, class U, class... Args>
make_optional(std::initializer_list<U> il,Args &&...args)2633 constexpr Optional<T> make_optional(std::initializer_list<U> il,
2634                                     Args&&... args) {
2635   return Optional<T>(in_place, il, std::forward<Args>(args)...);
2636 }
2637 
2638 // Partial specialization for a function template is not allowed. Also, it is
2639 // not allowed to add overload function to std namespace, while it is allowed
2640 // to specialize the template in std. Thus, swap() (kind of) overloading is
2641 // defined in base namespace, instead.
2642 template <class T>
2643 typename std::enable_if<std::is_move_constructible<T>::value &&
2644                         internal::IsSwappable<T>::value>::type
swap(Optional<T> & lhs,Optional<T> & rhs)2645 swap(Optional<T>& lhs, Optional<T>& rhs) {
2646   lhs.swap(rhs);
2647 }
2648 
2649 }  // namespace base
2650 }  // namespace perfetto
2651 
2652 namespace std {
2653 
2654 template <class T>
2655 struct hash<perfetto::base::Optional<T>> {
operator ()std::hash2656   size_t operator()(const perfetto::base::Optional<T>& opt) const {
2657     return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
2658   }
2659 };
2660 
2661 }  // namespace std
2662 
2663 #endif  // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
2664 // gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
2665 // gen_amalgamated begin header: include/perfetto/ext/base/hash.h
2666 /*
2667  * Copyright (C) 2019 The Android Open Source Project
2668  *
2669  * Licensed under the Apache License, Version 2.0 (the "License");
2670  * you may not use this file except in compliance with the License.
2671  * You may obtain a copy of the License at
2672  *
2673  *      http://www.apache.org/licenses/LICENSE-2.0
2674  *
2675  * Unless required by applicable law or agreed to in writing, software
2676  * distributed under the License is distributed on an "AS IS" BASIS,
2677  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2678  * See the License for the specific language governing permissions and
2679  * limitations under the License.
2680  */
2681 
2682 #ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
2683 #define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
2684 
2685 #include <stddef.h>
2686 #include <stdint.h>
2687 #include <type_traits>
2688 
2689 namespace perfetto {
2690 namespace base {
2691 
2692 // A helper class which computes a 64-bit hash of the input data.
2693 // The algorithm used is FNV-1a as it is fast and easy to implement and has
2694 // relatively few collisions.
2695 // WARNING: This hash function should not be used for any cryptographic purpose.
2696 class Hash {
2697  public:
2698   // Creates an empty hash object
Hash()2699   Hash() {}
2700 
2701   // Hashes a numeric value.
2702   template <typename T,
2703             typename std::enable_if<std::is_arithmetic<T>::value>* = nullptr>
Update(T data)2704   void Update(T data) {
2705     Update(reinterpret_cast<const char*>(&data), sizeof(data));
2706   }
2707 
2708   // Hashes a byte array.
Update(const char * data,size_t size)2709   void Update(const char* data, size_t size) {
2710     for (size_t i = 0; i < size; i++) {
2711       result_ ^= static_cast<uint8_t>(data[i]);
2712       result_ *= kFnv1a64Prime;
2713     }
2714   }
2715 
digest()2716   uint64_t digest() { return result_; }
2717 
2718  private:
2719   static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
2720   static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
2721 
2722   uint64_t result_ = kFnv1a64OffsetBasis;
2723 };
2724 
2725 }  // namespace base
2726 }  // namespace perfetto
2727 
2728 #endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
2729 /*
2730  * Copyright (C) 2018 The Android Open Source Project
2731  *
2732  * Licensed under the Apache License, Version 2.0 (the "License");
2733  * you may not use this file except in compliance with the License.
2734  * You may obtain a copy of the License at
2735  *
2736  *      http://www.apache.org/licenses/LICENSE-2.0
2737  *
2738  * Unless required by applicable law or agreed to in writing, software
2739  * distributed under the License is distributed on an "AS IS" BASIS,
2740  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2741  * See the License for the specific language governing permissions and
2742  * limitations under the License.
2743  */
2744 
2745 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
2746 #define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
2747 
2748 #include <string.h>
2749 
2750 #include <algorithm>
2751 #include <string>
2752 
2753 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2754 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2755 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
2756 
2757 namespace perfetto {
2758 namespace base {
2759 
2760 // A string-like object that refers to a non-owned piece of memory.
2761 // Strings are internally NOT null terminated.
2762 class StringView {
2763  public:
2764   static constexpr size_t npos = static_cast<size_t>(-1);
2765 
StringView()2766   StringView() : data_(nullptr), size_(0) {}
2767   StringView(const StringView&) = default;
2768   StringView& operator=(const StringView&) = default;
StringView(const char * data,size_t size)2769   StringView(const char* data, size_t size) : data_(data), size_(size) {
2770     PERFETTO_DCHECK(size == 0 || data != nullptr);
2771   }
2772 
2773   // Allow implicit conversion from any class that has a |data| and |size| field
2774   // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
2775   template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
StringView(const T & x)2776   StringView(const T& x) : StringView(x.data, x.size) {
2777     PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
2778   }
2779 
2780   // Creates a StringView from a null-terminated C string.
2781   // Deliberately not "explicit".
StringView(const char * cstr)2782   StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
2783     PERFETTO_DCHECK(cstr != nullptr);
2784   }
2785 
2786   // This instead has to be explicit, as creating a StringView out of a
2787   // std::string can be subtle.
StringView(const std::string & str)2788   explicit StringView(const std::string& str)
2789       : data_(str.data()), size_(str.size()) {}
2790 
empty() const2791   bool empty() const { return size_ == 0; }
size() const2792   size_t size() const { return size_; }
data() const2793   const char* data() const { return data_; }
begin() const2794   const char* begin() const { return data_; }
end() const2795   const char* end() const { return data_ + size_; }
2796 
at(size_t pos) const2797   char at(size_t pos) const {
2798     PERFETTO_DCHECK(pos < size_);
2799     return data_[pos];
2800   }
2801 
find(char c,size_t start_pos=0) const2802   size_t find(char c, size_t start_pos = 0) const {
2803     for (size_t i = start_pos; i < size_; ++i) {
2804       if (data_[i] == c)
2805         return i;
2806     }
2807     return npos;
2808   }
2809 
find(const StringView & str,size_t start_pos=0) const2810   size_t find(const StringView& str, size_t start_pos = 0) const {
2811     if (start_pos > size())
2812       return npos;
2813     auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
2814     size_t pos = static_cast<size_t>(it - begin());
2815     return pos + str.size() <= size() ? pos : npos;
2816   }
2817 
find(const char * str,size_t start_pos=0) const2818   size_t find(const char* str, size_t start_pos = 0) const {
2819     return find(StringView(str), start_pos);
2820   }
2821 
rfind(char c) const2822   size_t rfind(char c) const {
2823     for (size_t i = size_; i > 0; --i) {
2824       if (data_[i - 1] == c)
2825         return i - 1;
2826     }
2827     return npos;
2828   }
2829 
substr(size_t pos,size_t count=npos) const2830   StringView substr(size_t pos, size_t count = npos) const {
2831     if (pos >= size_)
2832       return StringView("", 0);
2833     size_t rcount = std::min(count, size_ - pos);
2834     return StringView(data_ + pos, rcount);
2835   }
2836 
CaseInsensitiveEq(const StringView & other)2837   bool CaseInsensitiveEq(const StringView& other) {
2838     if (size() != other.size())
2839       return false;
2840     if (size() == 0)
2841       return true;
2842 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2843     return _strnicmp(data(), other.data(), size()) == 0;
2844 #else
2845     return strncasecmp(data(), other.data(), size()) == 0;
2846 #endif
2847   }
2848 
ToStdString() const2849   std::string ToStdString() const {
2850     return data_ == nullptr ? "" : std::string(data_, size_);
2851   }
2852 
Hash() const2853   uint64_t Hash() const {
2854     base::Hash hasher;
2855     hasher.Update(data_, size_);
2856     return hasher.digest();
2857   }
2858 
2859  private:
2860   const char* data_ = nullptr;
2861   size_t size_ = 0;
2862 };
2863 
operator ==(const StringView & x,const StringView & y)2864 inline bool operator==(const StringView& x, const StringView& y) {
2865   if (x.size() != y.size())
2866     return false;
2867   if (x.size() == 0)
2868     return true;
2869   return memcmp(x.data(), y.data(), x.size()) == 0;
2870 }
2871 
operator !=(const StringView & x,const StringView & y)2872 inline bool operator!=(const StringView& x, const StringView& y) {
2873   return !(x == y);
2874 }
2875 
operator <(const StringView & x,const StringView & y)2876 inline bool operator<(const StringView& x, const StringView& y) {
2877   auto size = std::min(x.size(), y.size());
2878   if (size == 0)
2879     return x.size() < y.size();
2880   int result = memcmp(x.data(), y.data(), size);
2881   return result < 0 || (result == 0 && x.size() < y.size());
2882 }
2883 
operator >=(const StringView & x,const StringView & y)2884 inline bool operator>=(const StringView& x, const StringView& y) {
2885   return !(x < y);
2886 }
2887 
operator >(const StringView & x,const StringView & y)2888 inline bool operator>(const StringView& x, const StringView& y) {
2889   return y < x;
2890 }
2891 
operator <=(const StringView & x,const StringView & y)2892 inline bool operator<=(const StringView& x, const StringView& y) {
2893   return !(y < x);
2894 }
2895 
2896 }  // namespace base
2897 }  // namespace perfetto
2898 
2899 namespace std {
2900 
2901 template <>
2902 struct hash<::perfetto::base::StringView> {
operator ()std::hash2903   size_t operator()(const ::perfetto::base::StringView& sv) const {
2904     return static_cast<size_t>(sv.Hash());
2905   }
2906 };
2907 
2908 }  // namespace std
2909 
2910 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
2911 /*
2912  * Copyright (C) 2018 The Android Open Source Project
2913  *
2914  * Licensed under the Apache License, Version 2.0 (the "License");
2915  * you may not use this file except in compliance with the License.
2916  * You may obtain a copy of the License at
2917  *
2918  *      http://www.apache.org/licenses/LICENSE-2.0
2919  *
2920  * Unless required by applicable law or agreed to in writing, software
2921  * distributed under the License is distributed on an "AS IS" BASIS,
2922  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2923  * See the License for the specific language governing permissions and
2924  * limitations under the License.
2925  */
2926 
2927 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
2928 #define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
2929 
2930 #include <string>
2931 #include <vector>
2932 
2933 #include <inttypes.h>
2934 #include <stdlib.h>
2935 
2936 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
2937 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
2938 
2939 namespace perfetto {
2940 namespace base {
2941 
Lowercase(char c)2942 inline char Lowercase(char c) {
2943   return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
2944 }
2945 
Uppercase(char c)2946 inline char Uppercase(char c) {
2947   return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
2948 }
2949 
CStringToUInt32(const char * s,int base=10)2950 inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
2951   char* endptr = nullptr;
2952   auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
2953   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2954 }
2955 
CStringToInt32(const char * s,int base=10)2956 inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
2957   char* endptr = nullptr;
2958   auto value = static_cast<int32_t>(strtol(s, &endptr, base));
2959   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2960 }
2961 
2962 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
CStringToInt64(const char * s,int base=10)2963 inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
2964   char* endptr = nullptr;
2965   auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
2966   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2967 }
2968 
CStringToUInt64(const char * s,int base=10)2969 inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
2970   char* endptr = nullptr;
2971   auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
2972   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
2973 }
2974 
CStringToDouble(const char * s)2975 inline Optional<double> CStringToDouble(const char* s) {
2976   char* endptr = nullptr;
2977   double value = strtod(s, &endptr);
2978   Optional<double> result(base::nullopt);
2979   if (*s != '\0' && *endptr == '\0')
2980     result = value;
2981   return result;
2982 }
2983 
StringToUInt32(const std::string & s,int base=10)2984 inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
2985   return CStringToUInt32(s.c_str(), base);
2986 }
2987 
StringToInt32(const std::string & s,int base=10)2988 inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
2989   return CStringToInt32(s.c_str(), base);
2990 }
2991 
StringToUInt64(const std::string & s,int base=10)2992 inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
2993   return CStringToUInt64(s.c_str(), base);
2994 }
2995 
StringToInt64(const std::string & s,int base=10)2996 inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
2997   return CStringToInt64(s.c_str(), base);
2998 }
2999 
StringToDouble(const std::string & s)3000 inline Optional<double> StringToDouble(const std::string& s) {
3001   return CStringToDouble(s.c_str());
3002 }
3003 
3004 bool StartsWith(const std::string& str, const std::string& prefix);
3005 bool EndsWith(const std::string& str, const std::string& suffix);
3006 bool Contains(const std::string& haystack, const std::string& needle);
3007 size_t Find(const StringView& needle, const StringView& haystack);
3008 bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
3009 std::string Join(const std::vector<std::string>& parts,
3010                  const std::string& delim);
3011 std::vector<std::string> SplitString(const std::string& text,
3012                                      const std::string& delimiter);
3013 std::string StripPrefix(const std::string& str, const std::string& prefix);
3014 std::string StripSuffix(const std::string& str, const std::string& suffix);
3015 std::string ToLower(const std::string& str);
3016 std::string ToUpper(const std::string& str);
3017 std::string StripChars(const std::string& str,
3018                        const std::string& chars,
3019                        char replacement);
3020 std::string ToHex(const char* data, size_t size);
ToHex(const std::string & s)3021 inline std::string ToHex(const std::string& s) {
3022   return ToHex(s.c_str(), s.size());
3023 }
3024 std::string IntToHexString(uint32_t number);
3025 std::string ReplaceAll(std::string str,
3026                        const std::string& to_replace,
3027                        const std::string& replacement);
3028 std::string TrimLeading(const std::string& str);
3029 
3030 }  // namespace base
3031 }  // namespace perfetto
3032 
3033 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
3034 /*
3035  * Copyright (C) 2018 The Android Open Source Project
3036  *
3037  * Licensed under the Apache License, Version 2.0 (the "License");
3038  * you may not use this file except in compliance with the License.
3039  * You may obtain a copy of the License at
3040  *
3041  *      http://www.apache.org/licenses/LICENSE-2.0
3042  *
3043  * Unless required by applicable law or agreed to in writing, software
3044  * distributed under the License is distributed on an "AS IS" BASIS,
3045  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3046  * See the License for the specific language governing permissions and
3047  * limitations under the License.
3048  */
3049 
3050 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
3051 
3052 #include <string.h>
3053 
3054 #include <algorithm>
3055 
3056 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3057 
3058 namespace perfetto {
3059 namespace base {
3060 
StartsWith(const std::string & str,const std::string & prefix)3061 bool StartsWith(const std::string& str, const std::string& prefix) {
3062   return str.compare(0, prefix.length(), prefix) == 0;
3063 }
3064 
EndsWith(const std::string & str,const std::string & suffix)3065 bool EndsWith(const std::string& str, const std::string& suffix) {
3066   if (suffix.size() > str.size())
3067     return false;
3068   return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
3069 }
3070 
Contains(const std::string & haystack,const std::string & needle)3071 bool Contains(const std::string& haystack, const std::string& needle) {
3072   return haystack.find(needle) != std::string::npos;
3073 }
3074 
Find(const StringView & needle,const StringView & haystack)3075 size_t Find(const StringView& needle, const StringView& haystack) {
3076   if (needle.size() == 0)
3077     return 0;
3078   if (needle.size() > haystack.size())
3079     return std::string::npos;
3080   for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
3081     if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
3082       return i;
3083   }
3084   return std::string::npos;
3085 }
3086 
CaseInsensitiveEqual(const std::string & first,const std::string & second)3087 bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
3088   return first.size() == second.size() &&
3089          std::equal(
3090              first.begin(), first.end(), second.begin(),
3091              [](char a, char b) { return Lowercase(a) == Lowercase(b); });
3092 }
3093 
Join(const std::vector<std::string> & parts,const std::string & delim)3094 std::string Join(const std::vector<std::string>& parts,
3095                  const std::string& delim) {
3096   std::string acc;
3097   for (size_t i = 0; i < parts.size(); ++i) {
3098     acc += parts[i];
3099     if (i + 1 != parts.size()) {
3100       acc += delim;
3101     }
3102   }
3103   return acc;
3104 }
3105 
SplitString(const std::string & text,const std::string & delimiter)3106 std::vector<std::string> SplitString(const std::string& text,
3107                                      const std::string& delimiter) {
3108   PERFETTO_CHECK(!delimiter.empty());
3109 
3110   std::vector<std::string> output;
3111   size_t start = 0;
3112   size_t next;
3113   for (;;) {
3114     next = std::min(text.find(delimiter, start), text.size());
3115     if (next > start)
3116       output.emplace_back(&text[start], next - start);
3117     start = next + delimiter.size();
3118     if (start >= text.size())
3119       break;
3120   }
3121   return output;
3122 }
3123 
StripPrefix(const std::string & str,const std::string & prefix)3124 std::string StripPrefix(const std::string& str, const std::string& prefix) {
3125   return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
3126 }
3127 
StripSuffix(const std::string & str,const std::string & suffix)3128 std::string StripSuffix(const std::string& str, const std::string& suffix) {
3129   return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
3130                                : str;
3131 }
3132 
ToUpper(const std::string & str)3133 std::string ToUpper(const std::string& str) {
3134   // Don't use toupper(), it depends on the locale.
3135   std::string res(str);
3136   auto end = res.end();
3137   for (auto c = res.begin(); c != end; ++c)
3138     *c = Uppercase(*c);
3139   return res;
3140 }
3141 
ToLower(const std::string & str)3142 std::string ToLower(const std::string& str) {
3143   // Don't use tolower(), it depends on the locale.
3144   std::string res(str);
3145   auto end = res.end();
3146   for (auto c = res.begin(); c != end; ++c)
3147     *c = Lowercase(*c);
3148   return res;
3149 }
3150 
ToHex(const char * data,size_t size)3151 std::string ToHex(const char* data, size_t size) {
3152   std::string hex(2 * size + 1, 'x');
3153   for (size_t i = 0; i < size; ++i) {
3154     // snprintf prints 3 characters, the two hex digits and a null byte. As we
3155     // write left to right, we keep overwriting the nullbytes, except for the
3156     // last call to snprintf.
3157     snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
3158   }
3159   // Remove the trailing nullbyte produced by the last snprintf.
3160   hex.resize(2 * size);
3161   return hex;
3162 }
3163 
IntToHexString(uint32_t number)3164 std::string IntToHexString(uint32_t number) {
3165   size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
3166   std::string buf;
3167   buf.resize(max_size);
3168   auto final_size = snprintf(&buf[0], max_size, "0x%02x", number);
3169   PERFETTO_DCHECK(final_size >= 0);
3170   buf.resize(static_cast<size_t>(final_size));  // Cuts off the final null byte.
3171   return buf;
3172 }
3173 
StripChars(const std::string & str,const std::string & chars,char replacement)3174 std::string StripChars(const std::string& str,
3175                        const std::string& chars,
3176                        char replacement) {
3177   std::string res(str);
3178   const char* start = res.c_str();
3179   const char* remove = chars.c_str();
3180   for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
3181     res[static_cast<uintptr_t>(c - start)] = replacement;
3182   return res;
3183 }
3184 
ReplaceAll(std::string str,const std::string & to_replace,const std::string & replacement)3185 std::string ReplaceAll(std::string str,
3186                        const std::string& to_replace,
3187                        const std::string& replacement) {
3188   PERFETTO_CHECK(!to_replace.empty());
3189   size_t pos = 0;
3190   while ((pos = str.find(to_replace, pos)) != std::string::npos) {
3191     str.replace(pos, to_replace.length(), replacement);
3192     pos += replacement.length();
3193   }
3194   return str;
3195 }
3196 
TrimLeading(const std::string & str)3197 std::string TrimLeading(const std::string& str) {
3198   size_t idx = str.find_first_not_of(' ');
3199   return idx == std::string::npos ? str : str.substr(idx);
3200 }
3201 
3202 }  // namespace base
3203 }  // namespace perfetto
3204 // gen_amalgamated begin source: src/base/string_view.cc
3205 /*
3206  * Copyright (C) 2019 The Android Open Source Project
3207  *
3208  * Licensed under the Apache License, Version 2.0 (the "License");
3209  * you may not use this file except in compliance with the License.
3210  * You may obtain a copy of the License at
3211  *
3212  *      http://www.apache.org/licenses/LICENSE-2.0
3213  *
3214  * Unless required by applicable law or agreed to in writing, software
3215  * distributed under the License is distributed on an "AS IS" BASIS,
3216  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3217  * See the License for the specific language governing permissions and
3218  * limitations under the License.
3219  */
3220 
3221 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
3222 
3223 namespace perfetto {
3224 namespace base {
3225 
3226 // static
3227 constexpr size_t StringView::npos;
3228 
3229 }  // namespace base
3230 }  // namespace perfetto
3231 // gen_amalgamated begin source: src/base/subprocess.cc
3232 // gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
3233 // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
3234 /*
3235  * Copyright (C) 2018 The Android Open Source Project
3236  *
3237  * Licensed under the Apache License, Version 2.0 (the "License");
3238  * you may not use this file except in compliance with the License.
3239  * You may obtain a copy of the License at
3240  *
3241  *      http://www.apache.org/licenses/LICENSE-2.0
3242  *
3243  * Unless required by applicable law or agreed to in writing, software
3244  * distributed under the License is distributed on an "AS IS" BASIS,
3245  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3246  * See the License for the specific language governing permissions and
3247  * limitations under the License.
3248  */
3249 
3250 #ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
3251 #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
3252 
3253 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
3254 
3255 namespace perfetto {
3256 namespace base {
3257 
3258 class Pipe {
3259  public:
3260   enum Flags {
3261     kBothBlock = 0,
3262     kBothNonBlock,
3263     kRdNonBlock,
3264     kWrNonBlock,
3265   };
3266 
3267   static Pipe Create(Flags = kBothBlock);
3268 
3269   Pipe();
3270   Pipe(Pipe&&) noexcept;
3271   Pipe& operator=(Pipe&&);
3272 
3273   ScopedFile rd;
3274   ScopedFile wr;
3275 };
3276 
3277 }  // namespace base
3278 }  // namespace perfetto
3279 
3280 #endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
3281 /*
3282  * Copyright (C) 2020 The Android Open Source Project
3283  *
3284  * Licensed under the Apache License, Version 2.0 (the "License");
3285  * you may not use this file except in compliance with the License.
3286  * You may obtain a copy of the License at
3287  *
3288  *      http://www.apache.org/licenses/LICENSE-2.0
3289  *
3290  * Unless required by applicable law or agreed to in writing, software
3291  * distributed under the License is distributed on an "AS IS" BASIS,
3292  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3293  * See the License for the specific language governing permissions and
3294  * limitations under the License.
3295  */
3296 
3297 #ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
3298 #define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
3299 
3300 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3301 
3302 // This is a #if as opposite to a GN condition, because GN conditions aren't propagated when
3303 // translating to Bazel or other build systems, as they get resolved at translation time. Without
3304 // this, the Bazel build breaks on Windows.
3305 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
3306     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
3307     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
3308 #define PERFETTO_HAS_SUBPROCESS() 1
3309 #else
3310 #define PERFETTO_HAS_SUBPROCESS() 0
3311 #endif
3312 
3313 #include <functional>
3314 #include <initializer_list>
3315 #include <string>
3316 #include <thread>
3317 #include <vector>
3318 
3319 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3320 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
3321 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
3322 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
3323 
3324 namespace perfetto {
3325 namespace base {
3326 
3327 // Handles creation and lifecycle management of subprocesses, taking care of
3328 // all subtleties involved in handling processes on UNIX.
3329 // This class allows to deal with macro two use-cases:
3330 // 1) fork() + exec() equivalent: for spawning a brand new process image.
3331 //    This happens when |args.exec_cmd| is not empty.
3332 //    This is safe to use even in a multi-threaded environment.
3333 // 2) fork(): for spawning a process and running a function.
3334 //    This happens when |args.entrypoint_for_testing| is not empty.
3335 //    This is intended only for tests as it is extremely subtle.
3336 //    This mode must be used with extreme care. Before the entrypoint is
3337 //    invoked all file descriptors other than stdin/out/err and the ones
3338 //    specified in |args.preserve_fds| will be closed, to avoid each process
3339 //    retaining a dupe of other subprocesses pipes. This however means that
3340 //    any non trivial calls (including logging) must be avoided as they might
3341 //    refer to FDs that are now closed. The entrypoint should really be used
3342 //    just to signal a pipe or similar for synchronizing sequencing in tests.
3343 
3344 //
3345 // This class allows to control stdin/out/err pipe redirection and takes care
3346 // of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
3347 // fashion of python's subprocess.Communicate()
3348 // stdin: is always piped and closed once the |args.input| buffer is written.
3349 // stdout/err can be either:
3350 //   - dup()ed onto the parent process stdout/err.
3351 //   - redirected onto /dev/null.
3352 //   - piped onto a buffer (see output() method). There is only one output
3353 //     buffer in total. If both stdout and stderr are set to kBuffer mode, they
3354 //     will be merged onto the same. There doesn't seem any use case where they
3355 //     are needed distinctly.
3356 //
3357 // Some caveats worth mentioning:
3358 // - It always waitpid()s, to avoid leaving zombies around. If the process is
3359 //   not terminated by the time the destructor is reached, the dtor will
3360 //   send a SIGKILL and wait for the termination.
3361 // - After fork()-ing it will close all file descriptors, preserving only
3362 //   stdin/out/err and the fds listed in |args.preserve_fds|.
3363 // - On Linux/Android, the child process will be SIGKILL-ed if the calling
3364 //   thread exists, even if the Subprocess is std::move()-d onto another thread.
3365 //   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
3366 //   child processes are leaked in the case of a crash of the parent (frequent
3367 //   in tests). However, the child process might still be leaked if execing
3368 //   a setuid/setgid binary (see man 2 prctl).
3369 //
3370 // Usage:
3371 // base::Subprocess p({"/bin/cat", "-"});
3372 // (or equivalently:
3373 //     base::Subprocess p;
3374 //     p.args.exec_cmd.push_back("/bin/cat");
3375 //     p.args.exec_cmd.push_back("-");
3376 //  )
3377 // p.args.stdout_mode = base::Subprocess::kBuffer;
3378 // p.args.stderr_mode = base::Subprocess::kInherit;
3379 // p.args.input = "stdin contents";
3380 // p.Call();
3381 // (or equivalently:
3382 //     p.Start();
3383 //     p.Wait();
3384 // )
3385 // EXPECT_EQ(p.status(), base::Subprocess::kExited);
3386 // EXPECT_EQ(p.returncode(), 0);
3387 class Subprocess {
3388  public:
3389   enum Status {
3390     kNotStarted = 0,  // Before calling Start() or Call().
3391     kRunning,         // After calling Start(), before Wait().
3392     kExited,          // The subprocess exited (either succesully or not).
3393     kKilledBySignal,  // The subprocess has been killed by a signal.
3394   };
3395 
3396   enum OutputMode {
3397     kInherit = 0,  // Inherit's the caller process stdout/stderr.
3398     kDevNull,      // dup() onto /dev/null
3399     kBuffer,       // dup() onto a pipe and move it into the output() buffer.
3400     kFd,           // dup() onto the passed args.fd.
3401   };
3402 
3403   // Input arguments for configuring the subprocess behavior.
3404   struct Args {
Argsperfetto::base::Subprocess::Args3405     Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
3406     Args(Args&&) noexcept;
3407     Args& operator=(Args&&);
3408     // If non-empty this will cause an exec() when Start()/Call() are called.
3409     std::vector<std::string> exec_cmd;
3410 
3411     // If non-empty, it changes the argv[0] argument passed to exec. If
3412     // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
3413     // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
3414     std::string argv0_override;
3415 
3416     // If non-empty this will be invoked on the fork()-ed child process, after
3417     // stdin/out/err has been redirected and all other file descriptor are
3418     // closed.
3419     // It is valid to specify both |exec_cmd| AND |entrypoint_for_testing|.
3420     // In this case |entrypoint_for_testing| will be invoked just before the
3421     // exec() call, but after having closed all fds % stdin/out/err.
3422     // This is for synchronization barriers in tests.
3423     std::function<void()> entrypoint_for_testing;
3424 
3425     // If non-empty, replaces the environment passed to exec().
3426     std::vector<std::string> env;
3427 
3428     // The file descriptors in this list will not be closed.
3429     std::vector<int> preserve_fds;
3430 
3431     // The data to push in the child process stdin.
3432     std::string input;
3433 
3434     OutputMode stdout_mode = kInherit;
3435     OutputMode stderr_mode = kInherit;
3436 
3437     base::ScopedFile out_fd;
3438 
3439     // Returns " ".join(exec_cmd), quoting arguments.
3440     std::string GetCmdString() const;
3441   };
3442 
3443   struct ResourceUsage {
3444     uint32_t cpu_utime_ms = 0;
3445     uint32_t cpu_stime_ms = 0;
3446     uint32_t max_rss_kb = 0;
3447     uint32_t min_page_faults = 0;
3448     uint32_t maj_page_faults = 0;
3449     uint32_t vol_ctx_switch = 0;
3450     uint32_t invol_ctx_switch = 0;
3451 
cpu_time_msperfetto::base::Subprocess::ResourceUsage3452     uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
3453   };
3454 
3455   explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
3456   Subprocess(Subprocess&&) noexcept;
3457   Subprocess& operator=(Subprocess&&);
3458   ~Subprocess();  // It will KillAndWaitForTermination() if still alive.
3459 
3460   // Starts the subprocess but doesn't wait for its termination. The caller
3461   // is expected to either call Wait() or Poll() after this call.
3462   void Start();
3463 
3464   // Wait for process termination. Can be called more than once.
3465   // Args:
3466   //   |timeout_ms| = 0: wait indefinitely.
3467   //   |timeout_ms| > 0: wait for at most |timeout_ms|.
3468   // Returns:
3469   //  True: The process terminated. See status() and returncode().
3470   //  False: Timeout reached, the process is still running. In this case the
3471   //         process will be left in the kRunning state.
3472   bool Wait(int timeout_ms = 0);
3473 
3474   // Equivalent of Start() + Wait();
3475   // Returns true if the process exited cleanly with return code 0. False in
3476   // any othe case.
3477   bool Call(int timeout_ms = 0);
3478 
3479   Status Poll();
3480 
3481   // Sends a signal (SIGKILL if not specified) and wait for process termination.
3482   void KillAndWaitForTermination(int sig_num = 0);
3483 
pid() const3484   PlatformProcessId pid() const { return s_.pid; }
3485 
3486   // The accessors below are updated only after a call to Poll(), Wait() or
3487   // KillAndWaitForTermination().
3488   // In most cases you want to call Poll() rather than these accessors.
3489 
status() const3490   Status status() const { return s_.status; }
returncode() const3491   int returncode() const { return s_.returncode; }
3492 
3493   // This contains both stdout and stderr (if the corresponding _mode ==
3494   // kBuffer). It's non-const so the caller can std::move() it.
output()3495   std::string& output() { return s_.output; }
rusage() const3496   const ResourceUsage& rusage() const { return *s_.rusage; }
3497 
3498   Args args;
3499 
3500  private:
3501   Subprocess(const Subprocess&) = delete;
3502   Subprocess& operator=(const Subprocess&) = delete;
3503   void TryPushStdin();
3504   void TryReadStdoutAndErr();
3505   void TryReadExitStatus();
3506   void KillAtMostOnce();
3507   bool PollInternal(int poll_timeout_ms);
3508 
3509   // This is to deal robustly with the move operators, without having to
3510   // manually maintain member-wise move instructions.
3511   struct MovableState {
3512     base::Pipe stdin_pipe;
3513     base::Pipe stdouterr_pipe;
3514     base::Pipe exit_status_pipe;
3515     PlatformProcessId pid;
3516     size_t input_written = 0;
3517     Status status = kNotStarted;
3518     int returncode = -1;
3519     std::string output;  // Stdin+stderr. Only when kBuffer.
3520     std::thread waitpid_thread;
3521     std::unique_ptr<ResourceUsage> rusage;
3522   };
3523 
3524   MovableState s_;
3525 };
3526 
3527 }  // namespace base
3528 }  // namespace perfetto
3529 
3530 #endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
3531 /*
3532  * Copyright (C) 2020 The Android Open Source Project
3533  *
3534  * Licensed under the Apache License, Version 2.0 (the "License");
3535  * you may not use this file except in compliance with the License.
3536  * You may obtain a copy of the License at
3537  *
3538  *      http://www.apache.org/licenses/LICENSE-2.0
3539  *
3540  * Unless required by applicable law or agreed to in writing, software
3541  * distributed under the License is distributed on an "AS IS" BASIS,
3542  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3543  * See the License for the specific language governing permissions and
3544  * limitations under the License.
3545  */
3546 
3547 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
3548 
3549 #if PERFETTO_HAS_SUBPROCESS()
3550 
3551 #include <poll.h>
3552 #include <signal.h>
3553 #include <stdio.h>
3554 #include <sys/resource.h>
3555 #include <sys/types.h>
3556 #include <sys/wait.h>
3557 #include <unistd.h>
3558 
3559 #include <algorithm>
3560 #include <thread>
3561 #include <tuple>
3562 
3563 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3564 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3565 // gen_amalgamated expanded: #include "perfetto/base/time.h"
3566 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
3567 
3568 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3569     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3570 #include <sys/prctl.h>
3571 #endif
3572 
3573 // In MacOS this is not defined in any header.
3574 extern "C" char** environ;
3575 
3576 namespace perfetto {
3577 namespace base {
3578 
3579 namespace {
3580 
3581 struct ChildProcessArgs {
3582   Subprocess::Args* create_args;
3583   const char* exec_cmd = nullptr;
3584   std::vector<char*> argv;
3585   std::vector<char*> env;
3586   int stdin_pipe_rd = -1;
3587   int stdouterr_pipe_wr = -1;
3588 };
3589 
3590 // Don't add any dynamic allocation in this function. This will be invoked
3591 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)3592 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
3593 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3594     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3595   // In no case we want a child process to outlive its parent process. This is
3596   // relevant for tests, so that a test failure/crash doesn't leave child
3597   // processes around that get reparented to init.
3598   prctl(PR_SET_PDEATHSIG, SIGKILL);
3599 #endif
3600 
3601   auto die = [args](const char* err) __attribute__((noreturn)) {
3602     base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
3603     base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
3604     // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
3605     // "In particular, the value 128 is used to indicate failure to execute
3606     // another program in a subprocess. This convention is not universally
3607     // obeyed, but it is a good idea to follow it in your programs."
3608     _exit(128);
3609   };
3610 
3611   auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
3612     int flags = fcntl(fd, F_GETFD, 0);
3613     if (flags < 0)
3614       die("fcntl(F_GETFD) failed");
3615     flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
3616     if (fcntl(fd, F_SETFD, flags) < 0)
3617       die("fcntl(F_SETFD) failed");
3618   };
3619 
3620   if (getppid() == 1)
3621     die("terminating because parent process died");
3622 
3623   if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
3624     die("Failed to dup2(STDIN)");
3625   close(args->stdin_pipe_rd);
3626 
3627   switch (args->create_args->stdout_mode) {
3628     case Subprocess::kInherit:
3629       break;
3630     case Subprocess::kDevNull: {
3631       if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
3632         die("Failed to dup2(STDOUT)");
3633       break;
3634     }
3635     case Subprocess::kBuffer:
3636       if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
3637         die("Failed to dup2(STDOUT)");
3638       break;
3639     case Subprocess::kFd:
3640       if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
3641         die("Failed to dup2(STDOUT)");
3642       break;
3643   }
3644 
3645   switch (args->create_args->stderr_mode) {
3646     case Subprocess::kInherit:
3647       break;
3648     case Subprocess::kDevNull: {
3649       if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
3650         die("Failed to dup2(STDERR)");
3651       break;
3652     }
3653     case Subprocess::kBuffer:
3654       if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
3655         die("Failed to dup2(STDERR)");
3656       break;
3657     case Subprocess::kFd:
3658       if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
3659         die("Failed to dup2(STDERR)");
3660       break;
3661   }
3662 
3663   // Close all FDs % stdin/out/err and the ones that the client explicitly
3664   // asked to retain. The reason for this is twofold:
3665   // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
3666   //    that didn't get marked as O_CLOEXEC by accident.
3667   // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
3668   //    that would prevent the parent process to receive EOFs (tests usually use
3669   //    pipes as a synchronization mechanism between subprocesses).
3670   const auto& preserve_fds = args->create_args->preserve_fds;
3671   for (int i = 0; i < 512; i++) {
3672     if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
3673         i != args->stdouterr_pipe_wr &&
3674         !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
3675       close(i);
3676     }
3677   }
3678 
3679   // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
3680   // to be preserved after the exec().
3681   set_fd_close_on_exec(STDIN_FILENO, false);
3682   set_fd_close_on_exec(STDOUT_FILENO, false);
3683   set_fd_close_on_exec(STDERR_FILENO, false);
3684 
3685   // If the caller specified a std::function entrypoint, run that first.
3686   if (args->create_args->entrypoint_for_testing)
3687     args->create_args->entrypoint_for_testing();
3688 
3689   // If the caller specified only an entrypoint, without any args, exit now.
3690   // Otherwise proceed with the exec() below.
3691   if (!args->exec_cmd)
3692     _exit(0);
3693 
3694   // If |args[0]| is a path use execv() (which takes a path), othewise use
3695   // exevp(), which uses the shell and follows PATH.
3696   if (strchr(args->exec_cmd, '/')) {
3697     char** env = args->env.empty() ? environ : args->env.data();
3698     execve(args->exec_cmd, args->argv.data(), env);
3699   } else {
3700     // There is no execvpe() on Mac.
3701     if (!args->env.empty())
3702       die("A full path is required for |exec_cmd| when setting |env|");
3703     execvp(args->exec_cmd, args->argv.data());
3704   }
3705 
3706   // Reached only if execv fails.
3707   die("execve() failed");
3708 }
3709 
3710 }  // namespace
3711 
3712 Subprocess::Args::Args(Args&&) noexcept = default;
3713 Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
3714 
Subprocess(std::initializer_list<std::string> a)3715 Subprocess::Subprocess(std::initializer_list<std::string> a) : args(a) {
3716   s_.rusage.reset(new ResourceUsage());
3717 }
3718 
Subprocess(Subprocess && other)3719 Subprocess::Subprocess(Subprocess&& other) noexcept {
3720   static_assert(sizeof(Subprocess) == sizeof(std::tuple<MovableState, Args>),
3721                 "base::Subprocess' move ctor needs updating");
3722   s_ = std::move(other.s_);
3723   args = std::move(other.args);
3724 
3725   // Reset the state of the moved-from object.
3726   other.s_.status = kNotStarted;  // So the dtor doesn't try to kill().
3727   other.~Subprocess();
3728   new (&other) Subprocess();
3729 }
3730 
operator =(Subprocess && other)3731 Subprocess& Subprocess::operator=(Subprocess&& other) {
3732   this->~Subprocess();
3733   new (this) Subprocess(std::move(other));
3734   return *this;
3735 }
3736 
~Subprocess()3737 Subprocess::~Subprocess() {
3738   if (s_.status == kRunning)
3739     KillAndWaitForTermination();
3740   PERFETTO_CHECK(!s_.waitpid_thread.joinable());
3741 }
3742 
Start()3743 void Subprocess::Start() {
3744   ChildProcessArgs proc_args;
3745   proc_args.create_args = &args;
3746 
3747   // Setup argv.
3748   if (!args.exec_cmd.empty()) {
3749     proc_args.exec_cmd = args.exec_cmd[0].c_str();
3750     for (const std::string& arg : args.exec_cmd)
3751       proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
3752     proc_args.argv.push_back(nullptr);
3753 
3754     if (!args.argv0_override.empty())
3755       proc_args.argv[0] = const_cast<char*>(args.argv0_override.c_str());
3756   }
3757 
3758   // Setup env.
3759   if (!args.env.empty()) {
3760     for (const std::string& str : args.env)
3761       proc_args.env.push_back(const_cast<char*>(str.c_str()));
3762     proc_args.env.push_back(nullptr);
3763   }
3764 
3765   // Setup the pipes for stdin/err redirection.
3766   s_.stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
3767   proc_args.stdin_pipe_rd = *s_.stdin_pipe.rd;
3768   s_.stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
3769   proc_args.stdouterr_pipe_wr = *s_.stdouterr_pipe.wr;
3770 
3771   // Spawn the child process that will exec().
3772   s_.pid = fork();
3773   PERFETTO_CHECK(s_.pid >= 0);
3774   if (s_.pid == 0) {
3775     // Close the parent-ends of the pipes.
3776     s_.stdin_pipe.wr.reset();
3777     s_.stdouterr_pipe.rd.reset();
3778     ChildProcess(&proc_args);
3779     // ChildProcess() doesn't return, not even in case of failures.
3780     PERFETTO_FATAL("not reached");
3781   }
3782 
3783   s_.status = kRunning;
3784 
3785   // Close the child-end of the pipes.
3786   // Deliberately NOT closing the s_.stdin_pipe.rd. This is to avoid crashing
3787   // with a SIGPIPE if the process exits without consuming its stdin, while
3788   // the parent tries to write() on the other end of the stdin pipe.
3789   s_.stdouterr_pipe.wr.reset();
3790 
3791   // Spawn a thread that is blocked on waitpid() and writes the termination
3792   // status onto a pipe. The problem here is that waipid() doesn't have a
3793   // timeout option and can't be passed to poll(). The alternative would be
3794   // using a SIGCHLD handler, but anecdotally signal handlers introduce more
3795   // problems than what they solve.
3796   s_.exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
3797 
3798   // Both ends of the pipe are closed after the thread.join().
3799   int pid = s_.pid;
3800   int exit_status_pipe_wr = s_.exit_status_pipe.wr.release();
3801   auto* rusage = s_.rusage.get();
3802   s_.waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
3803     int pid_stat = -1;
3804     struct rusage usg {};
3805     int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
3806     PERFETTO_CHECK(wait_res == pid);
3807 
3808     auto tv_to_ms = [](const struct timeval& tv) {
3809       return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
3810     };
3811     rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
3812     rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
3813     rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
3814     rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
3815     rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
3816     rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
3817     rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
3818 
3819     base::ignore_result(PERFETTO_EINTR(
3820         write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
3821     PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
3822   });
3823 }
3824 
Poll()3825 Subprocess::Status Subprocess::Poll() {
3826   if (s_.status != kRunning)
3827     return s_.status;  // Nothing to poll.
3828   while (PollInternal(0 /* don't block*/)) {
3829   }
3830   return s_.status;
3831 }
3832 
3833 // |timeout_ms| semantic:
3834 //   -1: Block indefinitely.
3835 //    0: Don't block, return immediately.
3836 //   >0: Block for at most X ms.
3837 // Returns:
3838 //  True: Read at least one fd (so there might be more queued).
3839 //  False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)3840 bool Subprocess::PollInternal(int poll_timeout_ms) {
3841   struct pollfd fds[3]{};
3842   size_t num_fds = 0;
3843   if (s_.exit_status_pipe.rd) {
3844     fds[num_fds].fd = *s_.exit_status_pipe.rd;
3845     fds[num_fds].events = POLLIN;
3846     num_fds++;
3847   }
3848   if (s_.stdouterr_pipe.rd) {
3849     fds[num_fds].fd = *s_.stdouterr_pipe.rd;
3850     fds[num_fds].events = POLLIN;
3851     num_fds++;
3852   }
3853   if (s_.stdin_pipe.wr) {
3854     fds[num_fds].fd = *s_.stdin_pipe.wr;
3855     fds[num_fds].events = POLLOUT;
3856     num_fds++;
3857   }
3858 
3859   if (num_fds == 0)
3860     return false;
3861 
3862   auto nfds = static_cast<nfds_t>(num_fds);
3863   int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
3864   PERFETTO_CHECK(poll_res >= 0);
3865 
3866   TryReadStdoutAndErr();
3867   TryPushStdin();
3868   TryReadExitStatus();
3869 
3870   return poll_res > 0;
3871 }
3872 
Wait(int timeout_ms)3873 bool Subprocess::Wait(int timeout_ms) {
3874   PERFETTO_CHECK(s_.status != kNotStarted);
3875 
3876   // Break out of the loop only after both conditions are satisfied:
3877   // - All stdout/stderr data has been read (if kBuffer).
3878   // - The process exited.
3879   // Note that the two events can happen arbitrary order. After the process
3880   // exits, there might be still data in the pipe buffer, which we want to
3881   // read fully.
3882   //
3883   // Instead, don't wait on the stdin to be fully written. The child process
3884   // might exit prematurely (or crash). If that happens, we can end up in a
3885   // state where the write(stdin_pipe_.wr) will never unblock.
3886 
3887   const int64_t t_start = base::GetWallTimeMs().count();
3888   while (s_.exit_status_pipe.rd || s_.stdouterr_pipe.rd) {
3889     int poll_timeout_ms = -1;  // Block until a FD is ready.
3890     if (timeout_ms > 0) {
3891       const int64_t now = GetWallTimeMs().count();
3892       poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
3893       if (poll_timeout_ms <= 0)
3894         return false;
3895     }
3896     PollInternal(poll_timeout_ms);
3897   }  // while(...)
3898   return true;
3899 }
3900 
Call(int timeout_ms)3901 bool Subprocess::Call(int timeout_ms) {
3902   PERFETTO_CHECK(s_.status == kNotStarted);
3903   Start();
3904 
3905   if (!Wait(timeout_ms)) {
3906     KillAndWaitForTermination();
3907     // TryReadExitStatus must have joined the thread.
3908     PERFETTO_DCHECK(!s_.waitpid_thread.joinable());
3909   }
3910   PERFETTO_DCHECK(s_.status != kRunning);
3911   return s_.status == kExited && s_.returncode == 0;
3912 }
3913 
TryReadExitStatus()3914 void Subprocess::TryReadExitStatus() {
3915   if (!s_.exit_status_pipe.rd)
3916     return;
3917 
3918   int pid_stat = -1;
3919   int64_t rsize = PERFETTO_EINTR(
3920       read(*s_.exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
3921   if (rsize < 0 && errno == EAGAIN)
3922     return;
3923 
3924   if (rsize > 0) {
3925     PERFETTO_CHECK(rsize == sizeof(pid_stat));
3926   } else if (rsize < 0) {
3927     PERFETTO_PLOG("Subprocess read(s_.exit_status_pipe) failed");
3928   }
3929   s_.waitpid_thread.join();
3930   s_.exit_status_pipe.rd.reset();
3931 
3932   if (WIFEXITED(pid_stat)) {
3933     s_.returncode = WEXITSTATUS(pid_stat);
3934     s_.status = kExited;
3935   } else if (WIFSIGNALED(pid_stat)) {
3936     s_.returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
3937     s_.status = kKilledBySignal;
3938   } else {
3939     PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
3940   }
3941 }
3942 
3943 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()3944 void Subprocess::TryPushStdin() {
3945   if (!s_.stdin_pipe.wr)
3946     return;
3947 
3948   PERFETTO_DCHECK(args.input.empty() || s_.input_written < args.input.size());
3949   if (args.input.size()) {
3950     int64_t wsize =
3951         PERFETTO_EINTR(write(*s_.stdin_pipe.wr, &args.input[s_.input_written],
3952                              args.input.size() - s_.input_written));
3953     if (wsize < 0 && errno == EAGAIN)
3954       return;
3955 
3956     if (wsize >= 0) {
3957       // Whether write() can return 0 is one of the greatest mysteries of UNIX.
3958       // Just ignore it.
3959       s_.input_written += static_cast<size_t>(wsize);
3960     } else {
3961       PERFETTO_PLOG("Subprocess write(stdin) failed");
3962       s_.stdin_pipe.wr.reset();
3963     }
3964   }
3965   PERFETTO_DCHECK(s_.input_written <= args.input.size());
3966   if (s_.input_written == args.input.size())
3967     s_.stdin_pipe.wr.reset();  // Close stdin.
3968 }
3969 
TryReadStdoutAndErr()3970 void Subprocess::TryReadStdoutAndErr() {
3971   if (!s_.stdouterr_pipe.rd)
3972     return;
3973   char buf[4096];
3974   int64_t rsize = PERFETTO_EINTR(read(*s_.stdouterr_pipe.rd, buf, sizeof(buf)));
3975   if (rsize < 0 && errno == EAGAIN)
3976     return;
3977 
3978   if (rsize > 0) {
3979     s_.output.append(buf, static_cast<size_t>(rsize));
3980   } else if (rsize == 0 /* EOF */) {
3981     s_.stdouterr_pipe.rd.reset();
3982   } else {
3983     PERFETTO_PLOG("Subprocess read(stdout/err) failed");
3984     s_.stdouterr_pipe.rd.reset();
3985   }
3986 }
3987 
KillAndWaitForTermination(int sig_num)3988 void Subprocess::KillAndWaitForTermination(int sig_num) {
3989   kill(s_.pid, sig_num ? sig_num : SIGKILL);
3990   Wait();
3991 }
3992 
GetCmdString() const3993 std::string Subprocess::Args::GetCmdString() const {
3994   std::string str;
3995   for (size_t i = 0; i < exec_cmd.size(); i++) {
3996     str += i > 0 ? " \"" : "";
3997     str += exec_cmd[i];
3998     str += i > 0 ? "\"" : "";
3999   }
4000   return str;
4001 }
4002 
4003 }  // namespace base
4004 }  // namespace perfetto
4005 
4006 #endif  // PERFETTO_HAS_SUBPROCESS()
4007 // gen_amalgamated begin source: src/base/thread_checker.cc
4008 // gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
4009 /*
4010  * Copyright (C) 2017 The Android Open Source Project
4011  *
4012  * Licensed under the Apache License, Version 2.0 (the "License");
4013  * you may not use this file except in compliance with the License.
4014  * You may obtain a copy of the License at
4015  *
4016  *      http://www.apache.org/licenses/LICENSE-2.0
4017  *
4018  * Unless required by applicable law or agreed to in writing, software
4019  * distributed under the License is distributed on an "AS IS" BASIS,
4020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4021  * See the License for the specific language governing permissions and
4022  * limitations under the License.
4023  */
4024 
4025 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4026 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4027 
4028 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4029 
4030 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4031 #include <pthread.h>
4032 #endif
4033 #include <atomic>
4034 
4035 // gen_amalgamated expanded: #include "perfetto/base/export.h"
4036 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4037 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4038 
4039 namespace perfetto {
4040 namespace base {
4041 
4042 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4043 using ThreadID = unsigned long;
4044 #else
4045 using ThreadID = pthread_t;
4046 #endif
4047 
4048 class PERFETTO_EXPORT ThreadChecker {
4049  public:
4050   ThreadChecker();
4051   ~ThreadChecker();
4052   ThreadChecker(const ThreadChecker&);
4053   ThreadChecker& operator=(const ThreadChecker&);
4054   bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
4055   void DetachFromThread();
4056 
4057  private:
4058   mutable std::atomic<ThreadID> thread_id_;
4059 };
4060 
4061 #if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
4062 // TODO(primiano) Use Chromium's thread checker in Chromium.
4063 #define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
4064 #define PERFETTO_DCHECK_THREAD(name) \
4065   PERFETTO_DCHECK((name).CalledOnValidThread())
4066 #define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
4067 #else
4068 #define PERFETTO_THREAD_CHECKER(name)
4069 #define PERFETTO_DCHECK_THREAD(name)
4070 #define PERFETTO_DETACH_FROM_THREAD(name)
4071 #endif  // PERFETTO_DCHECK_IS_ON()
4072 
4073 }  // namespace base
4074 }  // namespace perfetto
4075 
4076 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4077 /*
4078  * Copyright (C) 2017 The Android Open Source Project
4079  *
4080  * Licensed under the Apache License, Version 2.0 (the "License");
4081  * you may not use this file except in compliance with the License.
4082  * You may obtain a copy of the License at
4083  *
4084  *      http://www.apache.org/licenses/LICENSE-2.0
4085  *
4086  * Unless required by applicable law or agreed to in writing, software
4087  * distributed under the License is distributed on an "AS IS" BASIS,
4088  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4089  * See the License for the specific language governing permissions and
4090  * limitations under the License.
4091  */
4092 
4093 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
4094 
4095 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4096 #include <Windows.h>
4097 #endif
4098 
4099 namespace perfetto {
4100 namespace base {
4101 
4102 namespace {
4103 constexpr ThreadID kDetached{};
4104 
CurrentThreadId()4105 ThreadID CurrentThreadId() {
4106 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4107   return ::GetCurrentThreadId();
4108 #else
4109   return pthread_self();
4110 #endif
4111 }
4112 }  // namespace
4113 
ThreadChecker()4114 ThreadChecker::ThreadChecker() {
4115   thread_id_.store(CurrentThreadId());
4116 }
4117 
4118 ThreadChecker::~ThreadChecker() = default;
4119 
ThreadChecker(const ThreadChecker & other)4120 ThreadChecker::ThreadChecker(const ThreadChecker& other) {
4121   thread_id_ = other.thread_id_.load();
4122 }
4123 
operator =(const ThreadChecker & other)4124 ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
4125   thread_id_ = other.thread_id_.load();
4126   return *this;
4127 }
4128 
CalledOnValidThread() const4129 bool ThreadChecker::CalledOnValidThread() const {
4130   auto self = CurrentThreadId();
4131 
4132   // Will re-attach if previously detached using DetachFromThread().
4133   auto prev_value = kDetached;
4134   if (thread_id_.compare_exchange_strong(prev_value, self))
4135     return true;
4136   return prev_value == self;
4137 }
4138 
DetachFromThread()4139 void ThreadChecker::DetachFromThread() {
4140   thread_id_.store(kDetached);
4141 }
4142 
4143 }  // namespace base
4144 }  // namespace perfetto
4145 // gen_amalgamated begin source: src/base/time.cc
4146 /*
4147  * Copyright (C) 2018 The Android Open Source Project
4148  *
4149  * Licensed under the Apache License, Version 2.0 (the "License");
4150  * you may not use this file except in compliance with the License.
4151  * You may obtain a copy of the License at
4152  *
4153  *      http://www.apache.org/licenses/LICENSE-2.0
4154  *
4155  * Unless required by applicable law or agreed to in writing, software
4156  * distributed under the License is distributed on an "AS IS" BASIS,
4157  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4158  * See the License for the specific language governing permissions and
4159  * limitations under the License.
4160  */
4161 
4162 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4163 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4164 
4165 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4166 #include <Windows.h>
4167 #else
4168 #include <unistd.h>
4169 #endif
4170 
4171 namespace perfetto {
4172 namespace base {
4173 
4174 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4175 
GetWallTimeNs()4176 TimeNanos GetWallTimeNs() {
4177   LARGE_INTEGER freq;
4178   ::QueryPerformanceFrequency(&freq);
4179   LARGE_INTEGER counter;
4180   ::QueryPerformanceCounter(&counter);
4181   double elapsed_nanoseconds = (1e9 * counter.QuadPart) / freq.QuadPart;
4182   return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
4183 }
4184 
GetThreadCPUTimeNs()4185 TimeNanos GetThreadCPUTimeNs() {
4186   FILETIME dummy, kernel_ftime, user_ftime;
4187   ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
4188                    &user_ftime);
4189   uint64_t kernel_time = kernel_ftime.dwHighDateTime * 0x100000000 +
4190                          kernel_ftime.dwLowDateTime;
4191   uint64_t user_time = user_ftime.dwHighDateTime * 0x100000000 +
4192                        user_ftime.dwLowDateTime;
4193 
4194   return TimeNanos((kernel_time + user_time) * 100);
4195 }
4196 
SleepMicroseconds(unsigned interval_us)4197 void SleepMicroseconds(unsigned interval_us) {
4198   // The Windows Sleep function takes a millisecond count. Round up so that
4199   // short sleeps don't turn into a busy wait. Note that the sleep granularity
4200   // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
4201   // being a short sleep.
4202   ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
4203 }
4204 
4205 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4206 
4207 void SleepMicroseconds(unsigned interval_us) {
4208   ::usleep(static_cast<useconds_t>(interval_us));
4209 }
4210 
4211 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4212 
4213 }  // namespace base
4214 }  // namespace perfetto
4215 // gen_amalgamated begin source: src/base/uuid.cc
4216 // gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
4217 /*
4218  * Copyright (C) 2019 The Android Open Source Project
4219  *
4220  * Licensed under the Apache License, Version 2.0 (the "License");
4221  * you may not use this file except in compliance with the License.
4222  * You may obtain a copy of the License at
4223  *
4224  *      http://www.apache.org/licenses/LICENSE-2.0
4225  *
4226  * Unless required by applicable law or agreed to in writing, software
4227  * distributed under the License is distributed on an "AS IS" BASIS,
4228  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4229  * See the License for the specific language governing permissions and
4230  * limitations under the License.
4231  */
4232 
4233 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
4234 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
4235 
4236 #include <array>
4237 #include <string>
4238 
4239 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
4240 
4241 namespace perfetto {
4242 namespace base {
4243 
4244 class Uuid {
4245  public:
4246   explicit Uuid(const std::string& s);
4247   explicit Uuid(int64_t lsb, int64_t msb);
4248   Uuid();
4249 
data()4250   std::array<uint8_t, 16>* data() { return &data_; }
data() const4251   const std::array<uint8_t, 16>* data() const { return &data_; }
4252 
operator ==(const Uuid & other) const4253   bool operator==(const Uuid& other) const { return data_ == other.data_; }
4254 
operator !=(const Uuid & other) const4255   bool operator!=(const Uuid& other) const { return !(*this == other); }
4256 
msb() const4257   int64_t msb() const {
4258     int64_t result;
4259     memcpy(&result, data_.data() + 8, 8);
4260     return result;
4261   }
4262 
lsb() const4263   int64_t lsb() const {
4264     int64_t result;
4265     memcpy(&result, data_.data(), 8);
4266     return result;
4267   }
4268 
set_lsb_msb(int64_t lsb,int64_t msb)4269   void set_lsb_msb(int64_t lsb, int64_t msb) {
4270     set_lsb(lsb);
4271     set_msb(msb);
4272   }
set_msb(int64_t msb)4273   void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
set_lsb(int64_t lsb)4274   void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
4275 
4276   std::string ToString() const;
4277   std::string ToPrettyString() const;
4278 
4279  private:
4280   std::array<uint8_t, 16> data_{};
4281 };
4282 
4283 Uuid Uuidv4();
4284 
4285 }  // namespace base
4286 }  // namespace perfetto
4287 
4288 #endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
4289 /*
4290  * Copyright (C) 2019 The Android Open Source Project
4291  *
4292  * Licensed under the Apache License, Version 2.0 (the "License");
4293  * you may not use this file except in compliance with the License.
4294  * You may obtain a copy of the License at
4295  *
4296  *      http://www.apache.org/licenses/LICENSE-2.0
4297  *
4298  * Unless required by applicable law or agreed to in writing, software
4299  * distributed under the License is distributed on an "AS IS" BASIS,
4300  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4301  * See the License for the specific language governing permissions and
4302  * limitations under the License.
4303  */
4304 
4305 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
4306 
4307 #include <random>
4308 
4309 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4310 
4311 namespace perfetto {
4312 namespace base {
4313 namespace {
4314 
4315 constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
4316                             '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
4317 }  // namespace
4318 
4319 // See https://www.ietf.org/rfc/rfc4122.txt
Uuidv4()4320 Uuid Uuidv4() {
4321   static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
4322   Uuid uuid;
4323   auto& data = *uuid.data();
4324 
4325   for (size_t i = 0; i < 16; ++i)
4326     data[i] = static_cast<uint8_t>(rng());
4327 
4328   // version:
4329   data[6] = (data[6] & 0x0f) | 0x40;
4330   // clock_seq_hi_and_reserved:
4331   data[8] = (data[8] & 0x3f) | 0x80;
4332 
4333   return uuid;
4334 }
4335 
Uuid()4336 Uuid::Uuid() {}
4337 
Uuid(const std::string & s)4338 Uuid::Uuid(const std::string& s) {
4339   PERFETTO_CHECK(s.size() == data_.size());
4340   memcpy(data_.data(), s.data(), s.size());
4341 }
4342 
Uuid(int64_t lsb,int64_t msb)4343 Uuid::Uuid(int64_t lsb, int64_t msb) {
4344   set_lsb_msb(lsb, msb);
4345 }
4346 
ToString() const4347 std::string Uuid::ToString() const {
4348   return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
4349 }
4350 
ToPrettyString() const4351 std::string Uuid::ToPrettyString() const {
4352   std::string s(data_.size() * 2 + 4, '-');
4353   // Format is 123e4567-e89b-12d3-a456-426655443322.
4354   size_t j = 0;
4355   for (size_t i = 0; i < data_.size(); ++i) {
4356     if (i == 4 || i == 6 || i == 8 || i == 10)
4357       j++;
4358     s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
4359     s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
4360   }
4361   return s;
4362 }
4363 
4364 }  // namespace base
4365 }  // namespace perfetto
4366 // gen_amalgamated begin source: src/base/virtual_destructors.cc
4367 /*
4368  * Copyright (C) 2017 The Android Open Source Project
4369  *
4370  * Licensed under the Apache License, Version 2.0 (the "License");
4371  * you may not use this file except in compliance with the License.
4372  * You may obtain a copy of the License at
4373  *
4374  *      http://www.apache.org/licenses/LICENSE-2.0
4375  *
4376  * Unless required by applicable law or agreed to in writing, software
4377  * distributed under the License is distributed on an "AS IS" BASIS,
4378  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4379  * See the License for the specific language governing permissions and
4380  * limitations under the License.
4381  */
4382 
4383 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
4384 
4385 // This translation unit contains the definitions for the destructor of pure
4386 // virtual interfaces for the current build target. The alternative would be
4387 // introducing a one-liner .cc file for each pure virtual interface, which is
4388 // overkill. This is for compliance with -Wweak-vtables.
4389 
4390 namespace perfetto {
4391 namespace base {
4392 
4393 TaskRunner::~TaskRunner() = default;
4394 
4395 }  // namespace base
4396 }  // namespace perfetto
4397 // gen_amalgamated begin source: src/base/waitable_event.cc
4398 // gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
4399 /*
4400  * Copyright (C) 2019 The Android Open Source Project
4401  *
4402  * Licensed under the Apache License, Version 2.0 (the "License");
4403  * you may not use this file except in compliance with the License.
4404  * You may obtain a copy of the License at
4405  *
4406  *      http://www.apache.org/licenses/LICENSE-2.0
4407  *
4408  * Unless required by applicable law or agreed to in writing, software
4409  * distributed under the License is distributed on an "AS IS" BASIS,
4410  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4411  * See the License for the specific language governing permissions and
4412  * limitations under the License.
4413  */
4414 
4415 #ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
4416 #define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
4417 
4418 #include <condition_variable>
4419 #include <mutex>
4420 
4421 namespace perfetto {
4422 namespace base {
4423 
4424 // A waitable event for cross-thread synchronization.
4425 // All methods on this class can be called from any thread.
4426 class WaitableEvent {
4427  public:
4428   WaitableEvent();
4429   ~WaitableEvent();
4430   WaitableEvent(const WaitableEvent&) = delete;
4431   WaitableEvent operator=(const WaitableEvent&) = delete;
4432 
4433   // Synchronously block until the event is notified.
4434   void Wait();
4435 
4436   // Signal the event, waking up blocked waiters.
4437   void Notify();
4438 
4439  private:
4440   std::mutex mutex_;
4441   std::condition_variable event_;
4442   bool notified_ = false;
4443 };
4444 
4445 }  // namespace base
4446 }  // namespace perfetto
4447 
4448 #endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
4449 /*
4450  * Copyright (C) 2019 The Android Open Source Project
4451  *
4452  * Licensed under the Apache License, Version 2.0 (the "License");
4453  * you may not use this file except in compliance with the License.
4454  * You may obtain a copy of the License at
4455  *
4456  *      http://www.apache.org/licenses/LICENSE-2.0
4457  *
4458  * Unless required by applicable law or agreed to in writing, software
4459  * distributed under the License is distributed on an "AS IS" BASIS,
4460  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4461  * See the License for the specific language governing permissions and
4462  * limitations under the License.
4463  */
4464 
4465 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
4466 
4467 namespace perfetto {
4468 namespace base {
4469 
4470 WaitableEvent::WaitableEvent() = default;
4471 WaitableEvent::~WaitableEvent() = default;
4472 
Wait()4473 void WaitableEvent::Wait() {
4474   std::unique_lock<std::mutex> lock(mutex_);
4475   return event_.wait(lock, [this] { return notified_; });
4476 }
4477 
Notify()4478 void WaitableEvent::Notify() {
4479   std::unique_lock<std::mutex> lock(mutex_);
4480   notified_ = true;
4481   event_.notify_all();
4482 }
4483 
4484 }  // namespace base
4485 }  // namespace perfetto
4486 // gen_amalgamated begin source: src/base/watchdog_posix.cc
4487 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
4488 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
4489 /*
4490  * Copyright (C) 2018 The Android Open Source Project
4491  *
4492  * Licensed under the Apache License, Version 2.0 (the "License");
4493  * you may not use this file except in compliance with the License.
4494  * You may obtain a copy of the License at
4495  *
4496  *      http://www.apache.org/licenses/LICENSE-2.0
4497  *
4498  * Unless required by applicable law or agreed to in writing, software
4499  * distributed under the License is distributed on an "AS IS" BASIS,
4500  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4501  * See the License for the specific language governing permissions and
4502  * limitations under the License.
4503  */
4504 
4505 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
4506 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
4507 
4508 #include <stdint.h>
4509 
4510 namespace perfetto {
4511 namespace base {
4512 
4513 class Watchdog {
4514  public:
4515   class Timer {
4516    public:
4517     // Define an empty dtor to avoid "unused variable" errors on the call site.
Timer()4518     Timer() {}
Timer(const Timer &)4519     Timer(const Timer&) {}
~Timer()4520     ~Timer() {}
4521   };
GetInstance()4522   static Watchdog* GetInstance() {
4523     static Watchdog* watchdog = new Watchdog();
4524     return watchdog;
4525   }
CreateFatalTimer(uint32_t)4526   Timer CreateFatalTimer(uint32_t /*ms*/) { return Timer(); }
Start()4527   void Start() {}
SetMemoryLimit(uint64_t,uint32_t)4528   void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
SetCpuLimit(uint32_t,uint32_t)4529   void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
4530 };
4531 
4532 }  // namespace base
4533 }  // namespace perfetto
4534 
4535 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
4536 /*
4537  * Copyright (C) 2018 The Android Open Source Project
4538  *
4539  * Licensed under the Apache License, Version 2.0 (the "License");
4540  * you may not use this file except in compliance with the License.
4541  * You may obtain a copy of the License at
4542  *
4543  *      http://www.apache.org/licenses/LICENSE-2.0
4544  *
4545  * Unless required by applicable law or agreed to in writing, software
4546  * distributed under the License is distributed on an "AS IS" BASIS,
4547  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4548  * See the License for the specific language governing permissions and
4549  * limitations under the License.
4550  */
4551 
4552 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
4553 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
4554 
4555 #include <functional>
4556 
4557 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4558 
4559 // The POSIX watchdog is only supported on Linux and Android in non-embedder
4560 // builds.
4561 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
4562 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
4563 #else
4564 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
4565 #endif
4566 
4567 namespace perfetto {
4568 namespace base {
4569 
4570 // Make the limits more relaxed on desktop, where multi-GB traces are likely.
4571 // Multi-GB traces can take bursts of cpu time to write into disk at the end of
4572 // the trace.
4573 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4574 constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
4575 constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
4576 #else
4577 constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
4578 constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
4579 #endif
4580 
4581 // The default memory margin we give to our processes. This is used as as a
4582 // constant to put on top of the trace buffers.
4583 constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
4584 constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.
4585 
RunTaskWithWatchdogGuard(const std::function<void ()> & task)4586 inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
4587   // Maximum time a single task can take in a TaskRunner before the
4588   // program suicides.
4589   constexpr int64_t kWatchdogMillis = 30000;  // 30s
4590 
4591   Watchdog::Timer handle =
4592       base::Watchdog::GetInstance()->CreateFatalTimer(kWatchdogMillis);
4593   task();
4594 
4595   // Suppress unused variable warnings in the client library amalgamated build.
4596   (void)kWatchdogDefaultCpuLimit;
4597   (void)kWatchdogDefaultCpuWindow;
4598   (void)kWatchdogDefaultMemorySlack;
4599   (void)kWatchdogDefaultMemoryWindow;
4600 }
4601 
4602 }  // namespace base
4603 }  // namespace perfetto
4604 
4605 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
4606 /*
4607  * Copyright (C) 2018 The Android Open Source Project
4608  *
4609  * Licensed under the Apache License, Version 2.0 (the "License");
4610  * you may not use this file except in compliance with the License.
4611  * You may obtain a copy of the License at
4612  *
4613  *      http://www.apache.org/licenses/LICENSE-2.0
4614  *
4615  * Unless required by applicable law or agreed to in writing, software
4616  * distributed under the License is distributed on an "AS IS" BASIS,
4617  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4618  * See the License for the specific language governing permissions and
4619  * limitations under the License.
4620  */
4621 
4622 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
4623 
4624 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
4625 
4626 #include <fcntl.h>
4627 #include <inttypes.h>
4628 #include <signal.h>
4629 #include <stdint.h>
4630 
4631 #include <fstream>
4632 #include <thread>
4633 
4634 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4635 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4636 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
4637 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
4638 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4639 
4640 namespace perfetto {
4641 namespace base {
4642 
4643 namespace {
4644 
4645 constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
4646 
IsMultipleOf(uint32_t number,uint32_t divisor)4647 bool IsMultipleOf(uint32_t number, uint32_t divisor) {
4648   return number >= divisor && number % divisor == 0;
4649 }
4650 
MeanForArray(const uint64_t array[],size_t size)4651 double MeanForArray(const uint64_t array[], size_t size) {
4652   uint64_t total = 0;
4653   for (size_t i = 0; i < size; i++) {
4654     total += array[i];
4655   }
4656   return static_cast<double>(total / size);
4657 
4658 }
4659 
4660 }  //  namespace
4661 
ReadProcStat(int fd,ProcStat * out)4662 bool ReadProcStat(int fd, ProcStat* out) {
4663   char c[512];
4664   size_t c_pos = 0;
4665   while (c_pos < sizeof(c) - 1) {
4666     ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
4667     if (rd < 0) {
4668       PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
4669       return false;
4670     }
4671     if (rd == 0)
4672       break;
4673     c_pos += static_cast<size_t>(rd);
4674   }
4675   PERFETTO_CHECK(c_pos < sizeof(c));
4676   c[c_pos] = '\0';
4677 
4678   if (sscanf(c,
4679              "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu"
4680              "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
4681              &out->utime, &out->stime, &out->rss_pages) != 3) {
4682     PERFETTO_ELOG("Invalid stat format: %s", c);
4683     return false;
4684   }
4685   return true;
4686 }
4687 
Watchdog(uint32_t polling_interval_ms)4688 Watchdog::Watchdog(uint32_t polling_interval_ms)
4689     : polling_interval_ms_(polling_interval_ms) {}
4690 
~Watchdog()4691 Watchdog::~Watchdog() {
4692   if (!thread_.joinable()) {
4693     PERFETTO_DCHECK(!enabled_);
4694     return;
4695   }
4696   PERFETTO_DCHECK(enabled_);
4697   enabled_ = false;
4698   exit_signal_.notify_one();
4699   thread_.join();
4700 }
4701 
GetInstance()4702 Watchdog* Watchdog::GetInstance() {
4703   static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
4704   return watchdog;
4705 }
4706 
CreateFatalTimer(uint32_t ms)4707 Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
4708   if (!enabled_.load(std::memory_order_relaxed))
4709     return Watchdog::Timer(0);
4710 
4711   return Watchdog::Timer(ms);
4712 }
4713 
Start()4714 void Watchdog::Start() {
4715   std::lock_guard<std::mutex> guard(mutex_);
4716   if (thread_.joinable()) {
4717     PERFETTO_DCHECK(enabled_);
4718   } else {
4719     PERFETTO_DCHECK(!enabled_);
4720 
4721 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
4722     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4723     // Kick the thread to start running but only on Android or Linux.
4724     enabled_ = true;
4725     thread_ = std::thread(&Watchdog::ThreadMain, this);
4726 #endif
4727   }
4728 }
4729 
SetMemoryLimit(uint64_t bytes,uint32_t window_ms)4730 void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
4731   // Update the fields under the lock.
4732   std::lock_guard<std::mutex> guard(mutex_);
4733 
4734   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
4735 
4736   size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
4737   memory_window_bytes_.Reset(size);
4738   memory_limit_bytes_ = bytes;
4739 }
4740 
SetCpuLimit(uint32_t percentage,uint32_t window_ms)4741 void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
4742   std::lock_guard<std::mutex> guard(mutex_);
4743 
4744   PERFETTO_CHECK(percentage <= 100);
4745   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
4746                  percentage == 0);
4747 
4748   size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
4749   cpu_window_time_ticks_.Reset(size);
4750   cpu_limit_percentage_ = percentage;
4751 }
4752 
ThreadMain()4753 void Watchdog::ThreadMain() {
4754   base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
4755   if (!stat_fd) {
4756     PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
4757     return;
4758   }
4759 
4760   std::unique_lock<std::mutex> guard(mutex_);
4761   for (;;) {
4762     exit_signal_.wait_for(guard,
4763                           std::chrono::milliseconds(polling_interval_ms_));
4764     if (!enabled_)
4765       return;
4766 
4767     lseek(stat_fd.get(), 0, SEEK_SET);
4768 
4769     ProcStat stat;
4770     if (!ReadProcStat(stat_fd.get(), &stat)) {
4771       return;
4772     }
4773 
4774     uint64_t cpu_time = stat.utime + stat.stime;
4775     uint64_t rss_bytes =
4776         static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
4777 
4778     CheckMemory(rss_bytes);
4779     CheckCpu(cpu_time);
4780   }
4781 }
4782 
CheckMemory(uint64_t rss_bytes)4783 void Watchdog::CheckMemory(uint64_t rss_bytes) {
4784   if (memory_limit_bytes_ == 0)
4785     return;
4786 
4787   // Add the current stat value to the ring buffer and check that the mean
4788   // remains under our threshold.
4789   if (memory_window_bytes_.Push(rss_bytes)) {
4790     if (memory_window_bytes_.Mean() > static_cast<double>(memory_limit_bytes_)) {
4791       PERFETTO_ELOG(
4792           "Memory watchdog trigger. Memory window of %f bytes is above the "
4793           "%" PRIu64 " bytes limit.",
4794           memory_window_bytes_.Mean(), memory_limit_bytes_);
4795       kill(getpid(), SIGABRT);
4796     }
4797   }
4798 }
4799 
CheckCpu(uint64_t cpu_time)4800 void Watchdog::CheckCpu(uint64_t cpu_time) {
4801   if (cpu_limit_percentage_ == 0)
4802     return;
4803 
4804   // Add the cpu time to the ring buffer.
4805   if (cpu_window_time_ticks_.Push(cpu_time)) {
4806     // Compute the percentage over the whole window and check that it remains
4807     // under the threshold.
4808     uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
4809                                 cpu_window_time_ticks_.OldestWhenFull();
4810     double window_interval_ticks =
4811         (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
4812          1000.0) *
4813         static_cast<double>(sysconf(_SC_CLK_TCK));
4814     double percentage = static_cast<double>(difference_ticks) /
4815                         static_cast<double>(window_interval_ticks) * 100;
4816     if (percentage > cpu_limit_percentage_) {
4817       PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
4818                     "%% CPU limit.",
4819                     percentage, cpu_limit_percentage_);
4820       kill(getpid(), SIGABRT);
4821     }
4822   }
4823 }
4824 
WindowTimeForRingBuffer(const WindowedInterval & window)4825 uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
4826   return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
4827 }
4828 
Push(uint64_t sample)4829 bool Watchdog::WindowedInterval::Push(uint64_t sample) {
4830   // Add the sample to the current position in the ring buffer.
4831   buffer_[position_] = sample;
4832 
4833   // Update the position with next one circularily.
4834   position_ = (position_ + 1) % size_;
4835 
4836   // Set the filled flag the first time we wrap.
4837   filled_ = filled_ || position_ == 0;
4838   return filled_;
4839 }
4840 
Mean() const4841 double Watchdog::WindowedInterval::Mean() const {
4842   return MeanForArray(buffer_.get(), size_);
4843 }
4844 
Clear()4845 void Watchdog::WindowedInterval::Clear() {
4846   position_ = 0;
4847   buffer_.reset(new uint64_t[size_]());
4848 }
4849 
Reset(size_t new_size)4850 void Watchdog::WindowedInterval::Reset(size_t new_size) {
4851   position_ = 0;
4852   size_ = new_size;
4853   buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
4854 }
4855 
Timer(uint32_t ms)4856 Watchdog::Timer::Timer(uint32_t ms) {
4857   if (!ms)
4858     return;  // No-op timer created when the watchdog is disabled.
4859 
4860   struct sigevent sev = {};
4861   sev.sigev_notify = SIGEV_THREAD_ID;
4862   sev._sigev_un._tid = base::GetThreadId();
4863   sev.sigev_signo = SIGABRT;
4864   PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid_) != -1);
4865   struct itimerspec its = {};
4866   its.it_value.tv_sec = ms / 1000;
4867   its.it_value.tv_nsec = 1000000L * (ms % 1000);
4868   PERFETTO_CHECK(timer_settime(timerid_, 0, &its, nullptr) != -1);
4869 }
4870 
~Timer()4871 Watchdog::Timer::~Timer() {
4872   if (timerid_ != nullptr) {
4873     timer_delete(timerid_);
4874   }
4875 }
4876 
Timer(Timer && other)4877 Watchdog::Timer::Timer(Timer&& other) noexcept {
4878   timerid_ = other.timerid_;
4879   other.timerid_ = nullptr;
4880 }
4881 
4882 }  // namespace base
4883 }  // namespace perfetto
4884 
4885 #endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
4886 // gen_amalgamated begin source: src/base/event_fd.cc
4887 // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
4888 /*
4889  * Copyright (C) 2018 The Android Open Source Project
4890  *
4891  * Licensed under the Apache License, Version 2.0 (the "License");
4892  * you may not use this file except in compliance with the License.
4893  * You may obtain a copy of the License at
4894  *
4895  *      http://www.apache.org/licenses/LICENSE-2.0
4896  *
4897  * Unless required by applicable law or agreed to in writing, software
4898  * distributed under the License is distributed on an "AS IS" BASIS,
4899  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4900  * See the License for the specific language governing permissions and
4901  * limitations under the License.
4902  */
4903 
4904 #ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
4905 #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
4906 
4907 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4908 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
4909 
4910 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
4911     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
4912 #define PERFETTO_USE_EVENTFD() 1
4913 #else
4914 #define PERFETTO_USE_EVENTFD() 0
4915 #endif
4916 
4917 namespace perfetto {
4918 namespace base {
4919 
4920 // A waitable event that can be used with poll/select.
4921 // This is really a wrapper around eventfd_create with a pipe-based fallback
4922 // for other platforms where eventfd is not supported.
4923 class EventFd {
4924  public:
4925   EventFd();
4926   ~EventFd();
4927   EventFd(EventFd&&) noexcept = default;
4928   EventFd& operator=(EventFd&&) = default;
4929 
4930   // The non-blocking file descriptor that can be polled to wait for the event.
fd() const4931   int fd() const { return fd_.get(); }
4932 
4933   // Can be called from any thread.
4934   void Notify();
4935 
4936   // Can be called from any thread. If more Notify() are queued a Clear() call
4937   // can clear all of them (up to 16 per call).
4938   void Clear();
4939 
4940  private:
4941   // The eventfd, when eventfd is supported, otherwise this is the read end of
4942   // the pipe for fallback mode.
4943   ScopedFile fd_;
4944 
4945 #if !PERFETTO_USE_EVENTFD()
4946   // The write end of the wakeup pipe.
4947   ScopedFile write_fd_;
4948 #endif
4949 };
4950 
4951 }  // namespace base
4952 }  // namespace perfetto
4953 
4954 #endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
4955 /*
4956  * Copyright (C) 2018 The Android Open Source Project
4957  *
4958  * Licensed under the Apache License, Version 2.0 (the "License");
4959  * you may not use this file except in compliance with the License.
4960  * You may obtain a copy of the License at
4961  *
4962  *      http://www.apache.org/licenses/LICENSE-2.0
4963  *
4964  * Unless required by applicable law or agreed to in writing, software
4965  * distributed under the License is distributed on an "AS IS" BASIS,
4966  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4967  * See the License for the specific language governing permissions and
4968  * limitations under the License.
4969  */
4970 
4971 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4972 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4973 
4974 #include <stdint.h>
4975 #include <unistd.h>
4976 
4977 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4978 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
4979 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
4980 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4981 
4982 #if PERFETTO_USE_EVENTFD()
4983 #include <sys/eventfd.h>
4984 #endif
4985 
4986 namespace perfetto {
4987 namespace base {
4988 
EventFd()4989 EventFd::EventFd() {
4990 #if PERFETTO_USE_EVENTFD()
4991   fd_.reset(eventfd(/* start value */ 0, EFD_CLOEXEC | EFD_NONBLOCK));
4992   PERFETTO_CHECK(fd_);
4993 #else
4994   // Make the pipe non-blocking so that we never block the waking thread (either
4995   // the main thread or another one) when scheduling a wake-up.
4996   Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
4997   fd_ = std::move(pipe.rd);
4998   write_fd_ = std::move(pipe.wr);
4999 #endif  // !PERFETTO_USE_EVENTFD()
5000 }
5001 
5002 EventFd::~EventFd() = default;
5003 
Notify()5004 void EventFd::Notify() {
5005   const uint64_t value = 1;
5006 
5007 #if PERFETTO_USE_EVENTFD()
5008   ssize_t ret = write(fd_.get(), &value, sizeof(value));
5009 #else
5010   ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
5011 #endif
5012 
5013   if (ret <= 0 && errno != EAGAIN) {
5014     PERFETTO_DFATAL("write()");
5015   }
5016 }
5017 
Clear()5018 void EventFd::Clear() {
5019 #if PERFETTO_USE_EVENTFD()
5020   uint64_t value;
5021   ssize_t ret = read(fd_.get(), &value, sizeof(value));
5022 #else
5023   // Drain the byte(s) written to the wake-up pipe. We can potentially read
5024   // more than one byte if several wake-ups have been scheduled.
5025   char buffer[16];
5026   ssize_t ret = read(fd_.get(), &buffer[0], sizeof(buffer));
5027 #endif
5028   if (ret <= 0 && errno != EAGAIN)
5029     PERFETTO_DPLOG("read()");
5030 }
5031 
5032 }  // namespace base
5033 }  // namespace perfetto
5034 
5035 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5036 // gen_amalgamated begin source: src/base/pipe.cc
5037 /*
5038  * Copyright (C) 2018 The Android Open Source Project
5039  *
5040  * Licensed under the Apache License, Version 2.0 (the "License");
5041  * you may not use this file except in compliance with the License.
5042  * You may obtain a copy of the License at
5043  *
5044  *      http://www.apache.org/licenses/LICENSE-2.0
5045  *
5046  * Unless required by applicable law or agreed to in writing, software
5047  * distributed under the License is distributed on an "AS IS" BASIS,
5048  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5049  * See the License for the specific language governing permissions and
5050  * limitations under the License.
5051  */
5052 
5053 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5054 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5055 
5056 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
5057 
5058 #include <sys/types.h>
5059 #include <unistd.h>
5060 
5061 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5062 
5063 namespace perfetto {
5064 namespace base {
5065 
5066 Pipe::Pipe() = default;
5067 Pipe::Pipe(Pipe&&) noexcept = default;
5068 Pipe& Pipe::operator=(Pipe&&) = default;
5069 
Create(Flags flags)5070 Pipe Pipe::Create(Flags flags) {
5071   int fds[2];
5072   PERFETTO_CHECK(pipe(fds) == 0);
5073   Pipe p;
5074   p.rd.reset(fds[0]);
5075   p.wr.reset(fds[1]);
5076 
5077   PERFETTO_CHECK(fcntl(*p.rd, F_SETFD, FD_CLOEXEC) == 0);
5078   PERFETTO_CHECK(fcntl(*p.wr, F_SETFD, FD_CLOEXEC) == 0);
5079 
5080   if (flags == kBothNonBlock || flags == kRdNonBlock) {
5081     int cur_flags = fcntl(*p.rd, F_GETFL, 0);
5082     PERFETTO_CHECK(cur_flags >= 0);
5083     PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5084   }
5085 
5086   if (flags == kBothNonBlock || flags == kWrNonBlock) {
5087     int cur_flags = fcntl(*p.wr, F_GETFL, 0);
5088     PERFETTO_CHECK(cur_flags >= 0);
5089     PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5090   }
5091   return p;
5092 }
5093 
5094 }  // namespace base
5095 }  // namespace perfetto
5096 
5097 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5098 // gen_amalgamated begin source: src/base/temp_file.cc
5099 // gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
5100 /*
5101  * Copyright (C) 2018 The Android Open Source Project
5102  *
5103  * Licensed under the Apache License, Version 2.0 (the "License");
5104  * you may not use this file except in compliance with the License.
5105  * You may obtain a copy of the License at
5106  *
5107  *      http://www.apache.org/licenses/LICENSE-2.0
5108  *
5109  * Unless required by applicable law or agreed to in writing, software
5110  * distributed under the License is distributed on an "AS IS" BASIS,
5111  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5112  * See the License for the specific language governing permissions and
5113  * limitations under the License.
5114  */
5115 
5116 #ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5117 #define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5118 
5119 #include <string>
5120 
5121 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5122 
5123 namespace perfetto {
5124 namespace base {
5125 
5126 std::string GetSysTempDir();
5127 
5128 class TempFile {
5129  public:
5130   static TempFile CreateUnlinked();
5131   static TempFile Create();
5132 
5133   TempFile(TempFile&&) noexcept;
5134   TempFile& operator=(TempFile&&);
5135   ~TempFile();
5136 
path() const5137   const std::string& path() const { return path_; }
fd() const5138   int fd() const { return *fd_; }
operator *() const5139   int operator*() const { return *fd_; }
5140 
5141   // Unlinks the file from the filesystem but keeps the fd() open.
5142   // It is safe to call this multiple times.
5143   void Unlink();
5144 
5145   // Releases the underlying file descriptor. Will unlink the file from the
5146   // filesystem if it was created via CreateUnlinked().
5147   ScopedFile ReleaseFD();
5148 
5149  private:
5150   TempFile();
5151   TempFile(const TempFile&) = delete;
5152   TempFile& operator=(const TempFile&) = delete;
5153 
5154   ScopedFile fd_;
5155   std::string path_;
5156 };
5157 
5158 class TempDir {
5159  public:
5160   static TempDir Create();
5161 
5162   TempDir(TempDir&&) noexcept;
5163   TempDir& operator=(TempDir&&);
5164   ~TempDir();
5165 
path() const5166   const std::string& path() const { return path_; }
5167 
5168  private:
5169   TempDir();
5170   TempDir(const TempDir&) = delete;
5171   TempDir& operator=(const TempDir&) = delete;
5172 
5173   std::string path_;
5174 };
5175 
5176 }  // namespace base
5177 }  // namespace perfetto
5178 
5179 #endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5180 /*
5181  * Copyright (C) 2018 The Android Open Source Project
5182  *
5183  * Licensed under the Apache License, Version 2.0 (the "License");
5184  * you may not use this file except in compliance with the License.
5185  * You may obtain a copy of the License at
5186  *
5187  *      http://www.apache.org/licenses/LICENSE-2.0
5188  *
5189  * Unless required by applicable law or agreed to in writing, software
5190  * distributed under the License is distributed on an "AS IS" BASIS,
5191  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5192  * See the License for the specific language governing permissions and
5193  * limitations under the License.
5194  */
5195 
5196 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5197 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5198 
5199 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
5200 
5201 #include <stdlib.h>
5202 #include <unistd.h>
5203 
5204 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
5205 
5206 namespace perfetto {
5207 namespace base {
5208 
GetSysTempDir()5209 std::string GetSysTempDir() {
5210   const char* tmpdir = getenv("TMPDIR");
5211   if (tmpdir)
5212     return base::StripSuffix(tmpdir, "/");
5213 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5214   return "/data/local/tmp";
5215 #else
5216   return "/tmp";
5217 #endif
5218 }
5219 
5220 // static
Create()5221 TempFile TempFile::Create() {
5222   TempFile temp_file;
5223   temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5224   temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
5225   if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
5226     PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
5227   }
5228   return temp_file;
5229 }
5230 
5231 // static
CreateUnlinked()5232 TempFile TempFile::CreateUnlinked() {
5233   TempFile temp_file = TempFile::Create();
5234   temp_file.Unlink();
5235   return temp_file;
5236 }
5237 
5238 TempFile::TempFile() = default;
5239 
~TempFile()5240 TempFile::~TempFile() {
5241   Unlink();
5242 }
5243 
ReleaseFD()5244 ScopedFile TempFile::ReleaseFD() {
5245   Unlink();
5246   return std::move(fd_);
5247 }
5248 
Unlink()5249 void TempFile::Unlink() {
5250   if (path_.empty())
5251     return;
5252   PERFETTO_CHECK(unlink(path_.c_str()) == 0);
5253   path_.clear();
5254 }
5255 
5256 TempFile::TempFile(TempFile&&) noexcept = default;
5257 TempFile& TempFile::operator=(TempFile&&) = default;
5258 
5259 // static
Create()5260 TempDir TempDir::Create() {
5261   TempDir temp_dir;
5262   temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
5263   PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
5264   return temp_dir;
5265 }
5266 
5267 TempDir::TempDir() = default;
5268 
~TempDir()5269 TempDir::~TempDir() {
5270   PERFETTO_CHECK(rmdir(path_.c_str()) == 0);
5271 }
5272 
5273 }  // namespace base
5274 }  // namespace perfetto
5275 
5276 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5277 // gen_amalgamated begin source: src/base/thread_task_runner.cc
5278 // gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
5279 // gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
5280 /*
5281  * Copyright (C) 2017 The Android Open Source Project
5282  *
5283  * Licensed under the Apache License, Version 2.0 (the "License");
5284  * you may not use this file except in compliance with the License.
5285  * You may obtain a copy of the License at
5286  *
5287  *      http://www.apache.org/licenses/LICENSE-2.0
5288  *
5289  * Unless required by applicable law or agreed to in writing, software
5290  * distributed under the License is distributed on an "AS IS" BASIS,
5291  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5292  * See the License for the specific language governing permissions and
5293  * limitations under the License.
5294  */
5295 
5296 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
5297 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
5298 
5299 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5300 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
5301 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
5302 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5303 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
5304 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5305 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5306 
5307 #include <poll.h>
5308 #include <chrono>
5309 #include <deque>
5310 #include <map>
5311 #include <mutex>
5312 #include <vector>
5313 
5314 namespace perfetto {
5315 namespace base {
5316 
5317 // Runs a task runner on the current thread.
5318 //
5319 // Implementation note: we currently assume (and enforce in debug builds) that
5320 // Run() is called from the thread that constructed the UnixTaskRunner. This is
5321 // not strictly necessary, and we could instead track the thread that invokes
5322 // Run(). However, a related property that *might* be important to enforce is
5323 // that the destructor runs on the task-running thread. Otherwise, if there are
5324 // still-pending tasks at the time of destruction, we would destroy those
5325 // outside of the task thread (which might be unexpected to the caller). On the
5326 // other hand, the std::function task interface discourages use of any
5327 // resource-owning tasks (as the callable needs to be copyable), so this might
5328 // not be important in practice.
5329 //
5330 // TODO(rsavitski): consider adding a thread-check in the destructor, after
5331 // auditing existing usages.
5332 class UnixTaskRunner : public TaskRunner {
5333  public:
5334   UnixTaskRunner();
5335   ~UnixTaskRunner() override;
5336 
5337   // Start executing tasks. Doesn't return until Quit() is called. Run() may be
5338   // called multiple times on the same task runner.
5339   void Run();
5340   void Quit();
5341 
5342   // Checks whether there are any pending immediate tasks to run. Note that
5343   // delayed tasks don't count even if they are due to run.
5344   bool IsIdleForTesting();
5345 
5346   // TaskRunner implementation:
5347   void PostTask(std::function<void()>) override;
5348   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
5349   void AddFileDescriptorWatch(int fd, std::function<void()>) override;
5350   void RemoveFileDescriptorWatch(int fd) override;
5351   bool RunsTasksOnCurrentThread() const override;
5352 
5353   // Returns true if the task runner is quitting, or has quit and hasn't been
5354   // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
5355   // normal use of this class.
5356   bool QuitCalled();
5357 
5358  private:
5359   void WakeUp();
5360 
5361   void UpdateWatchTasksLocked();
5362 
5363   int GetDelayMsToNextTaskLocked() const;
5364   void RunImmediateAndDelayedTask();
5365   void PostFileDescriptorWatches();
5366   void RunFileDescriptorWatch(int fd);
5367 
5368   ThreadChecker thread_checker_;
5369   PlatformThreadId created_thread_id_ = GetThreadId();
5370 
5371   // On Linux, an eventfd(2) used to waking up the task runner when a new task
5372   // is posted. Otherwise the read end of a pipe used for the same purpose.
5373   EventFd event_;
5374 
5375   std::vector<struct pollfd> poll_fds_;
5376 
5377   // --- Begin lock-protected members ---
5378 
5379   std::mutex lock_;
5380 
5381   std::deque<std::function<void()>> immediate_tasks_;
5382   std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
5383   bool quit_ = false;
5384 
5385   struct WatchTask {
5386     std::function<void()> callback;
5387     size_t poll_fd_index;  // Index into |poll_fds_|.
5388   };
5389 
5390   std::map<int, WatchTask> watch_tasks_;
5391   bool watch_tasks_changed_ = false;
5392 
5393   // --- End lock-protected members ---
5394 };
5395 
5396 }  // namespace base
5397 }  // namespace perfetto
5398 
5399 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
5400 /*
5401  * Copyright (C) 2019 The Android Open Source Project
5402  *
5403  * Licensed under the Apache License, Version 2.0 (the "License");
5404  * you may not use this file except in compliance with the License.
5405  * You may obtain a copy of the License at
5406  *
5407  *      http://www.apache.org/licenses/LICENSE-2.0
5408  *
5409  * Unless required by applicable law or agreed to in writing, software
5410  * distributed under the License is distributed on an "AS IS" BASIS,
5411  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5412  * See the License for the specific language governing permissions and
5413  * limitations under the License.
5414  */
5415 
5416 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
5417 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
5418 
5419 #include <functional>
5420 #include <thread>
5421 
5422 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
5423 
5424 namespace perfetto {
5425 namespace base {
5426 
5427 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
5428 // joins the thread upon destruction. Can be moved to transfer ownership.
5429 //
5430 // Guarantees that:
5431 // * the UnixTaskRunner will be constructed and destructed on the task thread.
5432 // * the task thread will live for the lifetime of the UnixTaskRunner.
5433 //
5434 class ThreadTaskRunner {
5435  public:
CreateAndStart(const std::string & name="")5436   static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
5437     return ThreadTaskRunner(name);
5438   }
5439 
5440   ThreadTaskRunner(const ThreadTaskRunner&) = delete;
5441   ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
5442 
5443   ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
5444   ThreadTaskRunner& operator=(ThreadTaskRunner&&);
5445   ~ThreadTaskRunner();
5446 
5447   // Executes the given function on the task runner thread and blocks the caller
5448   // thread until the function has run.
5449   void PostTaskAndWaitForTesting(std::function<void()>);
5450 
5451   // Can be called from another thread to get the CPU time of the thread the
5452   // task-runner is executing on.
5453   uint64_t GetThreadCPUTimeNsForTesting();
5454 
5455   // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
5456   // this ThreadTaskRunner object (unless this object is moved-from, in which
5457   // case the pointer remains valid for the lifetime of the new owning
5458   // ThreadTaskRunner).
5459   //
5460   // Warning: do not call Quit() on the returned runner pointer, the termination
5461   // should be handled exclusively by this class' destructor.
get() const5462   UnixTaskRunner* get() const { return task_runner_; }
5463 
5464  private:
5465   explicit ThreadTaskRunner(const std::string& name);
5466   void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
5467 
5468   std::thread thread_;
5469   std::string name_;
5470   UnixTaskRunner* task_runner_ = nullptr;
5471 };
5472 
5473 }  // namespace base
5474 }  // namespace perfetto
5475 
5476 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
5477 // gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
5478 /*
5479  * Copyright (C) 2020 The Android Open Source Project
5480  *
5481  * Licensed under the Apache License, Version 2.0 (the "License");
5482  * you may not use this file except in compliance with the License.
5483  * You may obtain a copy of the License at
5484  *
5485  *      http://www.apache.org/licenses/LICENSE-2.0
5486  *
5487  * Unless required by applicable law or agreed to in writing, software
5488  * distributed under the License is distributed on an "AS IS" BASIS,
5489  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5490  * See the License for the specific language governing permissions and
5491  * limitations under the License.
5492  */
5493 
5494 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
5495 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
5496 
5497 #include <string>
5498 
5499 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5500 
5501 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5502     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5503     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5504 #include <pthread.h>
5505 #include <string.h>
5506 #include <algorithm>
5507 #endif
5508 
5509 // Internal implementation utils that aren't as widely useful/supported as
5510 // base/thread_utils.h.
5511 
5512 namespace perfetto {
5513 namespace base {
5514 
5515 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5516     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5517     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5518 // Sets the "comm" of the calling thread to the first 15 chars of the given
5519 // string.
MaybeSetThreadName(const std::string & name)5520 inline bool MaybeSetThreadName(const std::string& name) {
5521   char buf[16] = {};
5522   size_t sz = std::min(name.size(), static_cast<size_t>(15));
5523   strncpy(buf, name.c_str(), sz);
5524 
5525 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5526   return pthread_setname_np(buf) == 0;
5527 #else
5528   return pthread_setname_np(pthread_self(), buf) == 0;
5529 #endif
5530 }
5531 #else
5532 inline void MaybeSetThreadName(const std::string&) {}
5533 #endif
5534 
5535 }  // namespace base
5536 }  // namespace perfetto
5537 
5538 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
5539 /*
5540  * Copyright (C) 2019 The Android Open Source Project
5541  *
5542  * Licensed under the Apache License, Version 2.0 (the "License");
5543  * you may not use this file except in compliance with the License.
5544  * You may obtain a copy of the License at
5545  *
5546  *      http://www.apache.org/licenses/LICENSE-2.0
5547  *
5548  * Unless required by applicable law or agreed to in writing, software
5549  * distributed under the License is distributed on an "AS IS" BASIS,
5550  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5551  * See the License for the specific language governing permissions and
5552  * limitations under the License.
5553  */
5554 
5555 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5556 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5557 
5558 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
5559 
5560 #include <condition_variable>
5561 #include <functional>
5562 #include <mutex>
5563 #include <thread>
5564 
5565 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5566 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
5567 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
5568 
5569 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5570     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
5571 #include <sys/prctl.h>
5572 #endif
5573 
5574 namespace perfetto {
5575 namespace base {
5576 
ThreadTaskRunner(ThreadTaskRunner && other)5577 ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
5578     : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
5579   other.task_runner_ = nullptr;
5580 }
5581 
operator =(ThreadTaskRunner && other)5582 ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
5583   this->~ThreadTaskRunner();
5584   new (this) ThreadTaskRunner(std::move(other));
5585   return *this;
5586 }
5587 
~ThreadTaskRunner()5588 ThreadTaskRunner::~ThreadTaskRunner() {
5589   if (task_runner_) {
5590     PERFETTO_CHECK(!task_runner_->QuitCalled());
5591     task_runner_->Quit();
5592 
5593     PERFETTO_DCHECK(thread_.joinable());
5594   }
5595   if (thread_.joinable())
5596     thread_.join();
5597 }
5598 
ThreadTaskRunner(const std::string & name)5599 ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
5600   std::mutex init_lock;
5601   std::condition_variable init_cv;
5602 
5603   std::function<void(UnixTaskRunner*)> initializer =
5604       [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
5605         std::lock_guard<std::mutex> lock(init_lock);
5606         task_runner_ = task_runner;
5607         // Notify while still holding the lock, as init_cv ceases to exist as
5608         // soon as the main thread observes a non-null task_runner_, and it can
5609         // wake up spuriously (i.e. before the notify if we had unlocked before
5610         // notifying).
5611         init_cv.notify_one();
5612       };
5613 
5614   thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
5615                         std::move(initializer));
5616 
5617   std::unique_lock<std::mutex> lock(init_lock);
5618   init_cv.wait(lock, [this] { return !!task_runner_; });
5619 }
5620 
RunTaskThread(std::function<void (UnixTaskRunner *)> initializer)5621 void ThreadTaskRunner::RunTaskThread(
5622     std::function<void(UnixTaskRunner*)> initializer) {
5623   if (!name_.empty()) {
5624     base::MaybeSetThreadName(name_);
5625   }
5626 
5627   UnixTaskRunner task_runner;
5628   task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
5629   task_runner.Run();
5630 }
5631 
PostTaskAndWaitForTesting(std::function<void ()> fn)5632 void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
5633   std::mutex mutex;
5634   std::condition_variable cv;
5635 
5636   std::unique_lock<std::mutex> lock(mutex);
5637   bool done = false;
5638   task_runner_->PostTask([&mutex, &cv, &done, &fn] {
5639     fn();
5640 
5641     std::lock_guard<std::mutex> inner_lock(mutex);
5642     done = true;
5643     cv.notify_one();
5644   });
5645   cv.wait(lock, [&done] { return done; });
5646 }
5647 
GetThreadCPUTimeNsForTesting()5648 uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
5649   uint64_t thread_time_ns = 0;
5650   PostTaskAndWaitForTesting([&thread_time_ns] {
5651     thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
5652   });
5653   return thread_time_ns;
5654 }
5655 
5656 }  // namespace base
5657 }  // namespace perfetto
5658 
5659 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5660 // gen_amalgamated begin source: src/base/unix_task_runner.cc
5661 /*
5662  * Copyright (C) 2017 The Android Open Source Project
5663  *
5664  * Licensed under the Apache License, Version 2.0 (the "License");
5665  * you may not use this file except in compliance with the License.
5666  * You may obtain a copy of the License at
5667  *
5668  *      http://www.apache.org/licenses/LICENSE-2.0
5669  *
5670  * Unless required by applicable law or agreed to in writing, software
5671  * distributed under the License is distributed on an "AS IS" BASIS,
5672  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5673  * See the License for the specific language governing permissions and
5674  * limitations under the License.
5675  */
5676 
5677 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5678 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5679 
5680 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
5681 
5682 #include <errno.h>
5683 #include <stdlib.h>
5684 #include <unistd.h>
5685 
5686 #include <limits>
5687 
5688 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
5689 
5690 namespace perfetto {
5691 namespace base {
5692 
UnixTaskRunner()5693 UnixTaskRunner::UnixTaskRunner() {
5694   AddFileDescriptorWatch(event_.fd(), [] {
5695     // Not reached -- see PostFileDescriptorWatches().
5696     PERFETTO_DFATAL("Should be unreachable.");
5697   });
5698 }
5699 
5700 UnixTaskRunner::~UnixTaskRunner() = default;
5701 
WakeUp()5702 void UnixTaskRunner::WakeUp() {
5703   event_.Notify();
5704 }
5705 
Run()5706 void UnixTaskRunner::Run() {
5707   PERFETTO_DCHECK_THREAD(thread_checker_);
5708   created_thread_id_ = GetThreadId();
5709   quit_ = false;
5710   for (;;) {
5711     int poll_timeout_ms;
5712     {
5713       std::lock_guard<std::mutex> lock(lock_);
5714       if (quit_)
5715         return;
5716       poll_timeout_ms = GetDelayMsToNextTaskLocked();
5717       UpdateWatchTasksLocked();
5718     }
5719     int ret = PERFETTO_EINTR(poll(
5720         &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
5721     PERFETTO_CHECK(ret >= 0);
5722 
5723     // To avoid starvation we always interleave all types of tasks -- immediate,
5724     // delayed and file descriptor watches.
5725     PostFileDescriptorWatches();
5726     RunImmediateAndDelayedTask();
5727   }
5728 }
5729 
Quit()5730 void UnixTaskRunner::Quit() {
5731   std::lock_guard<std::mutex> lock(lock_);
5732   quit_ = true;
5733   WakeUp();
5734 }
5735 
QuitCalled()5736 bool UnixTaskRunner::QuitCalled() {
5737   std::lock_guard<std::mutex> lock(lock_);
5738   return quit_;
5739 }
5740 
IsIdleForTesting()5741 bool UnixTaskRunner::IsIdleForTesting() {
5742   std::lock_guard<std::mutex> lock(lock_);
5743   return immediate_tasks_.empty();
5744 }
5745 
UpdateWatchTasksLocked()5746 void UnixTaskRunner::UpdateWatchTasksLocked() {
5747   PERFETTO_DCHECK_THREAD(thread_checker_);
5748   if (!watch_tasks_changed_)
5749     return;
5750   watch_tasks_changed_ = false;
5751   poll_fds_.clear();
5752   for (auto& it : watch_tasks_) {
5753     it.second.poll_fd_index = poll_fds_.size();
5754     poll_fds_.push_back({it.first, POLLIN | POLLHUP, 0});
5755   }
5756 }
5757 
RunImmediateAndDelayedTask()5758 void UnixTaskRunner::RunImmediateAndDelayedTask() {
5759   // If locking overhead becomes an issue, add a separate work queue.
5760   std::function<void()> immediate_task;
5761   std::function<void()> delayed_task;
5762   TimeMillis now = GetWallTimeMs();
5763   {
5764     std::lock_guard<std::mutex> lock(lock_);
5765     if (!immediate_tasks_.empty()) {
5766       immediate_task = std::move(immediate_tasks_.front());
5767       immediate_tasks_.pop_front();
5768     }
5769     if (!delayed_tasks_.empty()) {
5770       auto it = delayed_tasks_.begin();
5771       if (now >= it->first) {
5772         delayed_task = std::move(it->second);
5773         delayed_tasks_.erase(it);
5774       }
5775     }
5776   }
5777 
5778   errno = 0;
5779   if (immediate_task)
5780     RunTaskWithWatchdogGuard(immediate_task);
5781   errno = 0;
5782   if (delayed_task)
5783     RunTaskWithWatchdogGuard(delayed_task);
5784 }
5785 
PostFileDescriptorWatches()5786 void UnixTaskRunner::PostFileDescriptorWatches() {
5787   PERFETTO_DCHECK_THREAD(thread_checker_);
5788   for (size_t i = 0; i < poll_fds_.size(); i++) {
5789     if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
5790       continue;
5791     poll_fds_[i].revents = 0;
5792 
5793     // The wake-up event is handled inline to avoid an infinite recursion of
5794     // posted tasks.
5795     if (poll_fds_[i].fd == event_.fd()) {
5796       event_.Clear();
5797       continue;
5798     }
5799 
5800     // Binding to |this| is safe since we are the only object executing the
5801     // task.
5802     PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this,
5803                        poll_fds_[i].fd));
5804 
5805     // Make the fd negative while a posted task is pending. This makes poll(2)
5806     // ignore the fd.
5807     PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
5808     poll_fds_[i].fd = -poll_fds_[i].fd;
5809   }
5810 }
5811 
RunFileDescriptorWatch(int fd)5812 void UnixTaskRunner::RunFileDescriptorWatch(int fd) {
5813   std::function<void()> task;
5814   {
5815     std::lock_guard<std::mutex> lock(lock_);
5816     auto it = watch_tasks_.find(fd);
5817     if (it == watch_tasks_.end())
5818       return;
5819     // Make poll(2) pay attention to the fd again. Since another thread may have
5820     // updated this watch we need to refresh the set first.
5821     UpdateWatchTasksLocked();
5822     size_t fd_index = it->second.poll_fd_index;
5823     PERFETTO_DCHECK(fd_index < poll_fds_.size());
5824     PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
5825     poll_fds_[fd_index].fd = fd;
5826     task = it->second.callback;
5827   }
5828   errno = 0;
5829   RunTaskWithWatchdogGuard(task);
5830 }
5831 
GetDelayMsToNextTaskLocked() const5832 int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
5833   PERFETTO_DCHECK_THREAD(thread_checker_);
5834   if (!immediate_tasks_.empty())
5835     return 0;
5836   if (!delayed_tasks_.empty()) {
5837     TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
5838     return std::max(0, static_cast<int>(diff.count()));
5839   }
5840   return -1;
5841 }
5842 
PostTask(std::function<void ()> task)5843 void UnixTaskRunner::PostTask(std::function<void()> task) {
5844   bool was_empty;
5845   {
5846     std::lock_guard<std::mutex> lock(lock_);
5847     was_empty = immediate_tasks_.empty();
5848     immediate_tasks_.push_back(std::move(task));
5849   }
5850   if (was_empty)
5851     WakeUp();
5852 }
5853 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)5854 void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
5855                                      uint32_t delay_ms) {
5856   TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
5857   {
5858     std::lock_guard<std::mutex> lock(lock_);
5859     delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
5860   }
5861   WakeUp();
5862 }
5863 
AddFileDescriptorWatch(int fd,std::function<void ()> task)5864 void UnixTaskRunner::AddFileDescriptorWatch(int fd,
5865                                             std::function<void()> task) {
5866   PERFETTO_DCHECK(fd >= 0);
5867   {
5868     std::lock_guard<std::mutex> lock(lock_);
5869     PERFETTO_DCHECK(!watch_tasks_.count(fd));
5870     watch_tasks_[fd] = {std::move(task), SIZE_MAX};
5871     watch_tasks_changed_ = true;
5872   }
5873   WakeUp();
5874 }
5875 
RemoveFileDescriptorWatch(int fd)5876 void UnixTaskRunner::RemoveFileDescriptorWatch(int fd) {
5877   PERFETTO_DCHECK(fd >= 0);
5878   {
5879     std::lock_guard<std::mutex> lock(lock_);
5880     PERFETTO_DCHECK(watch_tasks_.count(fd));
5881     watch_tasks_.erase(fd);
5882     watch_tasks_changed_ = true;
5883   }
5884   // No need to schedule a wake-up for this.
5885 }
5886 
RunsTasksOnCurrentThread() const5887 bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
5888   return GetThreadId() == created_thread_id_;
5889 }
5890 
5891 }  // namespace base
5892 }  // namespace perfetto
5893 
5894 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5895 // gen_amalgamated begin source: src/protozero/field.cc
5896 /*
5897  * Copyright (C) 2019 The Android Open Source Project
5898  *
5899  * Licensed under the Apache License, Version 2.0 (the "License");
5900  * you may not use this file except in compliance with the License.
5901  * You may obtain a copy of the License at
5902  *
5903  *      http://www.apache.org/licenses/LICENSE-2.0
5904  *
5905  * Unless required by applicable law or agreed to in writing, software
5906  * distributed under the License is distributed on an "AS IS" BASIS,
5907  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5908  * See the License for the specific language governing permissions and
5909  * limitations under the License.
5910  */
5911 
5912 // gen_amalgamated expanded: #include "perfetto/protozero/field.h"
5913 
5914 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5915 
5916 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
5917 // The memcpy() for fixed32/64 below needs to be adjusted if we want to
5918 // support big endian CPUs. There doesn't seem to be a compelling need today.
5919 #error Unimplemented for big endian archs.
5920 #endif
5921 
5922 namespace protozero {
5923 
5924 template <typename Container>
SerializeAndAppendToInternal(Container * dst) const5925 void Field::SerializeAndAppendToInternal(Container* dst) const {
5926   namespace pu = proto_utils;
5927   size_t initial_size = dst->size();
5928   dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
5929   uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
5930   uint8_t* wptr = start;
5931   switch (type_) {
5932     case static_cast<int>(pu::ProtoWireType::kVarInt): {
5933       wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
5934       wptr = pu::WriteVarInt(int_value_, wptr);
5935       break;
5936     }
5937     case static_cast<int>(pu::ProtoWireType::kFixed32): {
5938       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
5939       uint32_t value32 = static_cast<uint32_t>(int_value_);
5940       memcpy(wptr, &value32, sizeof(value32));
5941       wptr += sizeof(uint32_t);
5942       break;
5943     }
5944     case static_cast<int>(pu::ProtoWireType::kFixed64): {
5945       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
5946       memcpy(wptr, &int_value_, sizeof(int_value_));
5947       wptr += sizeof(uint64_t);
5948       break;
5949     }
5950     case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
5951       ConstBytes payload = as_bytes();
5952       wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
5953       wptr = pu::WriteVarInt(payload.size, wptr);
5954       memcpy(wptr, payload.data, payload.size);
5955       wptr += payload.size;
5956       break;
5957     }
5958     default:
5959       PERFETTO_FATAL("Unknown field type %u", type_);
5960   }
5961   size_t written_size = static_cast<size_t>(wptr - start);
5962   PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
5963   PERFETTO_DCHECK(initial_size + written_size <= dst->size());
5964   dst->resize(initial_size + written_size);
5965 }
5966 
SerializeAndAppendTo(std::string * dst) const5967 void Field::SerializeAndAppendTo(std::string* dst) const {
5968   SerializeAndAppendToInternal(dst);
5969 }
5970 
SerializeAndAppendTo(std::vector<uint8_t> * dst) const5971 void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
5972   SerializeAndAppendToInternal(dst);
5973 }
5974 
5975 }  // namespace protozero
5976 // gen_amalgamated begin source: src/protozero/message.cc
5977 /*
5978  * Copyright (C) 2017 The Android Open Source Project
5979  *
5980  * Licensed under the Apache License, Version 2.0 (the "License");
5981  * you may not use this file except in compliance with the License.
5982  * You may obtain a copy of the License at
5983  *
5984  *      http://www.apache.org/licenses/LICENSE-2.0
5985  *
5986  * Unless required by applicable law or agreed to in writing, software
5987  * distributed under the License is distributed on an "AS IS" BASIS,
5988  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5989  * See the License for the specific language governing permissions and
5990  * limitations under the License.
5991  */
5992 
5993 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
5994 
5995 #include <atomic>
5996 #include <type_traits>
5997 
5998 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5999 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
6000 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
6001 
6002 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
6003 // The memcpy() for float and double below needs to be adjusted if we want to
6004 // support big endian CPUs. There doesn't seem to be a compelling need today.
6005 #error Unimplemented for big endian archs.
6006 #endif
6007 
6008 namespace protozero {
6009 
6010 namespace {
6011 
6012 #if PERFETTO_DCHECK_IS_ON()
6013 std::atomic<uint32_t> g_generation;
6014 #endif
6015 
6016 }  // namespace
6017 
6018 // Do NOT put any code in the constructor or use default initialization.
6019 // Use the Reset() method below instead.
6020 
6021 // This method is called to initialize both root and nested messages.
Reset(ScatteredStreamWriter * stream_writer,MessageArena * arena)6022 void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
6023 // Older versions of libstdcxx don't have is_trivially_constructible.
6024 #if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
6025   static_assert(std::is_trivially_constructible<Message>::value,
6026                 "Message must be trivially constructible");
6027 #endif
6028 
6029   static_assert(std::is_trivially_destructible<Message>::value,
6030                 "Message must be trivially destructible");
6031   stream_writer_ = stream_writer;
6032   arena_ = arena;
6033   size_ = 0;
6034   size_field_ = nullptr;
6035   size_already_written_ = 0;
6036   nested_message_ = nullptr;
6037   finalized_ = false;
6038 #if PERFETTO_DCHECK_IS_ON()
6039   handle_ = nullptr;
6040   generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
6041 #endif
6042 }
6043 
AppendString(uint32_t field_id,const char * str)6044 void Message::AppendString(uint32_t field_id, const char* str) {
6045   AppendBytes(field_id, str, strlen(str));
6046 }
6047 
AppendBytes(uint32_t field_id,const void * src,size_t size)6048 void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
6049   if (nested_message_)
6050     EndNestedMessage();
6051 
6052   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
6053   // Write the proto preamble (field id, type and length of the field).
6054   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
6055   uint8_t* pos = buffer;
6056   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
6057                                  pos);
6058   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
6059   WriteToStream(buffer, pos);
6060 
6061   const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
6062   WriteToStream(src_u8, src_u8 + size);
6063 }
6064 
AppendScatteredBytes(uint32_t field_id,ContiguousMemoryRange * ranges,size_t num_ranges)6065 size_t Message::AppendScatteredBytes(uint32_t field_id,
6066                                      ContiguousMemoryRange* ranges,
6067                                      size_t num_ranges) {
6068   size_t size = 0;
6069   for (size_t i = 0; i < num_ranges; ++i) {
6070     size += ranges[i].size();
6071   }
6072 
6073   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
6074 
6075   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
6076   uint8_t* pos = buffer;
6077   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
6078                                  pos);
6079   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
6080   WriteToStream(buffer, pos);
6081 
6082   for (size_t i = 0; i < num_ranges; ++i) {
6083     auto& range = ranges[i];
6084     WriteToStream(range.begin, range.end);
6085   }
6086 
6087   return size;
6088 }
6089 
Finalize()6090 uint32_t Message::Finalize() {
6091   if (finalized_)
6092     return size_;
6093 
6094   if (nested_message_)
6095     EndNestedMessage();
6096 
6097   // Write the length of the nested message a posteriori, using a leading-zero
6098   // redundant varint encoding.
6099   if (size_field_) {
6100     PERFETTO_DCHECK(!finalized_);
6101     PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
6102     PERFETTO_DCHECK(size_ >= size_already_written_);
6103     proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
6104                                       size_field_);
6105     size_field_ = nullptr;
6106   }
6107 
6108   finalized_ = true;
6109 #if PERFETTO_DCHECK_IS_ON()
6110   if (handle_)
6111     handle_->reset_message();
6112 #endif
6113 
6114   return size_;
6115 }
6116 
BeginNestedMessageInternal(uint32_t field_id)6117 Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
6118   if (nested_message_)
6119     EndNestedMessage();
6120 
6121   // Write the proto preamble for the nested message.
6122   uint8_t data[proto_utils::kMaxTagEncodedSize];
6123   uint8_t* data_end = proto_utils::WriteVarInt(
6124       proto_utils::MakeTagLengthDelimited(field_id), data);
6125   WriteToStream(data, data_end);
6126 
6127   Message* message = arena_->NewMessage();
6128   message->Reset(stream_writer_, arena_);
6129 
6130   // The length of the nested message cannot be known upfront. So right now
6131   // just reserve the bytes to encode the size after the nested message is done.
6132   message->set_size_field(
6133       stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
6134   size_ += proto_utils::kMessageLengthFieldSize;
6135 
6136   nested_message_ = message;
6137   return message;
6138 }
6139 
EndNestedMessage()6140 void Message::EndNestedMessage() {
6141   size_ += nested_message_->Finalize();
6142   arena_->DeleteLastMessage(nested_message_);
6143   nested_message_ = nullptr;
6144 }
6145 
6146 }  // namespace protozero
6147 // gen_amalgamated begin source: src/protozero/message_arena.cc
6148 /*
6149  * Copyright (C) 2020 The Android Open Source Project
6150  *
6151  * Licensed under the Apache License, Version 2.0 (the "License");
6152  * you may not use this file except in compliance with the License.
6153  * You may obtain a copy of the License at
6154  *
6155  *      http://www.apache.org/licenses/LICENSE-2.0
6156  *
6157  * Unless required by applicable law or agreed to in writing, software
6158  * distributed under the License is distributed on an "AS IS" BASIS,
6159  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6160  * See the License for the specific language governing permissions and
6161  * limitations under the License.
6162  */
6163 
6164 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
6165 
6166 #include <atomic>
6167 #include <type_traits>
6168 
6169 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6170 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
6171 
6172 namespace protozero {
6173 
MessageArena()6174 MessageArena::MessageArena() {
6175   // The code below assumes that there is always at least one block.
6176   blocks_.emplace_front();
6177   static_assert(std::alignment_of<decltype(blocks_.back().storage[0])>::value >=
6178                     alignof(Message),
6179                 "MessageArea's storage is not properly aligned");
6180 }
6181 
6182 MessageArena::~MessageArena() = default;
6183 
NewMessage()6184 Message* MessageArena::NewMessage() {
6185   PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.
6186 
6187   Block* block = &blocks_.back();
6188   if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
6189     blocks_.emplace_back();
6190     block = &blocks_.back();
6191   }
6192   const auto idx = block->entries++;
6193   void* storage = &block->storage[idx];
6194   PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
6195   return new (storage) Message();
6196 }
6197 
DeleteLastMessageInternal()6198 void MessageArena::DeleteLastMessageInternal() {
6199   PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
6200   Block* block = &blocks_.back();
6201   PERFETTO_DCHECK(block->entries > 0);
6202 
6203   // This is the reason why there is no ~Message() call here.
6204   // MessageArea::Reset() (see header) also relies on dtor being trivial.
6205   static_assert(std::is_trivially_destructible<Message>::value,
6206                 "Message must be trivially destructible");
6207 
6208   --block->entries;
6209   PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
6210 
6211   // Don't remove the first block to avoid malloc/free calls when the root
6212   // message is reset. Hitting the allocator all the times is a waste of time.
6213   if (block->entries == 0 && blocks_.size() > 1) {
6214     blocks_.pop_back();
6215   }
6216 }
6217 
6218 }  // namespace protozero
6219 // gen_amalgamated begin source: src/protozero/message_handle.cc
6220 /*
6221  * Copyright (C) 2017 The Android Open Source Project
6222  *
6223  * Licensed under the Apache License, Version 2.0 (the "License");
6224  * you may not use this file except in compliance with the License.
6225  * You may obtain a copy of the License at
6226  *
6227  *      http://www.apache.org/licenses/LICENSE-2.0
6228  *
6229  * Unless required by applicable law or agreed to in writing, software
6230  * distributed under the License is distributed on an "AS IS" BASIS,
6231  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6232  * See the License for the specific language governing permissions and
6233  * limitations under the License.
6234  */
6235 
6236 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
6237 
6238 #include <utility>
6239 
6240 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
6241 
6242 namespace protozero {
6243 
MessageHandleBase(Message * message)6244 MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
6245 #if PERFETTO_DCHECK_IS_ON()
6246   generation_ = message_ ? message->generation_ : 0;
6247   if (message_)
6248     message_->set_handle(this);
6249 #endif
6250 }
6251 
~MessageHandleBase()6252 MessageHandleBase::~MessageHandleBase() {
6253   if (message_) {
6254 #if PERFETTO_DCHECK_IS_ON()
6255     PERFETTO_DCHECK(generation_ == message_->generation_);
6256 #endif
6257     FinalizeMessage();
6258   }
6259 }
6260 
MessageHandleBase(MessageHandleBase && other)6261 MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
6262   Move(std::move(other));
6263 }
6264 
operator =(MessageHandleBase && other)6265 MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
6266   // If the current handle was pointing to a message and is being reset to a new
6267   // one, finalize the old message. However, if the other message is the same as
6268   // the one we point to, don't finalize.
6269   if (message_ && message_ != other.message_)
6270     FinalizeMessage();
6271   Move(std::move(other));
6272   return *this;
6273 }
6274 
Move(MessageHandleBase && other)6275 void MessageHandleBase::Move(MessageHandleBase&& other) {
6276   message_ = other.message_;
6277   other.message_ = nullptr;
6278 #if PERFETTO_DCHECK_IS_ON()
6279   if (message_) {
6280     generation_ = message_->generation_;
6281     message_->set_handle(this);
6282   }
6283 #endif
6284 }
6285 
6286 }  // namespace protozero
6287 // gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
6288 /*
6289  * Copyright (C) 2017 The Android Open Source Project
6290  *
6291  * Licensed under the Apache License, Version 2.0 (the "License");
6292  * you may not use this file except in compliance with the License.
6293  * You may obtain a copy of the License at
6294  *
6295  *      http://www.apache.org/licenses/LICENSE-2.0
6296  *
6297  * Unless required by applicable law or agreed to in writing, software
6298  * distributed under the License is distributed on an "AS IS" BASIS,
6299  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6300  * See the License for the specific language governing permissions and
6301  * limitations under the License.
6302  */
6303 
6304 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
6305 
6306 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
6307 
6308 namespace protozero {
6309 
6310 // static
6311 constexpr size_t PackedBufferBase::kOnStackStorageSize;
6312 
GrowSlowpath()6313 void PackedBufferBase::GrowSlowpath() {
6314   size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
6315   size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
6316   size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
6317   new_size = perfetto::base::AlignUp<4096>(new_size);
6318   std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
6319   memcpy(new_buf.get(), storage_begin_, old_size);
6320   heap_buf_ = std::move(new_buf);
6321   storage_begin_ = heap_buf_.get();
6322   storage_end_ = storage_begin_ + new_size;
6323   write_ptr_ = storage_begin_ + write_off;
6324 }
6325 
Reset()6326 void PackedBufferBase::Reset() {
6327   heap_buf_.reset();
6328   storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
6329   storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
6330   write_ptr_ = storage_begin_;
6331 }
6332 
6333 }  // namespace protozero
6334 // gen_amalgamated begin source: src/protozero/proto_decoder.cc
6335 /*
6336  * Copyright (C) 2018 The Android Open Source Project
6337  *
6338  * Licensed under the Apache License, Version 2.0 (the "License");
6339  * you may not use this file except in compliance with the License.
6340  * You may obtain a copy of the License at
6341  *
6342  *      http://www.apache.org/licenses/LICENSE-2.0
6343  *
6344  * Unless required by applicable law or agreed to in writing, software
6345  * distributed under the License is distributed on an "AS IS" BASIS,
6346  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6347  * See the License for the specific language governing permissions and
6348  * limitations under the License.
6349  */
6350 
6351 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
6352 
6353 #include <string.h>
6354 #include <limits>
6355 
6356 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6357 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
6358 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
6359 
6360 namespace protozero {
6361 
6362 using namespace proto_utils;
6363 
6364 #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
6365 #error Unimplemented for big endian archs.
6366 #endif
6367 
6368 namespace {
6369 
6370 struct ParseFieldResult {
6371   enum ParseResult { kAbort, kSkip, kOk };
6372   ParseResult parse_res;
6373   const uint8_t* next;
6374   Field field;
6375 };
6376 
6377 // Parses one field and returns the field itself and a pointer to the next
6378 // field to parse. If parsing fails, the returned |next| == |buffer|.
6379 PERFETTO_ALWAYS_INLINE ParseFieldResult
ParseOneField(const uint8_t * const buffer,const uint8_t * const end)6380 ParseOneField(const uint8_t* const buffer, const uint8_t* const end) {
6381   ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
6382 
6383   // The first byte of a proto field is structured as follows:
6384   // The least 3 significant bits determine the field type.
6385   // The most 5 significant bits determine the field id. If MSB == 1, the
6386   // field id continues on the next bytes following the VarInt encoding.
6387   const uint8_t kFieldTypeNumBits = 3;
6388   const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
6389   const uint8_t* pos = buffer;
6390 
6391   // If we've already hit the end, just return an invalid field.
6392   if (PERFETTO_UNLIKELY(pos >= end))
6393     return res;
6394 
6395   uint64_t preamble = 0;
6396   if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
6397     preamble = *(pos++);
6398   } else {
6399     const uint8_t* next = ParseVarInt(pos, end, &preamble);
6400     if (PERFETTO_UNLIKELY(pos == next))
6401       return res;
6402     pos = next;
6403   }
6404 
6405   uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
6406   if (field_id == 0 || pos >= end)
6407     return res;
6408 
6409   auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
6410   const uint8_t* new_pos = pos;
6411   uint64_t int_value = 0;
6412   uint64_t size = 0;
6413 
6414   switch (field_type) {
6415     case static_cast<uint8_t>(ProtoWireType::kVarInt): {
6416       new_pos = ParseVarInt(pos, end, &int_value);
6417 
6418       // new_pos not being greater than pos means ParseVarInt could not fully
6419       // parse the number. This is because we are out of space in the buffer.
6420       // Set the id to zero and return but don't update the offset so a future
6421       // read can read this field.
6422       if (PERFETTO_UNLIKELY(new_pos == pos))
6423         return res;
6424 
6425       break;
6426     }
6427 
6428     case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
6429       uint64_t payload_length;
6430       new_pos = ParseVarInt(pos, end, &payload_length);
6431       if (PERFETTO_UNLIKELY(new_pos == pos))
6432         return res;
6433 
6434       // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
6435       if (payload_length > static_cast<uint64_t>(end - new_pos))
6436         return res;
6437 
6438       const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
6439       int_value = payload_start;
6440       size = payload_length;
6441       new_pos += payload_length;
6442       break;
6443     }
6444 
6445     case static_cast<uint8_t>(ProtoWireType::kFixed64): {
6446       new_pos = pos + sizeof(uint64_t);
6447       if (PERFETTO_UNLIKELY(new_pos > end))
6448         return res;
6449       memcpy(&int_value, pos, sizeof(uint64_t));
6450       break;
6451     }
6452 
6453     case static_cast<uint8_t>(ProtoWireType::kFixed32): {
6454       new_pos = pos + sizeof(uint32_t);
6455       if (PERFETTO_UNLIKELY(new_pos > end))
6456         return res;
6457       memcpy(&int_value, pos, sizeof(uint32_t));
6458       break;
6459     }
6460 
6461     default:
6462       PERFETTO_DLOG("Invalid proto field type: %u", field_type);
6463       return res;
6464   }
6465 
6466   res.next = new_pos;
6467 
6468   if (PERFETTO_UNLIKELY(field_id > std::numeric_limits<uint16_t>::max())) {
6469     PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
6470                   field_id);
6471     res.parse_res = ParseFieldResult::kSkip;
6472     return res;
6473   }
6474 
6475   if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
6476     PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
6477                   " KB)",
6478                   field_id, size / 1024);
6479     res.parse_res = ParseFieldResult::kSkip;
6480     return res;
6481   }
6482 
6483   res.parse_res = ParseFieldResult::kOk;
6484   res.field.initialize(static_cast<uint16_t>(field_id), field_type, int_value,
6485                        static_cast<uint32_t>(size));
6486   return res;
6487 }
6488 
6489 }  // namespace
6490 
FindField(uint32_t field_id)6491 Field ProtoDecoder::FindField(uint32_t field_id) {
6492   Field res{};
6493   auto old_position = read_ptr_;
6494   read_ptr_ = begin_;
6495   for (auto f = ReadField(); f.valid(); f = ReadField()) {
6496     if (f.id() == field_id) {
6497       res = f;
6498       break;
6499     }
6500   }
6501   read_ptr_ = old_position;
6502   return res;
6503 }
6504 
6505 PERFETTO_ALWAYS_INLINE
ReadField()6506 Field ProtoDecoder::ReadField() {
6507   ParseFieldResult res;
6508   do {
6509     res = ParseOneField(read_ptr_, end_);
6510     read_ptr_ = res.next;
6511   } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
6512   return res.field;
6513 }
6514 
ParseAllFields()6515 void TypedProtoDecoderBase::ParseAllFields() {
6516   const uint8_t* cur = begin_;
6517   ParseFieldResult res;
6518   for (;;) {
6519     res = ParseOneField(cur, end_);
6520     PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
6521     cur = res.next;
6522     if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip)) {
6523       continue;
6524     } else if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort)) {
6525       break;
6526     }
6527     PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
6528     PERFETTO_DCHECK(res.field.valid());
6529     auto field_id = res.field.id();
6530     if (PERFETTO_UNLIKELY(field_id >= num_fields_))
6531       continue;
6532 
6533     Field* fld = &fields_[field_id];
6534     if (PERFETTO_LIKELY(!fld->valid())) {
6535       // This is the first time we see this field.
6536       *fld = std::move(res.field);
6537     } else {
6538       // Repeated field case.
6539       // In this case we need to:
6540       // 1. Append the last value of the field to end of the repeated field
6541       //    storage.
6542       // 2. Replace the default instance at offset |field_id| with the current
6543       //    value. This is because in case of repeated field a call to Get(X) is
6544       //    supposed to return the last value of X, not the first one.
6545       // This is so that the RepeatedFieldIterator will iterate in the right
6546       // order, see comments on RepeatedFieldIterator.
6547       if (PERFETTO_UNLIKELY(size_ >= capacity_)) {
6548         ExpandHeapStorage();
6549         // ExpandHeapStorage moves fields_ so we need to update the ptr to fld:
6550         fld = &fields_[field_id];
6551         PERFETTO_DCHECK(size_ < capacity_);
6552       }
6553       fields_[size_++] = *fld;
6554       *fld = std::move(res.field);
6555     }
6556   }
6557   read_ptr_ = res.next;
6558 }
6559 
ExpandHeapStorage()6560 void TypedProtoDecoderBase::ExpandHeapStorage() {
6561   uint32_t new_capacity = capacity_ * 2;
6562   PERFETTO_CHECK(new_capacity > size_);
6563   std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
6564 
6565   static_assert(std::is_trivially_copyable<Field>::value,
6566                 "Field must be trivially copyable");
6567   memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
6568 
6569   heap_storage_ = std::move(new_storage);
6570   fields_ = &heap_storage_[0];
6571   capacity_ = new_capacity;
6572 }
6573 
6574 }  // namespace protozero
6575 // gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
6576 /*
6577  * Copyright (C) 2017 The Android Open Source Project
6578  *
6579  * Licensed under the Apache License, Version 2.0 (the "License");
6580  * you may not use this file except in compliance with the License.
6581  * You may obtain a copy of the License at
6582  *
6583  *      http://www.apache.org/licenses/LICENSE-2.0
6584  *
6585  * Unless required by applicable law or agreed to in writing, software
6586  * distributed under the License is distributed on an "AS IS" BASIS,
6587  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6588  * See the License for the specific language governing permissions and
6589  * limitations under the License.
6590  */
6591 
6592 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
6593 
6594 #include <algorithm>
6595 
6596 namespace protozero {
6597 
Slice()6598 ScatteredHeapBuffer::Slice::Slice()
6599     : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
6600 
Slice(size_t size)6601 ScatteredHeapBuffer::Slice::Slice(size_t size)
6602     : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
6603       size_(size),
6604       unused_bytes_(size) {
6605   PERFETTO_DCHECK(size);
6606   Clear();
6607 }
6608 
6609 ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
6610 
6611 ScatteredHeapBuffer::Slice::~Slice() = default;
6612 
6613 ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
6614     default;
6615 
Clear()6616 void ScatteredHeapBuffer::Slice::Clear() {
6617   unused_bytes_ = size_;
6618 #if PERFETTO_DCHECK_IS_ON()
6619   memset(start(), 0xff, size_);
6620 #endif  // PERFETTO_DCHECK_IS_ON()
6621 }
6622 
ScatteredHeapBuffer(size_t initial_slice_size_bytes,size_t maximum_slice_size_bytes)6623 ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
6624                                          size_t maximum_slice_size_bytes)
6625     : next_slice_size_(initial_slice_size_bytes),
6626       maximum_slice_size_(maximum_slice_size_bytes) {
6627   PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
6628   PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
6629 }
6630 
6631 ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
6632 
GetNewBuffer()6633 protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
6634   PERFETTO_CHECK(writer_);
6635   AdjustUsedSizeOfCurrentSlice();
6636 
6637   if (cached_slice_.start()) {
6638     slices_.push_back(std::move(cached_slice_));
6639     PERFETTO_DCHECK(!cached_slice_.start());
6640   } else {
6641     slices_.emplace_back(next_slice_size_);
6642   }
6643   next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
6644   return slices_.back().GetTotalRange();
6645 }
6646 
StitchSlices()6647 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
6648   AdjustUsedSizeOfCurrentSlice();
6649   std::vector<uint8_t> buffer;
6650   for (const auto& slice : slices_) {
6651     auto used_range = slice.GetUsedRange();
6652     buffer.insert(buffer.end(), used_range.begin, used_range.end);
6653   }
6654   return buffer;
6655 }
6656 
GetRanges()6657 std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
6658   AdjustUsedSizeOfCurrentSlice();
6659   std::vector<protozero::ContiguousMemoryRange> ranges;
6660   for (const auto& slice : slices_)
6661     ranges.push_back(slice.GetUsedRange());
6662   return ranges;
6663 }
6664 
AdjustUsedSizeOfCurrentSlice()6665 void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
6666   if (!slices_.empty())
6667     slices_.back().set_unused_bytes(writer_->bytes_available());
6668 }
6669 
GetTotalSize()6670 size_t ScatteredHeapBuffer::GetTotalSize() {
6671   size_t total_size = 0;
6672   for (auto& slice : slices_) {
6673     total_size += slice.size();
6674   }
6675   return total_size;
6676 }
6677 
Reset()6678 void ScatteredHeapBuffer::Reset() {
6679   if (slices_.empty())
6680     return;
6681   cached_slice_ = std::move(slices_.front());
6682   cached_slice_.Clear();
6683   slices_.clear();
6684 }
6685 
6686 }  // namespace protozero
6687 // gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
6688 // gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
6689 /*
6690  * Copyright (C) 2018 The Android Open Source Project
6691  *
6692  * Licensed under the Apache License, Version 2.0 (the "License");
6693  * you may not use this file except in compliance with the License.
6694  * You may obtain a copy of the License at
6695  *
6696  *      http://www.apache.org/licenses/LICENSE-2.0
6697  *
6698  * Unless required by applicable law or agreed to in writing, software
6699  * distributed under the License is distributed on an "AS IS" BASIS,
6700  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6701  * See the License for the specific language governing permissions and
6702  * limitations under the License.
6703  */
6704 
6705 #ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
6706 #define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
6707 
6708 #include <memory>
6709 #include <vector>
6710 
6711 // gen_amalgamated expanded: #include "perfetto/base/export.h"
6712 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6713 // gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
6714 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
6715 
6716 namespace protozero {
6717 
6718 class PERFETTO_EXPORT ScatteredStreamWriterNullDelegate
6719     : public ScatteredStreamWriter::Delegate {
6720  public:
6721   explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
6722   ~ScatteredStreamWriterNullDelegate() override;
6723 
6724   // protozero::ScatteredStreamWriter::Delegate implementation.
6725   ContiguousMemoryRange GetNewBuffer() override;
6726 
6727  private:
6728   const size_t chunk_size_;
6729   std::unique_ptr<uint8_t[]> chunk_;
6730 };
6731 
6732 }  // namespace protozero
6733 
6734 #endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
6735 /*
6736  * Copyright (C) 2018 The Android Open Source Project
6737  *
6738  * Licensed under the Apache License, Version 2.0 (the "License");
6739  * you may not use this file except in compliance with the License.
6740  * You may obtain a copy of the License at
6741  *
6742  *      http://www.apache.org/licenses/LICENSE-2.0
6743  *
6744  * Unless required by applicable law or agreed to in writing, software
6745  * distributed under the License is distributed on an "AS IS" BASIS,
6746  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6747  * See the License for the specific language governing permissions and
6748  * limitations under the License.
6749  */
6750 
6751 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
6752 
6753 namespace protozero {
6754 
6755 // An implementation of ScatteredStreamWriter::Delegate which always returns
6756 // the same piece of memory.
6757 // This is used when we need to no-op the writers (e.g. during teardown or in
6758 // case of resource exhaustion), avoiding that the clients have to deal with
6759 // nullptr checks.
ScatteredStreamWriterNullDelegate(size_t chunk_size)6760 ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
6761     size_t chunk_size)
6762     : chunk_size_(chunk_size),
6763       chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
6764 
~ScatteredStreamWriterNullDelegate()6765 ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
6766 
GetNewBuffer()6767 ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
6768   return {chunk_.get(), chunk_.get() + chunk_size_};
6769 }
6770 
6771 }  // namespace protozero
6772 // gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
6773 /*
6774  * Copyright (C) 2017 The Android Open Source Project
6775  *
6776  * Licensed under the Apache License, Version 2.0 (the "License");
6777  * you may not use this file except in compliance with the License.
6778  * You may obtain a copy of the License at
6779  *
6780  *      http://www.apache.org/licenses/LICENSE-2.0
6781  *
6782  * Unless required by applicable law or agreed to in writing, software
6783  * distributed under the License is distributed on an "AS IS" BASIS,
6784  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6785  * See the License for the specific language governing permissions and
6786  * limitations under the License.
6787  */
6788 
6789 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
6790 
6791 #include <algorithm>
6792 
6793 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6794 
6795 namespace protozero {
6796 
~Delegate()6797 ScatteredStreamWriter::Delegate::~Delegate() {}
6798 
ScatteredStreamWriter(Delegate * delegate)6799 ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
6800     : delegate_(delegate),
6801       cur_range_({nullptr, nullptr}),
6802       write_ptr_(nullptr) {}
6803 
~ScatteredStreamWriter()6804 ScatteredStreamWriter::~ScatteredStreamWriter() {}
6805 
Reset(ContiguousMemoryRange range)6806 void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
6807   written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
6808   cur_range_ = range;
6809   write_ptr_ = range.begin;
6810   PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
6811 }
6812 
Extend()6813 void ScatteredStreamWriter::Extend() {
6814   Reset(delegate_->GetNewBuffer());
6815 }
6816 
WriteBytesSlowPath(const uint8_t * src,size_t size)6817 void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
6818                                                size_t size) {
6819   size_t bytes_left = size;
6820   while (bytes_left > 0) {
6821     if (write_ptr_ >= cur_range_.end)
6822       Extend();
6823     const size_t burst_size = std::min(bytes_available(), bytes_left);
6824     WriteBytesUnsafe(src, burst_size);
6825     bytes_left -= burst_size;
6826     src += burst_size;
6827   }
6828 }
6829 
6830 // TODO(primiano): perf optimization: I suspect that at the end this will always
6831 // be called with |size| == 4, in which case we might just hardcode it.
ReserveBytes(size_t size)6832 uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
6833   if (write_ptr_ + size > cur_range_.end) {
6834     // Assume the reservations are always < Delegate::GetNewBuffer().size(),
6835     // so that one single call to Extend() will definitely give enough headroom.
6836     Extend();
6837     PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
6838   }
6839   uint8_t* begin = write_ptr_;
6840   write_ptr_ += size;
6841 #if PERFETTO_DCHECK_IS_ON()
6842   memset(begin, 0, size);
6843 #endif
6844   return begin;
6845 }
6846 
6847 }  // namespace protozero
6848 // gen_amalgamated begin source: src/protozero/static_buffer.cc
6849 // gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
6850 /*
6851  * Copyright (C) 2019 The Android Open Source Project
6852  *
6853  * Licensed under the Apache License, Version 2.0 (the "License");
6854  * you may not use this file except in compliance with the License.
6855  * You may obtain a copy of the License at
6856  *
6857  *      http://www.apache.org/licenses/LICENSE-2.0
6858  *
6859  * Unless required by applicable law or agreed to in writing, software
6860  * distributed under the License is distributed on an "AS IS" BASIS,
6861  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6862  * See the License for the specific language governing permissions and
6863  * limitations under the License.
6864  */
6865 
6866 #ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
6867 #define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
6868 
6869 #include <memory>
6870 #include <string>
6871 #include <vector>
6872 
6873 // gen_amalgamated expanded: #include "perfetto/base/export.h"
6874 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
6875 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
6876 
6877 namespace protozero {
6878 
6879 class Message;
6880 
6881 // A simple implementation of ScatteredStreamWriter::Delegate backed by a
6882 // fixed-size buffer. It doesn't support expansion. The caller needs to ensure
6883 // to never write more than the size of the buffer. Will CHECK() otherwise.
6884 class PERFETTO_EXPORT StaticBufferDelegate
6885     : public ScatteredStreamWriter::Delegate {
6886  public:
StaticBufferDelegate(uint8_t * buf,size_t len)6887   StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
6888   ~StaticBufferDelegate() override;
6889 
6890   // ScatteredStreamWriter::Delegate implementation.
6891   ContiguousMemoryRange GetNewBuffer() override;
6892 
6893   ContiguousMemoryRange const range_;
6894   bool get_new_buffer_called_once_ = false;
6895 };
6896 
6897 // Helper function to create protozero messages backed by a fixed-size buffer
6898 // in one line. You can write:
6899 //   protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
6900 //   msg->set_stuff(...);
6901 //   size_t bytes_encoded = msg.Finalize();
6902 template <typename T /* protozero::Message */>
6903 class StaticBuffered {
6904  public:
StaticBuffered(void * buf,size_t len)6905   StaticBuffered(void* buf, size_t len)
6906       : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
6907     msg_.Reset(&writer_);
6908   }
6909 
6910   // This can't be neither copied nor moved because Message hands out pointers
6911   // to itself when creating submessages.
6912   StaticBuffered(const StaticBuffered&) = delete;
6913   StaticBuffered& operator=(const StaticBuffered&) = delete;
6914   StaticBuffered(StaticBuffered&&) = delete;
6915   StaticBuffered& operator=(StaticBuffered&&) = delete;
6916 
get()6917   T* get() { return &msg_; }
operator ->()6918   T* operator->() { return &msg_; }
6919 
6920   // The lack of a size() method is deliberate. It's to prevent that one
6921   // accidentally calls size() before Finalize().
6922 
6923   // Returns the number of encoded bytes (<= the size passed in the ctor).
Finalize()6924   size_t Finalize() {
6925     msg_.Finalize();
6926     return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
6927   }
6928 
6929  private:
6930   StaticBufferDelegate delegate_;
6931   ScatteredStreamWriter writer_;
6932   RootMessage<T> msg_;
6933 };
6934 
6935 // Helper function to create stack-based protozero messages in one line.
6936 // You can write:
6937 //   protozero::StackBuffered<protozero::MyMessage, 16> msg;
6938 //   msg->set_stuff(...);
6939 //   size_t bytes_encoded = msg.Finalize();
6940 template <typename T /* protozero::Message */, size_t N>
6941 class StackBuffered : public StaticBuffered<T> {
6942  public:
StackBuffered()6943   StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
6944 
6945  private:
6946   uint8_t buf_[N];  // Deliberately not initialized.
6947 };
6948 
6949 }  // namespace protozero
6950 
6951 #endif  // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
6952 /*
6953  * Copyright (C) 2019 The Android Open Source Project
6954  *
6955  * Licensed under the Apache License, Version 2.0 (the "License");
6956  * you may not use this file except in compliance with the License.
6957  * You may obtain a copy of the License at
6958  *
6959  *      http://www.apache.org/licenses/LICENSE-2.0
6960  *
6961  * Unless required by applicable law or agreed to in writing, software
6962  * distributed under the License is distributed on an "AS IS" BASIS,
6963  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6964  * See the License for the specific language governing permissions and
6965  * limitations under the License.
6966  */
6967 
6968 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
6969 
6970 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6971 
6972 namespace protozero {
6973 
6974 StaticBufferDelegate::~StaticBufferDelegate() = default;
6975 
GetNewBuffer()6976 ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
6977   if (get_new_buffer_called_once_) {
6978     // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
6979     // shouldn't try to grow the buffer after the initial call.
6980     PERFETTO_FATAL("Static buffer too small");
6981   }
6982   get_new_buffer_called_once_ = true;
6983   return range_;
6984 }
6985 
6986 }  // namespace protozero
6987 // gen_amalgamated begin source: src/protozero/virtual_destructors.cc
6988 /*
6989  * Copyright (C) 2019 The Android Open Source Project
6990  *
6991  * Licensed under the Apache License, Version 2.0 (the "License");
6992  * you may not use this file except in compliance with the License.
6993  * You may obtain a copy of the License at
6994  *
6995  *      http://www.apache.org/licenses/LICENSE-2.0
6996  *
6997  * Unless required by applicable law or agreed to in writing, software
6998  * distributed under the License is distributed on an "AS IS" BASIS,
6999  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7000  * See the License for the specific language governing permissions and
7001  * limitations under the License.
7002  */
7003 
7004 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7005 
7006 namespace protozero {
7007 
7008 CppMessageObj::~CppMessageObj() = default;
7009 
7010 }  // namespace protozero
7011 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
7012 // gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
7013 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7014 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
7015 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
7016 
7017 #include <stdint.h>
7018 #include <bitset>
7019 #include <vector>
7020 #include <string>
7021 #include <type_traits>
7022 
7023 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7024 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7025 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7026 
7027 namespace perfetto {
7028 namespace protos {
7029 namespace gen {
7030 enum AndroidLogId : int;
7031 enum AndroidLogPriority : int;
7032 }  // namespace perfetto
7033 }  // namespace protos
7034 }  // namespace gen
7035 
7036 namespace protozero {
7037 class Message;
7038 }  // namespace protozero
7039 
7040 namespace perfetto {
7041 namespace protos {
7042 namespace gen {
7043 enum AndroidLogId : int {
7044   LID_DEFAULT = 0,
7045   LID_RADIO = 1,
7046   LID_EVENTS = 2,
7047   LID_SYSTEM = 3,
7048   LID_CRASH = 4,
7049   LID_STATS = 5,
7050   LID_SECURITY = 6,
7051   LID_KERNEL = 7,
7052 };
7053 enum AndroidLogPriority : int {
7054   PRIO_UNSPECIFIED = 0,
7055   PRIO_UNUSED = 1,
7056   PRIO_VERBOSE = 2,
7057   PRIO_DEBUG = 3,
7058   PRIO_INFO = 4,
7059   PRIO_WARN = 5,
7060   PRIO_ERROR = 6,
7061   PRIO_FATAL = 7,
7062 };
7063 }  // namespace perfetto
7064 }  // namespace protos
7065 }  // namespace gen
7066 
7067 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
7068 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7069 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7070 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7071 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7072 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7073 #pragma GCC diagnostic push
7074 #pragma GCC diagnostic ignored "-Wfloat-equal"
7075 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
7076 
7077 namespace perfetto {
7078 namespace protos {
7079 namespace gen {
7080 }  // namespace perfetto
7081 }  // namespace protos
7082 }  // namespace gen
7083 #pragma GCC diagnostic pop
7084 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
7085 // gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
7086 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7087 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
7088 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
7089 
7090 #include <stdint.h>
7091 #include <bitset>
7092 #include <vector>
7093 #include <string>
7094 #include <type_traits>
7095 
7096 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7097 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7098 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7099 
7100 namespace perfetto {
7101 namespace protos {
7102 namespace gen {
7103 enum BuiltinClock : int;
7104 }  // namespace perfetto
7105 }  // namespace protos
7106 }  // namespace gen
7107 
7108 namespace protozero {
7109 class Message;
7110 }  // namespace protozero
7111 
7112 namespace perfetto {
7113 namespace protos {
7114 namespace gen {
7115 enum BuiltinClock : int {
7116   BUILTIN_CLOCK_UNKNOWN = 0,
7117   BUILTIN_CLOCK_REALTIME = 1,
7118   BUILTIN_CLOCK_REALTIME_COARSE = 2,
7119   BUILTIN_CLOCK_MONOTONIC = 3,
7120   BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
7121   BUILTIN_CLOCK_MONOTONIC_RAW = 5,
7122   BUILTIN_CLOCK_BOOTTIME = 6,
7123   BUILTIN_CLOCK_MAX_ID = 63,
7124 };
7125 }  // namespace perfetto
7126 }  // namespace protos
7127 }  // namespace gen
7128 
7129 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
7130 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7131 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7132 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7133 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7134 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7135 #pragma GCC diagnostic push
7136 #pragma GCC diagnostic ignored "-Wfloat-equal"
7137 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
7138 
7139 namespace perfetto {
7140 namespace protos {
7141 namespace gen {
7142 }  // namespace perfetto
7143 }  // namespace protos
7144 }  // namespace gen
7145 #pragma GCC diagnostic pop
7146 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
7147 // gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
7148 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7149 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
7150 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
7151 
7152 #include <stdint.h>
7153 #include <bitset>
7154 #include <vector>
7155 #include <string>
7156 #include <type_traits>
7157 
7158 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7159 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7160 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7161 
7162 namespace perfetto {
7163 namespace protos {
7164 namespace gen {
7165 class CommitDataRequest;
7166 class CommitDataRequest_ChunkToPatch;
7167 class CommitDataRequest_ChunkToPatch_Patch;
7168 class CommitDataRequest_ChunksToMove;
7169 }  // namespace perfetto
7170 }  // namespace protos
7171 }  // namespace gen
7172 
7173 namespace protozero {
7174 class Message;
7175 }  // namespace protozero
7176 
7177 namespace perfetto {
7178 namespace protos {
7179 namespace gen {
7180 
7181 class PERFETTO_EXPORT CommitDataRequest : public ::protozero::CppMessageObj {
7182  public:
7183   using ChunksToMove = CommitDataRequest_ChunksToMove;
7184   using ChunkToPatch = CommitDataRequest_ChunkToPatch;
7185   enum FieldNumbers {
7186     kChunksToMoveFieldNumber = 1,
7187     kChunksToPatchFieldNumber = 2,
7188     kFlushRequestIdFieldNumber = 3,
7189   };
7190 
7191   CommitDataRequest();
7192   ~CommitDataRequest() override;
7193   CommitDataRequest(CommitDataRequest&&) noexcept;
7194   CommitDataRequest& operator=(CommitDataRequest&&);
7195   CommitDataRequest(const CommitDataRequest&);
7196   CommitDataRequest& operator=(const CommitDataRequest&);
7197   bool operator==(const CommitDataRequest&) const;
operator !=(const CommitDataRequest & other) const7198   bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
7199 
7200   bool ParseFromArray(const void*, size_t) override;
7201   std::string SerializeAsString() const override;
7202   std::vector<uint8_t> SerializeAsArray() const override;
7203   void Serialize(::protozero::Message*) const;
7204 
chunks_to_move_size() const7205   int chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
chunks_to_move() const7206   const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
mutable_chunks_to_move()7207   std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
clear_chunks_to_move()7208   void clear_chunks_to_move() { chunks_to_move_.clear(); }
add_chunks_to_move()7209   CommitDataRequest_ChunksToMove* add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
7210 
chunks_to_patch_size() const7211   int chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
chunks_to_patch() const7212   const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
mutable_chunks_to_patch()7213   std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
clear_chunks_to_patch()7214   void clear_chunks_to_patch() { chunks_to_patch_.clear(); }
add_chunks_to_patch()7215   CommitDataRequest_ChunkToPatch* add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
7216 
has_flush_request_id() const7217   bool has_flush_request_id() const { return _has_field_[3]; }
flush_request_id() const7218   uint64_t flush_request_id() const { return flush_request_id_; }
set_flush_request_id(uint64_t value)7219   void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
7220 
7221  private:
7222   std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
7223   std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
7224   uint64_t flush_request_id_{};
7225 
7226   // Allows to preserve unknown protobuf fields for compatibility
7227   // with future versions of .proto files.
7228   std::string unknown_fields_;
7229 
7230   std::bitset<4> _has_field_{};
7231 };
7232 
7233 
7234 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
7235  public:
7236   using Patch = CommitDataRequest_ChunkToPatch_Patch;
7237   enum FieldNumbers {
7238     kTargetBufferFieldNumber = 1,
7239     kWriterIdFieldNumber = 2,
7240     kChunkIdFieldNumber = 3,
7241     kPatchesFieldNumber = 4,
7242     kHasMorePatchesFieldNumber = 5,
7243   };
7244 
7245   CommitDataRequest_ChunkToPatch();
7246   ~CommitDataRequest_ChunkToPatch() override;
7247   CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
7248   CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
7249   CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
7250   CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
7251   bool operator==(const CommitDataRequest_ChunkToPatch&) const;
operator !=(const CommitDataRequest_ChunkToPatch & other) const7252   bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
7253 
7254   bool ParseFromArray(const void*, size_t) override;
7255   std::string SerializeAsString() const override;
7256   std::vector<uint8_t> SerializeAsArray() const override;
7257   void Serialize(::protozero::Message*) const;
7258 
has_target_buffer() const7259   bool has_target_buffer() const { return _has_field_[1]; }
target_buffer() const7260   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)7261   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
7262 
has_writer_id() const7263   bool has_writer_id() const { return _has_field_[2]; }
writer_id() const7264   uint32_t writer_id() const { return writer_id_; }
set_writer_id(uint32_t value)7265   void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
7266 
has_chunk_id() const7267   bool has_chunk_id() const { return _has_field_[3]; }
chunk_id() const7268   uint32_t chunk_id() const { return chunk_id_; }
set_chunk_id(uint32_t value)7269   void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
7270 
patches_size() const7271   int patches_size() const { return static_cast<int>(patches_.size()); }
patches() const7272   const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
mutable_patches()7273   std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
clear_patches()7274   void clear_patches() { patches_.clear(); }
add_patches()7275   CommitDataRequest_ChunkToPatch_Patch* add_patches() { patches_.emplace_back(); return &patches_.back(); }
7276 
has_has_more_patches() const7277   bool has_has_more_patches() const { return _has_field_[5]; }
has_more_patches() const7278   bool has_more_patches() const { return has_more_patches_; }
set_has_more_patches(bool value)7279   void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
7280 
7281  private:
7282   uint32_t target_buffer_{};
7283   uint32_t writer_id_{};
7284   uint32_t chunk_id_{};
7285   std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
7286   bool has_more_patches_{};
7287 
7288   // Allows to preserve unknown protobuf fields for compatibility
7289   // with future versions of .proto files.
7290   std::string unknown_fields_;
7291 
7292   std::bitset<6> _has_field_{};
7293 };
7294 
7295 
7296 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
7297  public:
7298   enum FieldNumbers {
7299     kOffsetFieldNumber = 1,
7300     kDataFieldNumber = 2,
7301   };
7302 
7303   CommitDataRequest_ChunkToPatch_Patch();
7304   ~CommitDataRequest_ChunkToPatch_Patch() override;
7305   CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
7306   CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
7307   CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
7308   CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
7309   bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
operator !=(const CommitDataRequest_ChunkToPatch_Patch & other) const7310   bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
7311 
7312   bool ParseFromArray(const void*, size_t) override;
7313   std::string SerializeAsString() const override;
7314   std::vector<uint8_t> SerializeAsArray() const override;
7315   void Serialize(::protozero::Message*) const;
7316 
has_offset() const7317   bool has_offset() const { return _has_field_[1]; }
offset() const7318   uint32_t offset() const { return offset_; }
set_offset(uint32_t value)7319   void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
7320 
has_data() const7321   bool has_data() const { return _has_field_[2]; }
data() const7322   const std::string& data() const { return data_; }
set_data(const std::string & value)7323   void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
set_data(const void * p,size_t s)7324   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
7325 
7326  private:
7327   uint32_t offset_{};
7328   std::string data_{};
7329 
7330   // Allows to preserve unknown protobuf fields for compatibility
7331   // with future versions of .proto files.
7332   std::string unknown_fields_;
7333 
7334   std::bitset<3> _has_field_{};
7335 };
7336 
7337 
7338 class PERFETTO_EXPORT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
7339  public:
7340   enum FieldNumbers {
7341     kPageFieldNumber = 1,
7342     kChunkFieldNumber = 2,
7343     kTargetBufferFieldNumber = 3,
7344   };
7345 
7346   CommitDataRequest_ChunksToMove();
7347   ~CommitDataRequest_ChunksToMove() override;
7348   CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
7349   CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
7350   CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
7351   CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
7352   bool operator==(const CommitDataRequest_ChunksToMove&) const;
operator !=(const CommitDataRequest_ChunksToMove & other) const7353   bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
7354 
7355   bool ParseFromArray(const void*, size_t) override;
7356   std::string SerializeAsString() const override;
7357   std::vector<uint8_t> SerializeAsArray() const override;
7358   void Serialize(::protozero::Message*) const;
7359 
has_page() const7360   bool has_page() const { return _has_field_[1]; }
page() const7361   uint32_t page() const { return page_; }
set_page(uint32_t value)7362   void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
7363 
has_chunk() const7364   bool has_chunk() const { return _has_field_[2]; }
chunk() const7365   uint32_t chunk() const { return chunk_; }
set_chunk(uint32_t value)7366   void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
7367 
has_target_buffer() const7368   bool has_target_buffer() const { return _has_field_[3]; }
target_buffer() const7369   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)7370   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
7371 
7372  private:
7373   uint32_t page_{};
7374   uint32_t chunk_{};
7375   uint32_t target_buffer_{};
7376 
7377   // Allows to preserve unknown protobuf fields for compatibility
7378   // with future versions of .proto files.
7379   std::string unknown_fields_;
7380 
7381   std::bitset<4> _has_field_{};
7382 };
7383 
7384 }  // namespace perfetto
7385 }  // namespace protos
7386 }  // namespace gen
7387 
7388 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
7389 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7390 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7391 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7392 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7393 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7394 #pragma GCC diagnostic push
7395 #pragma GCC diagnostic ignored "-Wfloat-equal"
7396 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
7397 
7398 namespace perfetto {
7399 namespace protos {
7400 namespace gen {
7401 
7402 CommitDataRequest::CommitDataRequest() = default;
7403 CommitDataRequest::~CommitDataRequest() = default;
7404 CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
7405 CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
7406 CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
7407 CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
7408 
operator ==(const CommitDataRequest & other) const7409 bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
7410   return unknown_fields_ == other.unknown_fields_
7411    && chunks_to_move_ == other.chunks_to_move_
7412    && chunks_to_patch_ == other.chunks_to_patch_
7413    && flush_request_id_ == other.flush_request_id_;
7414 }
7415 
ParseFromArray(const void * raw,size_t size)7416 bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
7417   chunks_to_move_.clear();
7418   chunks_to_patch_.clear();
7419   unknown_fields_.clear();
7420   bool packed_error = false;
7421 
7422   ::protozero::ProtoDecoder dec(raw, size);
7423   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7424     if (field.id() < _has_field_.size()) {
7425       _has_field_.set(field.id());
7426     }
7427     switch (field.id()) {
7428       case 1 /* chunks_to_move */:
7429         chunks_to_move_.emplace_back();
7430         chunks_to_move_.back().ParseFromString(field.as_std_string());
7431         break;
7432       case 2 /* chunks_to_patch */:
7433         chunks_to_patch_.emplace_back();
7434         chunks_to_patch_.back().ParseFromString(field.as_std_string());
7435         break;
7436       case 3 /* flush_request_id */:
7437         field.get(&flush_request_id_);
7438         break;
7439       default:
7440         field.SerializeAndAppendTo(&unknown_fields_);
7441         break;
7442     }
7443   }
7444   return !packed_error && !dec.bytes_left();
7445 }
7446 
SerializeAsString() const7447 std::string CommitDataRequest::SerializeAsString() const {
7448   ::protozero::HeapBuffered<::protozero::Message> msg;
7449   Serialize(msg.get());
7450   return msg.SerializeAsString();
7451 }
7452 
SerializeAsArray() const7453 std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
7454   ::protozero::HeapBuffered<::protozero::Message> msg;
7455   Serialize(msg.get());
7456   return msg.SerializeAsArray();
7457 }
7458 
Serialize(::protozero::Message * msg) const7459 void CommitDataRequest::Serialize(::protozero::Message* msg) const {
7460   // Field 1: chunks_to_move
7461   for (auto& it : chunks_to_move_) {
7462     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
7463   }
7464 
7465   // Field 2: chunks_to_patch
7466   for (auto& it : chunks_to_patch_) {
7467     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
7468   }
7469 
7470   // Field 3: flush_request_id
7471   if (_has_field_[3]) {
7472     msg->AppendVarInt(3, flush_request_id_);
7473   }
7474 
7475   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7476 }
7477 
7478 
7479 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
7480 CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
7481 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
7482 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
7483 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
7484 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
7485 
operator ==(const CommitDataRequest_ChunkToPatch & other) const7486 bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
7487   return unknown_fields_ == other.unknown_fields_
7488    && target_buffer_ == other.target_buffer_
7489    && writer_id_ == other.writer_id_
7490    && chunk_id_ == other.chunk_id_
7491    && patches_ == other.patches_
7492    && has_more_patches_ == other.has_more_patches_;
7493 }
7494 
ParseFromArray(const void * raw,size_t size)7495 bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
7496   patches_.clear();
7497   unknown_fields_.clear();
7498   bool packed_error = false;
7499 
7500   ::protozero::ProtoDecoder dec(raw, size);
7501   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7502     if (field.id() < _has_field_.size()) {
7503       _has_field_.set(field.id());
7504     }
7505     switch (field.id()) {
7506       case 1 /* target_buffer */:
7507         field.get(&target_buffer_);
7508         break;
7509       case 2 /* writer_id */:
7510         field.get(&writer_id_);
7511         break;
7512       case 3 /* chunk_id */:
7513         field.get(&chunk_id_);
7514         break;
7515       case 4 /* patches */:
7516         patches_.emplace_back();
7517         patches_.back().ParseFromString(field.as_std_string());
7518         break;
7519       case 5 /* has_more_patches */:
7520         field.get(&has_more_patches_);
7521         break;
7522       default:
7523         field.SerializeAndAppendTo(&unknown_fields_);
7524         break;
7525     }
7526   }
7527   return !packed_error && !dec.bytes_left();
7528 }
7529 
SerializeAsString() const7530 std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
7531   ::protozero::HeapBuffered<::protozero::Message> msg;
7532   Serialize(msg.get());
7533   return msg.SerializeAsString();
7534 }
7535 
SerializeAsArray() const7536 std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
7537   ::protozero::HeapBuffered<::protozero::Message> msg;
7538   Serialize(msg.get());
7539   return msg.SerializeAsArray();
7540 }
7541 
Serialize(::protozero::Message * msg) const7542 void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
7543   // Field 1: target_buffer
7544   if (_has_field_[1]) {
7545     msg->AppendVarInt(1, target_buffer_);
7546   }
7547 
7548   // Field 2: writer_id
7549   if (_has_field_[2]) {
7550     msg->AppendVarInt(2, writer_id_);
7551   }
7552 
7553   // Field 3: chunk_id
7554   if (_has_field_[3]) {
7555     msg->AppendVarInt(3, chunk_id_);
7556   }
7557 
7558   // Field 4: patches
7559   for (auto& it : patches_) {
7560     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
7561   }
7562 
7563   // Field 5: has_more_patches
7564   if (_has_field_[5]) {
7565     msg->AppendTinyVarInt(5, has_more_patches_);
7566   }
7567 
7568   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7569 }
7570 
7571 
7572 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
7573 CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
7574 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
7575 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
7576 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
7577 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
7578 
operator ==(const CommitDataRequest_ChunkToPatch_Patch & other) const7579 bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
7580   return unknown_fields_ == other.unknown_fields_
7581    && offset_ == other.offset_
7582    && data_ == other.data_;
7583 }
7584 
ParseFromArray(const void * raw,size_t size)7585 bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
7586   unknown_fields_.clear();
7587   bool packed_error = false;
7588 
7589   ::protozero::ProtoDecoder dec(raw, size);
7590   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7591     if (field.id() < _has_field_.size()) {
7592       _has_field_.set(field.id());
7593     }
7594     switch (field.id()) {
7595       case 1 /* offset */:
7596         field.get(&offset_);
7597         break;
7598       case 2 /* data */:
7599         field.get(&data_);
7600         break;
7601       default:
7602         field.SerializeAndAppendTo(&unknown_fields_);
7603         break;
7604     }
7605   }
7606   return !packed_error && !dec.bytes_left();
7607 }
7608 
SerializeAsString() const7609 std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
7610   ::protozero::HeapBuffered<::protozero::Message> msg;
7611   Serialize(msg.get());
7612   return msg.SerializeAsString();
7613 }
7614 
SerializeAsArray() const7615 std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
7616   ::protozero::HeapBuffered<::protozero::Message> msg;
7617   Serialize(msg.get());
7618   return msg.SerializeAsArray();
7619 }
7620 
Serialize(::protozero::Message * msg) const7621 void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
7622   // Field 1: offset
7623   if (_has_field_[1]) {
7624     msg->AppendVarInt(1, offset_);
7625   }
7626 
7627   // Field 2: data
7628   if (_has_field_[2]) {
7629     msg->AppendString(2, data_);
7630   }
7631 
7632   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7633 }
7634 
7635 
7636 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
7637 CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
7638 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
7639 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
7640 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
7641 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
7642 
operator ==(const CommitDataRequest_ChunksToMove & other) const7643 bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
7644   return unknown_fields_ == other.unknown_fields_
7645    && page_ == other.page_
7646    && chunk_ == other.chunk_
7647    && target_buffer_ == other.target_buffer_;
7648 }
7649 
ParseFromArray(const void * raw,size_t size)7650 bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
7651   unknown_fields_.clear();
7652   bool packed_error = false;
7653 
7654   ::protozero::ProtoDecoder dec(raw, size);
7655   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7656     if (field.id() < _has_field_.size()) {
7657       _has_field_.set(field.id());
7658     }
7659     switch (field.id()) {
7660       case 1 /* page */:
7661         field.get(&page_);
7662         break;
7663       case 2 /* chunk */:
7664         field.get(&chunk_);
7665         break;
7666       case 3 /* target_buffer */:
7667         field.get(&target_buffer_);
7668         break;
7669       default:
7670         field.SerializeAndAppendTo(&unknown_fields_);
7671         break;
7672     }
7673   }
7674   return !packed_error && !dec.bytes_left();
7675 }
7676 
SerializeAsString() const7677 std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
7678   ::protozero::HeapBuffered<::protozero::Message> msg;
7679   Serialize(msg.get());
7680   return msg.SerializeAsString();
7681 }
7682 
SerializeAsArray() const7683 std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
7684   ::protozero::HeapBuffered<::protozero::Message> msg;
7685   Serialize(msg.get());
7686   return msg.SerializeAsArray();
7687 }
7688 
Serialize(::protozero::Message * msg) const7689 void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
7690   // Field 1: page
7691   if (_has_field_[1]) {
7692     msg->AppendVarInt(1, page_);
7693   }
7694 
7695   // Field 2: chunk
7696   if (_has_field_[2]) {
7697     msg->AppendVarInt(2, chunk_);
7698   }
7699 
7700   // Field 3: target_buffer
7701   if (_has_field_[3]) {
7702     msg->AppendVarInt(3, target_buffer_);
7703   }
7704 
7705   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7706 }
7707 
7708 }  // namespace perfetto
7709 }  // namespace protos
7710 }  // namespace gen
7711 #pragma GCC diagnostic pop
7712 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
7713 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
7714 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
7715 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
7716 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
7717 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7718 #pragma GCC diagnostic push
7719 #pragma GCC diagnostic ignored "-Wfloat-equal"
7720 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
7721 
7722 namespace perfetto {
7723 namespace protos {
7724 namespace gen {
7725 
7726 DataSourceDescriptor::DataSourceDescriptor() = default;
7727 DataSourceDescriptor::~DataSourceDescriptor() = default;
7728 DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
7729 DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
7730 DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
7731 DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
7732 
operator ==(const DataSourceDescriptor & other) const7733 bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
7734   return unknown_fields_ == other.unknown_fields_
7735    && name_ == other.name_
7736    && will_notify_on_stop_ == other.will_notify_on_stop_
7737    && will_notify_on_start_ == other.will_notify_on_start_
7738    && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
7739    && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
7740    && track_event_descriptor_ == other.track_event_descriptor_;
7741 }
7742 
ParseFromArray(const void * raw,size_t size)7743 bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
7744   unknown_fields_.clear();
7745   bool packed_error = false;
7746 
7747   ::protozero::ProtoDecoder dec(raw, size);
7748   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
7749     if (field.id() < _has_field_.size()) {
7750       _has_field_.set(field.id());
7751     }
7752     switch (field.id()) {
7753       case 1 /* name */:
7754         field.get(&name_);
7755         break;
7756       case 2 /* will_notify_on_stop */:
7757         field.get(&will_notify_on_stop_);
7758         break;
7759       case 3 /* will_notify_on_start */:
7760         field.get(&will_notify_on_start_);
7761         break;
7762       case 4 /* handles_incremental_state_clear */:
7763         field.get(&handles_incremental_state_clear_);
7764         break;
7765       case 5 /* gpu_counter_descriptor */:
7766         gpu_counter_descriptor_ = field.as_std_string();
7767         break;
7768       case 6 /* track_event_descriptor */:
7769         track_event_descriptor_ = field.as_std_string();
7770         break;
7771       default:
7772         field.SerializeAndAppendTo(&unknown_fields_);
7773         break;
7774     }
7775   }
7776   return !packed_error && !dec.bytes_left();
7777 }
7778 
SerializeAsString() const7779 std::string DataSourceDescriptor::SerializeAsString() const {
7780   ::protozero::HeapBuffered<::protozero::Message> msg;
7781   Serialize(msg.get());
7782   return msg.SerializeAsString();
7783 }
7784 
SerializeAsArray() const7785 std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
7786   ::protozero::HeapBuffered<::protozero::Message> msg;
7787   Serialize(msg.get());
7788   return msg.SerializeAsArray();
7789 }
7790 
Serialize(::protozero::Message * msg) const7791 void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
7792   // Field 1: name
7793   if (_has_field_[1]) {
7794     msg->AppendString(1, name_);
7795   }
7796 
7797   // Field 2: will_notify_on_stop
7798   if (_has_field_[2]) {
7799     msg->AppendTinyVarInt(2, will_notify_on_stop_);
7800   }
7801 
7802   // Field 3: will_notify_on_start
7803   if (_has_field_[3]) {
7804     msg->AppendTinyVarInt(3, will_notify_on_start_);
7805   }
7806 
7807   // Field 4: handles_incremental_state_clear
7808   if (_has_field_[4]) {
7809     msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
7810   }
7811 
7812   // Field 5: gpu_counter_descriptor
7813   if (_has_field_[5]) {
7814     msg->AppendString(5, gpu_counter_descriptor_);
7815   }
7816 
7817   // Field 6: track_event_descriptor
7818   if (_has_field_[6]) {
7819     msg->AppendString(6, track_event_descriptor_);
7820   }
7821 
7822   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
7823 }
7824 
7825 }  // namespace perfetto
7826 }  // namespace protos
7827 }  // namespace gen
7828 #pragma GCC diagnostic pop
7829 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
7830 // gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
7831 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
7832 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
7833 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
7834 
7835 #include <stdint.h>
7836 #include <bitset>
7837 #include <vector>
7838 #include <string>
7839 #include <type_traits>
7840 
7841 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
7842 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
7843 // gen_amalgamated expanded: #include "perfetto/base/export.h"
7844 
7845 namespace perfetto {
7846 namespace protos {
7847 namespace gen {
7848 class OneofOptions;
7849 class EnumValueDescriptorProto;
7850 class EnumDescriptorProto;
7851 class OneofDescriptorProto;
7852 class FieldDescriptorProto;
7853 class DescriptorProto;
7854 class DescriptorProto_ReservedRange;
7855 class FileDescriptorProto;
7856 class FileDescriptorSet;
7857 enum FieldDescriptorProto_Type : int;
7858 enum FieldDescriptorProto_Label : int;
7859 }  // namespace perfetto
7860 }  // namespace protos
7861 }  // namespace gen
7862 
7863 namespace protozero {
7864 class Message;
7865 }  // namespace protozero
7866 
7867 namespace perfetto {
7868 namespace protos {
7869 namespace gen {
7870 enum FieldDescriptorProto_Type : int {
7871   FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
7872   FieldDescriptorProto_Type_TYPE_FLOAT = 2,
7873   FieldDescriptorProto_Type_TYPE_INT64 = 3,
7874   FieldDescriptorProto_Type_TYPE_UINT64 = 4,
7875   FieldDescriptorProto_Type_TYPE_INT32 = 5,
7876   FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
7877   FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
7878   FieldDescriptorProto_Type_TYPE_BOOL = 8,
7879   FieldDescriptorProto_Type_TYPE_STRING = 9,
7880   FieldDescriptorProto_Type_TYPE_GROUP = 10,
7881   FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
7882   FieldDescriptorProto_Type_TYPE_BYTES = 12,
7883   FieldDescriptorProto_Type_TYPE_UINT32 = 13,
7884   FieldDescriptorProto_Type_TYPE_ENUM = 14,
7885   FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
7886   FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
7887   FieldDescriptorProto_Type_TYPE_SINT32 = 17,
7888   FieldDescriptorProto_Type_TYPE_SINT64 = 18,
7889 };
7890 enum FieldDescriptorProto_Label : int {
7891   FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
7892   FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
7893   FieldDescriptorProto_Label_LABEL_REPEATED = 3,
7894 };
7895 
7896 class PERFETTO_EXPORT OneofOptions : public ::protozero::CppMessageObj {
7897  public:
7898   enum FieldNumbers {
7899   };
7900 
7901   OneofOptions();
7902   ~OneofOptions() override;
7903   OneofOptions(OneofOptions&&) noexcept;
7904   OneofOptions& operator=(OneofOptions&&);
7905   OneofOptions(const OneofOptions&);
7906   OneofOptions& operator=(const OneofOptions&);
7907   bool operator==(const OneofOptions&) const;
operator !=(const OneofOptions & other) const7908   bool operator!=(const OneofOptions& other) const { return !(*this == other); }
7909 
7910   bool ParseFromArray(const void*, size_t) override;
7911   std::string SerializeAsString() const override;
7912   std::vector<uint8_t> SerializeAsArray() const override;
7913   void Serialize(::protozero::Message*) const;
7914 
7915  private:
7916 
7917   // Allows to preserve unknown protobuf fields for compatibility
7918   // with future versions of .proto files.
7919   std::string unknown_fields_;
7920 
7921   std::bitset<2> _has_field_{};
7922 };
7923 
7924 
7925 class PERFETTO_EXPORT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
7926  public:
7927   enum FieldNumbers {
7928     kNameFieldNumber = 1,
7929     kNumberFieldNumber = 2,
7930   };
7931 
7932   EnumValueDescriptorProto();
7933   ~EnumValueDescriptorProto() override;
7934   EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
7935   EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
7936   EnumValueDescriptorProto(const EnumValueDescriptorProto&);
7937   EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
7938   bool operator==(const EnumValueDescriptorProto&) const;
operator !=(const EnumValueDescriptorProto & other) const7939   bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
7940 
7941   bool ParseFromArray(const void*, size_t) override;
7942   std::string SerializeAsString() const override;
7943   std::vector<uint8_t> SerializeAsArray() const override;
7944   void Serialize(::protozero::Message*) const;
7945 
has_name() const7946   bool has_name() const { return _has_field_[1]; }
name() const7947   const std::string& name() const { return name_; }
set_name(const std::string & value)7948   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
7949 
has_number() const7950   bool has_number() const { return _has_field_[2]; }
number() const7951   int32_t number() const { return number_; }
set_number(int32_t value)7952   void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
7953 
7954  private:
7955   std::string name_{};
7956   int32_t number_{};
7957 
7958   // Allows to preserve unknown protobuf fields for compatibility
7959   // with future versions of .proto files.
7960   std::string unknown_fields_;
7961 
7962   std::bitset<3> _has_field_{};
7963 };
7964 
7965 
7966 class PERFETTO_EXPORT EnumDescriptorProto : public ::protozero::CppMessageObj {
7967  public:
7968   enum FieldNumbers {
7969     kNameFieldNumber = 1,
7970     kValueFieldNumber = 2,
7971     kReservedNameFieldNumber = 5,
7972   };
7973 
7974   EnumDescriptorProto();
7975   ~EnumDescriptorProto() override;
7976   EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
7977   EnumDescriptorProto& operator=(EnumDescriptorProto&&);
7978   EnumDescriptorProto(const EnumDescriptorProto&);
7979   EnumDescriptorProto& operator=(const EnumDescriptorProto&);
7980   bool operator==(const EnumDescriptorProto&) const;
operator !=(const EnumDescriptorProto & other) const7981   bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
7982 
7983   bool ParseFromArray(const void*, size_t) override;
7984   std::string SerializeAsString() const override;
7985   std::vector<uint8_t> SerializeAsArray() const override;
7986   void Serialize(::protozero::Message*) const;
7987 
has_name() const7988   bool has_name() const { return _has_field_[1]; }
name() const7989   const std::string& name() const { return name_; }
set_name(const std::string & value)7990   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
7991 
value_size() const7992   int value_size() const { return static_cast<int>(value_.size()); }
value() const7993   const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
mutable_value()7994   std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
clear_value()7995   void clear_value() { value_.clear(); }
add_value()7996   EnumValueDescriptorProto* add_value() { value_.emplace_back(); return &value_.back(); }
7997 
reserved_name_size() const7998   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
reserved_name() const7999   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()8000   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
clear_reserved_name()8001   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)8002   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()8003   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
8004 
8005  private:
8006   std::string name_{};
8007   std::vector<EnumValueDescriptorProto> value_;
8008   std::vector<std::string> reserved_name_;
8009 
8010   // Allows to preserve unknown protobuf fields for compatibility
8011   // with future versions of .proto files.
8012   std::string unknown_fields_;
8013 
8014   std::bitset<6> _has_field_{};
8015 };
8016 
8017 
8018 class PERFETTO_EXPORT OneofDescriptorProto : public ::protozero::CppMessageObj {
8019  public:
8020   enum FieldNumbers {
8021     kNameFieldNumber = 1,
8022     kOptionsFieldNumber = 2,
8023   };
8024 
8025   OneofDescriptorProto();
8026   ~OneofDescriptorProto() override;
8027   OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
8028   OneofDescriptorProto& operator=(OneofDescriptorProto&&);
8029   OneofDescriptorProto(const OneofDescriptorProto&);
8030   OneofDescriptorProto& operator=(const OneofDescriptorProto&);
8031   bool operator==(const OneofDescriptorProto&) const;
operator !=(const OneofDescriptorProto & other) const8032   bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
8033 
8034   bool ParseFromArray(const void*, size_t) override;
8035   std::string SerializeAsString() const override;
8036   std::vector<uint8_t> SerializeAsArray() const override;
8037   void Serialize(::protozero::Message*) const;
8038 
has_name() const8039   bool has_name() const { return _has_field_[1]; }
name() const8040   const std::string& name() const { return name_; }
set_name(const std::string & value)8041   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8042 
has_options() const8043   bool has_options() const { return _has_field_[2]; }
options() const8044   const OneofOptions& options() const { return *options_; }
mutable_options()8045   OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
8046 
8047  private:
8048   std::string name_{};
8049   ::protozero::CopyablePtr<OneofOptions> options_;
8050 
8051   // Allows to preserve unknown protobuf fields for compatibility
8052   // with future versions of .proto files.
8053   std::string unknown_fields_;
8054 
8055   std::bitset<3> _has_field_{};
8056 };
8057 
8058 
8059 class PERFETTO_EXPORT FieldDescriptorProto : public ::protozero::CppMessageObj {
8060  public:
8061   using Type = FieldDescriptorProto_Type;
8062   static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
8063   static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
8064   static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
8065   static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
8066   static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
8067   static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
8068   static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
8069   static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
8070   static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
8071   static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
8072   static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
8073   static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
8074   static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
8075   static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
8076   static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
8077   static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
8078   static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
8079   static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
8080   static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
8081   static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
8082   using Label = FieldDescriptorProto_Label;
8083   static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
8084   static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
8085   static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
8086   static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
8087   static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
8088   enum FieldNumbers {
8089     kNameFieldNumber = 1,
8090     kNumberFieldNumber = 3,
8091     kLabelFieldNumber = 4,
8092     kTypeFieldNumber = 5,
8093     kTypeNameFieldNumber = 6,
8094     kExtendeeFieldNumber = 2,
8095     kDefaultValueFieldNumber = 7,
8096     kOneofIndexFieldNumber = 9,
8097   };
8098 
8099   FieldDescriptorProto();
8100   ~FieldDescriptorProto() override;
8101   FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
8102   FieldDescriptorProto& operator=(FieldDescriptorProto&&);
8103   FieldDescriptorProto(const FieldDescriptorProto&);
8104   FieldDescriptorProto& operator=(const FieldDescriptorProto&);
8105   bool operator==(const FieldDescriptorProto&) const;
operator !=(const FieldDescriptorProto & other) const8106   bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
8107 
8108   bool ParseFromArray(const void*, size_t) override;
8109   std::string SerializeAsString() const override;
8110   std::vector<uint8_t> SerializeAsArray() const override;
8111   void Serialize(::protozero::Message*) const;
8112 
has_name() const8113   bool has_name() const { return _has_field_[1]; }
name() const8114   const std::string& name() const { return name_; }
set_name(const std::string & value)8115   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8116 
has_number() const8117   bool has_number() const { return _has_field_[3]; }
number() const8118   int32_t number() const { return number_; }
set_number(int32_t value)8119   void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
8120 
has_label() const8121   bool has_label() const { return _has_field_[4]; }
label() const8122   FieldDescriptorProto_Label label() const { return label_; }
set_label(FieldDescriptorProto_Label value)8123   void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
8124 
has_type() const8125   bool has_type() const { return _has_field_[5]; }
type() const8126   FieldDescriptorProto_Type type() const { return type_; }
set_type(FieldDescriptorProto_Type value)8127   void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
8128 
has_type_name() const8129   bool has_type_name() const { return _has_field_[6]; }
type_name() const8130   const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & value)8131   void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
8132 
has_extendee() const8133   bool has_extendee() const { return _has_field_[2]; }
extendee() const8134   const std::string& extendee() const { return extendee_; }
set_extendee(const std::string & value)8135   void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
8136 
has_default_value() const8137   bool has_default_value() const { return _has_field_[7]; }
default_value() const8138   const std::string& default_value() const { return default_value_; }
set_default_value(const std::string & value)8139   void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
8140 
has_oneof_index() const8141   bool has_oneof_index() const { return _has_field_[9]; }
oneof_index() const8142   int32_t oneof_index() const { return oneof_index_; }
set_oneof_index(int32_t value)8143   void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
8144 
8145  private:
8146   std::string name_{};
8147   int32_t number_{};
8148   FieldDescriptorProto_Label label_{};
8149   FieldDescriptorProto_Type type_{};
8150   std::string type_name_{};
8151   std::string extendee_{};
8152   std::string default_value_{};
8153   int32_t oneof_index_{};
8154 
8155   // Allows to preserve unknown protobuf fields for compatibility
8156   // with future versions of .proto files.
8157   std::string unknown_fields_;
8158 
8159   std::bitset<10> _has_field_{};
8160 };
8161 
8162 
8163 class PERFETTO_EXPORT DescriptorProto : public ::protozero::CppMessageObj {
8164  public:
8165   using ReservedRange = DescriptorProto_ReservedRange;
8166   enum FieldNumbers {
8167     kNameFieldNumber = 1,
8168     kFieldFieldNumber = 2,
8169     kExtensionFieldNumber = 6,
8170     kNestedTypeFieldNumber = 3,
8171     kEnumTypeFieldNumber = 4,
8172     kOneofDeclFieldNumber = 8,
8173     kReservedRangeFieldNumber = 9,
8174     kReservedNameFieldNumber = 10,
8175   };
8176 
8177   DescriptorProto();
8178   ~DescriptorProto() override;
8179   DescriptorProto(DescriptorProto&&) noexcept;
8180   DescriptorProto& operator=(DescriptorProto&&);
8181   DescriptorProto(const DescriptorProto&);
8182   DescriptorProto& operator=(const DescriptorProto&);
8183   bool operator==(const DescriptorProto&) const;
operator !=(const DescriptorProto & other) const8184   bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
8185 
8186   bool ParseFromArray(const void*, size_t) override;
8187   std::string SerializeAsString() const override;
8188   std::vector<uint8_t> SerializeAsArray() const override;
8189   void Serialize(::protozero::Message*) const;
8190 
has_name() const8191   bool has_name() const { return _has_field_[1]; }
name() const8192   const std::string& name() const { return name_; }
set_name(const std::string & value)8193   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8194 
field_size() const8195   int field_size() const { return static_cast<int>(field_.size()); }
field() const8196   const std::vector<FieldDescriptorProto>& field() const { return field_; }
mutable_field()8197   std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
clear_field()8198   void clear_field() { field_.clear(); }
add_field()8199   FieldDescriptorProto* add_field() { field_.emplace_back(); return &field_.back(); }
8200 
extension_size() const8201   int extension_size() const { return static_cast<int>(extension_.size()); }
extension() const8202   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()8203   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
clear_extension()8204   void clear_extension() { extension_.clear(); }
add_extension()8205   FieldDescriptorProto* add_extension() { extension_.emplace_back(); return &extension_.back(); }
8206 
nested_type_size() const8207   int nested_type_size() const { return static_cast<int>(nested_type_.size()); }
nested_type() const8208   const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
mutable_nested_type()8209   std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
clear_nested_type()8210   void clear_nested_type() { nested_type_.clear(); }
add_nested_type()8211   DescriptorProto* add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
8212 
enum_type_size() const8213   int enum_type_size() const { return static_cast<int>(enum_type_.size()); }
enum_type() const8214   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()8215   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
clear_enum_type()8216   void clear_enum_type() { enum_type_.clear(); }
add_enum_type()8217   EnumDescriptorProto* add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
8218 
oneof_decl_size() const8219   int oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
oneof_decl() const8220   const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
mutable_oneof_decl()8221   std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
clear_oneof_decl()8222   void clear_oneof_decl() { oneof_decl_.clear(); }
add_oneof_decl()8223   OneofDescriptorProto* add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
8224 
reserved_range_size() const8225   int reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
reserved_range() const8226   const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
mutable_reserved_range()8227   std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
clear_reserved_range()8228   void clear_reserved_range() { reserved_range_.clear(); }
add_reserved_range()8229   DescriptorProto_ReservedRange* add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
8230 
reserved_name_size() const8231   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
reserved_name() const8232   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()8233   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
clear_reserved_name()8234   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)8235   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()8236   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
8237 
8238  private:
8239   std::string name_{};
8240   std::vector<FieldDescriptorProto> field_;
8241   std::vector<FieldDescriptorProto> extension_;
8242   std::vector<DescriptorProto> nested_type_;
8243   std::vector<EnumDescriptorProto> enum_type_;
8244   std::vector<OneofDescriptorProto> oneof_decl_;
8245   std::vector<DescriptorProto_ReservedRange> reserved_range_;
8246   std::vector<std::string> reserved_name_;
8247 
8248   // Allows to preserve unknown protobuf fields for compatibility
8249   // with future versions of .proto files.
8250   std::string unknown_fields_;
8251 
8252   std::bitset<11> _has_field_{};
8253 };
8254 
8255 
8256 class PERFETTO_EXPORT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
8257  public:
8258   enum FieldNumbers {
8259     kStartFieldNumber = 1,
8260     kEndFieldNumber = 2,
8261   };
8262 
8263   DescriptorProto_ReservedRange();
8264   ~DescriptorProto_ReservedRange() override;
8265   DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
8266   DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
8267   DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
8268   DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
8269   bool operator==(const DescriptorProto_ReservedRange&) const;
operator !=(const DescriptorProto_ReservedRange & other) const8270   bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
8271 
8272   bool ParseFromArray(const void*, size_t) override;
8273   std::string SerializeAsString() const override;
8274   std::vector<uint8_t> SerializeAsArray() const override;
8275   void Serialize(::protozero::Message*) const;
8276 
has_start() const8277   bool has_start() const { return _has_field_[1]; }
start() const8278   int32_t start() const { return start_; }
set_start(int32_t value)8279   void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
8280 
has_end() const8281   bool has_end() const { return _has_field_[2]; }
end() const8282   int32_t end() const { return end_; }
set_end(int32_t value)8283   void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
8284 
8285  private:
8286   int32_t start_{};
8287   int32_t end_{};
8288 
8289   // Allows to preserve unknown protobuf fields for compatibility
8290   // with future versions of .proto files.
8291   std::string unknown_fields_;
8292 
8293   std::bitset<3> _has_field_{};
8294 };
8295 
8296 
8297 class PERFETTO_EXPORT FileDescriptorProto : public ::protozero::CppMessageObj {
8298  public:
8299   enum FieldNumbers {
8300     kNameFieldNumber = 1,
8301     kPackageFieldNumber = 2,
8302     kDependencyFieldNumber = 3,
8303     kPublicDependencyFieldNumber = 10,
8304     kWeakDependencyFieldNumber = 11,
8305     kMessageTypeFieldNumber = 4,
8306     kEnumTypeFieldNumber = 5,
8307     kExtensionFieldNumber = 7,
8308   };
8309 
8310   FileDescriptorProto();
8311   ~FileDescriptorProto() override;
8312   FileDescriptorProto(FileDescriptorProto&&) noexcept;
8313   FileDescriptorProto& operator=(FileDescriptorProto&&);
8314   FileDescriptorProto(const FileDescriptorProto&);
8315   FileDescriptorProto& operator=(const FileDescriptorProto&);
8316   bool operator==(const FileDescriptorProto&) const;
operator !=(const FileDescriptorProto & other) const8317   bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
8318 
8319   bool ParseFromArray(const void*, size_t) override;
8320   std::string SerializeAsString() const override;
8321   std::vector<uint8_t> SerializeAsArray() const override;
8322   void Serialize(::protozero::Message*) const;
8323 
has_name() const8324   bool has_name() const { return _has_field_[1]; }
name() const8325   const std::string& name() const { return name_; }
set_name(const std::string & value)8326   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
8327 
has_package() const8328   bool has_package() const { return _has_field_[2]; }
package() const8329   const std::string& package() const { return package_; }
set_package(const std::string & value)8330   void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
8331 
dependency_size() const8332   int dependency_size() const { return static_cast<int>(dependency_.size()); }
dependency() const8333   const std::vector<std::string>& dependency() const { return dependency_; }
mutable_dependency()8334   std::vector<std::string>* mutable_dependency() { return &dependency_; }
clear_dependency()8335   void clear_dependency() { dependency_.clear(); }
add_dependency(std::string value)8336   void add_dependency(std::string value) { dependency_.emplace_back(value); }
add_dependency()8337   std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
8338 
public_dependency_size() const8339   int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
public_dependency() const8340   const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
mutable_public_dependency()8341   std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
clear_public_dependency()8342   void clear_public_dependency() { public_dependency_.clear(); }
add_public_dependency(int32_t value)8343   void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
add_public_dependency()8344   int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
8345 
weak_dependency_size() const8346   int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
weak_dependency() const8347   const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
mutable_weak_dependency()8348   std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
clear_weak_dependency()8349   void clear_weak_dependency() { weak_dependency_.clear(); }
add_weak_dependency(int32_t value)8350   void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
add_weak_dependency()8351   int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
8352 
message_type_size() const8353   int message_type_size() const { return static_cast<int>(message_type_.size()); }
message_type() const8354   const std::vector<DescriptorProto>& message_type() const { return message_type_; }
mutable_message_type()8355   std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
clear_message_type()8356   void clear_message_type() { message_type_.clear(); }
add_message_type()8357   DescriptorProto* add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
8358 
enum_type_size() const8359   int enum_type_size() const { return static_cast<int>(enum_type_.size()); }
enum_type() const8360   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()8361   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
clear_enum_type()8362   void clear_enum_type() { enum_type_.clear(); }
add_enum_type()8363   EnumDescriptorProto* add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
8364 
extension_size() const8365   int extension_size() const { return static_cast<int>(extension_.size()); }
extension() const8366   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()8367   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
clear_extension()8368   void clear_extension() { extension_.clear(); }
add_extension()8369   FieldDescriptorProto* add_extension() { extension_.emplace_back(); return &extension_.back(); }
8370 
8371  private:
8372   std::string name_{};
8373   std::string package_{};
8374   std::vector<std::string> dependency_;
8375   std::vector<int32_t> public_dependency_;
8376   std::vector<int32_t> weak_dependency_;
8377   std::vector<DescriptorProto> message_type_;
8378   std::vector<EnumDescriptorProto> enum_type_;
8379   std::vector<FieldDescriptorProto> extension_;
8380 
8381   // Allows to preserve unknown protobuf fields for compatibility
8382   // with future versions of .proto files.
8383   std::string unknown_fields_;
8384 
8385   std::bitset<12> _has_field_{};
8386 };
8387 
8388 
8389 class PERFETTO_EXPORT FileDescriptorSet : public ::protozero::CppMessageObj {
8390  public:
8391   enum FieldNumbers {
8392     kFileFieldNumber = 1,
8393   };
8394 
8395   FileDescriptorSet();
8396   ~FileDescriptorSet() override;
8397   FileDescriptorSet(FileDescriptorSet&&) noexcept;
8398   FileDescriptorSet& operator=(FileDescriptorSet&&);
8399   FileDescriptorSet(const FileDescriptorSet&);
8400   FileDescriptorSet& operator=(const FileDescriptorSet&);
8401   bool operator==(const FileDescriptorSet&) const;
operator !=(const FileDescriptorSet & other) const8402   bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
8403 
8404   bool ParseFromArray(const void*, size_t) override;
8405   std::string SerializeAsString() const override;
8406   std::vector<uint8_t> SerializeAsArray() const override;
8407   void Serialize(::protozero::Message*) const;
8408 
file_size() const8409   int file_size() const { return static_cast<int>(file_.size()); }
file() const8410   const std::vector<FileDescriptorProto>& file() const { return file_; }
mutable_file()8411   std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
clear_file()8412   void clear_file() { file_.clear(); }
add_file()8413   FileDescriptorProto* add_file() { file_.emplace_back(); return &file_.back(); }
8414 
8415  private:
8416   std::vector<FileDescriptorProto> file_;
8417 
8418   // Allows to preserve unknown protobuf fields for compatibility
8419   // with future versions of .proto files.
8420   std::string unknown_fields_;
8421 
8422   std::bitset<2> _has_field_{};
8423 };
8424 
8425 }  // namespace perfetto
8426 }  // namespace protos
8427 }  // namespace gen
8428 
8429 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
8430 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
8431 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
8432 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
8433 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
8434 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
8435 #pragma GCC diagnostic push
8436 #pragma GCC diagnostic ignored "-Wfloat-equal"
8437 // gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
8438 
8439 namespace perfetto {
8440 namespace protos {
8441 namespace gen {
8442 
8443 OneofOptions::OneofOptions() = default;
8444 OneofOptions::~OneofOptions() = default;
8445 OneofOptions::OneofOptions(const OneofOptions&) = default;
8446 OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
8447 OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
8448 OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
8449 
operator ==(const OneofOptions & other) const8450 bool OneofOptions::operator==(const OneofOptions& other) const {
8451   return unknown_fields_ == other.unknown_fields_;
8452 }
8453 
ParseFromArray(const void * raw,size_t size)8454 bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
8455   unknown_fields_.clear();
8456   bool packed_error = false;
8457 
8458   ::protozero::ProtoDecoder dec(raw, size);
8459   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8460     if (field.id() < _has_field_.size()) {
8461       _has_field_.set(field.id());
8462     }
8463     switch (field.id()) {
8464       default:
8465         field.SerializeAndAppendTo(&unknown_fields_);
8466         break;
8467     }
8468   }
8469   return !packed_error && !dec.bytes_left();
8470 }
8471 
SerializeAsString() const8472 std::string OneofOptions::SerializeAsString() const {
8473   ::protozero::HeapBuffered<::protozero::Message> msg;
8474   Serialize(msg.get());
8475   return msg.SerializeAsString();
8476 }
8477 
SerializeAsArray() const8478 std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
8479   ::protozero::HeapBuffered<::protozero::Message> msg;
8480   Serialize(msg.get());
8481   return msg.SerializeAsArray();
8482 }
8483 
Serialize(::protozero::Message * msg) const8484 void OneofOptions::Serialize(::protozero::Message* msg) const {
8485   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8486 }
8487 
8488 
8489 EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
8490 EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
8491 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
8492 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
8493 EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
8494 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
8495 
operator ==(const EnumValueDescriptorProto & other) const8496 bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
8497   return unknown_fields_ == other.unknown_fields_
8498    && name_ == other.name_
8499    && number_ == other.number_;
8500 }
8501 
ParseFromArray(const void * raw,size_t size)8502 bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8503   unknown_fields_.clear();
8504   bool packed_error = false;
8505 
8506   ::protozero::ProtoDecoder dec(raw, size);
8507   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8508     if (field.id() < _has_field_.size()) {
8509       _has_field_.set(field.id());
8510     }
8511     switch (field.id()) {
8512       case 1 /* name */:
8513         field.get(&name_);
8514         break;
8515       case 2 /* number */:
8516         field.get(&number_);
8517         break;
8518       default:
8519         field.SerializeAndAppendTo(&unknown_fields_);
8520         break;
8521     }
8522   }
8523   return !packed_error && !dec.bytes_left();
8524 }
8525 
SerializeAsString() const8526 std::string EnumValueDescriptorProto::SerializeAsString() const {
8527   ::protozero::HeapBuffered<::protozero::Message> msg;
8528   Serialize(msg.get());
8529   return msg.SerializeAsString();
8530 }
8531 
SerializeAsArray() const8532 std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
8533   ::protozero::HeapBuffered<::protozero::Message> msg;
8534   Serialize(msg.get());
8535   return msg.SerializeAsArray();
8536 }
8537 
Serialize(::protozero::Message * msg) const8538 void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
8539   // Field 1: name
8540   if (_has_field_[1]) {
8541     msg->AppendString(1, name_);
8542   }
8543 
8544   // Field 2: number
8545   if (_has_field_[2]) {
8546     msg->AppendVarInt(2, number_);
8547   }
8548 
8549   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8550 }
8551 
8552 
8553 EnumDescriptorProto::EnumDescriptorProto() = default;
8554 EnumDescriptorProto::~EnumDescriptorProto() = default;
8555 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
8556 EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
8557 EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
8558 EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
8559 
operator ==(const EnumDescriptorProto & other) const8560 bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
8561   return unknown_fields_ == other.unknown_fields_
8562    && name_ == other.name_
8563    && value_ == other.value_
8564    && reserved_name_ == other.reserved_name_;
8565 }
8566 
ParseFromArray(const void * raw,size_t size)8567 bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8568   value_.clear();
8569   reserved_name_.clear();
8570   unknown_fields_.clear();
8571   bool packed_error = false;
8572 
8573   ::protozero::ProtoDecoder dec(raw, size);
8574   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8575     if (field.id() < _has_field_.size()) {
8576       _has_field_.set(field.id());
8577     }
8578     switch (field.id()) {
8579       case 1 /* name */:
8580         field.get(&name_);
8581         break;
8582       case 2 /* value */:
8583         value_.emplace_back();
8584         value_.back().ParseFromString(field.as_std_string());
8585         break;
8586       case 5 /* reserved_name */:
8587         reserved_name_.emplace_back();
8588         field.get(&reserved_name_.back());
8589         break;
8590       default:
8591         field.SerializeAndAppendTo(&unknown_fields_);
8592         break;
8593     }
8594   }
8595   return !packed_error && !dec.bytes_left();
8596 }
8597 
SerializeAsString() const8598 std::string EnumDescriptorProto::SerializeAsString() const {
8599   ::protozero::HeapBuffered<::protozero::Message> msg;
8600   Serialize(msg.get());
8601   return msg.SerializeAsString();
8602 }
8603 
SerializeAsArray() const8604 std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
8605   ::protozero::HeapBuffered<::protozero::Message> msg;
8606   Serialize(msg.get());
8607   return msg.SerializeAsArray();
8608 }
8609 
Serialize(::protozero::Message * msg) const8610 void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
8611   // Field 1: name
8612   if (_has_field_[1]) {
8613     msg->AppendString(1, name_);
8614   }
8615 
8616   // Field 2: value
8617   for (auto& it : value_) {
8618     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
8619   }
8620 
8621   // Field 5: reserved_name
8622   for (auto& it : reserved_name_) {
8623     msg->AppendString(5, it);
8624   }
8625 
8626   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8627 }
8628 
8629 
8630 OneofDescriptorProto::OneofDescriptorProto() = default;
8631 OneofDescriptorProto::~OneofDescriptorProto() = default;
8632 OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
8633 OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
8634 OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
8635 OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
8636 
operator ==(const OneofDescriptorProto & other) const8637 bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
8638   return unknown_fields_ == other.unknown_fields_
8639    && name_ == other.name_
8640    && options_ == other.options_;
8641 }
8642 
ParseFromArray(const void * raw,size_t size)8643 bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8644   unknown_fields_.clear();
8645   bool packed_error = false;
8646 
8647   ::protozero::ProtoDecoder dec(raw, size);
8648   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8649     if (field.id() < _has_field_.size()) {
8650       _has_field_.set(field.id());
8651     }
8652     switch (field.id()) {
8653       case 1 /* name */:
8654         field.get(&name_);
8655         break;
8656       case 2 /* options */:
8657         (*options_).ParseFromString(field.as_std_string());
8658         break;
8659       default:
8660         field.SerializeAndAppendTo(&unknown_fields_);
8661         break;
8662     }
8663   }
8664   return !packed_error && !dec.bytes_left();
8665 }
8666 
SerializeAsString() const8667 std::string OneofDescriptorProto::SerializeAsString() const {
8668   ::protozero::HeapBuffered<::protozero::Message> msg;
8669   Serialize(msg.get());
8670   return msg.SerializeAsString();
8671 }
8672 
SerializeAsArray() const8673 std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
8674   ::protozero::HeapBuffered<::protozero::Message> msg;
8675   Serialize(msg.get());
8676   return msg.SerializeAsArray();
8677 }
8678 
Serialize(::protozero::Message * msg) const8679 void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
8680   // Field 1: name
8681   if (_has_field_[1]) {
8682     msg->AppendString(1, name_);
8683   }
8684 
8685   // Field 2: options
8686   if (_has_field_[2]) {
8687     (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
8688   }
8689 
8690   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8691 }
8692 
8693 
8694 FieldDescriptorProto::FieldDescriptorProto() = default;
8695 FieldDescriptorProto::~FieldDescriptorProto() = default;
8696 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
8697 FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
8698 FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
8699 FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
8700 
operator ==(const FieldDescriptorProto & other) const8701 bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
8702   return unknown_fields_ == other.unknown_fields_
8703    && name_ == other.name_
8704    && number_ == other.number_
8705    && label_ == other.label_
8706    && type_ == other.type_
8707    && type_name_ == other.type_name_
8708    && extendee_ == other.extendee_
8709    && default_value_ == other.default_value_
8710    && oneof_index_ == other.oneof_index_;
8711 }
8712 
ParseFromArray(const void * raw,size_t size)8713 bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
8714   unknown_fields_.clear();
8715   bool packed_error = false;
8716 
8717   ::protozero::ProtoDecoder dec(raw, size);
8718   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8719     if (field.id() < _has_field_.size()) {
8720       _has_field_.set(field.id());
8721     }
8722     switch (field.id()) {
8723       case 1 /* name */:
8724         field.get(&name_);
8725         break;
8726       case 3 /* number */:
8727         field.get(&number_);
8728         break;
8729       case 4 /* label */:
8730         field.get(&label_);
8731         break;
8732       case 5 /* type */:
8733         field.get(&type_);
8734         break;
8735       case 6 /* type_name */:
8736         field.get(&type_name_);
8737         break;
8738       case 2 /* extendee */:
8739         field.get(&extendee_);
8740         break;
8741       case 7 /* default_value */:
8742         field.get(&default_value_);
8743         break;
8744       case 9 /* oneof_index */:
8745         field.get(&oneof_index_);
8746         break;
8747       default:
8748         field.SerializeAndAppendTo(&unknown_fields_);
8749         break;
8750     }
8751   }
8752   return !packed_error && !dec.bytes_left();
8753 }
8754 
SerializeAsString() const8755 std::string FieldDescriptorProto::SerializeAsString() const {
8756   ::protozero::HeapBuffered<::protozero::Message> msg;
8757   Serialize(msg.get());
8758   return msg.SerializeAsString();
8759 }
8760 
SerializeAsArray() const8761 std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
8762   ::protozero::HeapBuffered<::protozero::Message> msg;
8763   Serialize(msg.get());
8764   return msg.SerializeAsArray();
8765 }
8766 
Serialize(::protozero::Message * msg) const8767 void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
8768   // Field 1: name
8769   if (_has_field_[1]) {
8770     msg->AppendString(1, name_);
8771   }
8772 
8773   // Field 3: number
8774   if (_has_field_[3]) {
8775     msg->AppendVarInt(3, number_);
8776   }
8777 
8778   // Field 4: label
8779   if (_has_field_[4]) {
8780     msg->AppendVarInt(4, label_);
8781   }
8782 
8783   // Field 5: type
8784   if (_has_field_[5]) {
8785     msg->AppendVarInt(5, type_);
8786   }
8787 
8788   // Field 6: type_name
8789   if (_has_field_[6]) {
8790     msg->AppendString(6, type_name_);
8791   }
8792 
8793   // Field 2: extendee
8794   if (_has_field_[2]) {
8795     msg->AppendString(2, extendee_);
8796   }
8797 
8798   // Field 7: default_value
8799   if (_has_field_[7]) {
8800     msg->AppendString(7, default_value_);
8801   }
8802 
8803   // Field 9: oneof_index
8804   if (_has_field_[9]) {
8805     msg->AppendVarInt(9, oneof_index_);
8806   }
8807 
8808   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8809 }
8810 
8811 
8812 DescriptorProto::DescriptorProto() = default;
8813 DescriptorProto::~DescriptorProto() = default;
8814 DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
8815 DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
8816 DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
8817 DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
8818 
operator ==(const DescriptorProto & other) const8819 bool DescriptorProto::operator==(const DescriptorProto& other) const {
8820   return unknown_fields_ == other.unknown_fields_
8821    && name_ == other.name_
8822    && field_ == other.field_
8823    && extension_ == other.extension_
8824    && nested_type_ == other.nested_type_
8825    && enum_type_ == other.enum_type_
8826    && oneof_decl_ == other.oneof_decl_
8827    && reserved_range_ == other.reserved_range_
8828    && reserved_name_ == other.reserved_name_;
8829 }
8830 
ParseFromArray(const void * raw,size_t size)8831 bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
8832   field_.clear();
8833   extension_.clear();
8834   nested_type_.clear();
8835   enum_type_.clear();
8836   oneof_decl_.clear();
8837   reserved_range_.clear();
8838   reserved_name_.clear();
8839   unknown_fields_.clear();
8840   bool packed_error = false;
8841 
8842   ::protozero::ProtoDecoder dec(raw, size);
8843   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8844     if (field.id() < _has_field_.size()) {
8845       _has_field_.set(field.id());
8846     }
8847     switch (field.id()) {
8848       case 1 /* name */:
8849         field.get(&name_);
8850         break;
8851       case 2 /* field */:
8852         field_.emplace_back();
8853         field_.back().ParseFromString(field.as_std_string());
8854         break;
8855       case 6 /* extension */:
8856         extension_.emplace_back();
8857         extension_.back().ParseFromString(field.as_std_string());
8858         break;
8859       case 3 /* nested_type */:
8860         nested_type_.emplace_back();
8861         nested_type_.back().ParseFromString(field.as_std_string());
8862         break;
8863       case 4 /* enum_type */:
8864         enum_type_.emplace_back();
8865         enum_type_.back().ParseFromString(field.as_std_string());
8866         break;
8867       case 8 /* oneof_decl */:
8868         oneof_decl_.emplace_back();
8869         oneof_decl_.back().ParseFromString(field.as_std_string());
8870         break;
8871       case 9 /* reserved_range */:
8872         reserved_range_.emplace_back();
8873         reserved_range_.back().ParseFromString(field.as_std_string());
8874         break;
8875       case 10 /* reserved_name */:
8876         reserved_name_.emplace_back();
8877         field.get(&reserved_name_.back());
8878         break;
8879       default:
8880         field.SerializeAndAppendTo(&unknown_fields_);
8881         break;
8882     }
8883   }
8884   return !packed_error && !dec.bytes_left();
8885 }
8886 
SerializeAsString() const8887 std::string DescriptorProto::SerializeAsString() const {
8888   ::protozero::HeapBuffered<::protozero::Message> msg;
8889   Serialize(msg.get());
8890   return msg.SerializeAsString();
8891 }
8892 
SerializeAsArray() const8893 std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
8894   ::protozero::HeapBuffered<::protozero::Message> msg;
8895   Serialize(msg.get());
8896   return msg.SerializeAsArray();
8897 }
8898 
Serialize(::protozero::Message * msg) const8899 void DescriptorProto::Serialize(::protozero::Message* msg) const {
8900   // Field 1: name
8901   if (_has_field_[1]) {
8902     msg->AppendString(1, name_);
8903   }
8904 
8905   // Field 2: field
8906   for (auto& it : field_) {
8907     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
8908   }
8909 
8910   // Field 6: extension
8911   for (auto& it : extension_) {
8912     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
8913   }
8914 
8915   // Field 3: nested_type
8916   for (auto& it : nested_type_) {
8917     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
8918   }
8919 
8920   // Field 4: enum_type
8921   for (auto& it : enum_type_) {
8922     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
8923   }
8924 
8925   // Field 8: oneof_decl
8926   for (auto& it : oneof_decl_) {
8927     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
8928   }
8929 
8930   // Field 9: reserved_range
8931   for (auto& it : reserved_range_) {
8932     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
8933   }
8934 
8935   // Field 10: reserved_name
8936   for (auto& it : reserved_name_) {
8937     msg->AppendString(10, it);
8938   }
8939 
8940   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
8941 }
8942 
8943 
8944 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
8945 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
8946 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
8947 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
8948 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
8949 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
8950 
operator ==(const DescriptorProto_ReservedRange & other) const8951 bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
8952   return unknown_fields_ == other.unknown_fields_
8953    && start_ == other.start_
8954    && end_ == other.end_;
8955 }
8956 
ParseFromArray(const void * raw,size_t size)8957 bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
8958   unknown_fields_.clear();
8959   bool packed_error = false;
8960 
8961   ::protozero::ProtoDecoder dec(raw, size);
8962   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
8963     if (field.id() < _has_field_.size()) {
8964       _has_field_.set(field.id());
8965     }
8966     switch (field.id()) {
8967       case 1 /* start */:
8968         field.get(&start_);
8969         break;
8970       case 2 /* end */:
8971         field.get(&end_);
8972         break;
8973       default:
8974         field.SerializeAndAppendTo(&unknown_fields_);
8975         break;
8976     }
8977   }
8978   return !packed_error && !dec.bytes_left();
8979 }
8980 
SerializeAsString() const8981 std::string DescriptorProto_ReservedRange::SerializeAsString() const {
8982   ::protozero::HeapBuffered<::protozero::Message> msg;
8983   Serialize(msg.get());
8984   return msg.SerializeAsString();
8985 }
8986 
SerializeAsArray() const8987 std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
8988   ::protozero::HeapBuffered<::protozero::Message> msg;
8989   Serialize(msg.get());
8990   return msg.SerializeAsArray();
8991 }
8992 
Serialize(::protozero::Message * msg) const8993 void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
8994   // Field 1: start
8995   if (_has_field_[1]) {
8996     msg->AppendVarInt(1, start_);
8997   }
8998 
8999   // Field 2: end
9000   if (_has_field_[2]) {
9001     msg->AppendVarInt(2, end_);
9002   }
9003 
9004   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9005 }
9006 
9007 
9008 FileDescriptorProto::FileDescriptorProto() = default;
9009 FileDescriptorProto::~FileDescriptorProto() = default;
9010 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
9011 FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
9012 FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
9013 FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
9014 
operator ==(const FileDescriptorProto & other) const9015 bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
9016   return unknown_fields_ == other.unknown_fields_
9017    && name_ == other.name_
9018    && package_ == other.package_
9019    && dependency_ == other.dependency_
9020    && public_dependency_ == other.public_dependency_
9021    && weak_dependency_ == other.weak_dependency_
9022    && message_type_ == other.message_type_
9023    && enum_type_ == other.enum_type_
9024    && extension_ == other.extension_;
9025 }
9026 
ParseFromArray(const void * raw,size_t size)9027 bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
9028   dependency_.clear();
9029   public_dependency_.clear();
9030   weak_dependency_.clear();
9031   message_type_.clear();
9032   enum_type_.clear();
9033   extension_.clear();
9034   unknown_fields_.clear();
9035   bool packed_error = false;
9036 
9037   ::protozero::ProtoDecoder dec(raw, size);
9038   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9039     if (field.id() < _has_field_.size()) {
9040       _has_field_.set(field.id());
9041     }
9042     switch (field.id()) {
9043       case 1 /* name */:
9044         field.get(&name_);
9045         break;
9046       case 2 /* package */:
9047         field.get(&package_);
9048         break;
9049       case 3 /* dependency */:
9050         dependency_.emplace_back();
9051         field.get(&dependency_.back());
9052         break;
9053       case 10 /* public_dependency */:
9054         public_dependency_.emplace_back();
9055         field.get(&public_dependency_.back());
9056         break;
9057       case 11 /* weak_dependency */:
9058         weak_dependency_.emplace_back();
9059         field.get(&weak_dependency_.back());
9060         break;
9061       case 4 /* message_type */:
9062         message_type_.emplace_back();
9063         message_type_.back().ParseFromString(field.as_std_string());
9064         break;
9065       case 5 /* enum_type */:
9066         enum_type_.emplace_back();
9067         enum_type_.back().ParseFromString(field.as_std_string());
9068         break;
9069       case 7 /* extension */:
9070         extension_.emplace_back();
9071         extension_.back().ParseFromString(field.as_std_string());
9072         break;
9073       default:
9074         field.SerializeAndAppendTo(&unknown_fields_);
9075         break;
9076     }
9077   }
9078   return !packed_error && !dec.bytes_left();
9079 }
9080 
SerializeAsString() const9081 std::string FileDescriptorProto::SerializeAsString() const {
9082   ::protozero::HeapBuffered<::protozero::Message> msg;
9083   Serialize(msg.get());
9084   return msg.SerializeAsString();
9085 }
9086 
SerializeAsArray() const9087 std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
9088   ::protozero::HeapBuffered<::protozero::Message> msg;
9089   Serialize(msg.get());
9090   return msg.SerializeAsArray();
9091 }
9092 
Serialize(::protozero::Message * msg) const9093 void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
9094   // Field 1: name
9095   if (_has_field_[1]) {
9096     msg->AppendString(1, name_);
9097   }
9098 
9099   // Field 2: package
9100   if (_has_field_[2]) {
9101     msg->AppendString(2, package_);
9102   }
9103 
9104   // Field 3: dependency
9105   for (auto& it : dependency_) {
9106     msg->AppendString(3, it);
9107   }
9108 
9109   // Field 10: public_dependency
9110   for (auto& it : public_dependency_) {
9111     msg->AppendVarInt(10, it);
9112   }
9113 
9114   // Field 11: weak_dependency
9115   for (auto& it : weak_dependency_) {
9116     msg->AppendVarInt(11, it);
9117   }
9118 
9119   // Field 4: message_type
9120   for (auto& it : message_type_) {
9121     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
9122   }
9123 
9124   // Field 5: enum_type
9125   for (auto& it : enum_type_) {
9126     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
9127   }
9128 
9129   // Field 7: extension
9130   for (auto& it : extension_) {
9131     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
9132   }
9133 
9134   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9135 }
9136 
9137 
9138 FileDescriptorSet::FileDescriptorSet() = default;
9139 FileDescriptorSet::~FileDescriptorSet() = default;
9140 FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
9141 FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
9142 FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
9143 FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
9144 
operator ==(const FileDescriptorSet & other) const9145 bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
9146   return unknown_fields_ == other.unknown_fields_
9147    && file_ == other.file_;
9148 }
9149 
ParseFromArray(const void * raw,size_t size)9150 bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
9151   file_.clear();
9152   unknown_fields_.clear();
9153   bool packed_error = false;
9154 
9155   ::protozero::ProtoDecoder dec(raw, size);
9156   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9157     if (field.id() < _has_field_.size()) {
9158       _has_field_.set(field.id());
9159     }
9160     switch (field.id()) {
9161       case 1 /* file */:
9162         file_.emplace_back();
9163         file_.back().ParseFromString(field.as_std_string());
9164         break;
9165       default:
9166         field.SerializeAndAppendTo(&unknown_fields_);
9167         break;
9168     }
9169   }
9170   return !packed_error && !dec.bytes_left();
9171 }
9172 
SerializeAsString() const9173 std::string FileDescriptorSet::SerializeAsString() const {
9174   ::protozero::HeapBuffered<::protozero::Message> msg;
9175   Serialize(msg.get());
9176   return msg.SerializeAsString();
9177 }
9178 
SerializeAsArray() const9179 std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
9180   ::protozero::HeapBuffered<::protozero::Message> msg;
9181   Serialize(msg.get());
9182   return msg.SerializeAsArray();
9183 }
9184 
Serialize(::protozero::Message * msg) const9185 void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
9186   // Field 1: file
9187   for (auto& it : file_) {
9188     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9189   }
9190 
9191   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9192 }
9193 
9194 }  // namespace perfetto
9195 }  // namespace protos
9196 }  // namespace gen
9197 #pragma GCC diagnostic pop
9198 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
9199 // gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
9200 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9201 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
9202 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
9203 
9204 #include <stdint.h>
9205 #include <bitset>
9206 #include <vector>
9207 #include <string>
9208 #include <type_traits>
9209 
9210 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9211 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9212 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9213 
9214 namespace perfetto {
9215 namespace protos {
9216 namespace gen {
9217 class GpuCounterDescriptor;
9218 class GpuCounterDescriptor_GpuCounterBlock;
9219 class GpuCounterDescriptor_GpuCounterSpec;
9220 enum GpuCounterDescriptor_GpuCounterGroup : int;
9221 enum GpuCounterDescriptor_MeasureUnit : int;
9222 }  // namespace perfetto
9223 }  // namespace protos
9224 }  // namespace gen
9225 
9226 namespace protozero {
9227 class Message;
9228 }  // namespace protozero
9229 
9230 namespace perfetto {
9231 namespace protos {
9232 namespace gen {
9233 enum GpuCounterDescriptor_GpuCounterGroup : int {
9234   GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
9235   GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
9236   GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
9237   GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
9238   GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
9239   GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
9240   GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
9241 };
9242 enum GpuCounterDescriptor_MeasureUnit : int {
9243   GpuCounterDescriptor_MeasureUnit_NONE = 0,
9244   GpuCounterDescriptor_MeasureUnit_BIT = 1,
9245   GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
9246   GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
9247   GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
9248   GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
9249   GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
9250   GpuCounterDescriptor_MeasureUnit_BYTE = 7,
9251   GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
9252   GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
9253   GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
9254   GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
9255   GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
9256   GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
9257   GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
9258   GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
9259   GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
9260   GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
9261   GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
9262   GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
9263   GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
9264   GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
9265   GpuCounterDescriptor_MeasureUnit_SECOND = 22,
9266   GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
9267   GpuCounterDescriptor_MeasureUnit_HOUR = 24,
9268   GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
9269   GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
9270   GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
9271   GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
9272   GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
9273   GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
9274   GpuCounterDescriptor_MeasureUnit_WATT = 29,
9275   GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
9276   GpuCounterDescriptor_MeasureUnit_JOULE = 31,
9277   GpuCounterDescriptor_MeasureUnit_VOLT = 32,
9278   GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
9279   GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
9280   GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
9281   GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
9282   GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
9283   GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
9284 };
9285 
9286 class PERFETTO_EXPORT GpuCounterDescriptor : public ::protozero::CppMessageObj {
9287  public:
9288   using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
9289   using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
9290   using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
9291   static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
9292   static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
9293   static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
9294   static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
9295   static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
9296   static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
9297   static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
9298   static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
9299   static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
9300   using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
9301   static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
9302   static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
9303   static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
9304   static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
9305   static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
9306   static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
9307   static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
9308   static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
9309   static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
9310   static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
9311   static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
9312   static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
9313   static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
9314   static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
9315   static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
9316   static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
9317   static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
9318   static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
9319   static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
9320   static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
9321   static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
9322   static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
9323   static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
9324   static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
9325   static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
9326   static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
9327   static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
9328   static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
9329   static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
9330   static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
9331   static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
9332   static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
9333   static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
9334   static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
9335   static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
9336   static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
9337   static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
9338   static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
9339   static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
9340   static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
9341   static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
9342   static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
9343   static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
9344   enum FieldNumbers {
9345     kSpecsFieldNumber = 1,
9346     kBlocksFieldNumber = 2,
9347     kMinSamplingPeriodNsFieldNumber = 3,
9348     kMaxSamplingPeriodNsFieldNumber = 4,
9349     kSupportsInstrumentedSamplingFieldNumber = 5,
9350   };
9351 
9352   GpuCounterDescriptor();
9353   ~GpuCounterDescriptor() override;
9354   GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
9355   GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
9356   GpuCounterDescriptor(const GpuCounterDescriptor&);
9357   GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
9358   bool operator==(const GpuCounterDescriptor&) const;
operator !=(const GpuCounterDescriptor & other) const9359   bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
9360 
9361   bool ParseFromArray(const void*, size_t) override;
9362   std::string SerializeAsString() const override;
9363   std::vector<uint8_t> SerializeAsArray() const override;
9364   void Serialize(::protozero::Message*) const;
9365 
specs_size() const9366   int specs_size() const { return static_cast<int>(specs_.size()); }
specs() const9367   const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
mutable_specs()9368   std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
clear_specs()9369   void clear_specs() { specs_.clear(); }
add_specs()9370   GpuCounterDescriptor_GpuCounterSpec* add_specs() { specs_.emplace_back(); return &specs_.back(); }
9371 
blocks_size() const9372   int blocks_size() const { return static_cast<int>(blocks_.size()); }
blocks() const9373   const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
mutable_blocks()9374   std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
clear_blocks()9375   void clear_blocks() { blocks_.clear(); }
add_blocks()9376   GpuCounterDescriptor_GpuCounterBlock* add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
9377 
has_min_sampling_period_ns() const9378   bool has_min_sampling_period_ns() const { return _has_field_[3]; }
min_sampling_period_ns() const9379   uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
set_min_sampling_period_ns(uint64_t value)9380   void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
9381 
has_max_sampling_period_ns() const9382   bool has_max_sampling_period_ns() const { return _has_field_[4]; }
max_sampling_period_ns() const9383   uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
set_max_sampling_period_ns(uint64_t value)9384   void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
9385 
has_supports_instrumented_sampling() const9386   bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
supports_instrumented_sampling() const9387   bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
set_supports_instrumented_sampling(bool value)9388   void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
9389 
9390  private:
9391   std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
9392   std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
9393   uint64_t min_sampling_period_ns_{};
9394   uint64_t max_sampling_period_ns_{};
9395   bool supports_instrumented_sampling_{};
9396 
9397   // Allows to preserve unknown protobuf fields for compatibility
9398   // with future versions of .proto files.
9399   std::string unknown_fields_;
9400 
9401   std::bitset<6> _has_field_{};
9402 };
9403 
9404 
9405 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
9406  public:
9407   enum FieldNumbers {
9408     kBlockIdFieldNumber = 1,
9409     kBlockCapacityFieldNumber = 2,
9410     kNameFieldNumber = 3,
9411     kDescriptionFieldNumber = 4,
9412     kCounterIdsFieldNumber = 5,
9413   };
9414 
9415   GpuCounterDescriptor_GpuCounterBlock();
9416   ~GpuCounterDescriptor_GpuCounterBlock() override;
9417   GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
9418   GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
9419   GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
9420   GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
9421   bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
operator !=(const GpuCounterDescriptor_GpuCounterBlock & other) const9422   bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
9423 
9424   bool ParseFromArray(const void*, size_t) override;
9425   std::string SerializeAsString() const override;
9426   std::vector<uint8_t> SerializeAsArray() const override;
9427   void Serialize(::protozero::Message*) const;
9428 
has_block_id() const9429   bool has_block_id() const { return _has_field_[1]; }
block_id() const9430   uint32_t block_id() const { return block_id_; }
set_block_id(uint32_t value)9431   void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
9432 
has_block_capacity() const9433   bool has_block_capacity() const { return _has_field_[2]; }
block_capacity() const9434   uint32_t block_capacity() const { return block_capacity_; }
set_block_capacity(uint32_t value)9435   void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
9436 
has_name() const9437   bool has_name() const { return _has_field_[3]; }
name() const9438   const std::string& name() const { return name_; }
set_name(const std::string & value)9439   void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
9440 
has_description() const9441   bool has_description() const { return _has_field_[4]; }
description() const9442   const std::string& description() const { return description_; }
set_description(const std::string & value)9443   void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
9444 
counter_ids_size() const9445   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
counter_ids() const9446   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()9447   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
clear_counter_ids()9448   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)9449   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()9450   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
9451 
9452  private:
9453   uint32_t block_id_{};
9454   uint32_t block_capacity_{};
9455   std::string name_{};
9456   std::string description_{};
9457   std::vector<uint32_t> counter_ids_;
9458 
9459   // Allows to preserve unknown protobuf fields for compatibility
9460   // with future versions of .proto files.
9461   std::string unknown_fields_;
9462 
9463   std::bitset<6> _has_field_{};
9464 };
9465 
9466 
9467 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
9468  public:
9469   enum FieldNumbers {
9470     kCounterIdFieldNumber = 1,
9471     kNameFieldNumber = 2,
9472     kDescriptionFieldNumber = 3,
9473     kIntPeakValueFieldNumber = 5,
9474     kDoublePeakValueFieldNumber = 6,
9475     kNumeratorUnitsFieldNumber = 7,
9476     kDenominatorUnitsFieldNumber = 8,
9477     kSelectByDefaultFieldNumber = 9,
9478     kGroupsFieldNumber = 10,
9479   };
9480 
9481   GpuCounterDescriptor_GpuCounterSpec();
9482   ~GpuCounterDescriptor_GpuCounterSpec() override;
9483   GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
9484   GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
9485   GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
9486   GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
9487   bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
operator !=(const GpuCounterDescriptor_GpuCounterSpec & other) const9488   bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
9489 
9490   bool ParseFromArray(const void*, size_t) override;
9491   std::string SerializeAsString() const override;
9492   std::vector<uint8_t> SerializeAsArray() const override;
9493   void Serialize(::protozero::Message*) const;
9494 
has_counter_id() const9495   bool has_counter_id() const { return _has_field_[1]; }
counter_id() const9496   uint32_t counter_id() const { return counter_id_; }
set_counter_id(uint32_t value)9497   void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
9498 
has_name() const9499   bool has_name() const { return _has_field_[2]; }
name() const9500   const std::string& name() const { return name_; }
set_name(const std::string & value)9501   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
9502 
has_description() const9503   bool has_description() const { return _has_field_[3]; }
description() const9504   const std::string& description() const { return description_; }
set_description(const std::string & value)9505   void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
9506 
has_int_peak_value() const9507   bool has_int_peak_value() const { return _has_field_[5]; }
int_peak_value() const9508   int64_t int_peak_value() const { return int_peak_value_; }
set_int_peak_value(int64_t value)9509   void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
9510 
has_double_peak_value() const9511   bool has_double_peak_value() const { return _has_field_[6]; }
double_peak_value() const9512   double double_peak_value() const { return double_peak_value_; }
set_double_peak_value(double value)9513   void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
9514 
numerator_units_size() const9515   int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
numerator_units() const9516   const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
mutable_numerator_units()9517   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
clear_numerator_units()9518   void clear_numerator_units() { numerator_units_.clear(); }
add_numerator_units(GpuCounterDescriptor_MeasureUnit value)9519   void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
add_numerator_units()9520   GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
9521 
denominator_units_size() const9522   int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
denominator_units() const9523   const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
mutable_denominator_units()9524   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
clear_denominator_units()9525   void clear_denominator_units() { denominator_units_.clear(); }
add_denominator_units(GpuCounterDescriptor_MeasureUnit value)9526   void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
add_denominator_units()9527   GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
9528 
has_select_by_default() const9529   bool has_select_by_default() const { return _has_field_[9]; }
select_by_default() const9530   bool select_by_default() const { return select_by_default_; }
set_select_by_default(bool value)9531   void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
9532 
groups_size() const9533   int groups_size() const { return static_cast<int>(groups_.size()); }
groups() const9534   const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
mutable_groups()9535   std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
clear_groups()9536   void clear_groups() { groups_.clear(); }
add_groups(GpuCounterDescriptor_GpuCounterGroup value)9537   void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
add_groups()9538   GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
9539 
9540  private:
9541   uint32_t counter_id_{};
9542   std::string name_{};
9543   std::string description_{};
9544   int64_t int_peak_value_{};
9545   double double_peak_value_{};
9546   std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
9547   std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
9548   bool select_by_default_{};
9549   std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
9550 
9551   // Allows to preserve unknown protobuf fields for compatibility
9552   // with future versions of .proto files.
9553   std::string unknown_fields_;
9554 
9555   std::bitset<11> _has_field_{};
9556 };
9557 
9558 }  // namespace perfetto
9559 }  // namespace protos
9560 }  // namespace gen
9561 
9562 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
9563 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9564 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9565 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9566 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
9567 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9568 #pragma GCC diagnostic push
9569 #pragma GCC diagnostic ignored "-Wfloat-equal"
9570 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
9571 
9572 namespace perfetto {
9573 namespace protos {
9574 namespace gen {
9575 
9576 GpuCounterDescriptor::GpuCounterDescriptor() = default;
9577 GpuCounterDescriptor::~GpuCounterDescriptor() = default;
9578 GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
9579 GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
9580 GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
9581 GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
9582 
operator ==(const GpuCounterDescriptor & other) const9583 bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
9584   return unknown_fields_ == other.unknown_fields_
9585    && specs_ == other.specs_
9586    && blocks_ == other.blocks_
9587    && min_sampling_period_ns_ == other.min_sampling_period_ns_
9588    && max_sampling_period_ns_ == other.max_sampling_period_ns_
9589    && supports_instrumented_sampling_ == other.supports_instrumented_sampling_;
9590 }
9591 
ParseFromArray(const void * raw,size_t size)9592 bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
9593   specs_.clear();
9594   blocks_.clear();
9595   unknown_fields_.clear();
9596   bool packed_error = false;
9597 
9598   ::protozero::ProtoDecoder dec(raw, size);
9599   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9600     if (field.id() < _has_field_.size()) {
9601       _has_field_.set(field.id());
9602     }
9603     switch (field.id()) {
9604       case 1 /* specs */:
9605         specs_.emplace_back();
9606         specs_.back().ParseFromString(field.as_std_string());
9607         break;
9608       case 2 /* blocks */:
9609         blocks_.emplace_back();
9610         blocks_.back().ParseFromString(field.as_std_string());
9611         break;
9612       case 3 /* min_sampling_period_ns */:
9613         field.get(&min_sampling_period_ns_);
9614         break;
9615       case 4 /* max_sampling_period_ns */:
9616         field.get(&max_sampling_period_ns_);
9617         break;
9618       case 5 /* supports_instrumented_sampling */:
9619         field.get(&supports_instrumented_sampling_);
9620         break;
9621       default:
9622         field.SerializeAndAppendTo(&unknown_fields_);
9623         break;
9624     }
9625   }
9626   return !packed_error && !dec.bytes_left();
9627 }
9628 
SerializeAsString() const9629 std::string GpuCounterDescriptor::SerializeAsString() const {
9630   ::protozero::HeapBuffered<::protozero::Message> msg;
9631   Serialize(msg.get());
9632   return msg.SerializeAsString();
9633 }
9634 
SerializeAsArray() const9635 std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
9636   ::protozero::HeapBuffered<::protozero::Message> msg;
9637   Serialize(msg.get());
9638   return msg.SerializeAsArray();
9639 }
9640 
Serialize(::protozero::Message * msg) const9641 void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
9642   // Field 1: specs
9643   for (auto& it : specs_) {
9644     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
9645   }
9646 
9647   // Field 2: blocks
9648   for (auto& it : blocks_) {
9649     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
9650   }
9651 
9652   // Field 3: min_sampling_period_ns
9653   if (_has_field_[3]) {
9654     msg->AppendVarInt(3, min_sampling_period_ns_);
9655   }
9656 
9657   // Field 4: max_sampling_period_ns
9658   if (_has_field_[4]) {
9659     msg->AppendVarInt(4, max_sampling_period_ns_);
9660   }
9661 
9662   // Field 5: supports_instrumented_sampling
9663   if (_has_field_[5]) {
9664     msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
9665   }
9666 
9667   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9668 }
9669 
9670 
9671 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
9672 GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
9673 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
9674 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
9675 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
9676 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
9677 
operator ==(const GpuCounterDescriptor_GpuCounterBlock & other) const9678 bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
9679   return unknown_fields_ == other.unknown_fields_
9680    && block_id_ == other.block_id_
9681    && block_capacity_ == other.block_capacity_
9682    && name_ == other.name_
9683    && description_ == other.description_
9684    && counter_ids_ == other.counter_ids_;
9685 }
9686 
ParseFromArray(const void * raw,size_t size)9687 bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
9688   counter_ids_.clear();
9689   unknown_fields_.clear();
9690   bool packed_error = false;
9691 
9692   ::protozero::ProtoDecoder dec(raw, size);
9693   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9694     if (field.id() < _has_field_.size()) {
9695       _has_field_.set(field.id());
9696     }
9697     switch (field.id()) {
9698       case 1 /* block_id */:
9699         field.get(&block_id_);
9700         break;
9701       case 2 /* block_capacity */:
9702         field.get(&block_capacity_);
9703         break;
9704       case 3 /* name */:
9705         field.get(&name_);
9706         break;
9707       case 4 /* description */:
9708         field.get(&description_);
9709         break;
9710       case 5 /* counter_ids */:
9711         counter_ids_.emplace_back();
9712         field.get(&counter_ids_.back());
9713         break;
9714       default:
9715         field.SerializeAndAppendTo(&unknown_fields_);
9716         break;
9717     }
9718   }
9719   return !packed_error && !dec.bytes_left();
9720 }
9721 
SerializeAsString() const9722 std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
9723   ::protozero::HeapBuffered<::protozero::Message> msg;
9724   Serialize(msg.get());
9725   return msg.SerializeAsString();
9726 }
9727 
SerializeAsArray() const9728 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
9729   ::protozero::HeapBuffered<::protozero::Message> msg;
9730   Serialize(msg.get());
9731   return msg.SerializeAsArray();
9732 }
9733 
Serialize(::protozero::Message * msg) const9734 void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
9735   // Field 1: block_id
9736   if (_has_field_[1]) {
9737     msg->AppendVarInt(1, block_id_);
9738   }
9739 
9740   // Field 2: block_capacity
9741   if (_has_field_[2]) {
9742     msg->AppendVarInt(2, block_capacity_);
9743   }
9744 
9745   // Field 3: name
9746   if (_has_field_[3]) {
9747     msg->AppendString(3, name_);
9748   }
9749 
9750   // Field 4: description
9751   if (_has_field_[4]) {
9752     msg->AppendString(4, description_);
9753   }
9754 
9755   // Field 5: counter_ids
9756   for (auto& it : counter_ids_) {
9757     msg->AppendVarInt(5, it);
9758   }
9759 
9760   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9761 }
9762 
9763 
9764 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
9765 GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
9766 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
9767 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
9768 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
9769 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
9770 
operator ==(const GpuCounterDescriptor_GpuCounterSpec & other) const9771 bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
9772   return unknown_fields_ == other.unknown_fields_
9773    && counter_id_ == other.counter_id_
9774    && name_ == other.name_
9775    && description_ == other.description_
9776    && int_peak_value_ == other.int_peak_value_
9777    && double_peak_value_ == other.double_peak_value_
9778    && numerator_units_ == other.numerator_units_
9779    && denominator_units_ == other.denominator_units_
9780    && select_by_default_ == other.select_by_default_
9781    && groups_ == other.groups_;
9782 }
9783 
ParseFromArray(const void * raw,size_t size)9784 bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
9785   numerator_units_.clear();
9786   denominator_units_.clear();
9787   groups_.clear();
9788   unknown_fields_.clear();
9789   bool packed_error = false;
9790 
9791   ::protozero::ProtoDecoder dec(raw, size);
9792   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
9793     if (field.id() < _has_field_.size()) {
9794       _has_field_.set(field.id());
9795     }
9796     switch (field.id()) {
9797       case 1 /* counter_id */:
9798         field.get(&counter_id_);
9799         break;
9800       case 2 /* name */:
9801         field.get(&name_);
9802         break;
9803       case 3 /* description */:
9804         field.get(&description_);
9805         break;
9806       case 5 /* int_peak_value */:
9807         field.get(&int_peak_value_);
9808         break;
9809       case 6 /* double_peak_value */:
9810         field.get(&double_peak_value_);
9811         break;
9812       case 7 /* numerator_units */:
9813         numerator_units_.emplace_back();
9814         field.get(&numerator_units_.back());
9815         break;
9816       case 8 /* denominator_units */:
9817         denominator_units_.emplace_back();
9818         field.get(&denominator_units_.back());
9819         break;
9820       case 9 /* select_by_default */:
9821         field.get(&select_by_default_);
9822         break;
9823       case 10 /* groups */:
9824         groups_.emplace_back();
9825         field.get(&groups_.back());
9826         break;
9827       default:
9828         field.SerializeAndAppendTo(&unknown_fields_);
9829         break;
9830     }
9831   }
9832   return !packed_error && !dec.bytes_left();
9833 }
9834 
SerializeAsString() const9835 std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
9836   ::protozero::HeapBuffered<::protozero::Message> msg;
9837   Serialize(msg.get());
9838   return msg.SerializeAsString();
9839 }
9840 
SerializeAsArray() const9841 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
9842   ::protozero::HeapBuffered<::protozero::Message> msg;
9843   Serialize(msg.get());
9844   return msg.SerializeAsArray();
9845 }
9846 
Serialize(::protozero::Message * msg) const9847 void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
9848   // Field 1: counter_id
9849   if (_has_field_[1]) {
9850     msg->AppendVarInt(1, counter_id_);
9851   }
9852 
9853   // Field 2: name
9854   if (_has_field_[2]) {
9855     msg->AppendString(2, name_);
9856   }
9857 
9858   // Field 3: description
9859   if (_has_field_[3]) {
9860     msg->AppendString(3, description_);
9861   }
9862 
9863   // Field 5: int_peak_value
9864   if (_has_field_[5]) {
9865     msg->AppendVarInt(5, int_peak_value_);
9866   }
9867 
9868   // Field 6: double_peak_value
9869   if (_has_field_[6]) {
9870     msg->AppendFixed(6, double_peak_value_);
9871   }
9872 
9873   // Field 7: numerator_units
9874   for (auto& it : numerator_units_) {
9875     msg->AppendVarInt(7, it);
9876   }
9877 
9878   // Field 8: denominator_units
9879   for (auto& it : denominator_units_) {
9880     msg->AppendVarInt(8, it);
9881   }
9882 
9883   // Field 9: select_by_default
9884   if (_has_field_[9]) {
9885     msg->AppendTinyVarInt(9, select_by_default_);
9886   }
9887 
9888   // Field 10: groups
9889   for (auto& it : groups_) {
9890     msg->AppendVarInt(10, it);
9891   }
9892 
9893   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
9894 }
9895 
9896 }  // namespace perfetto
9897 }  // namespace protos
9898 }  // namespace gen
9899 #pragma GCC diagnostic pop
9900 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
9901 // gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
9902 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
9903 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
9904 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
9905 
9906 #include <stdint.h>
9907 #include <bitset>
9908 #include <vector>
9909 #include <string>
9910 #include <type_traits>
9911 
9912 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
9913 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
9914 // gen_amalgamated expanded: #include "perfetto/base/export.h"
9915 
9916 namespace perfetto {
9917 namespace protos {
9918 namespace gen {
9919 class ObservableEvents;
9920 class ObservableEvents_DataSourceInstanceStateChange;
9921 enum ObservableEvents_Type : int;
9922 enum ObservableEvents_DataSourceInstanceState : int;
9923 }  // namespace perfetto
9924 }  // namespace protos
9925 }  // namespace gen
9926 
9927 namespace protozero {
9928 class Message;
9929 }  // namespace protozero
9930 
9931 namespace perfetto {
9932 namespace protos {
9933 namespace gen {
9934 enum ObservableEvents_Type : int {
9935   ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
9936   ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
9937   ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
9938 };
9939 enum ObservableEvents_DataSourceInstanceState : int {
9940   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
9941   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
9942 };
9943 
9944 class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
9945  public:
9946   using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
9947   using Type = ObservableEvents_Type;
9948   static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
9949   static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
9950   static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
9951   static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
9952   static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
9953   using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
9954   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
9955   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
9956   static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
9957   static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
9958   enum FieldNumbers {
9959     kInstanceStateChangesFieldNumber = 1,
9960     kAllDataSourcesStartedFieldNumber = 2,
9961   };
9962 
9963   ObservableEvents();
9964   ~ObservableEvents() override;
9965   ObservableEvents(ObservableEvents&&) noexcept;
9966   ObservableEvents& operator=(ObservableEvents&&);
9967   ObservableEvents(const ObservableEvents&);
9968   ObservableEvents& operator=(const ObservableEvents&);
9969   bool operator==(const ObservableEvents&) const;
operator !=(const ObservableEvents & other) const9970   bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
9971 
9972   bool ParseFromArray(const void*, size_t) override;
9973   std::string SerializeAsString() const override;
9974   std::vector<uint8_t> SerializeAsArray() const override;
9975   void Serialize(::protozero::Message*) const;
9976 
instance_state_changes_size() const9977   int instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
instance_state_changes() const9978   const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
mutable_instance_state_changes()9979   std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
clear_instance_state_changes()9980   void clear_instance_state_changes() { instance_state_changes_.clear(); }
add_instance_state_changes()9981   ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
9982 
has_all_data_sources_started() const9983   bool has_all_data_sources_started() const { return _has_field_[2]; }
all_data_sources_started() const9984   bool all_data_sources_started() const { return all_data_sources_started_; }
set_all_data_sources_started(bool value)9985   void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
9986 
9987  private:
9988   std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
9989   bool all_data_sources_started_{};
9990 
9991   // Allows to preserve unknown protobuf fields for compatibility
9992   // with future versions of .proto files.
9993   std::string unknown_fields_;
9994 
9995   std::bitset<3> _has_field_{};
9996 };
9997 
9998 
9999 class PERFETTO_EXPORT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
10000  public:
10001   enum FieldNumbers {
10002     kProducerNameFieldNumber = 1,
10003     kDataSourceNameFieldNumber = 2,
10004     kStateFieldNumber = 3,
10005   };
10006 
10007   ObservableEvents_DataSourceInstanceStateChange();
10008   ~ObservableEvents_DataSourceInstanceStateChange() override;
10009   ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
10010   ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
10011   ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
10012   ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
10013   bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
operator !=(const ObservableEvents_DataSourceInstanceStateChange & other) const10014   bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
10015 
10016   bool ParseFromArray(const void*, size_t) override;
10017   std::string SerializeAsString() const override;
10018   std::vector<uint8_t> SerializeAsArray() const override;
10019   void Serialize(::protozero::Message*) const;
10020 
has_producer_name() const10021   bool has_producer_name() const { return _has_field_[1]; }
producer_name() const10022   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)10023   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
10024 
has_data_source_name() const10025   bool has_data_source_name() const { return _has_field_[2]; }
data_source_name() const10026   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)10027   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
10028 
has_state() const10029   bool has_state() const { return _has_field_[3]; }
state() const10030   ObservableEvents_DataSourceInstanceState state() const { return state_; }
set_state(ObservableEvents_DataSourceInstanceState value)10031   void set_state(ObservableEvents_DataSourceInstanceState value) { state_ = value; _has_field_.set(3); }
10032 
10033  private:
10034   std::string producer_name_{};
10035   std::string data_source_name_{};
10036   ObservableEvents_DataSourceInstanceState state_{};
10037 
10038   // Allows to preserve unknown protobuf fields for compatibility
10039   // with future versions of .proto files.
10040   std::string unknown_fields_;
10041 
10042   std::bitset<4> _has_field_{};
10043 };
10044 
10045 }  // namespace perfetto
10046 }  // namespace protos
10047 }  // namespace gen
10048 
10049 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
10050 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10051 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10052 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10053 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10054 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10055 #pragma GCC diagnostic push
10056 #pragma GCC diagnostic ignored "-Wfloat-equal"
10057 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
10058 
10059 namespace perfetto {
10060 namespace protos {
10061 namespace gen {
10062 
10063 ObservableEvents::ObservableEvents() = default;
10064 ObservableEvents::~ObservableEvents() = default;
10065 ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
10066 ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
10067 ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
10068 ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;
10069 
operator ==(const ObservableEvents & other) const10070 bool ObservableEvents::operator==(const ObservableEvents& other) const {
10071   return unknown_fields_ == other.unknown_fields_
10072    && instance_state_changes_ == other.instance_state_changes_
10073    && all_data_sources_started_ == other.all_data_sources_started_;
10074 }
10075 
ParseFromArray(const void * raw,size_t size)10076 bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
10077   instance_state_changes_.clear();
10078   unknown_fields_.clear();
10079   bool packed_error = false;
10080 
10081   ::protozero::ProtoDecoder dec(raw, size);
10082   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10083     if (field.id() < _has_field_.size()) {
10084       _has_field_.set(field.id());
10085     }
10086     switch (field.id()) {
10087       case 1 /* instance_state_changes */:
10088         instance_state_changes_.emplace_back();
10089         instance_state_changes_.back().ParseFromString(field.as_std_string());
10090         break;
10091       case 2 /* all_data_sources_started */:
10092         field.get(&all_data_sources_started_);
10093         break;
10094       default:
10095         field.SerializeAndAppendTo(&unknown_fields_);
10096         break;
10097     }
10098   }
10099   return !packed_error && !dec.bytes_left();
10100 }
10101 
SerializeAsString() const10102 std::string ObservableEvents::SerializeAsString() const {
10103   ::protozero::HeapBuffered<::protozero::Message> msg;
10104   Serialize(msg.get());
10105   return msg.SerializeAsString();
10106 }
10107 
SerializeAsArray() const10108 std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
10109   ::protozero::HeapBuffered<::protozero::Message> msg;
10110   Serialize(msg.get());
10111   return msg.SerializeAsArray();
10112 }
10113 
Serialize(::protozero::Message * msg) const10114 void ObservableEvents::Serialize(::protozero::Message* msg) const {
10115   // Field 1: instance_state_changes
10116   for (auto& it : instance_state_changes_) {
10117     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
10118   }
10119 
10120   // Field 2: all_data_sources_started
10121   if (_has_field_[2]) {
10122     msg->AppendTinyVarInt(2, all_data_sources_started_);
10123   }
10124 
10125   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10126 }
10127 
10128 
10129 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
10130 ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
10131 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
10132 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
10133 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
10134 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;
10135 
operator ==(const ObservableEvents_DataSourceInstanceStateChange & other) const10136 bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
10137   return unknown_fields_ == other.unknown_fields_
10138    && producer_name_ == other.producer_name_
10139    && data_source_name_ == other.data_source_name_
10140    && state_ == other.state_;
10141 }
10142 
ParseFromArray(const void * raw,size_t size)10143 bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
10144   unknown_fields_.clear();
10145   bool packed_error = false;
10146 
10147   ::protozero::ProtoDecoder dec(raw, size);
10148   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10149     if (field.id() < _has_field_.size()) {
10150       _has_field_.set(field.id());
10151     }
10152     switch (field.id()) {
10153       case 1 /* producer_name */:
10154         field.get(&producer_name_);
10155         break;
10156       case 2 /* data_source_name */:
10157         field.get(&data_source_name_);
10158         break;
10159       case 3 /* state */:
10160         field.get(&state_);
10161         break;
10162       default:
10163         field.SerializeAndAppendTo(&unknown_fields_);
10164         break;
10165     }
10166   }
10167   return !packed_error && !dec.bytes_left();
10168 }
10169 
SerializeAsString() const10170 std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
10171   ::protozero::HeapBuffered<::protozero::Message> msg;
10172   Serialize(msg.get());
10173   return msg.SerializeAsString();
10174 }
10175 
SerializeAsArray() const10176 std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
10177   ::protozero::HeapBuffered<::protozero::Message> msg;
10178   Serialize(msg.get());
10179   return msg.SerializeAsArray();
10180 }
10181 
Serialize(::protozero::Message * msg) const10182 void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
10183   // Field 1: producer_name
10184   if (_has_field_[1]) {
10185     msg->AppendString(1, producer_name_);
10186   }
10187 
10188   // Field 2: data_source_name
10189   if (_has_field_[2]) {
10190     msg->AppendString(2, data_source_name_);
10191   }
10192 
10193   // Field 3: state
10194   if (_has_field_[3]) {
10195     msg->AppendVarInt(3, state_);
10196   }
10197 
10198   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10199 }
10200 
10201 }  // namespace perfetto
10202 }  // namespace protos
10203 }  // namespace gen
10204 #pragma GCC diagnostic pop
10205 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
10206 // gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.gen.h
10207 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10208 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
10209 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
10210 
10211 #include <stdint.h>
10212 #include <bitset>
10213 #include <vector>
10214 #include <string>
10215 #include <type_traits>
10216 
10217 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10218 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10219 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10220 
10221 namespace perfetto {
10222 namespace protos {
10223 namespace gen {
10224 enum MeminfoCounters : int;
10225 enum VmstatCounters : int;
10226 }  // namespace perfetto
10227 }  // namespace protos
10228 }  // namespace gen
10229 
10230 namespace protozero {
10231 class Message;
10232 }  // namespace protozero
10233 
10234 namespace perfetto {
10235 namespace protos {
10236 namespace gen {
10237 enum MeminfoCounters : int {
10238   MEMINFO_UNSPECIFIED = 0,
10239   MEMINFO_MEM_TOTAL = 1,
10240   MEMINFO_MEM_FREE = 2,
10241   MEMINFO_MEM_AVAILABLE = 3,
10242   MEMINFO_BUFFERS = 4,
10243   MEMINFO_CACHED = 5,
10244   MEMINFO_SWAP_CACHED = 6,
10245   MEMINFO_ACTIVE = 7,
10246   MEMINFO_INACTIVE = 8,
10247   MEMINFO_ACTIVE_ANON = 9,
10248   MEMINFO_INACTIVE_ANON = 10,
10249   MEMINFO_ACTIVE_FILE = 11,
10250   MEMINFO_INACTIVE_FILE = 12,
10251   MEMINFO_UNEVICTABLE = 13,
10252   MEMINFO_MLOCKED = 14,
10253   MEMINFO_SWAP_TOTAL = 15,
10254   MEMINFO_SWAP_FREE = 16,
10255   MEMINFO_DIRTY = 17,
10256   MEMINFO_WRITEBACK = 18,
10257   MEMINFO_ANON_PAGES = 19,
10258   MEMINFO_MAPPED = 20,
10259   MEMINFO_SHMEM = 21,
10260   MEMINFO_SLAB = 22,
10261   MEMINFO_SLAB_RECLAIMABLE = 23,
10262   MEMINFO_SLAB_UNRECLAIMABLE = 24,
10263   MEMINFO_KERNEL_STACK = 25,
10264   MEMINFO_PAGE_TABLES = 26,
10265   MEMINFO_COMMIT_LIMIT = 27,
10266   MEMINFO_COMMITED_AS = 28,
10267   MEMINFO_VMALLOC_TOTAL = 29,
10268   MEMINFO_VMALLOC_USED = 30,
10269   MEMINFO_VMALLOC_CHUNK = 31,
10270   MEMINFO_CMA_TOTAL = 32,
10271   MEMINFO_CMA_FREE = 33,
10272 };
10273 enum VmstatCounters : int {
10274   VMSTAT_UNSPECIFIED = 0,
10275   VMSTAT_NR_FREE_PAGES = 1,
10276   VMSTAT_NR_ALLOC_BATCH = 2,
10277   VMSTAT_NR_INACTIVE_ANON = 3,
10278   VMSTAT_NR_ACTIVE_ANON = 4,
10279   VMSTAT_NR_INACTIVE_FILE = 5,
10280   VMSTAT_NR_ACTIVE_FILE = 6,
10281   VMSTAT_NR_UNEVICTABLE = 7,
10282   VMSTAT_NR_MLOCK = 8,
10283   VMSTAT_NR_ANON_PAGES = 9,
10284   VMSTAT_NR_MAPPED = 10,
10285   VMSTAT_NR_FILE_PAGES = 11,
10286   VMSTAT_NR_DIRTY = 12,
10287   VMSTAT_NR_WRITEBACK = 13,
10288   VMSTAT_NR_SLAB_RECLAIMABLE = 14,
10289   VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
10290   VMSTAT_NR_PAGE_TABLE_PAGES = 16,
10291   VMSTAT_NR_KERNEL_STACK = 17,
10292   VMSTAT_NR_OVERHEAD = 18,
10293   VMSTAT_NR_UNSTABLE = 19,
10294   VMSTAT_NR_BOUNCE = 20,
10295   VMSTAT_NR_VMSCAN_WRITE = 21,
10296   VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
10297   VMSTAT_NR_WRITEBACK_TEMP = 23,
10298   VMSTAT_NR_ISOLATED_ANON = 24,
10299   VMSTAT_NR_ISOLATED_FILE = 25,
10300   VMSTAT_NR_SHMEM = 26,
10301   VMSTAT_NR_DIRTIED = 27,
10302   VMSTAT_NR_WRITTEN = 28,
10303   VMSTAT_NR_PAGES_SCANNED = 29,
10304   VMSTAT_WORKINGSET_REFAULT = 30,
10305   VMSTAT_WORKINGSET_ACTIVATE = 31,
10306   VMSTAT_WORKINGSET_NODERECLAIM = 32,
10307   VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
10308   VMSTAT_NR_FREE_CMA = 34,
10309   VMSTAT_NR_SWAPCACHE = 35,
10310   VMSTAT_NR_DIRTY_THRESHOLD = 36,
10311   VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
10312   VMSTAT_PGPGIN = 38,
10313   VMSTAT_PGPGOUT = 39,
10314   VMSTAT_PGPGOUTCLEAN = 40,
10315   VMSTAT_PSWPIN = 41,
10316   VMSTAT_PSWPOUT = 42,
10317   VMSTAT_PGALLOC_DMA = 43,
10318   VMSTAT_PGALLOC_NORMAL = 44,
10319   VMSTAT_PGALLOC_MOVABLE = 45,
10320   VMSTAT_PGFREE = 46,
10321   VMSTAT_PGACTIVATE = 47,
10322   VMSTAT_PGDEACTIVATE = 48,
10323   VMSTAT_PGFAULT = 49,
10324   VMSTAT_PGMAJFAULT = 50,
10325   VMSTAT_PGREFILL_DMA = 51,
10326   VMSTAT_PGREFILL_NORMAL = 52,
10327   VMSTAT_PGREFILL_MOVABLE = 53,
10328   VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
10329   VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
10330   VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
10331   VMSTAT_PGSTEAL_DIRECT_DMA = 57,
10332   VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
10333   VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
10334   VMSTAT_PGSCAN_KSWAPD_DMA = 60,
10335   VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
10336   VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
10337   VMSTAT_PGSCAN_DIRECT_DMA = 63,
10338   VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
10339   VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
10340   VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
10341   VMSTAT_PGINODESTEAL = 67,
10342   VMSTAT_SLABS_SCANNED = 68,
10343   VMSTAT_KSWAPD_INODESTEAL = 69,
10344   VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
10345   VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
10346   VMSTAT_PAGEOUTRUN = 72,
10347   VMSTAT_ALLOCSTALL = 73,
10348   VMSTAT_PGROTATED = 74,
10349   VMSTAT_DROP_PAGECACHE = 75,
10350   VMSTAT_DROP_SLAB = 76,
10351   VMSTAT_PGMIGRATE_SUCCESS = 77,
10352   VMSTAT_PGMIGRATE_FAIL = 78,
10353   VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
10354   VMSTAT_COMPACT_FREE_SCANNED = 80,
10355   VMSTAT_COMPACT_ISOLATED = 81,
10356   VMSTAT_COMPACT_STALL = 82,
10357   VMSTAT_COMPACT_FAIL = 83,
10358   VMSTAT_COMPACT_SUCCESS = 84,
10359   VMSTAT_COMPACT_DAEMON_WAKE = 85,
10360   VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
10361   VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
10362   VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
10363   VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
10364   VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
10365   VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
10366   VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
10367   VMSTAT_NR_ZSPAGES = 93,
10368   VMSTAT_NR_ION_HEAP = 94,
10369   VMSTAT_NR_GPU_HEAP = 95,
10370 };
10371 }  // namespace perfetto
10372 }  // namespace protos
10373 }  // namespace gen
10374 
10375 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
10376 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10377 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10378 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10379 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10380 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10381 #pragma GCC diagnostic push
10382 #pragma GCC diagnostic ignored "-Wfloat-equal"
10383 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
10384 
10385 namespace perfetto {
10386 namespace protos {
10387 namespace gen {
10388 }  // namespace perfetto
10389 }  // namespace protos
10390 }  // namespace gen
10391 #pragma GCC diagnostic pop
10392 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
10393 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.gen.h
10394 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10395 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
10396 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
10397 
10398 #include <stdint.h>
10399 #include <bitset>
10400 #include <vector>
10401 #include <string>
10402 #include <type_traits>
10403 
10404 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10405 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10406 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10407 
10408 namespace perfetto {
10409 namespace protos {
10410 namespace gen {
10411 class TraceStats;
10412 class TraceStats_BufferStats;
10413 }  // namespace perfetto
10414 }  // namespace protos
10415 }  // namespace gen
10416 
10417 namespace protozero {
10418 class Message;
10419 }  // namespace protozero
10420 
10421 namespace perfetto {
10422 namespace protos {
10423 namespace gen {
10424 
10425 class PERFETTO_EXPORT TraceStats : public ::protozero::CppMessageObj {
10426  public:
10427   using BufferStats = TraceStats_BufferStats;
10428   enum FieldNumbers {
10429     kBufferStatsFieldNumber = 1,
10430     kProducersConnectedFieldNumber = 2,
10431     kProducersSeenFieldNumber = 3,
10432     kDataSourcesRegisteredFieldNumber = 4,
10433     kDataSourcesSeenFieldNumber = 5,
10434     kTracingSessionsFieldNumber = 6,
10435     kTotalBuffersFieldNumber = 7,
10436     kChunksDiscardedFieldNumber = 8,
10437     kPatchesDiscardedFieldNumber = 9,
10438     kInvalidPacketsFieldNumber = 10,
10439   };
10440 
10441   TraceStats();
10442   ~TraceStats() override;
10443   TraceStats(TraceStats&&) noexcept;
10444   TraceStats& operator=(TraceStats&&);
10445   TraceStats(const TraceStats&);
10446   TraceStats& operator=(const TraceStats&);
10447   bool operator==(const TraceStats&) const;
operator !=(const TraceStats & other) const10448   bool operator!=(const TraceStats& other) const { return !(*this == other); }
10449 
10450   bool ParseFromArray(const void*, size_t) override;
10451   std::string SerializeAsString() const override;
10452   std::vector<uint8_t> SerializeAsArray() const override;
10453   void Serialize(::protozero::Message*) const;
10454 
buffer_stats_size() const10455   int buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
buffer_stats() const10456   const std::vector<TraceStats_BufferStats>& buffer_stats() const { return buffer_stats_; }
mutable_buffer_stats()10457   std::vector<TraceStats_BufferStats>* mutable_buffer_stats() { return &buffer_stats_; }
clear_buffer_stats()10458   void clear_buffer_stats() { buffer_stats_.clear(); }
add_buffer_stats()10459   TraceStats_BufferStats* add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
10460 
has_producers_connected() const10461   bool has_producers_connected() const { return _has_field_[2]; }
producers_connected() const10462   uint32_t producers_connected() const { return producers_connected_; }
set_producers_connected(uint32_t value)10463   void set_producers_connected(uint32_t value) { producers_connected_ = value; _has_field_.set(2); }
10464 
has_producers_seen() const10465   bool has_producers_seen() const { return _has_field_[3]; }
producers_seen() const10466   uint64_t producers_seen() const { return producers_seen_; }
set_producers_seen(uint64_t value)10467   void set_producers_seen(uint64_t value) { producers_seen_ = value; _has_field_.set(3); }
10468 
has_data_sources_registered() const10469   bool has_data_sources_registered() const { return _has_field_[4]; }
data_sources_registered() const10470   uint32_t data_sources_registered() const { return data_sources_registered_; }
set_data_sources_registered(uint32_t value)10471   void set_data_sources_registered(uint32_t value) { data_sources_registered_ = value; _has_field_.set(4); }
10472 
has_data_sources_seen() const10473   bool has_data_sources_seen() const { return _has_field_[5]; }
data_sources_seen() const10474   uint64_t data_sources_seen() const { return data_sources_seen_; }
set_data_sources_seen(uint64_t value)10475   void set_data_sources_seen(uint64_t value) { data_sources_seen_ = value; _has_field_.set(5); }
10476 
has_tracing_sessions() const10477   bool has_tracing_sessions() const { return _has_field_[6]; }
tracing_sessions() const10478   uint32_t tracing_sessions() const { return tracing_sessions_; }
set_tracing_sessions(uint32_t value)10479   void set_tracing_sessions(uint32_t value) { tracing_sessions_ = value; _has_field_.set(6); }
10480 
has_total_buffers() const10481   bool has_total_buffers() const { return _has_field_[7]; }
total_buffers() const10482   uint32_t total_buffers() const { return total_buffers_; }
set_total_buffers(uint32_t value)10483   void set_total_buffers(uint32_t value) { total_buffers_ = value; _has_field_.set(7); }
10484 
has_chunks_discarded() const10485   bool has_chunks_discarded() const { return _has_field_[8]; }
chunks_discarded() const10486   uint64_t chunks_discarded() const { return chunks_discarded_; }
set_chunks_discarded(uint64_t value)10487   void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(8); }
10488 
has_patches_discarded() const10489   bool has_patches_discarded() const { return _has_field_[9]; }
patches_discarded() const10490   uint64_t patches_discarded() const { return patches_discarded_; }
set_patches_discarded(uint64_t value)10491   void set_patches_discarded(uint64_t value) { patches_discarded_ = value; _has_field_.set(9); }
10492 
has_invalid_packets() const10493   bool has_invalid_packets() const { return _has_field_[10]; }
invalid_packets() const10494   uint64_t invalid_packets() const { return invalid_packets_; }
set_invalid_packets(uint64_t value)10495   void set_invalid_packets(uint64_t value) { invalid_packets_ = value; _has_field_.set(10); }
10496 
10497  private:
10498   std::vector<TraceStats_BufferStats> buffer_stats_;
10499   uint32_t producers_connected_{};
10500   uint64_t producers_seen_{};
10501   uint32_t data_sources_registered_{};
10502   uint64_t data_sources_seen_{};
10503   uint32_t tracing_sessions_{};
10504   uint32_t total_buffers_{};
10505   uint64_t chunks_discarded_{};
10506   uint64_t patches_discarded_{};
10507   uint64_t invalid_packets_{};
10508 
10509   // Allows to preserve unknown protobuf fields for compatibility
10510   // with future versions of .proto files.
10511   std::string unknown_fields_;
10512 
10513   std::bitset<11> _has_field_{};
10514 };
10515 
10516 
10517 class PERFETTO_EXPORT TraceStats_BufferStats : public ::protozero::CppMessageObj {
10518  public:
10519   enum FieldNumbers {
10520     kBufferSizeFieldNumber = 12,
10521     kBytesWrittenFieldNumber = 1,
10522     kBytesOverwrittenFieldNumber = 13,
10523     kBytesReadFieldNumber = 14,
10524     kPaddingBytesWrittenFieldNumber = 15,
10525     kPaddingBytesClearedFieldNumber = 16,
10526     kChunksWrittenFieldNumber = 2,
10527     kChunksRewrittenFieldNumber = 10,
10528     kChunksOverwrittenFieldNumber = 3,
10529     kChunksDiscardedFieldNumber = 18,
10530     kChunksReadFieldNumber = 17,
10531     kChunksCommittedOutOfOrderFieldNumber = 11,
10532     kWriteWrapCountFieldNumber = 4,
10533     kPatchesSucceededFieldNumber = 5,
10534     kPatchesFailedFieldNumber = 6,
10535     kReadaheadsSucceededFieldNumber = 7,
10536     kReadaheadsFailedFieldNumber = 8,
10537     kAbiViolationsFieldNumber = 9,
10538     kTraceWriterPacketLossFieldNumber = 19,
10539   };
10540 
10541   TraceStats_BufferStats();
10542   ~TraceStats_BufferStats() override;
10543   TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept;
10544   TraceStats_BufferStats& operator=(TraceStats_BufferStats&&);
10545   TraceStats_BufferStats(const TraceStats_BufferStats&);
10546   TraceStats_BufferStats& operator=(const TraceStats_BufferStats&);
10547   bool operator==(const TraceStats_BufferStats&) const;
operator !=(const TraceStats_BufferStats & other) const10548   bool operator!=(const TraceStats_BufferStats& other) const { return !(*this == other); }
10549 
10550   bool ParseFromArray(const void*, size_t) override;
10551   std::string SerializeAsString() const override;
10552   std::vector<uint8_t> SerializeAsArray() const override;
10553   void Serialize(::protozero::Message*) const;
10554 
has_buffer_size() const10555   bool has_buffer_size() const { return _has_field_[12]; }
buffer_size() const10556   uint64_t buffer_size() const { return buffer_size_; }
set_buffer_size(uint64_t value)10557   void set_buffer_size(uint64_t value) { buffer_size_ = value; _has_field_.set(12); }
10558 
has_bytes_written() const10559   bool has_bytes_written() const { return _has_field_[1]; }
bytes_written() const10560   uint64_t bytes_written() const { return bytes_written_; }
set_bytes_written(uint64_t value)10561   void set_bytes_written(uint64_t value) { bytes_written_ = value; _has_field_.set(1); }
10562 
has_bytes_overwritten() const10563   bool has_bytes_overwritten() const { return _has_field_[13]; }
bytes_overwritten() const10564   uint64_t bytes_overwritten() const { return bytes_overwritten_; }
set_bytes_overwritten(uint64_t value)10565   void set_bytes_overwritten(uint64_t value) { bytes_overwritten_ = value; _has_field_.set(13); }
10566 
has_bytes_read() const10567   bool has_bytes_read() const { return _has_field_[14]; }
bytes_read() const10568   uint64_t bytes_read() const { return bytes_read_; }
set_bytes_read(uint64_t value)10569   void set_bytes_read(uint64_t value) { bytes_read_ = value; _has_field_.set(14); }
10570 
has_padding_bytes_written() const10571   bool has_padding_bytes_written() const { return _has_field_[15]; }
padding_bytes_written() const10572   uint64_t padding_bytes_written() const { return padding_bytes_written_; }
set_padding_bytes_written(uint64_t value)10573   void set_padding_bytes_written(uint64_t value) { padding_bytes_written_ = value; _has_field_.set(15); }
10574 
has_padding_bytes_cleared() const10575   bool has_padding_bytes_cleared() const { return _has_field_[16]; }
padding_bytes_cleared() const10576   uint64_t padding_bytes_cleared() const { return padding_bytes_cleared_; }
set_padding_bytes_cleared(uint64_t value)10577   void set_padding_bytes_cleared(uint64_t value) { padding_bytes_cleared_ = value; _has_field_.set(16); }
10578 
has_chunks_written() const10579   bool has_chunks_written() const { return _has_field_[2]; }
chunks_written() const10580   uint64_t chunks_written() const { return chunks_written_; }
set_chunks_written(uint64_t value)10581   void set_chunks_written(uint64_t value) { chunks_written_ = value; _has_field_.set(2); }
10582 
has_chunks_rewritten() const10583   bool has_chunks_rewritten() const { return _has_field_[10]; }
chunks_rewritten() const10584   uint64_t chunks_rewritten() const { return chunks_rewritten_; }
set_chunks_rewritten(uint64_t value)10585   void set_chunks_rewritten(uint64_t value) { chunks_rewritten_ = value; _has_field_.set(10); }
10586 
has_chunks_overwritten() const10587   bool has_chunks_overwritten() const { return _has_field_[3]; }
chunks_overwritten() const10588   uint64_t chunks_overwritten() const { return chunks_overwritten_; }
set_chunks_overwritten(uint64_t value)10589   void set_chunks_overwritten(uint64_t value) { chunks_overwritten_ = value; _has_field_.set(3); }
10590 
has_chunks_discarded() const10591   bool has_chunks_discarded() const { return _has_field_[18]; }
chunks_discarded() const10592   uint64_t chunks_discarded() const { return chunks_discarded_; }
set_chunks_discarded(uint64_t value)10593   void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(18); }
10594 
has_chunks_read() const10595   bool has_chunks_read() const { return _has_field_[17]; }
chunks_read() const10596   uint64_t chunks_read() const { return chunks_read_; }
set_chunks_read(uint64_t value)10597   void set_chunks_read(uint64_t value) { chunks_read_ = value; _has_field_.set(17); }
10598 
has_chunks_committed_out_of_order() const10599   bool has_chunks_committed_out_of_order() const { return _has_field_[11]; }
chunks_committed_out_of_order() const10600   uint64_t chunks_committed_out_of_order() const { return chunks_committed_out_of_order_; }
set_chunks_committed_out_of_order(uint64_t value)10601   void set_chunks_committed_out_of_order(uint64_t value) { chunks_committed_out_of_order_ = value; _has_field_.set(11); }
10602 
has_write_wrap_count() const10603   bool has_write_wrap_count() const { return _has_field_[4]; }
write_wrap_count() const10604   uint64_t write_wrap_count() const { return write_wrap_count_; }
set_write_wrap_count(uint64_t value)10605   void set_write_wrap_count(uint64_t value) { write_wrap_count_ = value; _has_field_.set(4); }
10606 
has_patches_succeeded() const10607   bool has_patches_succeeded() const { return _has_field_[5]; }
patches_succeeded() const10608   uint64_t patches_succeeded() const { return patches_succeeded_; }
set_patches_succeeded(uint64_t value)10609   void set_patches_succeeded(uint64_t value) { patches_succeeded_ = value; _has_field_.set(5); }
10610 
has_patches_failed() const10611   bool has_patches_failed() const { return _has_field_[6]; }
patches_failed() const10612   uint64_t patches_failed() const { return patches_failed_; }
set_patches_failed(uint64_t value)10613   void set_patches_failed(uint64_t value) { patches_failed_ = value; _has_field_.set(6); }
10614 
has_readaheads_succeeded() const10615   bool has_readaheads_succeeded() const { return _has_field_[7]; }
readaheads_succeeded() const10616   uint64_t readaheads_succeeded() const { return readaheads_succeeded_; }
set_readaheads_succeeded(uint64_t value)10617   void set_readaheads_succeeded(uint64_t value) { readaheads_succeeded_ = value; _has_field_.set(7); }
10618 
has_readaheads_failed() const10619   bool has_readaheads_failed() const { return _has_field_[8]; }
readaheads_failed() const10620   uint64_t readaheads_failed() const { return readaheads_failed_; }
set_readaheads_failed(uint64_t value)10621   void set_readaheads_failed(uint64_t value) { readaheads_failed_ = value; _has_field_.set(8); }
10622 
has_abi_violations() const10623   bool has_abi_violations() const { return _has_field_[9]; }
abi_violations() const10624   uint64_t abi_violations() const { return abi_violations_; }
set_abi_violations(uint64_t value)10625   void set_abi_violations(uint64_t value) { abi_violations_ = value; _has_field_.set(9); }
10626 
has_trace_writer_packet_loss() const10627   bool has_trace_writer_packet_loss() const { return _has_field_[19]; }
trace_writer_packet_loss() const10628   uint64_t trace_writer_packet_loss() const { return trace_writer_packet_loss_; }
set_trace_writer_packet_loss(uint64_t value)10629   void set_trace_writer_packet_loss(uint64_t value) { trace_writer_packet_loss_ = value; _has_field_.set(19); }
10630 
10631  private:
10632   uint64_t buffer_size_{};
10633   uint64_t bytes_written_{};
10634   uint64_t bytes_overwritten_{};
10635   uint64_t bytes_read_{};
10636   uint64_t padding_bytes_written_{};
10637   uint64_t padding_bytes_cleared_{};
10638   uint64_t chunks_written_{};
10639   uint64_t chunks_rewritten_{};
10640   uint64_t chunks_overwritten_{};
10641   uint64_t chunks_discarded_{};
10642   uint64_t chunks_read_{};
10643   uint64_t chunks_committed_out_of_order_{};
10644   uint64_t write_wrap_count_{};
10645   uint64_t patches_succeeded_{};
10646   uint64_t patches_failed_{};
10647   uint64_t readaheads_succeeded_{};
10648   uint64_t readaheads_failed_{};
10649   uint64_t abi_violations_{};
10650   uint64_t trace_writer_packet_loss_{};
10651 
10652   // Allows to preserve unknown protobuf fields for compatibility
10653   // with future versions of .proto files.
10654   std::string unknown_fields_;
10655 
10656   std::bitset<20> _has_field_{};
10657 };
10658 
10659 }  // namespace perfetto
10660 }  // namespace protos
10661 }  // namespace gen
10662 
10663 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
10664 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10665 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10666 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10667 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10668 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10669 #pragma GCC diagnostic push
10670 #pragma GCC diagnostic ignored "-Wfloat-equal"
10671 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
10672 
10673 namespace perfetto {
10674 namespace protos {
10675 namespace gen {
10676 
10677 TraceStats::TraceStats() = default;
10678 TraceStats::~TraceStats() = default;
10679 TraceStats::TraceStats(const TraceStats&) = default;
10680 TraceStats& TraceStats::operator=(const TraceStats&) = default;
10681 TraceStats::TraceStats(TraceStats&&) noexcept = default;
10682 TraceStats& TraceStats::operator=(TraceStats&&) = default;
10683 
operator ==(const TraceStats & other) const10684 bool TraceStats::operator==(const TraceStats& other) const {
10685   return unknown_fields_ == other.unknown_fields_
10686    && buffer_stats_ == other.buffer_stats_
10687    && producers_connected_ == other.producers_connected_
10688    && producers_seen_ == other.producers_seen_
10689    && data_sources_registered_ == other.data_sources_registered_
10690    && data_sources_seen_ == other.data_sources_seen_
10691    && tracing_sessions_ == other.tracing_sessions_
10692    && total_buffers_ == other.total_buffers_
10693    && chunks_discarded_ == other.chunks_discarded_
10694    && patches_discarded_ == other.patches_discarded_
10695    && invalid_packets_ == other.invalid_packets_;
10696 }
10697 
ParseFromArray(const void * raw,size_t size)10698 bool TraceStats::ParseFromArray(const void* raw, size_t size) {
10699   buffer_stats_.clear();
10700   unknown_fields_.clear();
10701   bool packed_error = false;
10702 
10703   ::protozero::ProtoDecoder dec(raw, size);
10704   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10705     if (field.id() < _has_field_.size()) {
10706       _has_field_.set(field.id());
10707     }
10708     switch (field.id()) {
10709       case 1 /* buffer_stats */:
10710         buffer_stats_.emplace_back();
10711         buffer_stats_.back().ParseFromString(field.as_std_string());
10712         break;
10713       case 2 /* producers_connected */:
10714         field.get(&producers_connected_);
10715         break;
10716       case 3 /* producers_seen */:
10717         field.get(&producers_seen_);
10718         break;
10719       case 4 /* data_sources_registered */:
10720         field.get(&data_sources_registered_);
10721         break;
10722       case 5 /* data_sources_seen */:
10723         field.get(&data_sources_seen_);
10724         break;
10725       case 6 /* tracing_sessions */:
10726         field.get(&tracing_sessions_);
10727         break;
10728       case 7 /* total_buffers */:
10729         field.get(&total_buffers_);
10730         break;
10731       case 8 /* chunks_discarded */:
10732         field.get(&chunks_discarded_);
10733         break;
10734       case 9 /* patches_discarded */:
10735         field.get(&patches_discarded_);
10736         break;
10737       case 10 /* invalid_packets */:
10738         field.get(&invalid_packets_);
10739         break;
10740       default:
10741         field.SerializeAndAppendTo(&unknown_fields_);
10742         break;
10743     }
10744   }
10745   return !packed_error && !dec.bytes_left();
10746 }
10747 
SerializeAsString() const10748 std::string TraceStats::SerializeAsString() const {
10749   ::protozero::HeapBuffered<::protozero::Message> msg;
10750   Serialize(msg.get());
10751   return msg.SerializeAsString();
10752 }
10753 
SerializeAsArray() const10754 std::vector<uint8_t> TraceStats::SerializeAsArray() const {
10755   ::protozero::HeapBuffered<::protozero::Message> msg;
10756   Serialize(msg.get());
10757   return msg.SerializeAsArray();
10758 }
10759 
Serialize(::protozero::Message * msg) const10760 void TraceStats::Serialize(::protozero::Message* msg) const {
10761   // Field 1: buffer_stats
10762   for (auto& it : buffer_stats_) {
10763     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
10764   }
10765 
10766   // Field 2: producers_connected
10767   if (_has_field_[2]) {
10768     msg->AppendVarInt(2, producers_connected_);
10769   }
10770 
10771   // Field 3: producers_seen
10772   if (_has_field_[3]) {
10773     msg->AppendVarInt(3, producers_seen_);
10774   }
10775 
10776   // Field 4: data_sources_registered
10777   if (_has_field_[4]) {
10778     msg->AppendVarInt(4, data_sources_registered_);
10779   }
10780 
10781   // Field 5: data_sources_seen
10782   if (_has_field_[5]) {
10783     msg->AppendVarInt(5, data_sources_seen_);
10784   }
10785 
10786   // Field 6: tracing_sessions
10787   if (_has_field_[6]) {
10788     msg->AppendVarInt(6, tracing_sessions_);
10789   }
10790 
10791   // Field 7: total_buffers
10792   if (_has_field_[7]) {
10793     msg->AppendVarInt(7, total_buffers_);
10794   }
10795 
10796   // Field 8: chunks_discarded
10797   if (_has_field_[8]) {
10798     msg->AppendVarInt(8, chunks_discarded_);
10799   }
10800 
10801   // Field 9: patches_discarded
10802   if (_has_field_[9]) {
10803     msg->AppendVarInt(9, patches_discarded_);
10804   }
10805 
10806   // Field 10: invalid_packets
10807   if (_has_field_[10]) {
10808     msg->AppendVarInt(10, invalid_packets_);
10809   }
10810 
10811   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10812 }
10813 
10814 
10815 TraceStats_BufferStats::TraceStats_BufferStats() = default;
10816 TraceStats_BufferStats::~TraceStats_BufferStats() = default;
10817 TraceStats_BufferStats::TraceStats_BufferStats(const TraceStats_BufferStats&) = default;
10818 TraceStats_BufferStats& TraceStats_BufferStats::operator=(const TraceStats_BufferStats&) = default;
10819 TraceStats_BufferStats::TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept = default;
10820 TraceStats_BufferStats& TraceStats_BufferStats::operator=(TraceStats_BufferStats&&) = default;
10821 
operator ==(const TraceStats_BufferStats & other) const10822 bool TraceStats_BufferStats::operator==(const TraceStats_BufferStats& other) const {
10823   return unknown_fields_ == other.unknown_fields_
10824    && buffer_size_ == other.buffer_size_
10825    && bytes_written_ == other.bytes_written_
10826    && bytes_overwritten_ == other.bytes_overwritten_
10827    && bytes_read_ == other.bytes_read_
10828    && padding_bytes_written_ == other.padding_bytes_written_
10829    && padding_bytes_cleared_ == other.padding_bytes_cleared_
10830    && chunks_written_ == other.chunks_written_
10831    && chunks_rewritten_ == other.chunks_rewritten_
10832    && chunks_overwritten_ == other.chunks_overwritten_
10833    && chunks_discarded_ == other.chunks_discarded_
10834    && chunks_read_ == other.chunks_read_
10835    && chunks_committed_out_of_order_ == other.chunks_committed_out_of_order_
10836    && write_wrap_count_ == other.write_wrap_count_
10837    && patches_succeeded_ == other.patches_succeeded_
10838    && patches_failed_ == other.patches_failed_
10839    && readaheads_succeeded_ == other.readaheads_succeeded_
10840    && readaheads_failed_ == other.readaheads_failed_
10841    && abi_violations_ == other.abi_violations_
10842    && trace_writer_packet_loss_ == other.trace_writer_packet_loss_;
10843 }
10844 
ParseFromArray(const void * raw,size_t size)10845 bool TraceStats_BufferStats::ParseFromArray(const void* raw, size_t size) {
10846   unknown_fields_.clear();
10847   bool packed_error = false;
10848 
10849   ::protozero::ProtoDecoder dec(raw, size);
10850   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10851     if (field.id() < _has_field_.size()) {
10852       _has_field_.set(field.id());
10853     }
10854     switch (field.id()) {
10855       case 12 /* buffer_size */:
10856         field.get(&buffer_size_);
10857         break;
10858       case 1 /* bytes_written */:
10859         field.get(&bytes_written_);
10860         break;
10861       case 13 /* bytes_overwritten */:
10862         field.get(&bytes_overwritten_);
10863         break;
10864       case 14 /* bytes_read */:
10865         field.get(&bytes_read_);
10866         break;
10867       case 15 /* padding_bytes_written */:
10868         field.get(&padding_bytes_written_);
10869         break;
10870       case 16 /* padding_bytes_cleared */:
10871         field.get(&padding_bytes_cleared_);
10872         break;
10873       case 2 /* chunks_written */:
10874         field.get(&chunks_written_);
10875         break;
10876       case 10 /* chunks_rewritten */:
10877         field.get(&chunks_rewritten_);
10878         break;
10879       case 3 /* chunks_overwritten */:
10880         field.get(&chunks_overwritten_);
10881         break;
10882       case 18 /* chunks_discarded */:
10883         field.get(&chunks_discarded_);
10884         break;
10885       case 17 /* chunks_read */:
10886         field.get(&chunks_read_);
10887         break;
10888       case 11 /* chunks_committed_out_of_order */:
10889         field.get(&chunks_committed_out_of_order_);
10890         break;
10891       case 4 /* write_wrap_count */:
10892         field.get(&write_wrap_count_);
10893         break;
10894       case 5 /* patches_succeeded */:
10895         field.get(&patches_succeeded_);
10896         break;
10897       case 6 /* patches_failed */:
10898         field.get(&patches_failed_);
10899         break;
10900       case 7 /* readaheads_succeeded */:
10901         field.get(&readaheads_succeeded_);
10902         break;
10903       case 8 /* readaheads_failed */:
10904         field.get(&readaheads_failed_);
10905         break;
10906       case 9 /* abi_violations */:
10907         field.get(&abi_violations_);
10908         break;
10909       case 19 /* trace_writer_packet_loss */:
10910         field.get(&trace_writer_packet_loss_);
10911         break;
10912       default:
10913         field.SerializeAndAppendTo(&unknown_fields_);
10914         break;
10915     }
10916   }
10917   return !packed_error && !dec.bytes_left();
10918 }
10919 
SerializeAsString() const10920 std::string TraceStats_BufferStats::SerializeAsString() const {
10921   ::protozero::HeapBuffered<::protozero::Message> msg;
10922   Serialize(msg.get());
10923   return msg.SerializeAsString();
10924 }
10925 
SerializeAsArray() const10926 std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
10927   ::protozero::HeapBuffered<::protozero::Message> msg;
10928   Serialize(msg.get());
10929   return msg.SerializeAsArray();
10930 }
10931 
Serialize(::protozero::Message * msg) const10932 void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
10933   // Field 12: buffer_size
10934   if (_has_field_[12]) {
10935     msg->AppendVarInt(12, buffer_size_);
10936   }
10937 
10938   // Field 1: bytes_written
10939   if (_has_field_[1]) {
10940     msg->AppendVarInt(1, bytes_written_);
10941   }
10942 
10943   // Field 13: bytes_overwritten
10944   if (_has_field_[13]) {
10945     msg->AppendVarInt(13, bytes_overwritten_);
10946   }
10947 
10948   // Field 14: bytes_read
10949   if (_has_field_[14]) {
10950     msg->AppendVarInt(14, bytes_read_);
10951   }
10952 
10953   // Field 15: padding_bytes_written
10954   if (_has_field_[15]) {
10955     msg->AppendVarInt(15, padding_bytes_written_);
10956   }
10957 
10958   // Field 16: padding_bytes_cleared
10959   if (_has_field_[16]) {
10960     msg->AppendVarInt(16, padding_bytes_cleared_);
10961   }
10962 
10963   // Field 2: chunks_written
10964   if (_has_field_[2]) {
10965     msg->AppendVarInt(2, chunks_written_);
10966   }
10967 
10968   // Field 10: chunks_rewritten
10969   if (_has_field_[10]) {
10970     msg->AppendVarInt(10, chunks_rewritten_);
10971   }
10972 
10973   // Field 3: chunks_overwritten
10974   if (_has_field_[3]) {
10975     msg->AppendVarInt(3, chunks_overwritten_);
10976   }
10977 
10978   // Field 18: chunks_discarded
10979   if (_has_field_[18]) {
10980     msg->AppendVarInt(18, chunks_discarded_);
10981   }
10982 
10983   // Field 17: chunks_read
10984   if (_has_field_[17]) {
10985     msg->AppendVarInt(17, chunks_read_);
10986   }
10987 
10988   // Field 11: chunks_committed_out_of_order
10989   if (_has_field_[11]) {
10990     msg->AppendVarInt(11, chunks_committed_out_of_order_);
10991   }
10992 
10993   // Field 4: write_wrap_count
10994   if (_has_field_[4]) {
10995     msg->AppendVarInt(4, write_wrap_count_);
10996   }
10997 
10998   // Field 5: patches_succeeded
10999   if (_has_field_[5]) {
11000     msg->AppendVarInt(5, patches_succeeded_);
11001   }
11002 
11003   // Field 6: patches_failed
11004   if (_has_field_[6]) {
11005     msg->AppendVarInt(6, patches_failed_);
11006   }
11007 
11008   // Field 7: readaheads_succeeded
11009   if (_has_field_[7]) {
11010     msg->AppendVarInt(7, readaheads_succeeded_);
11011   }
11012 
11013   // Field 8: readaheads_failed
11014   if (_has_field_[8]) {
11015     msg->AppendVarInt(8, readaheads_failed_);
11016   }
11017 
11018   // Field 9: abi_violations
11019   if (_has_field_[9]) {
11020     msg->AppendVarInt(9, abi_violations_);
11021   }
11022 
11023   // Field 19: trace_writer_packet_loss
11024   if (_has_field_[19]) {
11025     msg->AppendVarInt(19, trace_writer_packet_loss_);
11026   }
11027 
11028   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11029 }
11030 
11031 }  // namespace perfetto
11032 }  // namespace protos
11033 }  // namespace gen
11034 #pragma GCC diagnostic pop
11035 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.gen.cc
11036 // gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.gen.h
11037 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11038 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
11039 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
11040 
11041 #include <stdint.h>
11042 #include <bitset>
11043 #include <vector>
11044 #include <string>
11045 #include <type_traits>
11046 
11047 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11048 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11049 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11050 
11051 namespace perfetto {
11052 namespace protos {
11053 namespace gen {
11054 class TracingServiceCapabilities;
11055 enum ObservableEvents_Type : int;
11056 }  // namespace perfetto
11057 }  // namespace protos
11058 }  // namespace gen
11059 
11060 namespace protozero {
11061 class Message;
11062 }  // namespace protozero
11063 
11064 namespace perfetto {
11065 namespace protos {
11066 namespace gen {
11067 
11068 class PERFETTO_EXPORT TracingServiceCapabilities : public ::protozero::CppMessageObj {
11069  public:
11070   enum FieldNumbers {
11071     kHasQueryCapabilitiesFieldNumber = 1,
11072     kObservableEventsFieldNumber = 2,
11073     kHasTraceConfigOutputPathFieldNumber = 3,
11074   };
11075 
11076   TracingServiceCapabilities();
11077   ~TracingServiceCapabilities() override;
11078   TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept;
11079   TracingServiceCapabilities& operator=(TracingServiceCapabilities&&);
11080   TracingServiceCapabilities(const TracingServiceCapabilities&);
11081   TracingServiceCapabilities& operator=(const TracingServiceCapabilities&);
11082   bool operator==(const TracingServiceCapabilities&) const;
operator !=(const TracingServiceCapabilities & other) const11083   bool operator!=(const TracingServiceCapabilities& other) const { return !(*this == other); }
11084 
11085   bool ParseFromArray(const void*, size_t) override;
11086   std::string SerializeAsString() const override;
11087   std::vector<uint8_t> SerializeAsArray() const override;
11088   void Serialize(::protozero::Message*) const;
11089 
has_has_query_capabilities() const11090   bool has_has_query_capabilities() const { return _has_field_[1]; }
has_query_capabilities() const11091   bool has_query_capabilities() const { return has_query_capabilities_; }
set_has_query_capabilities(bool value)11092   void set_has_query_capabilities(bool value) { has_query_capabilities_ = value; _has_field_.set(1); }
11093 
observable_events_size() const11094   int observable_events_size() const { return static_cast<int>(observable_events_.size()); }
observable_events() const11095   const std::vector<ObservableEvents_Type>& observable_events() const { return observable_events_; }
mutable_observable_events()11096   std::vector<ObservableEvents_Type>* mutable_observable_events() { return &observable_events_; }
clear_observable_events()11097   void clear_observable_events() { observable_events_.clear(); }
add_observable_events(ObservableEvents_Type value)11098   void add_observable_events(ObservableEvents_Type value) { observable_events_.emplace_back(value); }
add_observable_events()11099   ObservableEvents_Type* add_observable_events() { observable_events_.emplace_back(); return &observable_events_.back(); }
11100 
has_has_trace_config_output_path() const11101   bool has_has_trace_config_output_path() const { return _has_field_[3]; }
has_trace_config_output_path() const11102   bool has_trace_config_output_path() const { return has_trace_config_output_path_; }
set_has_trace_config_output_path(bool value)11103   void set_has_trace_config_output_path(bool value) { has_trace_config_output_path_ = value; _has_field_.set(3); }
11104 
11105  private:
11106   bool has_query_capabilities_{};
11107   std::vector<ObservableEvents_Type> observable_events_;
11108   bool has_trace_config_output_path_{};
11109 
11110   // Allows to preserve unknown protobuf fields for compatibility
11111   // with future versions of .proto files.
11112   std::string unknown_fields_;
11113 
11114   std::bitset<4> _has_field_{};
11115 };
11116 
11117 }  // namespace perfetto
11118 }  // namespace protos
11119 }  // namespace gen
11120 
11121 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
11122 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11123 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11124 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11125 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11126 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11127 #pragma GCC diagnostic push
11128 #pragma GCC diagnostic ignored "-Wfloat-equal"
11129 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
11130 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
11131 
11132 namespace perfetto {
11133 namespace protos {
11134 namespace gen {
11135 
11136 TracingServiceCapabilities::TracingServiceCapabilities() = default;
11137 TracingServiceCapabilities::~TracingServiceCapabilities() = default;
11138 TracingServiceCapabilities::TracingServiceCapabilities(const TracingServiceCapabilities&) = default;
11139 TracingServiceCapabilities& TracingServiceCapabilities::operator=(const TracingServiceCapabilities&) = default;
11140 TracingServiceCapabilities::TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept = default;
11141 TracingServiceCapabilities& TracingServiceCapabilities::operator=(TracingServiceCapabilities&&) = default;
11142 
operator ==(const TracingServiceCapabilities & other) const11143 bool TracingServiceCapabilities::operator==(const TracingServiceCapabilities& other) const {
11144   return unknown_fields_ == other.unknown_fields_
11145    && has_query_capabilities_ == other.has_query_capabilities_
11146    && observable_events_ == other.observable_events_
11147    && has_trace_config_output_path_ == other.has_trace_config_output_path_;
11148 }
11149 
ParseFromArray(const void * raw,size_t size)11150 bool TracingServiceCapabilities::ParseFromArray(const void* raw, size_t size) {
11151   observable_events_.clear();
11152   unknown_fields_.clear();
11153   bool packed_error = false;
11154 
11155   ::protozero::ProtoDecoder dec(raw, size);
11156   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11157     if (field.id() < _has_field_.size()) {
11158       _has_field_.set(field.id());
11159     }
11160     switch (field.id()) {
11161       case 1 /* has_query_capabilities */:
11162         field.get(&has_query_capabilities_);
11163         break;
11164       case 2 /* observable_events */:
11165         observable_events_.emplace_back();
11166         field.get(&observable_events_.back());
11167         break;
11168       case 3 /* has_trace_config_output_path */:
11169         field.get(&has_trace_config_output_path_);
11170         break;
11171       default:
11172         field.SerializeAndAppendTo(&unknown_fields_);
11173         break;
11174     }
11175   }
11176   return !packed_error && !dec.bytes_left();
11177 }
11178 
SerializeAsString() const11179 std::string TracingServiceCapabilities::SerializeAsString() const {
11180   ::protozero::HeapBuffered<::protozero::Message> msg;
11181   Serialize(msg.get());
11182   return msg.SerializeAsString();
11183 }
11184 
SerializeAsArray() const11185 std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
11186   ::protozero::HeapBuffered<::protozero::Message> msg;
11187   Serialize(msg.get());
11188   return msg.SerializeAsArray();
11189 }
11190 
Serialize(::protozero::Message * msg) const11191 void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
11192   // Field 1: has_query_capabilities
11193   if (_has_field_[1]) {
11194     msg->AppendTinyVarInt(1, has_query_capabilities_);
11195   }
11196 
11197   // Field 2: observable_events
11198   for (auto& it : observable_events_) {
11199     msg->AppendVarInt(2, it);
11200   }
11201 
11202   // Field 3: has_trace_config_output_path
11203   if (_has_field_[3]) {
11204     msg->AppendTinyVarInt(3, has_trace_config_output_path_);
11205   }
11206 
11207   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11208 }
11209 
11210 }  // namespace perfetto
11211 }  // namespace protos
11212 }  // namespace gen
11213 #pragma GCC diagnostic pop
11214 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.gen.cc
11215 // gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.gen.h
11216 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11217 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
11218 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
11219 
11220 #include <stdint.h>
11221 #include <bitset>
11222 #include <vector>
11223 #include <string>
11224 #include <type_traits>
11225 
11226 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11227 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11228 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11229 
11230 namespace perfetto {
11231 namespace protos {
11232 namespace gen {
11233 class TracingServiceState;
11234 class TracingServiceState_DataSource;
11235 class DataSourceDescriptor;
11236 class TracingServiceState_Producer;
11237 }  // namespace perfetto
11238 }  // namespace protos
11239 }  // namespace gen
11240 
11241 namespace protozero {
11242 class Message;
11243 }  // namespace protozero
11244 
11245 namespace perfetto {
11246 namespace protos {
11247 namespace gen {
11248 
11249 class PERFETTO_EXPORT TracingServiceState : public ::protozero::CppMessageObj {
11250  public:
11251   using Producer = TracingServiceState_Producer;
11252   using DataSource = TracingServiceState_DataSource;
11253   enum FieldNumbers {
11254     kProducersFieldNumber = 1,
11255     kDataSourcesFieldNumber = 2,
11256     kNumSessionsFieldNumber = 3,
11257     kNumSessionsStartedFieldNumber = 4,
11258   };
11259 
11260   TracingServiceState();
11261   ~TracingServiceState() override;
11262   TracingServiceState(TracingServiceState&&) noexcept;
11263   TracingServiceState& operator=(TracingServiceState&&);
11264   TracingServiceState(const TracingServiceState&);
11265   TracingServiceState& operator=(const TracingServiceState&);
11266   bool operator==(const TracingServiceState&) const;
operator !=(const TracingServiceState & other) const11267   bool operator!=(const TracingServiceState& other) const { return !(*this == other); }
11268 
11269   bool ParseFromArray(const void*, size_t) override;
11270   std::string SerializeAsString() const override;
11271   std::vector<uint8_t> SerializeAsArray() const override;
11272   void Serialize(::protozero::Message*) const;
11273 
producers_size() const11274   int producers_size() const { return static_cast<int>(producers_.size()); }
producers() const11275   const std::vector<TracingServiceState_Producer>& producers() const { return producers_; }
mutable_producers()11276   std::vector<TracingServiceState_Producer>* mutable_producers() { return &producers_; }
clear_producers()11277   void clear_producers() { producers_.clear(); }
add_producers()11278   TracingServiceState_Producer* add_producers() { producers_.emplace_back(); return &producers_.back(); }
11279 
data_sources_size() const11280   int data_sources_size() const { return static_cast<int>(data_sources_.size()); }
data_sources() const11281   const std::vector<TracingServiceState_DataSource>& data_sources() const { return data_sources_; }
mutable_data_sources()11282   std::vector<TracingServiceState_DataSource>* mutable_data_sources() { return &data_sources_; }
clear_data_sources()11283   void clear_data_sources() { data_sources_.clear(); }
add_data_sources()11284   TracingServiceState_DataSource* add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
11285 
has_num_sessions() const11286   bool has_num_sessions() const { return _has_field_[3]; }
num_sessions() const11287   int32_t num_sessions() const { return num_sessions_; }
set_num_sessions(int32_t value)11288   void set_num_sessions(int32_t value) { num_sessions_ = value; _has_field_.set(3); }
11289 
has_num_sessions_started() const11290   bool has_num_sessions_started() const { return _has_field_[4]; }
num_sessions_started() const11291   int32_t num_sessions_started() const { return num_sessions_started_; }
set_num_sessions_started(int32_t value)11292   void set_num_sessions_started(int32_t value) { num_sessions_started_ = value; _has_field_.set(4); }
11293 
11294  private:
11295   std::vector<TracingServiceState_Producer> producers_;
11296   std::vector<TracingServiceState_DataSource> data_sources_;
11297   int32_t num_sessions_{};
11298   int32_t num_sessions_started_{};
11299 
11300   // Allows to preserve unknown protobuf fields for compatibility
11301   // with future versions of .proto files.
11302   std::string unknown_fields_;
11303 
11304   std::bitset<5> _has_field_{};
11305 };
11306 
11307 
11308 class PERFETTO_EXPORT TracingServiceState_DataSource : public ::protozero::CppMessageObj {
11309  public:
11310   enum FieldNumbers {
11311     kDsDescriptorFieldNumber = 1,
11312     kProducerIdFieldNumber = 2,
11313   };
11314 
11315   TracingServiceState_DataSource();
11316   ~TracingServiceState_DataSource() override;
11317   TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept;
11318   TracingServiceState_DataSource& operator=(TracingServiceState_DataSource&&);
11319   TracingServiceState_DataSource(const TracingServiceState_DataSource&);
11320   TracingServiceState_DataSource& operator=(const TracingServiceState_DataSource&);
11321   bool operator==(const TracingServiceState_DataSource&) const;
operator !=(const TracingServiceState_DataSource & other) const11322   bool operator!=(const TracingServiceState_DataSource& other) const { return !(*this == other); }
11323 
11324   bool ParseFromArray(const void*, size_t) override;
11325   std::string SerializeAsString() const override;
11326   std::vector<uint8_t> SerializeAsArray() const override;
11327   void Serialize(::protozero::Message*) const;
11328 
has_ds_descriptor() const11329   bool has_ds_descriptor() const { return _has_field_[1]; }
ds_descriptor() const11330   const DataSourceDescriptor& ds_descriptor() const { return *ds_descriptor_; }
mutable_ds_descriptor()11331   DataSourceDescriptor* mutable_ds_descriptor() { _has_field_.set(1); return ds_descriptor_.get(); }
11332 
has_producer_id() const11333   bool has_producer_id() const { return _has_field_[2]; }
producer_id() const11334   int32_t producer_id() const { return producer_id_; }
set_producer_id(int32_t value)11335   void set_producer_id(int32_t value) { producer_id_ = value; _has_field_.set(2); }
11336 
11337  private:
11338   ::protozero::CopyablePtr<DataSourceDescriptor> ds_descriptor_;
11339   int32_t producer_id_{};
11340 
11341   // Allows to preserve unknown protobuf fields for compatibility
11342   // with future versions of .proto files.
11343   std::string unknown_fields_;
11344 
11345   std::bitset<3> _has_field_{};
11346 };
11347 
11348 
11349 class PERFETTO_EXPORT TracingServiceState_Producer : public ::protozero::CppMessageObj {
11350  public:
11351   enum FieldNumbers {
11352     kIdFieldNumber = 1,
11353     kNameFieldNumber = 2,
11354     kUidFieldNumber = 3,
11355   };
11356 
11357   TracingServiceState_Producer();
11358   ~TracingServiceState_Producer() override;
11359   TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept;
11360   TracingServiceState_Producer& operator=(TracingServiceState_Producer&&);
11361   TracingServiceState_Producer(const TracingServiceState_Producer&);
11362   TracingServiceState_Producer& operator=(const TracingServiceState_Producer&);
11363   bool operator==(const TracingServiceState_Producer&) const;
operator !=(const TracingServiceState_Producer & other) const11364   bool operator!=(const TracingServiceState_Producer& other) const { return !(*this == other); }
11365 
11366   bool ParseFromArray(const void*, size_t) override;
11367   std::string SerializeAsString() const override;
11368   std::vector<uint8_t> SerializeAsArray() const override;
11369   void Serialize(::protozero::Message*) const;
11370 
has_id() const11371   bool has_id() const { return _has_field_[1]; }
id() const11372   int32_t id() const { return id_; }
set_id(int32_t value)11373   void set_id(int32_t value) { id_ = value; _has_field_.set(1); }
11374 
has_name() const11375   bool has_name() const { return _has_field_[2]; }
name() const11376   const std::string& name() const { return name_; }
set_name(const std::string & value)11377   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
11378 
has_uid() const11379   bool has_uid() const { return _has_field_[3]; }
uid() const11380   int32_t uid() const { return uid_; }
set_uid(int32_t value)11381   void set_uid(int32_t value) { uid_ = value; _has_field_.set(3); }
11382 
11383  private:
11384   int32_t id_{};
11385   std::string name_{};
11386   int32_t uid_{};
11387 
11388   // Allows to preserve unknown protobuf fields for compatibility
11389   // with future versions of .proto files.
11390   std::string unknown_fields_;
11391 
11392   std::bitset<4> _has_field_{};
11393 };
11394 
11395 }  // namespace perfetto
11396 }  // namespace protos
11397 }  // namespace gen
11398 
11399 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
11400 // gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.gen.h
11401 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11402 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
11403 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
11404 
11405 #include <stdint.h>
11406 #include <bitset>
11407 #include <vector>
11408 #include <string>
11409 #include <type_traits>
11410 
11411 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11412 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11413 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11414 
11415 namespace perfetto {
11416 namespace protos {
11417 namespace gen {
11418 class TrackEventDescriptor;
11419 class TrackEventCategory;
11420 }  // namespace perfetto
11421 }  // namespace protos
11422 }  // namespace gen
11423 
11424 namespace protozero {
11425 class Message;
11426 }  // namespace protozero
11427 
11428 namespace perfetto {
11429 namespace protos {
11430 namespace gen {
11431 
11432 class PERFETTO_EXPORT TrackEventDescriptor : public ::protozero::CppMessageObj {
11433  public:
11434   enum FieldNumbers {
11435     kAvailableCategoriesFieldNumber = 1,
11436   };
11437 
11438   TrackEventDescriptor();
11439   ~TrackEventDescriptor() override;
11440   TrackEventDescriptor(TrackEventDescriptor&&) noexcept;
11441   TrackEventDescriptor& operator=(TrackEventDescriptor&&);
11442   TrackEventDescriptor(const TrackEventDescriptor&);
11443   TrackEventDescriptor& operator=(const TrackEventDescriptor&);
11444   bool operator==(const TrackEventDescriptor&) const;
operator !=(const TrackEventDescriptor & other) const11445   bool operator!=(const TrackEventDescriptor& other) const { return !(*this == other); }
11446 
11447   bool ParseFromArray(const void*, size_t) override;
11448   std::string SerializeAsString() const override;
11449   std::vector<uint8_t> SerializeAsArray() const override;
11450   void Serialize(::protozero::Message*) const;
11451 
available_categories_size() const11452   int available_categories_size() const { return static_cast<int>(available_categories_.size()); }
available_categories() const11453   const std::vector<TrackEventCategory>& available_categories() const { return available_categories_; }
mutable_available_categories()11454   std::vector<TrackEventCategory>* mutable_available_categories() { return &available_categories_; }
clear_available_categories()11455   void clear_available_categories() { available_categories_.clear(); }
add_available_categories()11456   TrackEventCategory* add_available_categories() { available_categories_.emplace_back(); return &available_categories_.back(); }
11457 
11458  private:
11459   std::vector<TrackEventCategory> available_categories_;
11460 
11461   // Allows to preserve unknown protobuf fields for compatibility
11462   // with future versions of .proto files.
11463   std::string unknown_fields_;
11464 
11465   std::bitset<2> _has_field_{};
11466 };
11467 
11468 
11469 class PERFETTO_EXPORT TrackEventCategory : public ::protozero::CppMessageObj {
11470  public:
11471   enum FieldNumbers {
11472     kNameFieldNumber = 1,
11473     kDescriptionFieldNumber = 2,
11474     kTagsFieldNumber = 3,
11475   };
11476 
11477   TrackEventCategory();
11478   ~TrackEventCategory() override;
11479   TrackEventCategory(TrackEventCategory&&) noexcept;
11480   TrackEventCategory& operator=(TrackEventCategory&&);
11481   TrackEventCategory(const TrackEventCategory&);
11482   TrackEventCategory& operator=(const TrackEventCategory&);
11483   bool operator==(const TrackEventCategory&) const;
operator !=(const TrackEventCategory & other) const11484   bool operator!=(const TrackEventCategory& other) const { return !(*this == other); }
11485 
11486   bool ParseFromArray(const void*, size_t) override;
11487   std::string SerializeAsString() const override;
11488   std::vector<uint8_t> SerializeAsArray() const override;
11489   void Serialize(::protozero::Message*) const;
11490 
has_name() const11491   bool has_name() const { return _has_field_[1]; }
name() const11492   const std::string& name() const { return name_; }
set_name(const std::string & value)11493   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11494 
has_description() const11495   bool has_description() const { return _has_field_[2]; }
description() const11496   const std::string& description() const { return description_; }
set_description(const std::string & value)11497   void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
11498 
tags_size() const11499   int tags_size() const { return static_cast<int>(tags_.size()); }
tags() const11500   const std::vector<std::string>& tags() const { return tags_; }
mutable_tags()11501   std::vector<std::string>* mutable_tags() { return &tags_; }
clear_tags()11502   void clear_tags() { tags_.clear(); }
add_tags(std::string value)11503   void add_tags(std::string value) { tags_.emplace_back(value); }
add_tags()11504   std::string* add_tags() { tags_.emplace_back(); return &tags_.back(); }
11505 
11506  private:
11507   std::string name_{};
11508   std::string description_{};
11509   std::vector<std::string> tags_;
11510 
11511   // Allows to preserve unknown protobuf fields for compatibility
11512   // with future versions of .proto files.
11513   std::string unknown_fields_;
11514 
11515   std::bitset<4> _has_field_{};
11516 };
11517 
11518 }  // namespace perfetto
11519 }  // namespace protos
11520 }  // namespace gen
11521 
11522 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
11523 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11524 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11525 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11526 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11527 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11528 #pragma GCC diagnostic push
11529 #pragma GCC diagnostic ignored "-Wfloat-equal"
11530 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
11531 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
11532 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
11533 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
11534 
11535 namespace perfetto {
11536 namespace protos {
11537 namespace gen {
11538 
11539 TracingServiceState::TracingServiceState() = default;
11540 TracingServiceState::~TracingServiceState() = default;
11541 TracingServiceState::TracingServiceState(const TracingServiceState&) = default;
11542 TracingServiceState& TracingServiceState::operator=(const TracingServiceState&) = default;
11543 TracingServiceState::TracingServiceState(TracingServiceState&&) noexcept = default;
11544 TracingServiceState& TracingServiceState::operator=(TracingServiceState&&) = default;
11545 
operator ==(const TracingServiceState & other) const11546 bool TracingServiceState::operator==(const TracingServiceState& other) const {
11547   return unknown_fields_ == other.unknown_fields_
11548    && producers_ == other.producers_
11549    && data_sources_ == other.data_sources_
11550    && num_sessions_ == other.num_sessions_
11551    && num_sessions_started_ == other.num_sessions_started_;
11552 }
11553 
ParseFromArray(const void * raw,size_t size)11554 bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
11555   producers_.clear();
11556   data_sources_.clear();
11557   unknown_fields_.clear();
11558   bool packed_error = false;
11559 
11560   ::protozero::ProtoDecoder dec(raw, size);
11561   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11562     if (field.id() < _has_field_.size()) {
11563       _has_field_.set(field.id());
11564     }
11565     switch (field.id()) {
11566       case 1 /* producers */:
11567         producers_.emplace_back();
11568         producers_.back().ParseFromString(field.as_std_string());
11569         break;
11570       case 2 /* data_sources */:
11571         data_sources_.emplace_back();
11572         data_sources_.back().ParseFromString(field.as_std_string());
11573         break;
11574       case 3 /* num_sessions */:
11575         field.get(&num_sessions_);
11576         break;
11577       case 4 /* num_sessions_started */:
11578         field.get(&num_sessions_started_);
11579         break;
11580       default:
11581         field.SerializeAndAppendTo(&unknown_fields_);
11582         break;
11583     }
11584   }
11585   return !packed_error && !dec.bytes_left();
11586 }
11587 
SerializeAsString() const11588 std::string TracingServiceState::SerializeAsString() const {
11589   ::protozero::HeapBuffered<::protozero::Message> msg;
11590   Serialize(msg.get());
11591   return msg.SerializeAsString();
11592 }
11593 
SerializeAsArray() const11594 std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
11595   ::protozero::HeapBuffered<::protozero::Message> msg;
11596   Serialize(msg.get());
11597   return msg.SerializeAsArray();
11598 }
11599 
Serialize(::protozero::Message * msg) const11600 void TracingServiceState::Serialize(::protozero::Message* msg) const {
11601   // Field 1: producers
11602   for (auto& it : producers_) {
11603     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11604   }
11605 
11606   // Field 2: data_sources
11607   for (auto& it : data_sources_) {
11608     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11609   }
11610 
11611   // Field 3: num_sessions
11612   if (_has_field_[3]) {
11613     msg->AppendVarInt(3, num_sessions_);
11614   }
11615 
11616   // Field 4: num_sessions_started
11617   if (_has_field_[4]) {
11618     msg->AppendVarInt(4, num_sessions_started_);
11619   }
11620 
11621   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11622 }
11623 
11624 
11625 TracingServiceState_DataSource::TracingServiceState_DataSource() = default;
11626 TracingServiceState_DataSource::~TracingServiceState_DataSource() = default;
11627 TracingServiceState_DataSource::TracingServiceState_DataSource(const TracingServiceState_DataSource&) = default;
11628 TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(const TracingServiceState_DataSource&) = default;
11629 TracingServiceState_DataSource::TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept = default;
11630 TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(TracingServiceState_DataSource&&) = default;
11631 
operator ==(const TracingServiceState_DataSource & other) const11632 bool TracingServiceState_DataSource::operator==(const TracingServiceState_DataSource& other) const {
11633   return unknown_fields_ == other.unknown_fields_
11634    && ds_descriptor_ == other.ds_descriptor_
11635    && producer_id_ == other.producer_id_;
11636 }
11637 
ParseFromArray(const void * raw,size_t size)11638 bool TracingServiceState_DataSource::ParseFromArray(const void* raw, size_t size) {
11639   unknown_fields_.clear();
11640   bool packed_error = false;
11641 
11642   ::protozero::ProtoDecoder dec(raw, size);
11643   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11644     if (field.id() < _has_field_.size()) {
11645       _has_field_.set(field.id());
11646     }
11647     switch (field.id()) {
11648       case 1 /* ds_descriptor */:
11649         (*ds_descriptor_).ParseFromString(field.as_std_string());
11650         break;
11651       case 2 /* producer_id */:
11652         field.get(&producer_id_);
11653         break;
11654       default:
11655         field.SerializeAndAppendTo(&unknown_fields_);
11656         break;
11657     }
11658   }
11659   return !packed_error && !dec.bytes_left();
11660 }
11661 
SerializeAsString() const11662 std::string TracingServiceState_DataSource::SerializeAsString() const {
11663   ::protozero::HeapBuffered<::protozero::Message> msg;
11664   Serialize(msg.get());
11665   return msg.SerializeAsString();
11666 }
11667 
SerializeAsArray() const11668 std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
11669   ::protozero::HeapBuffered<::protozero::Message> msg;
11670   Serialize(msg.get());
11671   return msg.SerializeAsArray();
11672 }
11673 
Serialize(::protozero::Message * msg) const11674 void TracingServiceState_DataSource::Serialize(::protozero::Message* msg) const {
11675   // Field 1: ds_descriptor
11676   if (_has_field_[1]) {
11677     (*ds_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11678   }
11679 
11680   // Field 2: producer_id
11681   if (_has_field_[2]) {
11682     msg->AppendVarInt(2, producer_id_);
11683   }
11684 
11685   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11686 }
11687 
11688 
11689 TracingServiceState_Producer::TracingServiceState_Producer() = default;
11690 TracingServiceState_Producer::~TracingServiceState_Producer() = default;
11691 TracingServiceState_Producer::TracingServiceState_Producer(const TracingServiceState_Producer&) = default;
11692 TracingServiceState_Producer& TracingServiceState_Producer::operator=(const TracingServiceState_Producer&) = default;
11693 TracingServiceState_Producer::TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept = default;
11694 TracingServiceState_Producer& TracingServiceState_Producer::operator=(TracingServiceState_Producer&&) = default;
11695 
operator ==(const TracingServiceState_Producer & other) const11696 bool TracingServiceState_Producer::operator==(const TracingServiceState_Producer& other) const {
11697   return unknown_fields_ == other.unknown_fields_
11698    && id_ == other.id_
11699    && name_ == other.name_
11700    && uid_ == other.uid_;
11701 }
11702 
ParseFromArray(const void * raw,size_t size)11703 bool TracingServiceState_Producer::ParseFromArray(const void* raw, size_t size) {
11704   unknown_fields_.clear();
11705   bool packed_error = false;
11706 
11707   ::protozero::ProtoDecoder dec(raw, size);
11708   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11709     if (field.id() < _has_field_.size()) {
11710       _has_field_.set(field.id());
11711     }
11712     switch (field.id()) {
11713       case 1 /* id */:
11714         field.get(&id_);
11715         break;
11716       case 2 /* name */:
11717         field.get(&name_);
11718         break;
11719       case 3 /* uid */:
11720         field.get(&uid_);
11721         break;
11722       default:
11723         field.SerializeAndAppendTo(&unknown_fields_);
11724         break;
11725     }
11726   }
11727   return !packed_error && !dec.bytes_left();
11728 }
11729 
SerializeAsString() const11730 std::string TracingServiceState_Producer::SerializeAsString() const {
11731   ::protozero::HeapBuffered<::protozero::Message> msg;
11732   Serialize(msg.get());
11733   return msg.SerializeAsString();
11734 }
11735 
SerializeAsArray() const11736 std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
11737   ::protozero::HeapBuffered<::protozero::Message> msg;
11738   Serialize(msg.get());
11739   return msg.SerializeAsArray();
11740 }
11741 
Serialize(::protozero::Message * msg) const11742 void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
11743   // Field 1: id
11744   if (_has_field_[1]) {
11745     msg->AppendVarInt(1, id_);
11746   }
11747 
11748   // Field 2: name
11749   if (_has_field_[2]) {
11750     msg->AppendString(2, name_);
11751   }
11752 
11753   // Field 3: uid
11754   if (_has_field_[3]) {
11755     msg->AppendVarInt(3, uid_);
11756   }
11757 
11758   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11759 }
11760 
11761 }  // namespace perfetto
11762 }  // namespace protos
11763 }  // namespace gen
11764 #pragma GCC diagnostic pop
11765 // gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.gen.cc
11766 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11767 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11768 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11769 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11770 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11771 #pragma GCC diagnostic push
11772 #pragma GCC diagnostic ignored "-Wfloat-equal"
11773 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
11774 
11775 namespace perfetto {
11776 namespace protos {
11777 namespace gen {
11778 
11779 TrackEventDescriptor::TrackEventDescriptor() = default;
11780 TrackEventDescriptor::~TrackEventDescriptor() = default;
11781 TrackEventDescriptor::TrackEventDescriptor(const TrackEventDescriptor&) = default;
11782 TrackEventDescriptor& TrackEventDescriptor::operator=(const TrackEventDescriptor&) = default;
11783 TrackEventDescriptor::TrackEventDescriptor(TrackEventDescriptor&&) noexcept = default;
11784 TrackEventDescriptor& TrackEventDescriptor::operator=(TrackEventDescriptor&&) = default;
11785 
operator ==(const TrackEventDescriptor & other) const11786 bool TrackEventDescriptor::operator==(const TrackEventDescriptor& other) const {
11787   return unknown_fields_ == other.unknown_fields_
11788    && available_categories_ == other.available_categories_;
11789 }
11790 
ParseFromArray(const void * raw,size_t size)11791 bool TrackEventDescriptor::ParseFromArray(const void* raw, size_t size) {
11792   available_categories_.clear();
11793   unknown_fields_.clear();
11794   bool packed_error = false;
11795 
11796   ::protozero::ProtoDecoder dec(raw, size);
11797   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11798     if (field.id() < _has_field_.size()) {
11799       _has_field_.set(field.id());
11800     }
11801     switch (field.id()) {
11802       case 1 /* available_categories */:
11803         available_categories_.emplace_back();
11804         available_categories_.back().ParseFromString(field.as_std_string());
11805         break;
11806       default:
11807         field.SerializeAndAppendTo(&unknown_fields_);
11808         break;
11809     }
11810   }
11811   return !packed_error && !dec.bytes_left();
11812 }
11813 
SerializeAsString() const11814 std::string TrackEventDescriptor::SerializeAsString() const {
11815   ::protozero::HeapBuffered<::protozero::Message> msg;
11816   Serialize(msg.get());
11817   return msg.SerializeAsString();
11818 }
11819 
SerializeAsArray() const11820 std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
11821   ::protozero::HeapBuffered<::protozero::Message> msg;
11822   Serialize(msg.get());
11823   return msg.SerializeAsArray();
11824 }
11825 
Serialize(::protozero::Message * msg) const11826 void TrackEventDescriptor::Serialize(::protozero::Message* msg) const {
11827   // Field 1: available_categories
11828   for (auto& it : available_categories_) {
11829     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11830   }
11831 
11832   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11833 }
11834 
11835 
11836 TrackEventCategory::TrackEventCategory() = default;
11837 TrackEventCategory::~TrackEventCategory() = default;
11838 TrackEventCategory::TrackEventCategory(const TrackEventCategory&) = default;
11839 TrackEventCategory& TrackEventCategory::operator=(const TrackEventCategory&) = default;
11840 TrackEventCategory::TrackEventCategory(TrackEventCategory&&) noexcept = default;
11841 TrackEventCategory& TrackEventCategory::operator=(TrackEventCategory&&) = default;
11842 
operator ==(const TrackEventCategory & other) const11843 bool TrackEventCategory::operator==(const TrackEventCategory& other) const {
11844   return unknown_fields_ == other.unknown_fields_
11845    && name_ == other.name_
11846    && description_ == other.description_
11847    && tags_ == other.tags_;
11848 }
11849 
ParseFromArray(const void * raw,size_t size)11850 bool TrackEventCategory::ParseFromArray(const void* raw, size_t size) {
11851   tags_.clear();
11852   unknown_fields_.clear();
11853   bool packed_error = false;
11854 
11855   ::protozero::ProtoDecoder dec(raw, size);
11856   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11857     if (field.id() < _has_field_.size()) {
11858       _has_field_.set(field.id());
11859     }
11860     switch (field.id()) {
11861       case 1 /* name */:
11862         field.get(&name_);
11863         break;
11864       case 2 /* description */:
11865         field.get(&description_);
11866         break;
11867       case 3 /* tags */:
11868         tags_.emplace_back();
11869         field.get(&tags_.back());
11870         break;
11871       default:
11872         field.SerializeAndAppendTo(&unknown_fields_);
11873         break;
11874     }
11875   }
11876   return !packed_error && !dec.bytes_left();
11877 }
11878 
SerializeAsString() const11879 std::string TrackEventCategory::SerializeAsString() const {
11880   ::protozero::HeapBuffered<::protozero::Message> msg;
11881   Serialize(msg.get());
11882   return msg.SerializeAsString();
11883 }
11884 
SerializeAsArray() const11885 std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
11886   ::protozero::HeapBuffered<::protozero::Message> msg;
11887   Serialize(msg.get());
11888   return msg.SerializeAsArray();
11889 }
11890 
Serialize(::protozero::Message * msg) const11891 void TrackEventCategory::Serialize(::protozero::Message* msg) const {
11892   // Field 1: name
11893   if (_has_field_[1]) {
11894     msg->AppendString(1, name_);
11895   }
11896 
11897   // Field 2: description
11898   if (_has_field_[2]) {
11899     msg->AppendString(2, description_);
11900   }
11901 
11902   // Field 3: tags
11903   for (auto& it : tags_) {
11904     msg->AppendString(3, it);
11905   }
11906 
11907   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11908 }
11909 
11910 }  // namespace perfetto
11911 }  // namespace protos
11912 }  // namespace gen
11913 #pragma GCC diagnostic pop
11914 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.gen.cc
11915 // gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.gen.h
11916 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11917 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
11918 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
11919 
11920 #include <stdint.h>
11921 #include <bitset>
11922 #include <vector>
11923 #include <string>
11924 #include <type_traits>
11925 
11926 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11927 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11928 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11929 
11930 namespace perfetto {
11931 namespace protos {
11932 namespace gen {
11933 class AndroidLogConfig;
11934 enum AndroidLogId : int;
11935 enum AndroidLogPriority : int;
11936 }  // namespace perfetto
11937 }  // namespace protos
11938 }  // namespace gen
11939 
11940 namespace protozero {
11941 class Message;
11942 }  // namespace protozero
11943 
11944 namespace perfetto {
11945 namespace protos {
11946 namespace gen {
11947 
11948 class PERFETTO_EXPORT AndroidLogConfig : public ::protozero::CppMessageObj {
11949  public:
11950   enum FieldNumbers {
11951     kLogIdsFieldNumber = 1,
11952     kMinPrioFieldNumber = 3,
11953     kFilterTagsFieldNumber = 4,
11954   };
11955 
11956   AndroidLogConfig();
11957   ~AndroidLogConfig() override;
11958   AndroidLogConfig(AndroidLogConfig&&) noexcept;
11959   AndroidLogConfig& operator=(AndroidLogConfig&&);
11960   AndroidLogConfig(const AndroidLogConfig&);
11961   AndroidLogConfig& operator=(const AndroidLogConfig&);
11962   bool operator==(const AndroidLogConfig&) const;
operator !=(const AndroidLogConfig & other) const11963   bool operator!=(const AndroidLogConfig& other) const { return !(*this == other); }
11964 
11965   bool ParseFromArray(const void*, size_t) override;
11966   std::string SerializeAsString() const override;
11967   std::vector<uint8_t> SerializeAsArray() const override;
11968   void Serialize(::protozero::Message*) const;
11969 
log_ids_size() const11970   int log_ids_size() const { return static_cast<int>(log_ids_.size()); }
log_ids() const11971   const std::vector<AndroidLogId>& log_ids() const { return log_ids_; }
mutable_log_ids()11972   std::vector<AndroidLogId>* mutable_log_ids() { return &log_ids_; }
clear_log_ids()11973   void clear_log_ids() { log_ids_.clear(); }
add_log_ids(AndroidLogId value)11974   void add_log_ids(AndroidLogId value) { log_ids_.emplace_back(value); }
add_log_ids()11975   AndroidLogId* add_log_ids() { log_ids_.emplace_back(); return &log_ids_.back(); }
11976 
has_min_prio() const11977   bool has_min_prio() const { return _has_field_[3]; }
min_prio() const11978   AndroidLogPriority min_prio() const { return min_prio_; }
set_min_prio(AndroidLogPriority value)11979   void set_min_prio(AndroidLogPriority value) { min_prio_ = value; _has_field_.set(3); }
11980 
filter_tags_size() const11981   int filter_tags_size() const { return static_cast<int>(filter_tags_.size()); }
filter_tags() const11982   const std::vector<std::string>& filter_tags() const { return filter_tags_; }
mutable_filter_tags()11983   std::vector<std::string>* mutable_filter_tags() { return &filter_tags_; }
clear_filter_tags()11984   void clear_filter_tags() { filter_tags_.clear(); }
add_filter_tags(std::string value)11985   void add_filter_tags(std::string value) { filter_tags_.emplace_back(value); }
add_filter_tags()11986   std::string* add_filter_tags() { filter_tags_.emplace_back(); return &filter_tags_.back(); }
11987 
11988  private:
11989   std::vector<AndroidLogId> log_ids_;
11990   AndroidLogPriority min_prio_{};
11991   std::vector<std::string> filter_tags_;
11992 
11993   // Allows to preserve unknown protobuf fields for compatibility
11994   // with future versions of .proto files.
11995   std::string unknown_fields_;
11996 
11997   std::bitset<5> _has_field_{};
11998 };
11999 
12000 }  // namespace perfetto
12001 }  // namespace protos
12002 }  // namespace gen
12003 
12004 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
12005 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12006 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12007 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12008 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12009 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12010 #pragma GCC diagnostic push
12011 #pragma GCC diagnostic ignored "-Wfloat-equal"
12012 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
12013 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
12014 
12015 namespace perfetto {
12016 namespace protos {
12017 namespace gen {
12018 
12019 AndroidLogConfig::AndroidLogConfig() = default;
12020 AndroidLogConfig::~AndroidLogConfig() = default;
12021 AndroidLogConfig::AndroidLogConfig(const AndroidLogConfig&) = default;
12022 AndroidLogConfig& AndroidLogConfig::operator=(const AndroidLogConfig&) = default;
12023 AndroidLogConfig::AndroidLogConfig(AndroidLogConfig&&) noexcept = default;
12024 AndroidLogConfig& AndroidLogConfig::operator=(AndroidLogConfig&&) = default;
12025 
operator ==(const AndroidLogConfig & other) const12026 bool AndroidLogConfig::operator==(const AndroidLogConfig& other) const {
12027   return unknown_fields_ == other.unknown_fields_
12028    && log_ids_ == other.log_ids_
12029    && min_prio_ == other.min_prio_
12030    && filter_tags_ == other.filter_tags_;
12031 }
12032 
ParseFromArray(const void * raw,size_t size)12033 bool AndroidLogConfig::ParseFromArray(const void* raw, size_t size) {
12034   log_ids_.clear();
12035   filter_tags_.clear();
12036   unknown_fields_.clear();
12037   bool packed_error = false;
12038 
12039   ::protozero::ProtoDecoder dec(raw, size);
12040   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12041     if (field.id() < _has_field_.size()) {
12042       _has_field_.set(field.id());
12043     }
12044     switch (field.id()) {
12045       case 1 /* log_ids */:
12046         log_ids_.emplace_back();
12047         field.get(&log_ids_.back());
12048         break;
12049       case 3 /* min_prio */:
12050         field.get(&min_prio_);
12051         break;
12052       case 4 /* filter_tags */:
12053         filter_tags_.emplace_back();
12054         field.get(&filter_tags_.back());
12055         break;
12056       default:
12057         field.SerializeAndAppendTo(&unknown_fields_);
12058         break;
12059     }
12060   }
12061   return !packed_error && !dec.bytes_left();
12062 }
12063 
SerializeAsString() const12064 std::string AndroidLogConfig::SerializeAsString() const {
12065   ::protozero::HeapBuffered<::protozero::Message> msg;
12066   Serialize(msg.get());
12067   return msg.SerializeAsString();
12068 }
12069 
SerializeAsArray() const12070 std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
12071   ::protozero::HeapBuffered<::protozero::Message> msg;
12072   Serialize(msg.get());
12073   return msg.SerializeAsArray();
12074 }
12075 
Serialize(::protozero::Message * msg) const12076 void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
12077   // Field 1: log_ids
12078   for (auto& it : log_ids_) {
12079     msg->AppendVarInt(1, it);
12080   }
12081 
12082   // Field 3: min_prio
12083   if (_has_field_[3]) {
12084     msg->AppendVarInt(3, min_prio_);
12085   }
12086 
12087   // Field 4: filter_tags
12088   for (auto& it : filter_tags_) {
12089     msg->AppendString(4, it);
12090   }
12091 
12092   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12093 }
12094 
12095 }  // namespace perfetto
12096 }  // namespace protos
12097 }  // namespace gen
12098 #pragma GCC diagnostic pop
12099 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.gen.cc
12100 // gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.gen.h
12101 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12102 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
12103 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
12104 
12105 #include <stdint.h>
12106 #include <bitset>
12107 #include <vector>
12108 #include <string>
12109 #include <type_traits>
12110 
12111 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12112 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12113 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12114 
12115 namespace perfetto {
12116 namespace protos {
12117 namespace gen {
12118 class AndroidPolledStateConfig;
12119 }  // namespace perfetto
12120 }  // namespace protos
12121 }  // namespace gen
12122 
12123 namespace protozero {
12124 class Message;
12125 }  // namespace protozero
12126 
12127 namespace perfetto {
12128 namespace protos {
12129 namespace gen {
12130 
12131 class PERFETTO_EXPORT AndroidPolledStateConfig : public ::protozero::CppMessageObj {
12132  public:
12133   enum FieldNumbers {
12134     kPollMsFieldNumber = 1,
12135   };
12136 
12137   AndroidPolledStateConfig();
12138   ~AndroidPolledStateConfig() override;
12139   AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept;
12140   AndroidPolledStateConfig& operator=(AndroidPolledStateConfig&&);
12141   AndroidPolledStateConfig(const AndroidPolledStateConfig&);
12142   AndroidPolledStateConfig& operator=(const AndroidPolledStateConfig&);
12143   bool operator==(const AndroidPolledStateConfig&) const;
operator !=(const AndroidPolledStateConfig & other) const12144   bool operator!=(const AndroidPolledStateConfig& other) const { return !(*this == other); }
12145 
12146   bool ParseFromArray(const void*, size_t) override;
12147   std::string SerializeAsString() const override;
12148   std::vector<uint8_t> SerializeAsArray() const override;
12149   void Serialize(::protozero::Message*) const;
12150 
has_poll_ms() const12151   bool has_poll_ms() const { return _has_field_[1]; }
poll_ms() const12152   uint32_t poll_ms() const { return poll_ms_; }
set_poll_ms(uint32_t value)12153   void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
12154 
12155  private:
12156   uint32_t poll_ms_{};
12157 
12158   // Allows to preserve unknown protobuf fields for compatibility
12159   // with future versions of .proto files.
12160   std::string unknown_fields_;
12161 
12162   std::bitset<2> _has_field_{};
12163 };
12164 
12165 }  // namespace perfetto
12166 }  // namespace protos
12167 }  // namespace gen
12168 
12169 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
12170 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12171 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12172 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12173 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12174 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12175 #pragma GCC diagnostic push
12176 #pragma GCC diagnostic ignored "-Wfloat-equal"
12177 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
12178 
12179 namespace perfetto {
12180 namespace protos {
12181 namespace gen {
12182 
12183 AndroidPolledStateConfig::AndroidPolledStateConfig() = default;
12184 AndroidPolledStateConfig::~AndroidPolledStateConfig() = default;
12185 AndroidPolledStateConfig::AndroidPolledStateConfig(const AndroidPolledStateConfig&) = default;
12186 AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(const AndroidPolledStateConfig&) = default;
12187 AndroidPolledStateConfig::AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept = default;
12188 AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(AndroidPolledStateConfig&&) = default;
12189 
operator ==(const AndroidPolledStateConfig & other) const12190 bool AndroidPolledStateConfig::operator==(const AndroidPolledStateConfig& other) const {
12191   return unknown_fields_ == other.unknown_fields_
12192    && poll_ms_ == other.poll_ms_;
12193 }
12194 
ParseFromArray(const void * raw,size_t size)12195 bool AndroidPolledStateConfig::ParseFromArray(const void* raw, size_t size) {
12196   unknown_fields_.clear();
12197   bool packed_error = false;
12198 
12199   ::protozero::ProtoDecoder dec(raw, size);
12200   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12201     if (field.id() < _has_field_.size()) {
12202       _has_field_.set(field.id());
12203     }
12204     switch (field.id()) {
12205       case 1 /* poll_ms */:
12206         field.get(&poll_ms_);
12207         break;
12208       default:
12209         field.SerializeAndAppendTo(&unknown_fields_);
12210         break;
12211     }
12212   }
12213   return !packed_error && !dec.bytes_left();
12214 }
12215 
SerializeAsString() const12216 std::string AndroidPolledStateConfig::SerializeAsString() const {
12217   ::protozero::HeapBuffered<::protozero::Message> msg;
12218   Serialize(msg.get());
12219   return msg.SerializeAsString();
12220 }
12221 
SerializeAsArray() const12222 std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
12223   ::protozero::HeapBuffered<::protozero::Message> msg;
12224   Serialize(msg.get());
12225   return msg.SerializeAsArray();
12226 }
12227 
Serialize(::protozero::Message * msg) const12228 void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
12229   // Field 1: poll_ms
12230   if (_has_field_[1]) {
12231     msg->AppendVarInt(1, poll_ms_);
12232   }
12233 
12234   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12235 }
12236 
12237 }  // namespace perfetto
12238 }  // namespace protos
12239 }  // namespace gen
12240 #pragma GCC diagnostic pop
12241 // gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.gen.cc
12242 // gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.gen.h
12243 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12244 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
12245 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
12246 
12247 #include <stdint.h>
12248 #include <bitset>
12249 #include <vector>
12250 #include <string>
12251 #include <type_traits>
12252 
12253 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12254 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12255 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12256 
12257 namespace perfetto {
12258 namespace protos {
12259 namespace gen {
12260 class PackagesListConfig;
12261 }  // namespace perfetto
12262 }  // namespace protos
12263 }  // namespace gen
12264 
12265 namespace protozero {
12266 class Message;
12267 }  // namespace protozero
12268 
12269 namespace perfetto {
12270 namespace protos {
12271 namespace gen {
12272 
12273 class PERFETTO_EXPORT PackagesListConfig : public ::protozero::CppMessageObj {
12274  public:
12275   enum FieldNumbers {
12276     kPackageNameFilterFieldNumber = 1,
12277   };
12278 
12279   PackagesListConfig();
12280   ~PackagesListConfig() override;
12281   PackagesListConfig(PackagesListConfig&&) noexcept;
12282   PackagesListConfig& operator=(PackagesListConfig&&);
12283   PackagesListConfig(const PackagesListConfig&);
12284   PackagesListConfig& operator=(const PackagesListConfig&);
12285   bool operator==(const PackagesListConfig&) const;
operator !=(const PackagesListConfig & other) const12286   bool operator!=(const PackagesListConfig& other) const { return !(*this == other); }
12287 
12288   bool ParseFromArray(const void*, size_t) override;
12289   std::string SerializeAsString() const override;
12290   std::vector<uint8_t> SerializeAsArray() const override;
12291   void Serialize(::protozero::Message*) const;
12292 
package_name_filter_size() const12293   int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
package_name_filter() const12294   const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
mutable_package_name_filter()12295   std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
clear_package_name_filter()12296   void clear_package_name_filter() { package_name_filter_.clear(); }
add_package_name_filter(std::string value)12297   void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
add_package_name_filter()12298   std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
12299 
12300  private:
12301   std::vector<std::string> package_name_filter_;
12302 
12303   // Allows to preserve unknown protobuf fields for compatibility
12304   // with future versions of .proto files.
12305   std::string unknown_fields_;
12306 
12307   std::bitset<2> _has_field_{};
12308 };
12309 
12310 }  // namespace perfetto
12311 }  // namespace protos
12312 }  // namespace gen
12313 
12314 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
12315 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12316 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12317 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12318 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12319 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12320 #pragma GCC diagnostic push
12321 #pragma GCC diagnostic ignored "-Wfloat-equal"
12322 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
12323 
12324 namespace perfetto {
12325 namespace protos {
12326 namespace gen {
12327 
12328 PackagesListConfig::PackagesListConfig() = default;
12329 PackagesListConfig::~PackagesListConfig() = default;
12330 PackagesListConfig::PackagesListConfig(const PackagesListConfig&) = default;
12331 PackagesListConfig& PackagesListConfig::operator=(const PackagesListConfig&) = default;
12332 PackagesListConfig::PackagesListConfig(PackagesListConfig&&) noexcept = default;
12333 PackagesListConfig& PackagesListConfig::operator=(PackagesListConfig&&) = default;
12334 
operator ==(const PackagesListConfig & other) const12335 bool PackagesListConfig::operator==(const PackagesListConfig& other) const {
12336   return unknown_fields_ == other.unknown_fields_
12337    && package_name_filter_ == other.package_name_filter_;
12338 }
12339 
ParseFromArray(const void * raw,size_t size)12340 bool PackagesListConfig::ParseFromArray(const void* raw, size_t size) {
12341   package_name_filter_.clear();
12342   unknown_fields_.clear();
12343   bool packed_error = false;
12344 
12345   ::protozero::ProtoDecoder dec(raw, size);
12346   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12347     if (field.id() < _has_field_.size()) {
12348       _has_field_.set(field.id());
12349     }
12350     switch (field.id()) {
12351       case 1 /* package_name_filter */:
12352         package_name_filter_.emplace_back();
12353         field.get(&package_name_filter_.back());
12354         break;
12355       default:
12356         field.SerializeAndAppendTo(&unknown_fields_);
12357         break;
12358     }
12359   }
12360   return !packed_error && !dec.bytes_left();
12361 }
12362 
SerializeAsString() const12363 std::string PackagesListConfig::SerializeAsString() const {
12364   ::protozero::HeapBuffered<::protozero::Message> msg;
12365   Serialize(msg.get());
12366   return msg.SerializeAsString();
12367 }
12368 
SerializeAsArray() const12369 std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
12370   ::protozero::HeapBuffered<::protozero::Message> msg;
12371   Serialize(msg.get());
12372   return msg.SerializeAsArray();
12373 }
12374 
Serialize(::protozero::Message * msg) const12375 void PackagesListConfig::Serialize(::protozero::Message* msg) const {
12376   // Field 1: package_name_filter
12377   for (auto& it : package_name_filter_) {
12378     msg->AppendString(1, it);
12379   }
12380 
12381   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12382 }
12383 
12384 }  // namespace perfetto
12385 }  // namespace protos
12386 }  // namespace gen
12387 #pragma GCC diagnostic pop
12388 // gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.gen.cc
12389 // gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.gen.h
12390 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12391 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
12392 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
12393 
12394 #include <stdint.h>
12395 #include <bitset>
12396 #include <vector>
12397 #include <string>
12398 #include <type_traits>
12399 
12400 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12401 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12402 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12403 
12404 namespace perfetto {
12405 namespace protos {
12406 namespace gen {
12407 class FtraceConfig;
12408 class FtraceConfig_CompactSchedConfig;
12409 }  // namespace perfetto
12410 }  // namespace protos
12411 }  // namespace gen
12412 
12413 namespace protozero {
12414 class Message;
12415 }  // namespace protozero
12416 
12417 namespace perfetto {
12418 namespace protos {
12419 namespace gen {
12420 
12421 class PERFETTO_EXPORT FtraceConfig : public ::protozero::CppMessageObj {
12422  public:
12423   using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
12424   enum FieldNumbers {
12425     kFtraceEventsFieldNumber = 1,
12426     kAtraceCategoriesFieldNumber = 2,
12427     kAtraceAppsFieldNumber = 3,
12428     kBufferSizeKbFieldNumber = 10,
12429     kDrainPeriodMsFieldNumber = 11,
12430     kCompactSchedFieldNumber = 12,
12431   };
12432 
12433   FtraceConfig();
12434   ~FtraceConfig() override;
12435   FtraceConfig(FtraceConfig&&) noexcept;
12436   FtraceConfig& operator=(FtraceConfig&&);
12437   FtraceConfig(const FtraceConfig&);
12438   FtraceConfig& operator=(const FtraceConfig&);
12439   bool operator==(const FtraceConfig&) const;
operator !=(const FtraceConfig & other) const12440   bool operator!=(const FtraceConfig& other) const { return !(*this == other); }
12441 
12442   bool ParseFromArray(const void*, size_t) override;
12443   std::string SerializeAsString() const override;
12444   std::vector<uint8_t> SerializeAsArray() const override;
12445   void Serialize(::protozero::Message*) const;
12446 
ftrace_events_size() const12447   int ftrace_events_size() const { return static_cast<int>(ftrace_events_.size()); }
ftrace_events() const12448   const std::vector<std::string>& ftrace_events() const { return ftrace_events_; }
mutable_ftrace_events()12449   std::vector<std::string>* mutable_ftrace_events() { return &ftrace_events_; }
clear_ftrace_events()12450   void clear_ftrace_events() { ftrace_events_.clear(); }
add_ftrace_events(std::string value)12451   void add_ftrace_events(std::string value) { ftrace_events_.emplace_back(value); }
add_ftrace_events()12452   std::string* add_ftrace_events() { ftrace_events_.emplace_back(); return &ftrace_events_.back(); }
12453 
atrace_categories_size() const12454   int atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
atrace_categories() const12455   const std::vector<std::string>& atrace_categories() const { return atrace_categories_; }
mutable_atrace_categories()12456   std::vector<std::string>* mutable_atrace_categories() { return &atrace_categories_; }
clear_atrace_categories()12457   void clear_atrace_categories() { atrace_categories_.clear(); }
add_atrace_categories(std::string value)12458   void add_atrace_categories(std::string value) { atrace_categories_.emplace_back(value); }
add_atrace_categories()12459   std::string* add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
12460 
atrace_apps_size() const12461   int atrace_apps_size() const { return static_cast<int>(atrace_apps_.size()); }
atrace_apps() const12462   const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
mutable_atrace_apps()12463   std::vector<std::string>* mutable_atrace_apps() { return &atrace_apps_; }
clear_atrace_apps()12464   void clear_atrace_apps() { atrace_apps_.clear(); }
add_atrace_apps(std::string value)12465   void add_atrace_apps(std::string value) { atrace_apps_.emplace_back(value); }
add_atrace_apps()12466   std::string* add_atrace_apps() { atrace_apps_.emplace_back(); return &atrace_apps_.back(); }
12467 
has_buffer_size_kb() const12468   bool has_buffer_size_kb() const { return _has_field_[10]; }
buffer_size_kb() const12469   uint32_t buffer_size_kb() const { return buffer_size_kb_; }
set_buffer_size_kb(uint32_t value)12470   void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; _has_field_.set(10); }
12471 
has_drain_period_ms() const12472   bool has_drain_period_ms() const { return _has_field_[11]; }
drain_period_ms() const12473   uint32_t drain_period_ms() const { return drain_period_ms_; }
set_drain_period_ms(uint32_t value)12474   void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; _has_field_.set(11); }
12475 
has_compact_sched() const12476   bool has_compact_sched() const { return _has_field_[12]; }
compact_sched() const12477   const FtraceConfig_CompactSchedConfig& compact_sched() const { return *compact_sched_; }
mutable_compact_sched()12478   FtraceConfig_CompactSchedConfig* mutable_compact_sched() { _has_field_.set(12); return compact_sched_.get(); }
12479 
12480  private:
12481   std::vector<std::string> ftrace_events_;
12482   std::vector<std::string> atrace_categories_;
12483   std::vector<std::string> atrace_apps_;
12484   uint32_t buffer_size_kb_{};
12485   uint32_t drain_period_ms_{};
12486   ::protozero::CopyablePtr<FtraceConfig_CompactSchedConfig> compact_sched_;
12487 
12488   // Allows to preserve unknown protobuf fields for compatibility
12489   // with future versions of .proto files.
12490   std::string unknown_fields_;
12491 
12492   std::bitset<13> _has_field_{};
12493 };
12494 
12495 
12496 class PERFETTO_EXPORT FtraceConfig_CompactSchedConfig : public ::protozero::CppMessageObj {
12497  public:
12498   enum FieldNumbers {
12499     kEnabledFieldNumber = 1,
12500   };
12501 
12502   FtraceConfig_CompactSchedConfig();
12503   ~FtraceConfig_CompactSchedConfig() override;
12504   FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept;
12505   FtraceConfig_CompactSchedConfig& operator=(FtraceConfig_CompactSchedConfig&&);
12506   FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&);
12507   FtraceConfig_CompactSchedConfig& operator=(const FtraceConfig_CompactSchedConfig&);
12508   bool operator==(const FtraceConfig_CompactSchedConfig&) const;
operator !=(const FtraceConfig_CompactSchedConfig & other) const12509   bool operator!=(const FtraceConfig_CompactSchedConfig& other) const { return !(*this == other); }
12510 
12511   bool ParseFromArray(const void*, size_t) override;
12512   std::string SerializeAsString() const override;
12513   std::vector<uint8_t> SerializeAsArray() const override;
12514   void Serialize(::protozero::Message*) const;
12515 
has_enabled() const12516   bool has_enabled() const { return _has_field_[1]; }
enabled() const12517   bool enabled() const { return enabled_; }
set_enabled(bool value)12518   void set_enabled(bool value) { enabled_ = value; _has_field_.set(1); }
12519 
12520  private:
12521   bool enabled_{};
12522 
12523   // Allows to preserve unknown protobuf fields for compatibility
12524   // with future versions of .proto files.
12525   std::string unknown_fields_;
12526 
12527   std::bitset<2> _has_field_{};
12528 };
12529 
12530 }  // namespace perfetto
12531 }  // namespace protos
12532 }  // namespace gen
12533 
12534 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
12535 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12536 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12537 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12538 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12539 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12540 #pragma GCC diagnostic push
12541 #pragma GCC diagnostic ignored "-Wfloat-equal"
12542 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
12543 
12544 namespace perfetto {
12545 namespace protos {
12546 namespace gen {
12547 
12548 FtraceConfig::FtraceConfig() = default;
12549 FtraceConfig::~FtraceConfig() = default;
12550 FtraceConfig::FtraceConfig(const FtraceConfig&) = default;
12551 FtraceConfig& FtraceConfig::operator=(const FtraceConfig&) = default;
12552 FtraceConfig::FtraceConfig(FtraceConfig&&) noexcept = default;
12553 FtraceConfig& FtraceConfig::operator=(FtraceConfig&&) = default;
12554 
operator ==(const FtraceConfig & other) const12555 bool FtraceConfig::operator==(const FtraceConfig& other) const {
12556   return unknown_fields_ == other.unknown_fields_
12557    && ftrace_events_ == other.ftrace_events_
12558    && atrace_categories_ == other.atrace_categories_
12559    && atrace_apps_ == other.atrace_apps_
12560    && buffer_size_kb_ == other.buffer_size_kb_
12561    && drain_period_ms_ == other.drain_period_ms_
12562    && compact_sched_ == other.compact_sched_;
12563 }
12564 
ParseFromArray(const void * raw,size_t size)12565 bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
12566   ftrace_events_.clear();
12567   atrace_categories_.clear();
12568   atrace_apps_.clear();
12569   unknown_fields_.clear();
12570   bool packed_error = false;
12571 
12572   ::protozero::ProtoDecoder dec(raw, size);
12573   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12574     if (field.id() < _has_field_.size()) {
12575       _has_field_.set(field.id());
12576     }
12577     switch (field.id()) {
12578       case 1 /* ftrace_events */:
12579         ftrace_events_.emplace_back();
12580         field.get(&ftrace_events_.back());
12581         break;
12582       case 2 /* atrace_categories */:
12583         atrace_categories_.emplace_back();
12584         field.get(&atrace_categories_.back());
12585         break;
12586       case 3 /* atrace_apps */:
12587         atrace_apps_.emplace_back();
12588         field.get(&atrace_apps_.back());
12589         break;
12590       case 10 /* buffer_size_kb */:
12591         field.get(&buffer_size_kb_);
12592         break;
12593       case 11 /* drain_period_ms */:
12594         field.get(&drain_period_ms_);
12595         break;
12596       case 12 /* compact_sched */:
12597         (*compact_sched_).ParseFromString(field.as_std_string());
12598         break;
12599       default:
12600         field.SerializeAndAppendTo(&unknown_fields_);
12601         break;
12602     }
12603   }
12604   return !packed_error && !dec.bytes_left();
12605 }
12606 
SerializeAsString() const12607 std::string FtraceConfig::SerializeAsString() const {
12608   ::protozero::HeapBuffered<::protozero::Message> msg;
12609   Serialize(msg.get());
12610   return msg.SerializeAsString();
12611 }
12612 
SerializeAsArray() const12613 std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
12614   ::protozero::HeapBuffered<::protozero::Message> msg;
12615   Serialize(msg.get());
12616   return msg.SerializeAsArray();
12617 }
12618 
Serialize(::protozero::Message * msg) const12619 void FtraceConfig::Serialize(::protozero::Message* msg) const {
12620   // Field 1: ftrace_events
12621   for (auto& it : ftrace_events_) {
12622     msg->AppendString(1, it);
12623   }
12624 
12625   // Field 2: atrace_categories
12626   for (auto& it : atrace_categories_) {
12627     msg->AppendString(2, it);
12628   }
12629 
12630   // Field 3: atrace_apps
12631   for (auto& it : atrace_apps_) {
12632     msg->AppendString(3, it);
12633   }
12634 
12635   // Field 10: buffer_size_kb
12636   if (_has_field_[10]) {
12637     msg->AppendVarInt(10, buffer_size_kb_);
12638   }
12639 
12640   // Field 11: drain_period_ms
12641   if (_has_field_[11]) {
12642     msg->AppendVarInt(11, drain_period_ms_);
12643   }
12644 
12645   // Field 12: compact_sched
12646   if (_has_field_[12]) {
12647     (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
12648   }
12649 
12650   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12651 }
12652 
12653 
12654 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig() = default;
12655 FtraceConfig_CompactSchedConfig::~FtraceConfig_CompactSchedConfig() = default;
12656 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&) = default;
12657 FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(const FtraceConfig_CompactSchedConfig&) = default;
12658 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept = default;
12659 FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(FtraceConfig_CompactSchedConfig&&) = default;
12660 
operator ==(const FtraceConfig_CompactSchedConfig & other) const12661 bool FtraceConfig_CompactSchedConfig::operator==(const FtraceConfig_CompactSchedConfig& other) const {
12662   return unknown_fields_ == other.unknown_fields_
12663    && enabled_ == other.enabled_;
12664 }
12665 
ParseFromArray(const void * raw,size_t size)12666 bool FtraceConfig_CompactSchedConfig::ParseFromArray(const void* raw, size_t size) {
12667   unknown_fields_.clear();
12668   bool packed_error = false;
12669 
12670   ::protozero::ProtoDecoder dec(raw, size);
12671   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12672     if (field.id() < _has_field_.size()) {
12673       _has_field_.set(field.id());
12674     }
12675     switch (field.id()) {
12676       case 1 /* enabled */:
12677         field.get(&enabled_);
12678         break;
12679       default:
12680         field.SerializeAndAppendTo(&unknown_fields_);
12681         break;
12682     }
12683   }
12684   return !packed_error && !dec.bytes_left();
12685 }
12686 
SerializeAsString() const12687 std::string FtraceConfig_CompactSchedConfig::SerializeAsString() const {
12688   ::protozero::HeapBuffered<::protozero::Message> msg;
12689   Serialize(msg.get());
12690   return msg.SerializeAsString();
12691 }
12692 
SerializeAsArray() const12693 std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
12694   ::protozero::HeapBuffered<::protozero::Message> msg;
12695   Serialize(msg.get());
12696   return msg.SerializeAsArray();
12697 }
12698 
Serialize(::protozero::Message * msg) const12699 void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
12700   // Field 1: enabled
12701   if (_has_field_[1]) {
12702     msg->AppendTinyVarInt(1, enabled_);
12703   }
12704 
12705   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12706 }
12707 
12708 }  // namespace perfetto
12709 }  // namespace protos
12710 }  // namespace gen
12711 #pragma GCC diagnostic pop
12712 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.cc
12713 // gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.h
12714 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12715 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
12716 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
12717 
12718 #include <stdint.h>
12719 #include <bitset>
12720 #include <vector>
12721 #include <string>
12722 #include <type_traits>
12723 
12724 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12725 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12726 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12727 
12728 namespace perfetto {
12729 namespace protos {
12730 namespace gen {
12731 class GpuCounterConfig;
12732 }  // namespace perfetto
12733 }  // namespace protos
12734 }  // namespace gen
12735 
12736 namespace protozero {
12737 class Message;
12738 }  // namespace protozero
12739 
12740 namespace perfetto {
12741 namespace protos {
12742 namespace gen {
12743 
12744 class PERFETTO_EXPORT GpuCounterConfig : public ::protozero::CppMessageObj {
12745  public:
12746   enum FieldNumbers {
12747     kCounterPeriodNsFieldNumber = 1,
12748     kCounterIdsFieldNumber = 2,
12749     kInstrumentedSamplingFieldNumber = 3,
12750     kFixGpuClockFieldNumber = 4,
12751   };
12752 
12753   GpuCounterConfig();
12754   ~GpuCounterConfig() override;
12755   GpuCounterConfig(GpuCounterConfig&&) noexcept;
12756   GpuCounterConfig& operator=(GpuCounterConfig&&);
12757   GpuCounterConfig(const GpuCounterConfig&);
12758   GpuCounterConfig& operator=(const GpuCounterConfig&);
12759   bool operator==(const GpuCounterConfig&) const;
operator !=(const GpuCounterConfig & other) const12760   bool operator!=(const GpuCounterConfig& other) const { return !(*this == other); }
12761 
12762   bool ParseFromArray(const void*, size_t) override;
12763   std::string SerializeAsString() const override;
12764   std::vector<uint8_t> SerializeAsArray() const override;
12765   void Serialize(::protozero::Message*) const;
12766 
has_counter_period_ns() const12767   bool has_counter_period_ns() const { return _has_field_[1]; }
counter_period_ns() const12768   uint64_t counter_period_ns() const { return counter_period_ns_; }
set_counter_period_ns(uint64_t value)12769   void set_counter_period_ns(uint64_t value) { counter_period_ns_ = value; _has_field_.set(1); }
12770 
counter_ids_size() const12771   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
counter_ids() const12772   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()12773   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
clear_counter_ids()12774   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)12775   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()12776   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
12777 
has_instrumented_sampling() const12778   bool has_instrumented_sampling() const { return _has_field_[3]; }
instrumented_sampling() const12779   bool instrumented_sampling() const { return instrumented_sampling_; }
set_instrumented_sampling(bool value)12780   void set_instrumented_sampling(bool value) { instrumented_sampling_ = value; _has_field_.set(3); }
12781 
has_fix_gpu_clock() const12782   bool has_fix_gpu_clock() const { return _has_field_[4]; }
fix_gpu_clock() const12783   bool fix_gpu_clock() const { return fix_gpu_clock_; }
set_fix_gpu_clock(bool value)12784   void set_fix_gpu_clock(bool value) { fix_gpu_clock_ = value; _has_field_.set(4); }
12785 
12786  private:
12787   uint64_t counter_period_ns_{};
12788   std::vector<uint32_t> counter_ids_;
12789   bool instrumented_sampling_{};
12790   bool fix_gpu_clock_{};
12791 
12792   // Allows to preserve unknown protobuf fields for compatibility
12793   // with future versions of .proto files.
12794   std::string unknown_fields_;
12795 
12796   std::bitset<5> _has_field_{};
12797 };
12798 
12799 }  // namespace perfetto
12800 }  // namespace protos
12801 }  // namespace gen
12802 
12803 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
12804 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12805 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12806 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12807 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12808 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12809 #pragma GCC diagnostic push
12810 #pragma GCC diagnostic ignored "-Wfloat-equal"
12811 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
12812 
12813 namespace perfetto {
12814 namespace protos {
12815 namespace gen {
12816 
12817 GpuCounterConfig::GpuCounterConfig() = default;
12818 GpuCounterConfig::~GpuCounterConfig() = default;
12819 GpuCounterConfig::GpuCounterConfig(const GpuCounterConfig&) = default;
12820 GpuCounterConfig& GpuCounterConfig::operator=(const GpuCounterConfig&) = default;
12821 GpuCounterConfig::GpuCounterConfig(GpuCounterConfig&&) noexcept = default;
12822 GpuCounterConfig& GpuCounterConfig::operator=(GpuCounterConfig&&) = default;
12823 
operator ==(const GpuCounterConfig & other) const12824 bool GpuCounterConfig::operator==(const GpuCounterConfig& other) const {
12825   return unknown_fields_ == other.unknown_fields_
12826    && counter_period_ns_ == other.counter_period_ns_
12827    && counter_ids_ == other.counter_ids_
12828    && instrumented_sampling_ == other.instrumented_sampling_
12829    && fix_gpu_clock_ == other.fix_gpu_clock_;
12830 }
12831 
ParseFromArray(const void * raw,size_t size)12832 bool GpuCounterConfig::ParseFromArray(const void* raw, size_t size) {
12833   counter_ids_.clear();
12834   unknown_fields_.clear();
12835   bool packed_error = false;
12836 
12837   ::protozero::ProtoDecoder dec(raw, size);
12838   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12839     if (field.id() < _has_field_.size()) {
12840       _has_field_.set(field.id());
12841     }
12842     switch (field.id()) {
12843       case 1 /* counter_period_ns */:
12844         field.get(&counter_period_ns_);
12845         break;
12846       case 2 /* counter_ids */:
12847         counter_ids_.emplace_back();
12848         field.get(&counter_ids_.back());
12849         break;
12850       case 3 /* instrumented_sampling */:
12851         field.get(&instrumented_sampling_);
12852         break;
12853       case 4 /* fix_gpu_clock */:
12854         field.get(&fix_gpu_clock_);
12855         break;
12856       default:
12857         field.SerializeAndAppendTo(&unknown_fields_);
12858         break;
12859     }
12860   }
12861   return !packed_error && !dec.bytes_left();
12862 }
12863 
SerializeAsString() const12864 std::string GpuCounterConfig::SerializeAsString() const {
12865   ::protozero::HeapBuffered<::protozero::Message> msg;
12866   Serialize(msg.get());
12867   return msg.SerializeAsString();
12868 }
12869 
SerializeAsArray() const12870 std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
12871   ::protozero::HeapBuffered<::protozero::Message> msg;
12872   Serialize(msg.get());
12873   return msg.SerializeAsArray();
12874 }
12875 
Serialize(::protozero::Message * msg) const12876 void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
12877   // Field 1: counter_period_ns
12878   if (_has_field_[1]) {
12879     msg->AppendVarInt(1, counter_period_ns_);
12880   }
12881 
12882   // Field 2: counter_ids
12883   for (auto& it : counter_ids_) {
12884     msg->AppendVarInt(2, it);
12885   }
12886 
12887   // Field 3: instrumented_sampling
12888   if (_has_field_[3]) {
12889     msg->AppendTinyVarInt(3, instrumented_sampling_);
12890   }
12891 
12892   // Field 4: fix_gpu_clock
12893   if (_has_field_[4]) {
12894     msg->AppendTinyVarInt(4, fix_gpu_clock_);
12895   }
12896 
12897   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12898 }
12899 
12900 }  // namespace perfetto
12901 }  // namespace protos
12902 }  // namespace gen
12903 #pragma GCC diagnostic pop
12904 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc
12905 // gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.h
12906 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12907 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
12908 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
12909 
12910 #include <stdint.h>
12911 #include <bitset>
12912 #include <vector>
12913 #include <string>
12914 #include <type_traits>
12915 
12916 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
12917 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
12918 // gen_amalgamated expanded: #include "perfetto/base/export.h"
12919 
12920 namespace perfetto {
12921 namespace protos {
12922 namespace gen {
12923 class VulkanMemoryConfig;
12924 }  // namespace perfetto
12925 }  // namespace protos
12926 }  // namespace gen
12927 
12928 namespace protozero {
12929 class Message;
12930 }  // namespace protozero
12931 
12932 namespace perfetto {
12933 namespace protos {
12934 namespace gen {
12935 
12936 class PERFETTO_EXPORT VulkanMemoryConfig : public ::protozero::CppMessageObj {
12937  public:
12938   enum FieldNumbers {
12939     kTrackDriverMemoryUsageFieldNumber = 1,
12940     kTrackDeviceMemoryUsageFieldNumber = 2,
12941   };
12942 
12943   VulkanMemoryConfig();
12944   ~VulkanMemoryConfig() override;
12945   VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept;
12946   VulkanMemoryConfig& operator=(VulkanMemoryConfig&&);
12947   VulkanMemoryConfig(const VulkanMemoryConfig&);
12948   VulkanMemoryConfig& operator=(const VulkanMemoryConfig&);
12949   bool operator==(const VulkanMemoryConfig&) const;
operator !=(const VulkanMemoryConfig & other) const12950   bool operator!=(const VulkanMemoryConfig& other) const { return !(*this == other); }
12951 
12952   bool ParseFromArray(const void*, size_t) override;
12953   std::string SerializeAsString() const override;
12954   std::vector<uint8_t> SerializeAsArray() const override;
12955   void Serialize(::protozero::Message*) const;
12956 
has_track_driver_memory_usage() const12957   bool has_track_driver_memory_usage() const { return _has_field_[1]; }
track_driver_memory_usage() const12958   bool track_driver_memory_usage() const { return track_driver_memory_usage_; }
set_track_driver_memory_usage(bool value)12959   void set_track_driver_memory_usage(bool value) { track_driver_memory_usage_ = value; _has_field_.set(1); }
12960 
has_track_device_memory_usage() const12961   bool has_track_device_memory_usage() const { return _has_field_[2]; }
track_device_memory_usage() const12962   bool track_device_memory_usage() const { return track_device_memory_usage_; }
set_track_device_memory_usage(bool value)12963   void set_track_device_memory_usage(bool value) { track_device_memory_usage_ = value; _has_field_.set(2); }
12964 
12965  private:
12966   bool track_driver_memory_usage_{};
12967   bool track_device_memory_usage_{};
12968 
12969   // Allows to preserve unknown protobuf fields for compatibility
12970   // with future versions of .proto files.
12971   std::string unknown_fields_;
12972 
12973   std::bitset<3> _has_field_{};
12974 };
12975 
12976 }  // namespace perfetto
12977 }  // namespace protos
12978 }  // namespace gen
12979 
12980 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
12981 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12982 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12983 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12984 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12985 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12986 #pragma GCC diagnostic push
12987 #pragma GCC diagnostic ignored "-Wfloat-equal"
12988 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
12989 
12990 namespace perfetto {
12991 namespace protos {
12992 namespace gen {
12993 
12994 VulkanMemoryConfig::VulkanMemoryConfig() = default;
12995 VulkanMemoryConfig::~VulkanMemoryConfig() = default;
12996 VulkanMemoryConfig::VulkanMemoryConfig(const VulkanMemoryConfig&) = default;
12997 VulkanMemoryConfig& VulkanMemoryConfig::operator=(const VulkanMemoryConfig&) = default;
12998 VulkanMemoryConfig::VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept = default;
12999 VulkanMemoryConfig& VulkanMemoryConfig::operator=(VulkanMemoryConfig&&) = default;
13000 
operator ==(const VulkanMemoryConfig & other) const13001 bool VulkanMemoryConfig::operator==(const VulkanMemoryConfig& other) const {
13002   return unknown_fields_ == other.unknown_fields_
13003    && track_driver_memory_usage_ == other.track_driver_memory_usage_
13004    && track_device_memory_usage_ == other.track_device_memory_usage_;
13005 }
13006 
ParseFromArray(const void * raw,size_t size)13007 bool VulkanMemoryConfig::ParseFromArray(const void* raw, size_t size) {
13008   unknown_fields_.clear();
13009   bool packed_error = false;
13010 
13011   ::protozero::ProtoDecoder dec(raw, size);
13012   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13013     if (field.id() < _has_field_.size()) {
13014       _has_field_.set(field.id());
13015     }
13016     switch (field.id()) {
13017       case 1 /* track_driver_memory_usage */:
13018         field.get(&track_driver_memory_usage_);
13019         break;
13020       case 2 /* track_device_memory_usage */:
13021         field.get(&track_device_memory_usage_);
13022         break;
13023       default:
13024         field.SerializeAndAppendTo(&unknown_fields_);
13025         break;
13026     }
13027   }
13028   return !packed_error && !dec.bytes_left();
13029 }
13030 
SerializeAsString() const13031 std::string VulkanMemoryConfig::SerializeAsString() const {
13032   ::protozero::HeapBuffered<::protozero::Message> msg;
13033   Serialize(msg.get());
13034   return msg.SerializeAsString();
13035 }
13036 
SerializeAsArray() const13037 std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
13038   ::protozero::HeapBuffered<::protozero::Message> msg;
13039   Serialize(msg.get());
13040   return msg.SerializeAsArray();
13041 }
13042 
Serialize(::protozero::Message * msg) const13043 void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
13044   // Field 1: track_driver_memory_usage
13045   if (_has_field_[1]) {
13046     msg->AppendTinyVarInt(1, track_driver_memory_usage_);
13047   }
13048 
13049   // Field 2: track_device_memory_usage
13050   if (_has_field_[2]) {
13051     msg->AppendTinyVarInt(2, track_device_memory_usage_);
13052   }
13053 
13054   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13055 }
13056 
13057 }  // namespace perfetto
13058 }  // namespace protos
13059 }  // namespace gen
13060 #pragma GCC diagnostic pop
13061 // gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.gen.cc
13062 // gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.gen.h
13063 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13064 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
13065 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
13066 
13067 #include <stdint.h>
13068 #include <bitset>
13069 #include <vector>
13070 #include <string>
13071 #include <type_traits>
13072 
13073 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13074 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13075 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13076 
13077 namespace perfetto {
13078 namespace protos {
13079 namespace gen {
13080 class InodeFileConfig;
13081 class InodeFileConfig_MountPointMappingEntry;
13082 }  // namespace perfetto
13083 }  // namespace protos
13084 }  // namespace gen
13085 
13086 namespace protozero {
13087 class Message;
13088 }  // namespace protozero
13089 
13090 namespace perfetto {
13091 namespace protos {
13092 namespace gen {
13093 
13094 class PERFETTO_EXPORT InodeFileConfig : public ::protozero::CppMessageObj {
13095  public:
13096   using MountPointMappingEntry = InodeFileConfig_MountPointMappingEntry;
13097   enum FieldNumbers {
13098     kScanIntervalMsFieldNumber = 1,
13099     kScanDelayMsFieldNumber = 2,
13100     kScanBatchSizeFieldNumber = 3,
13101     kDoNotScanFieldNumber = 4,
13102     kScanMountPointsFieldNumber = 5,
13103     kMountPointMappingFieldNumber = 6,
13104   };
13105 
13106   InodeFileConfig();
13107   ~InodeFileConfig() override;
13108   InodeFileConfig(InodeFileConfig&&) noexcept;
13109   InodeFileConfig& operator=(InodeFileConfig&&);
13110   InodeFileConfig(const InodeFileConfig&);
13111   InodeFileConfig& operator=(const InodeFileConfig&);
13112   bool operator==(const InodeFileConfig&) const;
operator !=(const InodeFileConfig & other) const13113   bool operator!=(const InodeFileConfig& other) const { return !(*this == other); }
13114 
13115   bool ParseFromArray(const void*, size_t) override;
13116   std::string SerializeAsString() const override;
13117   std::vector<uint8_t> SerializeAsArray() const override;
13118   void Serialize(::protozero::Message*) const;
13119 
has_scan_interval_ms() const13120   bool has_scan_interval_ms() const { return _has_field_[1]; }
scan_interval_ms() const13121   uint32_t scan_interval_ms() const { return scan_interval_ms_; }
set_scan_interval_ms(uint32_t value)13122   void set_scan_interval_ms(uint32_t value) { scan_interval_ms_ = value; _has_field_.set(1); }
13123 
has_scan_delay_ms() const13124   bool has_scan_delay_ms() const { return _has_field_[2]; }
scan_delay_ms() const13125   uint32_t scan_delay_ms() const { return scan_delay_ms_; }
set_scan_delay_ms(uint32_t value)13126   void set_scan_delay_ms(uint32_t value) { scan_delay_ms_ = value; _has_field_.set(2); }
13127 
has_scan_batch_size() const13128   bool has_scan_batch_size() const { return _has_field_[3]; }
scan_batch_size() const13129   uint32_t scan_batch_size() const { return scan_batch_size_; }
set_scan_batch_size(uint32_t value)13130   void set_scan_batch_size(uint32_t value) { scan_batch_size_ = value; _has_field_.set(3); }
13131 
has_do_not_scan() const13132   bool has_do_not_scan() const { return _has_field_[4]; }
do_not_scan() const13133   bool do_not_scan() const { return do_not_scan_; }
set_do_not_scan(bool value)13134   void set_do_not_scan(bool value) { do_not_scan_ = value; _has_field_.set(4); }
13135 
scan_mount_points_size() const13136   int scan_mount_points_size() const { return static_cast<int>(scan_mount_points_.size()); }
scan_mount_points() const13137   const std::vector<std::string>& scan_mount_points() const { return scan_mount_points_; }
mutable_scan_mount_points()13138   std::vector<std::string>* mutable_scan_mount_points() { return &scan_mount_points_; }
clear_scan_mount_points()13139   void clear_scan_mount_points() { scan_mount_points_.clear(); }
add_scan_mount_points(std::string value)13140   void add_scan_mount_points(std::string value) { scan_mount_points_.emplace_back(value); }
add_scan_mount_points()13141   std::string* add_scan_mount_points() { scan_mount_points_.emplace_back(); return &scan_mount_points_.back(); }
13142 
mount_point_mapping_size() const13143   int mount_point_mapping_size() const { return static_cast<int>(mount_point_mapping_.size()); }
mount_point_mapping() const13144   const std::vector<InodeFileConfig_MountPointMappingEntry>& mount_point_mapping() const { return mount_point_mapping_; }
mutable_mount_point_mapping()13145   std::vector<InodeFileConfig_MountPointMappingEntry>* mutable_mount_point_mapping() { return &mount_point_mapping_; }
clear_mount_point_mapping()13146   void clear_mount_point_mapping() { mount_point_mapping_.clear(); }
add_mount_point_mapping()13147   InodeFileConfig_MountPointMappingEntry* add_mount_point_mapping() { mount_point_mapping_.emplace_back(); return &mount_point_mapping_.back(); }
13148 
13149  private:
13150   uint32_t scan_interval_ms_{};
13151   uint32_t scan_delay_ms_{};
13152   uint32_t scan_batch_size_{};
13153   bool do_not_scan_{};
13154   std::vector<std::string> scan_mount_points_;
13155   std::vector<InodeFileConfig_MountPointMappingEntry> mount_point_mapping_;
13156 
13157   // Allows to preserve unknown protobuf fields for compatibility
13158   // with future versions of .proto files.
13159   std::string unknown_fields_;
13160 
13161   std::bitset<7> _has_field_{};
13162 };
13163 
13164 
13165 class PERFETTO_EXPORT InodeFileConfig_MountPointMappingEntry : public ::protozero::CppMessageObj {
13166  public:
13167   enum FieldNumbers {
13168     kMountpointFieldNumber = 1,
13169     kScanRootsFieldNumber = 2,
13170   };
13171 
13172   InodeFileConfig_MountPointMappingEntry();
13173   ~InodeFileConfig_MountPointMappingEntry() override;
13174   InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept;
13175   InodeFileConfig_MountPointMappingEntry& operator=(InodeFileConfig_MountPointMappingEntry&&);
13176   InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&);
13177   InodeFileConfig_MountPointMappingEntry& operator=(const InodeFileConfig_MountPointMappingEntry&);
13178   bool operator==(const InodeFileConfig_MountPointMappingEntry&) const;
operator !=(const InodeFileConfig_MountPointMappingEntry & other) const13179   bool operator!=(const InodeFileConfig_MountPointMappingEntry& other) const { return !(*this == other); }
13180 
13181   bool ParseFromArray(const void*, size_t) override;
13182   std::string SerializeAsString() const override;
13183   std::vector<uint8_t> SerializeAsArray() const override;
13184   void Serialize(::protozero::Message*) const;
13185 
has_mountpoint() const13186   bool has_mountpoint() const { return _has_field_[1]; }
mountpoint() const13187   const std::string& mountpoint() const { return mountpoint_; }
set_mountpoint(const std::string & value)13188   void set_mountpoint(const std::string& value) { mountpoint_ = value; _has_field_.set(1); }
13189 
scan_roots_size() const13190   int scan_roots_size() const { return static_cast<int>(scan_roots_.size()); }
scan_roots() const13191   const std::vector<std::string>& scan_roots() const { return scan_roots_; }
mutable_scan_roots()13192   std::vector<std::string>* mutable_scan_roots() { return &scan_roots_; }
clear_scan_roots()13193   void clear_scan_roots() { scan_roots_.clear(); }
add_scan_roots(std::string value)13194   void add_scan_roots(std::string value) { scan_roots_.emplace_back(value); }
add_scan_roots()13195   std::string* add_scan_roots() { scan_roots_.emplace_back(); return &scan_roots_.back(); }
13196 
13197  private:
13198   std::string mountpoint_{};
13199   std::vector<std::string> scan_roots_;
13200 
13201   // Allows to preserve unknown protobuf fields for compatibility
13202   // with future versions of .proto files.
13203   std::string unknown_fields_;
13204 
13205   std::bitset<3> _has_field_{};
13206 };
13207 
13208 }  // namespace perfetto
13209 }  // namespace protos
13210 }  // namespace gen
13211 
13212 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
13213 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13214 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13215 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13216 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13217 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13218 #pragma GCC diagnostic push
13219 #pragma GCC diagnostic ignored "-Wfloat-equal"
13220 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
13221 
13222 namespace perfetto {
13223 namespace protos {
13224 namespace gen {
13225 
13226 InodeFileConfig::InodeFileConfig() = default;
13227 InodeFileConfig::~InodeFileConfig() = default;
13228 InodeFileConfig::InodeFileConfig(const InodeFileConfig&) = default;
13229 InodeFileConfig& InodeFileConfig::operator=(const InodeFileConfig&) = default;
13230 InodeFileConfig::InodeFileConfig(InodeFileConfig&&) noexcept = default;
13231 InodeFileConfig& InodeFileConfig::operator=(InodeFileConfig&&) = default;
13232 
operator ==(const InodeFileConfig & other) const13233 bool InodeFileConfig::operator==(const InodeFileConfig& other) const {
13234   return unknown_fields_ == other.unknown_fields_
13235    && scan_interval_ms_ == other.scan_interval_ms_
13236    && scan_delay_ms_ == other.scan_delay_ms_
13237    && scan_batch_size_ == other.scan_batch_size_
13238    && do_not_scan_ == other.do_not_scan_
13239    && scan_mount_points_ == other.scan_mount_points_
13240    && mount_point_mapping_ == other.mount_point_mapping_;
13241 }
13242 
ParseFromArray(const void * raw,size_t size)13243 bool InodeFileConfig::ParseFromArray(const void* raw, size_t size) {
13244   scan_mount_points_.clear();
13245   mount_point_mapping_.clear();
13246   unknown_fields_.clear();
13247   bool packed_error = false;
13248 
13249   ::protozero::ProtoDecoder dec(raw, size);
13250   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13251     if (field.id() < _has_field_.size()) {
13252       _has_field_.set(field.id());
13253     }
13254     switch (field.id()) {
13255       case 1 /* scan_interval_ms */:
13256         field.get(&scan_interval_ms_);
13257         break;
13258       case 2 /* scan_delay_ms */:
13259         field.get(&scan_delay_ms_);
13260         break;
13261       case 3 /* scan_batch_size */:
13262         field.get(&scan_batch_size_);
13263         break;
13264       case 4 /* do_not_scan */:
13265         field.get(&do_not_scan_);
13266         break;
13267       case 5 /* scan_mount_points */:
13268         scan_mount_points_.emplace_back();
13269         field.get(&scan_mount_points_.back());
13270         break;
13271       case 6 /* mount_point_mapping */:
13272         mount_point_mapping_.emplace_back();
13273         mount_point_mapping_.back().ParseFromString(field.as_std_string());
13274         break;
13275       default:
13276         field.SerializeAndAppendTo(&unknown_fields_);
13277         break;
13278     }
13279   }
13280   return !packed_error && !dec.bytes_left();
13281 }
13282 
SerializeAsString() const13283 std::string InodeFileConfig::SerializeAsString() const {
13284   ::protozero::HeapBuffered<::protozero::Message> msg;
13285   Serialize(msg.get());
13286   return msg.SerializeAsString();
13287 }
13288 
SerializeAsArray() const13289 std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
13290   ::protozero::HeapBuffered<::protozero::Message> msg;
13291   Serialize(msg.get());
13292   return msg.SerializeAsArray();
13293 }
13294 
Serialize(::protozero::Message * msg) const13295 void InodeFileConfig::Serialize(::protozero::Message* msg) const {
13296   // Field 1: scan_interval_ms
13297   if (_has_field_[1]) {
13298     msg->AppendVarInt(1, scan_interval_ms_);
13299   }
13300 
13301   // Field 2: scan_delay_ms
13302   if (_has_field_[2]) {
13303     msg->AppendVarInt(2, scan_delay_ms_);
13304   }
13305 
13306   // Field 3: scan_batch_size
13307   if (_has_field_[3]) {
13308     msg->AppendVarInt(3, scan_batch_size_);
13309   }
13310 
13311   // Field 4: do_not_scan
13312   if (_has_field_[4]) {
13313     msg->AppendTinyVarInt(4, do_not_scan_);
13314   }
13315 
13316   // Field 5: scan_mount_points
13317   for (auto& it : scan_mount_points_) {
13318     msg->AppendString(5, it);
13319   }
13320 
13321   // Field 6: mount_point_mapping
13322   for (auto& it : mount_point_mapping_) {
13323     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
13324   }
13325 
13326   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13327 }
13328 
13329 
13330 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry() = default;
13331 InodeFileConfig_MountPointMappingEntry::~InodeFileConfig_MountPointMappingEntry() = default;
13332 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&) = default;
13333 InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(const InodeFileConfig_MountPointMappingEntry&) = default;
13334 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept = default;
13335 InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(InodeFileConfig_MountPointMappingEntry&&) = default;
13336 
operator ==(const InodeFileConfig_MountPointMappingEntry & other) const13337 bool InodeFileConfig_MountPointMappingEntry::operator==(const InodeFileConfig_MountPointMappingEntry& other) const {
13338   return unknown_fields_ == other.unknown_fields_
13339    && mountpoint_ == other.mountpoint_
13340    && scan_roots_ == other.scan_roots_;
13341 }
13342 
ParseFromArray(const void * raw,size_t size)13343 bool InodeFileConfig_MountPointMappingEntry::ParseFromArray(const void* raw, size_t size) {
13344   scan_roots_.clear();
13345   unknown_fields_.clear();
13346   bool packed_error = false;
13347 
13348   ::protozero::ProtoDecoder dec(raw, size);
13349   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13350     if (field.id() < _has_field_.size()) {
13351       _has_field_.set(field.id());
13352     }
13353     switch (field.id()) {
13354       case 1 /* mountpoint */:
13355         field.get(&mountpoint_);
13356         break;
13357       case 2 /* scan_roots */:
13358         scan_roots_.emplace_back();
13359         field.get(&scan_roots_.back());
13360         break;
13361       default:
13362         field.SerializeAndAppendTo(&unknown_fields_);
13363         break;
13364     }
13365   }
13366   return !packed_error && !dec.bytes_left();
13367 }
13368 
SerializeAsString() const13369 std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
13370   ::protozero::HeapBuffered<::protozero::Message> msg;
13371   Serialize(msg.get());
13372   return msg.SerializeAsString();
13373 }
13374 
SerializeAsArray() const13375 std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
13376   ::protozero::HeapBuffered<::protozero::Message> msg;
13377   Serialize(msg.get());
13378   return msg.SerializeAsArray();
13379 }
13380 
Serialize(::protozero::Message * msg) const13381 void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
13382   // Field 1: mountpoint
13383   if (_has_field_[1]) {
13384     msg->AppendString(1, mountpoint_);
13385   }
13386 
13387   // Field 2: scan_roots
13388   for (auto& it : scan_roots_) {
13389     msg->AppendString(2, it);
13390   }
13391 
13392   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13393 }
13394 
13395 }  // namespace perfetto
13396 }  // namespace protos
13397 }  // namespace gen
13398 #pragma GCC diagnostic pop
13399 // gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.gen.cc
13400 // gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.gen.h
13401 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13402 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
13403 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
13404 
13405 #include <stdint.h>
13406 #include <bitset>
13407 #include <vector>
13408 #include <string>
13409 #include <type_traits>
13410 
13411 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13412 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13413 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13414 
13415 namespace perfetto {
13416 namespace protos {
13417 namespace gen {
13418 class AndroidPowerConfig;
13419 enum AndroidPowerConfig_BatteryCounters : int;
13420 }  // namespace perfetto
13421 }  // namespace protos
13422 }  // namespace gen
13423 
13424 namespace protozero {
13425 class Message;
13426 }  // namespace protozero
13427 
13428 namespace perfetto {
13429 namespace protos {
13430 namespace gen {
13431 enum AndroidPowerConfig_BatteryCounters : int {
13432   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED = 0,
13433   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE = 1,
13434   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT = 2,
13435   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT = 3,
13436   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG = 4,
13437 };
13438 
13439 class PERFETTO_EXPORT AndroidPowerConfig : public ::protozero::CppMessageObj {
13440  public:
13441   using BatteryCounters = AndroidPowerConfig_BatteryCounters;
13442   static constexpr auto BATTERY_COUNTER_UNSPECIFIED = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
13443   static constexpr auto BATTERY_COUNTER_CHARGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE;
13444   static constexpr auto BATTERY_COUNTER_CAPACITY_PERCENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT;
13445   static constexpr auto BATTERY_COUNTER_CURRENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT;
13446   static constexpr auto BATTERY_COUNTER_CURRENT_AVG = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
13447   static constexpr auto BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
13448   static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
13449   enum FieldNumbers {
13450     kBatteryPollMsFieldNumber = 1,
13451     kBatteryCountersFieldNumber = 2,
13452     kCollectPowerRailsFieldNumber = 3,
13453   };
13454 
13455   AndroidPowerConfig();
13456   ~AndroidPowerConfig() override;
13457   AndroidPowerConfig(AndroidPowerConfig&&) noexcept;
13458   AndroidPowerConfig& operator=(AndroidPowerConfig&&);
13459   AndroidPowerConfig(const AndroidPowerConfig&);
13460   AndroidPowerConfig& operator=(const AndroidPowerConfig&);
13461   bool operator==(const AndroidPowerConfig&) const;
operator !=(const AndroidPowerConfig & other) const13462   bool operator!=(const AndroidPowerConfig& other) const { return !(*this == other); }
13463 
13464   bool ParseFromArray(const void*, size_t) override;
13465   std::string SerializeAsString() const override;
13466   std::vector<uint8_t> SerializeAsArray() const override;
13467   void Serialize(::protozero::Message*) const;
13468 
has_battery_poll_ms() const13469   bool has_battery_poll_ms() const { return _has_field_[1]; }
battery_poll_ms() const13470   uint32_t battery_poll_ms() const { return battery_poll_ms_; }
set_battery_poll_ms(uint32_t value)13471   void set_battery_poll_ms(uint32_t value) { battery_poll_ms_ = value; _has_field_.set(1); }
13472 
battery_counters_size() const13473   int battery_counters_size() const { return static_cast<int>(battery_counters_.size()); }
battery_counters() const13474   const std::vector<AndroidPowerConfig_BatteryCounters>& battery_counters() const { return battery_counters_; }
mutable_battery_counters()13475   std::vector<AndroidPowerConfig_BatteryCounters>* mutable_battery_counters() { return &battery_counters_; }
clear_battery_counters()13476   void clear_battery_counters() { battery_counters_.clear(); }
add_battery_counters(AndroidPowerConfig_BatteryCounters value)13477   void add_battery_counters(AndroidPowerConfig_BatteryCounters value) { battery_counters_.emplace_back(value); }
add_battery_counters()13478   AndroidPowerConfig_BatteryCounters* add_battery_counters() { battery_counters_.emplace_back(); return &battery_counters_.back(); }
13479 
has_collect_power_rails() const13480   bool has_collect_power_rails() const { return _has_field_[3]; }
collect_power_rails() const13481   bool collect_power_rails() const { return collect_power_rails_; }
set_collect_power_rails(bool value)13482   void set_collect_power_rails(bool value) { collect_power_rails_ = value; _has_field_.set(3); }
13483 
13484  private:
13485   uint32_t battery_poll_ms_{};
13486   std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
13487   bool collect_power_rails_{};
13488 
13489   // Allows to preserve unknown protobuf fields for compatibility
13490   // with future versions of .proto files.
13491   std::string unknown_fields_;
13492 
13493   std::bitset<4> _has_field_{};
13494 };
13495 
13496 }  // namespace perfetto
13497 }  // namespace protos
13498 }  // namespace gen
13499 
13500 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
13501 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13502 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13503 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13504 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13505 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13506 #pragma GCC diagnostic push
13507 #pragma GCC diagnostic ignored "-Wfloat-equal"
13508 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
13509 
13510 namespace perfetto {
13511 namespace protos {
13512 namespace gen {
13513 
13514 AndroidPowerConfig::AndroidPowerConfig() = default;
13515 AndroidPowerConfig::~AndroidPowerConfig() = default;
13516 AndroidPowerConfig::AndroidPowerConfig(const AndroidPowerConfig&) = default;
13517 AndroidPowerConfig& AndroidPowerConfig::operator=(const AndroidPowerConfig&) = default;
13518 AndroidPowerConfig::AndroidPowerConfig(AndroidPowerConfig&&) noexcept = default;
13519 AndroidPowerConfig& AndroidPowerConfig::operator=(AndroidPowerConfig&&) = default;
13520 
operator ==(const AndroidPowerConfig & other) const13521 bool AndroidPowerConfig::operator==(const AndroidPowerConfig& other) const {
13522   return unknown_fields_ == other.unknown_fields_
13523    && battery_poll_ms_ == other.battery_poll_ms_
13524    && battery_counters_ == other.battery_counters_
13525    && collect_power_rails_ == other.collect_power_rails_;
13526 }
13527 
ParseFromArray(const void * raw,size_t size)13528 bool AndroidPowerConfig::ParseFromArray(const void* raw, size_t size) {
13529   battery_counters_.clear();
13530   unknown_fields_.clear();
13531   bool packed_error = false;
13532 
13533   ::protozero::ProtoDecoder dec(raw, size);
13534   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13535     if (field.id() < _has_field_.size()) {
13536       _has_field_.set(field.id());
13537     }
13538     switch (field.id()) {
13539       case 1 /* battery_poll_ms */:
13540         field.get(&battery_poll_ms_);
13541         break;
13542       case 2 /* battery_counters */:
13543         battery_counters_.emplace_back();
13544         field.get(&battery_counters_.back());
13545         break;
13546       case 3 /* collect_power_rails */:
13547         field.get(&collect_power_rails_);
13548         break;
13549       default:
13550         field.SerializeAndAppendTo(&unknown_fields_);
13551         break;
13552     }
13553   }
13554   return !packed_error && !dec.bytes_left();
13555 }
13556 
SerializeAsString() const13557 std::string AndroidPowerConfig::SerializeAsString() const {
13558   ::protozero::HeapBuffered<::protozero::Message> msg;
13559   Serialize(msg.get());
13560   return msg.SerializeAsString();
13561 }
13562 
SerializeAsArray() const13563 std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
13564   ::protozero::HeapBuffered<::protozero::Message> msg;
13565   Serialize(msg.get());
13566   return msg.SerializeAsArray();
13567 }
13568 
Serialize(::protozero::Message * msg) const13569 void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
13570   // Field 1: battery_poll_ms
13571   if (_has_field_[1]) {
13572     msg->AppendVarInt(1, battery_poll_ms_);
13573   }
13574 
13575   // Field 2: battery_counters
13576   for (auto& it : battery_counters_) {
13577     msg->AppendVarInt(2, it);
13578   }
13579 
13580   // Field 3: collect_power_rails
13581   if (_has_field_[3]) {
13582     msg->AppendTinyVarInt(3, collect_power_rails_);
13583   }
13584 
13585   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13586 }
13587 
13588 }  // namespace perfetto
13589 }  // namespace protos
13590 }  // namespace gen
13591 #pragma GCC diagnostic pop
13592 // gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.gen.cc
13593 // gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.gen.h
13594 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13595 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
13596 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
13597 
13598 #include <stdint.h>
13599 #include <bitset>
13600 #include <vector>
13601 #include <string>
13602 #include <type_traits>
13603 
13604 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13605 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13606 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13607 
13608 namespace perfetto {
13609 namespace protos {
13610 namespace gen {
13611 class ProcessStatsConfig;
13612 enum ProcessStatsConfig_Quirks : int;
13613 }  // namespace perfetto
13614 }  // namespace protos
13615 }  // namespace gen
13616 
13617 namespace protozero {
13618 class Message;
13619 }  // namespace protozero
13620 
13621 namespace perfetto {
13622 namespace protos {
13623 namespace gen {
13624 enum ProcessStatsConfig_Quirks : int {
13625   ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED = 0,
13626   ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP = 1,
13627   ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND = 2,
13628 };
13629 
13630 class PERFETTO_EXPORT ProcessStatsConfig : public ::protozero::CppMessageObj {
13631  public:
13632   using Quirks = ProcessStatsConfig_Quirks;
13633   static constexpr auto QUIRKS_UNSPECIFIED = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
13634   static constexpr auto DISABLE_INITIAL_DUMP = ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP;
13635   static constexpr auto DISABLE_ON_DEMAND = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
13636   static constexpr auto Quirks_MIN = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
13637   static constexpr auto Quirks_MAX = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
13638   enum FieldNumbers {
13639     kQuirksFieldNumber = 1,
13640     kScanAllProcessesOnStartFieldNumber = 2,
13641     kRecordThreadNamesFieldNumber = 3,
13642     kProcStatsPollMsFieldNumber = 4,
13643     kProcStatsCacheTtlMsFieldNumber = 6,
13644     kRecordThreadTimeInStateFieldNumber = 7,
13645     kThreadTimeInStateCacheSizeFieldNumber = 8,
13646   };
13647 
13648   ProcessStatsConfig();
13649   ~ProcessStatsConfig() override;
13650   ProcessStatsConfig(ProcessStatsConfig&&) noexcept;
13651   ProcessStatsConfig& operator=(ProcessStatsConfig&&);
13652   ProcessStatsConfig(const ProcessStatsConfig&);
13653   ProcessStatsConfig& operator=(const ProcessStatsConfig&);
13654   bool operator==(const ProcessStatsConfig&) const;
operator !=(const ProcessStatsConfig & other) const13655   bool operator!=(const ProcessStatsConfig& other) const { return !(*this == other); }
13656 
13657   bool ParseFromArray(const void*, size_t) override;
13658   std::string SerializeAsString() const override;
13659   std::vector<uint8_t> SerializeAsArray() const override;
13660   void Serialize(::protozero::Message*) const;
13661 
quirks_size() const13662   int quirks_size() const { return static_cast<int>(quirks_.size()); }
quirks() const13663   const std::vector<ProcessStatsConfig_Quirks>& quirks() const { return quirks_; }
mutable_quirks()13664   std::vector<ProcessStatsConfig_Quirks>* mutable_quirks() { return &quirks_; }
clear_quirks()13665   void clear_quirks() { quirks_.clear(); }
add_quirks(ProcessStatsConfig_Quirks value)13666   void add_quirks(ProcessStatsConfig_Quirks value) { quirks_.emplace_back(value); }
add_quirks()13667   ProcessStatsConfig_Quirks* add_quirks() { quirks_.emplace_back(); return &quirks_.back(); }
13668 
has_scan_all_processes_on_start() const13669   bool has_scan_all_processes_on_start() const { return _has_field_[2]; }
scan_all_processes_on_start() const13670   bool scan_all_processes_on_start() const { return scan_all_processes_on_start_; }
set_scan_all_processes_on_start(bool value)13671   void set_scan_all_processes_on_start(bool value) { scan_all_processes_on_start_ = value; _has_field_.set(2); }
13672 
has_record_thread_names() const13673   bool has_record_thread_names() const { return _has_field_[3]; }
record_thread_names() const13674   bool record_thread_names() const { return record_thread_names_; }
set_record_thread_names(bool value)13675   void set_record_thread_names(bool value) { record_thread_names_ = value; _has_field_.set(3); }
13676 
has_proc_stats_poll_ms() const13677   bool has_proc_stats_poll_ms() const { return _has_field_[4]; }
proc_stats_poll_ms() const13678   uint32_t proc_stats_poll_ms() const { return proc_stats_poll_ms_; }
set_proc_stats_poll_ms(uint32_t value)13679   void set_proc_stats_poll_ms(uint32_t value) { proc_stats_poll_ms_ = value; _has_field_.set(4); }
13680 
has_proc_stats_cache_ttl_ms() const13681   bool has_proc_stats_cache_ttl_ms() const { return _has_field_[6]; }
proc_stats_cache_ttl_ms() const13682   uint32_t proc_stats_cache_ttl_ms() const { return proc_stats_cache_ttl_ms_; }
set_proc_stats_cache_ttl_ms(uint32_t value)13683   void set_proc_stats_cache_ttl_ms(uint32_t value) { proc_stats_cache_ttl_ms_ = value; _has_field_.set(6); }
13684 
has_record_thread_time_in_state() const13685   bool has_record_thread_time_in_state() const { return _has_field_[7]; }
record_thread_time_in_state() const13686   bool record_thread_time_in_state() const { return record_thread_time_in_state_; }
set_record_thread_time_in_state(bool value)13687   void set_record_thread_time_in_state(bool value) { record_thread_time_in_state_ = value; _has_field_.set(7); }
13688 
has_thread_time_in_state_cache_size() const13689   bool has_thread_time_in_state_cache_size() const { return _has_field_[8]; }
thread_time_in_state_cache_size() const13690   uint32_t thread_time_in_state_cache_size() const { return thread_time_in_state_cache_size_; }
set_thread_time_in_state_cache_size(uint32_t value)13691   void set_thread_time_in_state_cache_size(uint32_t value) { thread_time_in_state_cache_size_ = value; _has_field_.set(8); }
13692 
13693  private:
13694   std::vector<ProcessStatsConfig_Quirks> quirks_;
13695   bool scan_all_processes_on_start_{};
13696   bool record_thread_names_{};
13697   uint32_t proc_stats_poll_ms_{};
13698   uint32_t proc_stats_cache_ttl_ms_{};
13699   bool record_thread_time_in_state_{};
13700   uint32_t thread_time_in_state_cache_size_{};
13701 
13702   // Allows to preserve unknown protobuf fields for compatibility
13703   // with future versions of .proto files.
13704   std::string unknown_fields_;
13705 
13706   std::bitset<9> _has_field_{};
13707 };
13708 
13709 }  // namespace perfetto
13710 }  // namespace protos
13711 }  // namespace gen
13712 
13713 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
13714 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13715 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13716 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13717 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13718 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13719 #pragma GCC diagnostic push
13720 #pragma GCC diagnostic ignored "-Wfloat-equal"
13721 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
13722 
13723 namespace perfetto {
13724 namespace protos {
13725 namespace gen {
13726 
13727 ProcessStatsConfig::ProcessStatsConfig() = default;
13728 ProcessStatsConfig::~ProcessStatsConfig() = default;
13729 ProcessStatsConfig::ProcessStatsConfig(const ProcessStatsConfig&) = default;
13730 ProcessStatsConfig& ProcessStatsConfig::operator=(const ProcessStatsConfig&) = default;
13731 ProcessStatsConfig::ProcessStatsConfig(ProcessStatsConfig&&) noexcept = default;
13732 ProcessStatsConfig& ProcessStatsConfig::operator=(ProcessStatsConfig&&) = default;
13733 
operator ==(const ProcessStatsConfig & other) const13734 bool ProcessStatsConfig::operator==(const ProcessStatsConfig& other) const {
13735   return unknown_fields_ == other.unknown_fields_
13736    && quirks_ == other.quirks_
13737    && scan_all_processes_on_start_ == other.scan_all_processes_on_start_
13738    && record_thread_names_ == other.record_thread_names_
13739    && proc_stats_poll_ms_ == other.proc_stats_poll_ms_
13740    && proc_stats_cache_ttl_ms_ == other.proc_stats_cache_ttl_ms_
13741    && record_thread_time_in_state_ == other.record_thread_time_in_state_
13742    && thread_time_in_state_cache_size_ == other.thread_time_in_state_cache_size_;
13743 }
13744 
ParseFromArray(const void * raw,size_t size)13745 bool ProcessStatsConfig::ParseFromArray(const void* raw, size_t size) {
13746   quirks_.clear();
13747   unknown_fields_.clear();
13748   bool packed_error = false;
13749 
13750   ::protozero::ProtoDecoder dec(raw, size);
13751   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13752     if (field.id() < _has_field_.size()) {
13753       _has_field_.set(field.id());
13754     }
13755     switch (field.id()) {
13756       case 1 /* quirks */:
13757         quirks_.emplace_back();
13758         field.get(&quirks_.back());
13759         break;
13760       case 2 /* scan_all_processes_on_start */:
13761         field.get(&scan_all_processes_on_start_);
13762         break;
13763       case 3 /* record_thread_names */:
13764         field.get(&record_thread_names_);
13765         break;
13766       case 4 /* proc_stats_poll_ms */:
13767         field.get(&proc_stats_poll_ms_);
13768         break;
13769       case 6 /* proc_stats_cache_ttl_ms */:
13770         field.get(&proc_stats_cache_ttl_ms_);
13771         break;
13772       case 7 /* record_thread_time_in_state */:
13773         field.get(&record_thread_time_in_state_);
13774         break;
13775       case 8 /* thread_time_in_state_cache_size */:
13776         field.get(&thread_time_in_state_cache_size_);
13777         break;
13778       default:
13779         field.SerializeAndAppendTo(&unknown_fields_);
13780         break;
13781     }
13782   }
13783   return !packed_error && !dec.bytes_left();
13784 }
13785 
SerializeAsString() const13786 std::string ProcessStatsConfig::SerializeAsString() const {
13787   ::protozero::HeapBuffered<::protozero::Message> msg;
13788   Serialize(msg.get());
13789   return msg.SerializeAsString();
13790 }
13791 
SerializeAsArray() const13792 std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
13793   ::protozero::HeapBuffered<::protozero::Message> msg;
13794   Serialize(msg.get());
13795   return msg.SerializeAsArray();
13796 }
13797 
Serialize(::protozero::Message * msg) const13798 void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
13799   // Field 1: quirks
13800   for (auto& it : quirks_) {
13801     msg->AppendVarInt(1, it);
13802   }
13803 
13804   // Field 2: scan_all_processes_on_start
13805   if (_has_field_[2]) {
13806     msg->AppendTinyVarInt(2, scan_all_processes_on_start_);
13807   }
13808 
13809   // Field 3: record_thread_names
13810   if (_has_field_[3]) {
13811     msg->AppendTinyVarInt(3, record_thread_names_);
13812   }
13813 
13814   // Field 4: proc_stats_poll_ms
13815   if (_has_field_[4]) {
13816     msg->AppendVarInt(4, proc_stats_poll_ms_);
13817   }
13818 
13819   // Field 6: proc_stats_cache_ttl_ms
13820   if (_has_field_[6]) {
13821     msg->AppendVarInt(6, proc_stats_cache_ttl_ms_);
13822   }
13823 
13824   // Field 7: record_thread_time_in_state
13825   if (_has_field_[7]) {
13826     msg->AppendTinyVarInt(7, record_thread_time_in_state_);
13827   }
13828 
13829   // Field 8: thread_time_in_state_cache_size
13830   if (_has_field_[8]) {
13831     msg->AppendVarInt(8, thread_time_in_state_cache_size_);
13832   }
13833 
13834   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13835 }
13836 
13837 }  // namespace perfetto
13838 }  // namespace protos
13839 }  // namespace gen
13840 #pragma GCC diagnostic pop
13841 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.gen.cc
13842 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.gen.h
13843 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13844 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
13845 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
13846 
13847 #include <stdint.h>
13848 #include <bitset>
13849 #include <vector>
13850 #include <string>
13851 #include <type_traits>
13852 
13853 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13854 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13855 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13856 
13857 namespace perfetto {
13858 namespace protos {
13859 namespace gen {
13860 class HeapprofdConfig;
13861 class HeapprofdConfig_ContinuousDumpConfig;
13862 }  // namespace perfetto
13863 }  // namespace protos
13864 }  // namespace gen
13865 
13866 namespace protozero {
13867 class Message;
13868 }  // namespace protozero
13869 
13870 namespace perfetto {
13871 namespace protos {
13872 namespace gen {
13873 
13874 class PERFETTO_EXPORT HeapprofdConfig : public ::protozero::CppMessageObj {
13875  public:
13876   using ContinuousDumpConfig = HeapprofdConfig_ContinuousDumpConfig;
13877   enum FieldNumbers {
13878     kSamplingIntervalBytesFieldNumber = 1,
13879     kProcessCmdlineFieldNumber = 2,
13880     kPidFieldNumber = 4,
13881     kHeapsFieldNumber = 20,
13882     kAllHeapsFieldNumber = 21,
13883     kAllFieldNumber = 5,
13884     kMinAnonymousMemoryKbFieldNumber = 15,
13885     kMaxHeapprofdMemoryKbFieldNumber = 16,
13886     kMaxHeapprofdCpuSecsFieldNumber = 17,
13887     kSkipSymbolPrefixFieldNumber = 7,
13888     kContinuousDumpConfigFieldNumber = 6,
13889     kShmemSizeBytesFieldNumber = 8,
13890     kBlockClientFieldNumber = 9,
13891     kBlockClientTimeoutUsFieldNumber = 14,
13892     kNoStartupFieldNumber = 10,
13893     kNoRunningFieldNumber = 11,
13894     kIdleAllocationsFieldNumber = 12,
13895     kDumpAtMaxFieldNumber = 13,
13896     kDisableForkTeardownFieldNumber = 18,
13897     kDisableVforkDetectionFieldNumber = 19,
13898   };
13899 
13900   HeapprofdConfig();
13901   ~HeapprofdConfig() override;
13902   HeapprofdConfig(HeapprofdConfig&&) noexcept;
13903   HeapprofdConfig& operator=(HeapprofdConfig&&);
13904   HeapprofdConfig(const HeapprofdConfig&);
13905   HeapprofdConfig& operator=(const HeapprofdConfig&);
13906   bool operator==(const HeapprofdConfig&) const;
operator !=(const HeapprofdConfig & other) const13907   bool operator!=(const HeapprofdConfig& other) const { return !(*this == other); }
13908 
13909   bool ParseFromArray(const void*, size_t) override;
13910   std::string SerializeAsString() const override;
13911   std::vector<uint8_t> SerializeAsArray() const override;
13912   void Serialize(::protozero::Message*) const;
13913 
has_sampling_interval_bytes() const13914   bool has_sampling_interval_bytes() const { return _has_field_[1]; }
sampling_interval_bytes() const13915   uint64_t sampling_interval_bytes() const { return sampling_interval_bytes_; }
set_sampling_interval_bytes(uint64_t value)13916   void set_sampling_interval_bytes(uint64_t value) { sampling_interval_bytes_ = value; _has_field_.set(1); }
13917 
process_cmdline_size() const13918   int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
process_cmdline() const13919   const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
mutable_process_cmdline()13920   std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
clear_process_cmdline()13921   void clear_process_cmdline() { process_cmdline_.clear(); }
add_process_cmdline(std::string value)13922   void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
add_process_cmdline()13923   std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
13924 
pid_size() const13925   int pid_size() const { return static_cast<int>(pid_.size()); }
pid() const13926   const std::vector<uint64_t>& pid() const { return pid_; }
mutable_pid()13927   std::vector<uint64_t>* mutable_pid() { return &pid_; }
clear_pid()13928   void clear_pid() { pid_.clear(); }
add_pid(uint64_t value)13929   void add_pid(uint64_t value) { pid_.emplace_back(value); }
add_pid()13930   uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
13931 
heaps_size() const13932   int heaps_size() const { return static_cast<int>(heaps_.size()); }
heaps() const13933   const std::vector<std::string>& heaps() const { return heaps_; }
mutable_heaps()13934   std::vector<std::string>* mutable_heaps() { return &heaps_; }
clear_heaps()13935   void clear_heaps() { heaps_.clear(); }
add_heaps(std::string value)13936   void add_heaps(std::string value) { heaps_.emplace_back(value); }
add_heaps()13937   std::string* add_heaps() { heaps_.emplace_back(); return &heaps_.back(); }
13938 
has_all_heaps() const13939   bool has_all_heaps() const { return _has_field_[21]; }
all_heaps() const13940   bool all_heaps() const { return all_heaps_; }
set_all_heaps(bool value)13941   void set_all_heaps(bool value) { all_heaps_ = value; _has_field_.set(21); }
13942 
has_all() const13943   bool has_all() const { return _has_field_[5]; }
all() const13944   bool all() const { return all_; }
set_all(bool value)13945   void set_all(bool value) { all_ = value; _has_field_.set(5); }
13946 
has_min_anonymous_memory_kb() const13947   bool has_min_anonymous_memory_kb() const { return _has_field_[15]; }
min_anonymous_memory_kb() const13948   uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
set_min_anonymous_memory_kb(uint32_t value)13949   void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(15); }
13950 
has_max_heapprofd_memory_kb() const13951   bool has_max_heapprofd_memory_kb() const { return _has_field_[16]; }
max_heapprofd_memory_kb() const13952   uint32_t max_heapprofd_memory_kb() const { return max_heapprofd_memory_kb_; }
set_max_heapprofd_memory_kb(uint32_t value)13953   void set_max_heapprofd_memory_kb(uint32_t value) { max_heapprofd_memory_kb_ = value; _has_field_.set(16); }
13954 
has_max_heapprofd_cpu_secs() const13955   bool has_max_heapprofd_cpu_secs() const { return _has_field_[17]; }
max_heapprofd_cpu_secs() const13956   uint64_t max_heapprofd_cpu_secs() const { return max_heapprofd_cpu_secs_; }
set_max_heapprofd_cpu_secs(uint64_t value)13957   void set_max_heapprofd_cpu_secs(uint64_t value) { max_heapprofd_cpu_secs_ = value; _has_field_.set(17); }
13958 
skip_symbol_prefix_size() const13959   int skip_symbol_prefix_size() const { return static_cast<int>(skip_symbol_prefix_.size()); }
skip_symbol_prefix() const13960   const std::vector<std::string>& skip_symbol_prefix() const { return skip_symbol_prefix_; }
mutable_skip_symbol_prefix()13961   std::vector<std::string>* mutable_skip_symbol_prefix() { return &skip_symbol_prefix_; }
clear_skip_symbol_prefix()13962   void clear_skip_symbol_prefix() { skip_symbol_prefix_.clear(); }
add_skip_symbol_prefix(std::string value)13963   void add_skip_symbol_prefix(std::string value) { skip_symbol_prefix_.emplace_back(value); }
add_skip_symbol_prefix()13964   std::string* add_skip_symbol_prefix() { skip_symbol_prefix_.emplace_back(); return &skip_symbol_prefix_.back(); }
13965 
has_continuous_dump_config() const13966   bool has_continuous_dump_config() const { return _has_field_[6]; }
continuous_dump_config() const13967   const HeapprofdConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
mutable_continuous_dump_config()13968   HeapprofdConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(6); return continuous_dump_config_.get(); }
13969 
has_shmem_size_bytes() const13970   bool has_shmem_size_bytes() const { return _has_field_[8]; }
shmem_size_bytes() const13971   uint64_t shmem_size_bytes() const { return shmem_size_bytes_; }
set_shmem_size_bytes(uint64_t value)13972   void set_shmem_size_bytes(uint64_t value) { shmem_size_bytes_ = value; _has_field_.set(8); }
13973 
has_block_client() const13974   bool has_block_client() const { return _has_field_[9]; }
block_client() const13975   bool block_client() const { return block_client_; }
set_block_client(bool value)13976   void set_block_client(bool value) { block_client_ = value; _has_field_.set(9); }
13977 
has_block_client_timeout_us() const13978   bool has_block_client_timeout_us() const { return _has_field_[14]; }
block_client_timeout_us() const13979   uint32_t block_client_timeout_us() const { return block_client_timeout_us_; }
set_block_client_timeout_us(uint32_t value)13980   void set_block_client_timeout_us(uint32_t value) { block_client_timeout_us_ = value; _has_field_.set(14); }
13981 
has_no_startup() const13982   bool has_no_startup() const { return _has_field_[10]; }
no_startup() const13983   bool no_startup() const { return no_startup_; }
set_no_startup(bool value)13984   void set_no_startup(bool value) { no_startup_ = value; _has_field_.set(10); }
13985 
has_no_running() const13986   bool has_no_running() const { return _has_field_[11]; }
no_running() const13987   bool no_running() const { return no_running_; }
set_no_running(bool value)13988   void set_no_running(bool value) { no_running_ = value; _has_field_.set(11); }
13989 
has_idle_allocations() const13990   bool has_idle_allocations() const { return _has_field_[12]; }
idle_allocations() const13991   bool idle_allocations() const { return idle_allocations_; }
set_idle_allocations(bool value)13992   void set_idle_allocations(bool value) { idle_allocations_ = value; _has_field_.set(12); }
13993 
has_dump_at_max() const13994   bool has_dump_at_max() const { return _has_field_[13]; }
dump_at_max() const13995   bool dump_at_max() const { return dump_at_max_; }
set_dump_at_max(bool value)13996   void set_dump_at_max(bool value) { dump_at_max_ = value; _has_field_.set(13); }
13997 
has_disable_fork_teardown() const13998   bool has_disable_fork_teardown() const { return _has_field_[18]; }
disable_fork_teardown() const13999   bool disable_fork_teardown() const { return disable_fork_teardown_; }
set_disable_fork_teardown(bool value)14000   void set_disable_fork_teardown(bool value) { disable_fork_teardown_ = value; _has_field_.set(18); }
14001 
has_disable_vfork_detection() const14002   bool has_disable_vfork_detection() const { return _has_field_[19]; }
disable_vfork_detection() const14003   bool disable_vfork_detection() const { return disable_vfork_detection_; }
set_disable_vfork_detection(bool value)14004   void set_disable_vfork_detection(bool value) { disable_vfork_detection_ = value; _has_field_.set(19); }
14005 
14006  private:
14007   uint64_t sampling_interval_bytes_{};
14008   std::vector<std::string> process_cmdline_;
14009   std::vector<uint64_t> pid_;
14010   std::vector<std::string> heaps_;
14011   bool all_heaps_{};
14012   bool all_{};
14013   uint32_t min_anonymous_memory_kb_{};
14014   uint32_t max_heapprofd_memory_kb_{};
14015   uint64_t max_heapprofd_cpu_secs_{};
14016   std::vector<std::string> skip_symbol_prefix_;
14017   ::protozero::CopyablePtr<HeapprofdConfig_ContinuousDumpConfig> continuous_dump_config_;
14018   uint64_t shmem_size_bytes_{};
14019   bool block_client_{};
14020   uint32_t block_client_timeout_us_{};
14021   bool no_startup_{};
14022   bool no_running_{};
14023   bool idle_allocations_{};
14024   bool dump_at_max_{};
14025   bool disable_fork_teardown_{};
14026   bool disable_vfork_detection_{};
14027 
14028   // Allows to preserve unknown protobuf fields for compatibility
14029   // with future versions of .proto files.
14030   std::string unknown_fields_;
14031 
14032   std::bitset<22> _has_field_{};
14033 };
14034 
14035 
14036 class PERFETTO_EXPORT HeapprofdConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
14037  public:
14038   enum FieldNumbers {
14039     kDumpPhaseMsFieldNumber = 5,
14040     kDumpIntervalMsFieldNumber = 6,
14041   };
14042 
14043   HeapprofdConfig_ContinuousDumpConfig();
14044   ~HeapprofdConfig_ContinuousDumpConfig() override;
14045   HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept;
14046   HeapprofdConfig_ContinuousDumpConfig& operator=(HeapprofdConfig_ContinuousDumpConfig&&);
14047   HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&);
14048   HeapprofdConfig_ContinuousDumpConfig& operator=(const HeapprofdConfig_ContinuousDumpConfig&);
14049   bool operator==(const HeapprofdConfig_ContinuousDumpConfig&) const;
operator !=(const HeapprofdConfig_ContinuousDumpConfig & other) const14050   bool operator!=(const HeapprofdConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
14051 
14052   bool ParseFromArray(const void*, size_t) override;
14053   std::string SerializeAsString() const override;
14054   std::vector<uint8_t> SerializeAsArray() const override;
14055   void Serialize(::protozero::Message*) const;
14056 
has_dump_phase_ms() const14057   bool has_dump_phase_ms() const { return _has_field_[5]; }
dump_phase_ms() const14058   uint32_t dump_phase_ms() const { return dump_phase_ms_; }
set_dump_phase_ms(uint32_t value)14059   void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(5); }
14060 
has_dump_interval_ms() const14061   bool has_dump_interval_ms() const { return _has_field_[6]; }
dump_interval_ms() const14062   uint32_t dump_interval_ms() const { return dump_interval_ms_; }
set_dump_interval_ms(uint32_t value)14063   void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(6); }
14064 
14065  private:
14066   uint32_t dump_phase_ms_{};
14067   uint32_t dump_interval_ms_{};
14068 
14069   // Allows to preserve unknown protobuf fields for compatibility
14070   // with future versions of .proto files.
14071   std::string unknown_fields_;
14072 
14073   std::bitset<7> _has_field_{};
14074 };
14075 
14076 }  // namespace perfetto
14077 }  // namespace protos
14078 }  // namespace gen
14079 
14080 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
14081 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14082 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14083 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14084 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14085 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14086 #pragma GCC diagnostic push
14087 #pragma GCC diagnostic ignored "-Wfloat-equal"
14088 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
14089 
14090 namespace perfetto {
14091 namespace protos {
14092 namespace gen {
14093 
14094 HeapprofdConfig::HeapprofdConfig() = default;
14095 HeapprofdConfig::~HeapprofdConfig() = default;
14096 HeapprofdConfig::HeapprofdConfig(const HeapprofdConfig&) = default;
14097 HeapprofdConfig& HeapprofdConfig::operator=(const HeapprofdConfig&) = default;
14098 HeapprofdConfig::HeapprofdConfig(HeapprofdConfig&&) noexcept = default;
14099 HeapprofdConfig& HeapprofdConfig::operator=(HeapprofdConfig&&) = default;
14100 
operator ==(const HeapprofdConfig & other) const14101 bool HeapprofdConfig::operator==(const HeapprofdConfig& other) const {
14102   return unknown_fields_ == other.unknown_fields_
14103    && sampling_interval_bytes_ == other.sampling_interval_bytes_
14104    && process_cmdline_ == other.process_cmdline_
14105    && pid_ == other.pid_
14106    && heaps_ == other.heaps_
14107    && all_heaps_ == other.all_heaps_
14108    && all_ == other.all_
14109    && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
14110    && max_heapprofd_memory_kb_ == other.max_heapprofd_memory_kb_
14111    && max_heapprofd_cpu_secs_ == other.max_heapprofd_cpu_secs_
14112    && skip_symbol_prefix_ == other.skip_symbol_prefix_
14113    && continuous_dump_config_ == other.continuous_dump_config_
14114    && shmem_size_bytes_ == other.shmem_size_bytes_
14115    && block_client_ == other.block_client_
14116    && block_client_timeout_us_ == other.block_client_timeout_us_
14117    && no_startup_ == other.no_startup_
14118    && no_running_ == other.no_running_
14119    && idle_allocations_ == other.idle_allocations_
14120    && dump_at_max_ == other.dump_at_max_
14121    && disable_fork_teardown_ == other.disable_fork_teardown_
14122    && disable_vfork_detection_ == other.disable_vfork_detection_;
14123 }
14124 
ParseFromArray(const void * raw,size_t size)14125 bool HeapprofdConfig::ParseFromArray(const void* raw, size_t size) {
14126   process_cmdline_.clear();
14127   pid_.clear();
14128   heaps_.clear();
14129   skip_symbol_prefix_.clear();
14130   unknown_fields_.clear();
14131   bool packed_error = false;
14132 
14133   ::protozero::ProtoDecoder dec(raw, size);
14134   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14135     if (field.id() < _has_field_.size()) {
14136       _has_field_.set(field.id());
14137     }
14138     switch (field.id()) {
14139       case 1 /* sampling_interval_bytes */:
14140         field.get(&sampling_interval_bytes_);
14141         break;
14142       case 2 /* process_cmdline */:
14143         process_cmdline_.emplace_back();
14144         field.get(&process_cmdline_.back());
14145         break;
14146       case 4 /* pid */:
14147         pid_.emplace_back();
14148         field.get(&pid_.back());
14149         break;
14150       case 20 /* heaps */:
14151         heaps_.emplace_back();
14152         field.get(&heaps_.back());
14153         break;
14154       case 21 /* all_heaps */:
14155         field.get(&all_heaps_);
14156         break;
14157       case 5 /* all */:
14158         field.get(&all_);
14159         break;
14160       case 15 /* min_anonymous_memory_kb */:
14161         field.get(&min_anonymous_memory_kb_);
14162         break;
14163       case 16 /* max_heapprofd_memory_kb */:
14164         field.get(&max_heapprofd_memory_kb_);
14165         break;
14166       case 17 /* max_heapprofd_cpu_secs */:
14167         field.get(&max_heapprofd_cpu_secs_);
14168         break;
14169       case 7 /* skip_symbol_prefix */:
14170         skip_symbol_prefix_.emplace_back();
14171         field.get(&skip_symbol_prefix_.back());
14172         break;
14173       case 6 /* continuous_dump_config */:
14174         (*continuous_dump_config_).ParseFromString(field.as_std_string());
14175         break;
14176       case 8 /* shmem_size_bytes */:
14177         field.get(&shmem_size_bytes_);
14178         break;
14179       case 9 /* block_client */:
14180         field.get(&block_client_);
14181         break;
14182       case 14 /* block_client_timeout_us */:
14183         field.get(&block_client_timeout_us_);
14184         break;
14185       case 10 /* no_startup */:
14186         field.get(&no_startup_);
14187         break;
14188       case 11 /* no_running */:
14189         field.get(&no_running_);
14190         break;
14191       case 12 /* idle_allocations */:
14192         field.get(&idle_allocations_);
14193         break;
14194       case 13 /* dump_at_max */:
14195         field.get(&dump_at_max_);
14196         break;
14197       case 18 /* disable_fork_teardown */:
14198         field.get(&disable_fork_teardown_);
14199         break;
14200       case 19 /* disable_vfork_detection */:
14201         field.get(&disable_vfork_detection_);
14202         break;
14203       default:
14204         field.SerializeAndAppendTo(&unknown_fields_);
14205         break;
14206     }
14207   }
14208   return !packed_error && !dec.bytes_left();
14209 }
14210 
SerializeAsString() const14211 std::string HeapprofdConfig::SerializeAsString() const {
14212   ::protozero::HeapBuffered<::protozero::Message> msg;
14213   Serialize(msg.get());
14214   return msg.SerializeAsString();
14215 }
14216 
SerializeAsArray() const14217 std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
14218   ::protozero::HeapBuffered<::protozero::Message> msg;
14219   Serialize(msg.get());
14220   return msg.SerializeAsArray();
14221 }
14222 
Serialize(::protozero::Message * msg) const14223 void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
14224   // Field 1: sampling_interval_bytes
14225   if (_has_field_[1]) {
14226     msg->AppendVarInt(1, sampling_interval_bytes_);
14227   }
14228 
14229   // Field 2: process_cmdline
14230   for (auto& it : process_cmdline_) {
14231     msg->AppendString(2, it);
14232   }
14233 
14234   // Field 4: pid
14235   for (auto& it : pid_) {
14236     msg->AppendVarInt(4, it);
14237   }
14238 
14239   // Field 20: heaps
14240   for (auto& it : heaps_) {
14241     msg->AppendString(20, it);
14242   }
14243 
14244   // Field 21: all_heaps
14245   if (_has_field_[21]) {
14246     msg->AppendTinyVarInt(21, all_heaps_);
14247   }
14248 
14249   // Field 5: all
14250   if (_has_field_[5]) {
14251     msg->AppendTinyVarInt(5, all_);
14252   }
14253 
14254   // Field 15: min_anonymous_memory_kb
14255   if (_has_field_[15]) {
14256     msg->AppendVarInt(15, min_anonymous_memory_kb_);
14257   }
14258 
14259   // Field 16: max_heapprofd_memory_kb
14260   if (_has_field_[16]) {
14261     msg->AppendVarInt(16, max_heapprofd_memory_kb_);
14262   }
14263 
14264   // Field 17: max_heapprofd_cpu_secs
14265   if (_has_field_[17]) {
14266     msg->AppendVarInt(17, max_heapprofd_cpu_secs_);
14267   }
14268 
14269   // Field 7: skip_symbol_prefix
14270   for (auto& it : skip_symbol_prefix_) {
14271     msg->AppendString(7, it);
14272   }
14273 
14274   // Field 6: continuous_dump_config
14275   if (_has_field_[6]) {
14276     (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
14277   }
14278 
14279   // Field 8: shmem_size_bytes
14280   if (_has_field_[8]) {
14281     msg->AppendVarInt(8, shmem_size_bytes_);
14282   }
14283 
14284   // Field 9: block_client
14285   if (_has_field_[9]) {
14286     msg->AppendTinyVarInt(9, block_client_);
14287   }
14288 
14289   // Field 14: block_client_timeout_us
14290   if (_has_field_[14]) {
14291     msg->AppendVarInt(14, block_client_timeout_us_);
14292   }
14293 
14294   // Field 10: no_startup
14295   if (_has_field_[10]) {
14296     msg->AppendTinyVarInt(10, no_startup_);
14297   }
14298 
14299   // Field 11: no_running
14300   if (_has_field_[11]) {
14301     msg->AppendTinyVarInt(11, no_running_);
14302   }
14303 
14304   // Field 12: idle_allocations
14305   if (_has_field_[12]) {
14306     msg->AppendTinyVarInt(12, idle_allocations_);
14307   }
14308 
14309   // Field 13: dump_at_max
14310   if (_has_field_[13]) {
14311     msg->AppendTinyVarInt(13, dump_at_max_);
14312   }
14313 
14314   // Field 18: disable_fork_teardown
14315   if (_has_field_[18]) {
14316     msg->AppendTinyVarInt(18, disable_fork_teardown_);
14317   }
14318 
14319   // Field 19: disable_vfork_detection
14320   if (_has_field_[19]) {
14321     msg->AppendTinyVarInt(19, disable_vfork_detection_);
14322   }
14323 
14324   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14325 }
14326 
14327 
14328 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig() = default;
14329 HeapprofdConfig_ContinuousDumpConfig::~HeapprofdConfig_ContinuousDumpConfig() = default;
14330 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&) = default;
14331 HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(const HeapprofdConfig_ContinuousDumpConfig&) = default;
14332 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept = default;
14333 HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(HeapprofdConfig_ContinuousDumpConfig&&) = default;
14334 
operator ==(const HeapprofdConfig_ContinuousDumpConfig & other) const14335 bool HeapprofdConfig_ContinuousDumpConfig::operator==(const HeapprofdConfig_ContinuousDumpConfig& other) const {
14336   return unknown_fields_ == other.unknown_fields_
14337    && dump_phase_ms_ == other.dump_phase_ms_
14338    && dump_interval_ms_ == other.dump_interval_ms_;
14339 }
14340 
ParseFromArray(const void * raw,size_t size)14341 bool HeapprofdConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
14342   unknown_fields_.clear();
14343   bool packed_error = false;
14344 
14345   ::protozero::ProtoDecoder dec(raw, size);
14346   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14347     if (field.id() < _has_field_.size()) {
14348       _has_field_.set(field.id());
14349     }
14350     switch (field.id()) {
14351       case 5 /* dump_phase_ms */:
14352         field.get(&dump_phase_ms_);
14353         break;
14354       case 6 /* dump_interval_ms */:
14355         field.get(&dump_interval_ms_);
14356         break;
14357       default:
14358         field.SerializeAndAppendTo(&unknown_fields_);
14359         break;
14360     }
14361   }
14362   return !packed_error && !dec.bytes_left();
14363 }
14364 
SerializeAsString() const14365 std::string HeapprofdConfig_ContinuousDumpConfig::SerializeAsString() const {
14366   ::protozero::HeapBuffered<::protozero::Message> msg;
14367   Serialize(msg.get());
14368   return msg.SerializeAsString();
14369 }
14370 
SerializeAsArray() const14371 std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
14372   ::protozero::HeapBuffered<::protozero::Message> msg;
14373   Serialize(msg.get());
14374   return msg.SerializeAsArray();
14375 }
14376 
Serialize(::protozero::Message * msg) const14377 void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
14378   // Field 5: dump_phase_ms
14379   if (_has_field_[5]) {
14380     msg->AppendVarInt(5, dump_phase_ms_);
14381   }
14382 
14383   // Field 6: dump_interval_ms
14384   if (_has_field_[6]) {
14385     msg->AppendVarInt(6, dump_interval_ms_);
14386   }
14387 
14388   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14389 }
14390 
14391 }  // namespace perfetto
14392 }  // namespace protos
14393 }  // namespace gen
14394 #pragma GCC diagnostic pop
14395 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.gen.cc
14396 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.gen.h
14397 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14398 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
14399 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
14400 
14401 #include <stdint.h>
14402 #include <bitset>
14403 #include <vector>
14404 #include <string>
14405 #include <type_traits>
14406 
14407 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14408 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14409 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14410 
14411 namespace perfetto {
14412 namespace protos {
14413 namespace gen {
14414 class JavaHprofConfig;
14415 class JavaHprofConfig_ContinuousDumpConfig;
14416 }  // namespace perfetto
14417 }  // namespace protos
14418 }  // namespace gen
14419 
14420 namespace protozero {
14421 class Message;
14422 }  // namespace protozero
14423 
14424 namespace perfetto {
14425 namespace protos {
14426 namespace gen {
14427 
14428 class PERFETTO_EXPORT JavaHprofConfig : public ::protozero::CppMessageObj {
14429  public:
14430   using ContinuousDumpConfig = JavaHprofConfig_ContinuousDumpConfig;
14431   enum FieldNumbers {
14432     kProcessCmdlineFieldNumber = 1,
14433     kPidFieldNumber = 2,
14434     kContinuousDumpConfigFieldNumber = 3,
14435     kMinAnonymousMemoryKbFieldNumber = 4,
14436     kDumpSmapsFieldNumber = 5,
14437   };
14438 
14439   JavaHprofConfig();
14440   ~JavaHprofConfig() override;
14441   JavaHprofConfig(JavaHprofConfig&&) noexcept;
14442   JavaHprofConfig& operator=(JavaHprofConfig&&);
14443   JavaHprofConfig(const JavaHprofConfig&);
14444   JavaHprofConfig& operator=(const JavaHprofConfig&);
14445   bool operator==(const JavaHprofConfig&) const;
operator !=(const JavaHprofConfig & other) const14446   bool operator!=(const JavaHprofConfig& other) const { return !(*this == other); }
14447 
14448   bool ParseFromArray(const void*, size_t) override;
14449   std::string SerializeAsString() const override;
14450   std::vector<uint8_t> SerializeAsArray() const override;
14451   void Serialize(::protozero::Message*) const;
14452 
process_cmdline_size() const14453   int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
process_cmdline() const14454   const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
mutable_process_cmdline()14455   std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
clear_process_cmdline()14456   void clear_process_cmdline() { process_cmdline_.clear(); }
add_process_cmdline(std::string value)14457   void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
add_process_cmdline()14458   std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
14459 
pid_size() const14460   int pid_size() const { return static_cast<int>(pid_.size()); }
pid() const14461   const std::vector<uint64_t>& pid() const { return pid_; }
mutable_pid()14462   std::vector<uint64_t>* mutable_pid() { return &pid_; }
clear_pid()14463   void clear_pid() { pid_.clear(); }
add_pid(uint64_t value)14464   void add_pid(uint64_t value) { pid_.emplace_back(value); }
add_pid()14465   uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
14466 
has_continuous_dump_config() const14467   bool has_continuous_dump_config() const { return _has_field_[3]; }
continuous_dump_config() const14468   const JavaHprofConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
mutable_continuous_dump_config()14469   JavaHprofConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(3); return continuous_dump_config_.get(); }
14470 
has_min_anonymous_memory_kb() const14471   bool has_min_anonymous_memory_kb() const { return _has_field_[4]; }
min_anonymous_memory_kb() const14472   uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
set_min_anonymous_memory_kb(uint32_t value)14473   void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(4); }
14474 
has_dump_smaps() const14475   bool has_dump_smaps() const { return _has_field_[5]; }
dump_smaps() const14476   bool dump_smaps() const { return dump_smaps_; }
set_dump_smaps(bool value)14477   void set_dump_smaps(bool value) { dump_smaps_ = value; _has_field_.set(5); }
14478 
14479  private:
14480   std::vector<std::string> process_cmdline_;
14481   std::vector<uint64_t> pid_;
14482   ::protozero::CopyablePtr<JavaHprofConfig_ContinuousDumpConfig> continuous_dump_config_;
14483   uint32_t min_anonymous_memory_kb_{};
14484   bool dump_smaps_{};
14485 
14486   // Allows to preserve unknown protobuf fields for compatibility
14487   // with future versions of .proto files.
14488   std::string unknown_fields_;
14489 
14490   std::bitset<6> _has_field_{};
14491 };
14492 
14493 
14494 class PERFETTO_EXPORT JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
14495  public:
14496   enum FieldNumbers {
14497     kDumpPhaseMsFieldNumber = 1,
14498     kDumpIntervalMsFieldNumber = 2,
14499   };
14500 
14501   JavaHprofConfig_ContinuousDumpConfig();
14502   ~JavaHprofConfig_ContinuousDumpConfig() override;
14503   JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept;
14504   JavaHprofConfig_ContinuousDumpConfig& operator=(JavaHprofConfig_ContinuousDumpConfig&&);
14505   JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&);
14506   JavaHprofConfig_ContinuousDumpConfig& operator=(const JavaHprofConfig_ContinuousDumpConfig&);
14507   bool operator==(const JavaHprofConfig_ContinuousDumpConfig&) const;
operator !=(const JavaHprofConfig_ContinuousDumpConfig & other) const14508   bool operator!=(const JavaHprofConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
14509 
14510   bool ParseFromArray(const void*, size_t) override;
14511   std::string SerializeAsString() const override;
14512   std::vector<uint8_t> SerializeAsArray() const override;
14513   void Serialize(::protozero::Message*) const;
14514 
has_dump_phase_ms() const14515   bool has_dump_phase_ms() const { return _has_field_[1]; }
dump_phase_ms() const14516   uint32_t dump_phase_ms() const { return dump_phase_ms_; }
set_dump_phase_ms(uint32_t value)14517   void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(1); }
14518 
has_dump_interval_ms() const14519   bool has_dump_interval_ms() const { return _has_field_[2]; }
dump_interval_ms() const14520   uint32_t dump_interval_ms() const { return dump_interval_ms_; }
set_dump_interval_ms(uint32_t value)14521   void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(2); }
14522 
14523  private:
14524   uint32_t dump_phase_ms_{};
14525   uint32_t dump_interval_ms_{};
14526 
14527   // Allows to preserve unknown protobuf fields for compatibility
14528   // with future versions of .proto files.
14529   std::string unknown_fields_;
14530 
14531   std::bitset<3> _has_field_{};
14532 };
14533 
14534 }  // namespace perfetto
14535 }  // namespace protos
14536 }  // namespace gen
14537 
14538 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
14539 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14540 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14541 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14542 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14543 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14544 #pragma GCC diagnostic push
14545 #pragma GCC diagnostic ignored "-Wfloat-equal"
14546 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
14547 
14548 namespace perfetto {
14549 namespace protos {
14550 namespace gen {
14551 
14552 JavaHprofConfig::JavaHprofConfig() = default;
14553 JavaHprofConfig::~JavaHprofConfig() = default;
14554 JavaHprofConfig::JavaHprofConfig(const JavaHprofConfig&) = default;
14555 JavaHprofConfig& JavaHprofConfig::operator=(const JavaHprofConfig&) = default;
14556 JavaHprofConfig::JavaHprofConfig(JavaHprofConfig&&) noexcept = default;
14557 JavaHprofConfig& JavaHprofConfig::operator=(JavaHprofConfig&&) = default;
14558 
operator ==(const JavaHprofConfig & other) const14559 bool JavaHprofConfig::operator==(const JavaHprofConfig& other) const {
14560   return unknown_fields_ == other.unknown_fields_
14561    && process_cmdline_ == other.process_cmdline_
14562    && pid_ == other.pid_
14563    && continuous_dump_config_ == other.continuous_dump_config_
14564    && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
14565    && dump_smaps_ == other.dump_smaps_;
14566 }
14567 
ParseFromArray(const void * raw,size_t size)14568 bool JavaHprofConfig::ParseFromArray(const void* raw, size_t size) {
14569   process_cmdline_.clear();
14570   pid_.clear();
14571   unknown_fields_.clear();
14572   bool packed_error = false;
14573 
14574   ::protozero::ProtoDecoder dec(raw, size);
14575   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14576     if (field.id() < _has_field_.size()) {
14577       _has_field_.set(field.id());
14578     }
14579     switch (field.id()) {
14580       case 1 /* process_cmdline */:
14581         process_cmdline_.emplace_back();
14582         field.get(&process_cmdline_.back());
14583         break;
14584       case 2 /* pid */:
14585         pid_.emplace_back();
14586         field.get(&pid_.back());
14587         break;
14588       case 3 /* continuous_dump_config */:
14589         (*continuous_dump_config_).ParseFromString(field.as_std_string());
14590         break;
14591       case 4 /* min_anonymous_memory_kb */:
14592         field.get(&min_anonymous_memory_kb_);
14593         break;
14594       case 5 /* dump_smaps */:
14595         field.get(&dump_smaps_);
14596         break;
14597       default:
14598         field.SerializeAndAppendTo(&unknown_fields_);
14599         break;
14600     }
14601   }
14602   return !packed_error && !dec.bytes_left();
14603 }
14604 
SerializeAsString() const14605 std::string JavaHprofConfig::SerializeAsString() const {
14606   ::protozero::HeapBuffered<::protozero::Message> msg;
14607   Serialize(msg.get());
14608   return msg.SerializeAsString();
14609 }
14610 
SerializeAsArray() const14611 std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
14612   ::protozero::HeapBuffered<::protozero::Message> msg;
14613   Serialize(msg.get());
14614   return msg.SerializeAsArray();
14615 }
14616 
Serialize(::protozero::Message * msg) const14617 void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
14618   // Field 1: process_cmdline
14619   for (auto& it : process_cmdline_) {
14620     msg->AppendString(1, it);
14621   }
14622 
14623   // Field 2: pid
14624   for (auto& it : pid_) {
14625     msg->AppendVarInt(2, it);
14626   }
14627 
14628   // Field 3: continuous_dump_config
14629   if (_has_field_[3]) {
14630     (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
14631   }
14632 
14633   // Field 4: min_anonymous_memory_kb
14634   if (_has_field_[4]) {
14635     msg->AppendVarInt(4, min_anonymous_memory_kb_);
14636   }
14637 
14638   // Field 5: dump_smaps
14639   if (_has_field_[5]) {
14640     msg->AppendTinyVarInt(5, dump_smaps_);
14641   }
14642 
14643   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14644 }
14645 
14646 
14647 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig() = default;
14648 JavaHprofConfig_ContinuousDumpConfig::~JavaHprofConfig_ContinuousDumpConfig() = default;
14649 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&) = default;
14650 JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(const JavaHprofConfig_ContinuousDumpConfig&) = default;
14651 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept = default;
14652 JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(JavaHprofConfig_ContinuousDumpConfig&&) = default;
14653 
operator ==(const JavaHprofConfig_ContinuousDumpConfig & other) const14654 bool JavaHprofConfig_ContinuousDumpConfig::operator==(const JavaHprofConfig_ContinuousDumpConfig& other) const {
14655   return unknown_fields_ == other.unknown_fields_
14656    && dump_phase_ms_ == other.dump_phase_ms_
14657    && dump_interval_ms_ == other.dump_interval_ms_;
14658 }
14659 
ParseFromArray(const void * raw,size_t size)14660 bool JavaHprofConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
14661   unknown_fields_.clear();
14662   bool packed_error = false;
14663 
14664   ::protozero::ProtoDecoder dec(raw, size);
14665   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14666     if (field.id() < _has_field_.size()) {
14667       _has_field_.set(field.id());
14668     }
14669     switch (field.id()) {
14670       case 1 /* dump_phase_ms */:
14671         field.get(&dump_phase_ms_);
14672         break;
14673       case 2 /* dump_interval_ms */:
14674         field.get(&dump_interval_ms_);
14675         break;
14676       default:
14677         field.SerializeAndAppendTo(&unknown_fields_);
14678         break;
14679     }
14680   }
14681   return !packed_error && !dec.bytes_left();
14682 }
14683 
SerializeAsString() const14684 std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
14685   ::protozero::HeapBuffered<::protozero::Message> msg;
14686   Serialize(msg.get());
14687   return msg.SerializeAsString();
14688 }
14689 
SerializeAsArray() const14690 std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
14691   ::protozero::HeapBuffered<::protozero::Message> msg;
14692   Serialize(msg.get());
14693   return msg.SerializeAsArray();
14694 }
14695 
Serialize(::protozero::Message * msg) const14696 void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
14697   // Field 1: dump_phase_ms
14698   if (_has_field_[1]) {
14699     msg->AppendVarInt(1, dump_phase_ms_);
14700   }
14701 
14702   // Field 2: dump_interval_ms
14703   if (_has_field_[2]) {
14704     msg->AppendVarInt(2, dump_interval_ms_);
14705   }
14706 
14707   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14708 }
14709 
14710 }  // namespace perfetto
14711 }  // namespace protos
14712 }  // namespace gen
14713 #pragma GCC diagnostic pop
14714 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.gen.cc
14715 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.gen.h
14716 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14717 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
14718 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
14719 
14720 #include <stdint.h>
14721 #include <bitset>
14722 #include <vector>
14723 #include <string>
14724 #include <type_traits>
14725 
14726 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14727 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14728 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14729 
14730 namespace perfetto {
14731 namespace protos {
14732 namespace gen {
14733 class PerfEventConfig;
14734 }  // namespace perfetto
14735 }  // namespace protos
14736 }  // namespace gen
14737 
14738 namespace protozero {
14739 class Message;
14740 }  // namespace protozero
14741 
14742 namespace perfetto {
14743 namespace protos {
14744 namespace gen {
14745 
14746 class PERFETTO_EXPORT PerfEventConfig : public ::protozero::CppMessageObj {
14747  public:
14748   enum FieldNumbers {
14749     kAllCpusFieldNumber = 1,
14750     kSamplingFrequencyFieldNumber = 2,
14751     kRingBufferReadPeriodMsFieldNumber = 8,
14752     kRingBufferPagesFieldNumber = 3,
14753     kTargetPidFieldNumber = 4,
14754     kTargetCmdlineFieldNumber = 5,
14755     kExcludePidFieldNumber = 6,
14756     kExcludeCmdlineFieldNumber = 7,
14757     kRemoteDescriptorTimeoutMsFieldNumber = 9,
14758     kUnwindStateClearPeriodMsFieldNumber = 10,
14759   };
14760 
14761   PerfEventConfig();
14762   ~PerfEventConfig() override;
14763   PerfEventConfig(PerfEventConfig&&) noexcept;
14764   PerfEventConfig& operator=(PerfEventConfig&&);
14765   PerfEventConfig(const PerfEventConfig&);
14766   PerfEventConfig& operator=(const PerfEventConfig&);
14767   bool operator==(const PerfEventConfig&) const;
operator !=(const PerfEventConfig & other) const14768   bool operator!=(const PerfEventConfig& other) const { return !(*this == other); }
14769 
14770   bool ParseFromArray(const void*, size_t) override;
14771   std::string SerializeAsString() const override;
14772   std::vector<uint8_t> SerializeAsArray() const override;
14773   void Serialize(::protozero::Message*) const;
14774 
has_all_cpus() const14775   bool has_all_cpus() const { return _has_field_[1]; }
all_cpus() const14776   bool all_cpus() const { return all_cpus_; }
set_all_cpus(bool value)14777   void set_all_cpus(bool value) { all_cpus_ = value; _has_field_.set(1); }
14778 
has_sampling_frequency() const14779   bool has_sampling_frequency() const { return _has_field_[2]; }
sampling_frequency() const14780   uint32_t sampling_frequency() const { return sampling_frequency_; }
set_sampling_frequency(uint32_t value)14781   void set_sampling_frequency(uint32_t value) { sampling_frequency_ = value; _has_field_.set(2); }
14782 
has_ring_buffer_read_period_ms() const14783   bool has_ring_buffer_read_period_ms() const { return _has_field_[8]; }
ring_buffer_read_period_ms() const14784   uint32_t ring_buffer_read_period_ms() const { return ring_buffer_read_period_ms_; }
set_ring_buffer_read_period_ms(uint32_t value)14785   void set_ring_buffer_read_period_ms(uint32_t value) { ring_buffer_read_period_ms_ = value; _has_field_.set(8); }
14786 
has_ring_buffer_pages() const14787   bool has_ring_buffer_pages() const { return _has_field_[3]; }
ring_buffer_pages() const14788   uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
set_ring_buffer_pages(uint32_t value)14789   void set_ring_buffer_pages(uint32_t value) { ring_buffer_pages_ = value; _has_field_.set(3); }
14790 
target_pid_size() const14791   int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
target_pid() const14792   const std::vector<int32_t>& target_pid() const { return target_pid_; }
mutable_target_pid()14793   std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
clear_target_pid()14794   void clear_target_pid() { target_pid_.clear(); }
add_target_pid(int32_t value)14795   void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
add_target_pid()14796   int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
14797 
target_cmdline_size() const14798   int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
target_cmdline() const14799   const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
mutable_target_cmdline()14800   std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
clear_target_cmdline()14801   void clear_target_cmdline() { target_cmdline_.clear(); }
add_target_cmdline(std::string value)14802   void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
add_target_cmdline()14803   std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
14804 
exclude_pid_size() const14805   int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
exclude_pid() const14806   const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
mutable_exclude_pid()14807   std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
clear_exclude_pid()14808   void clear_exclude_pid() { exclude_pid_.clear(); }
add_exclude_pid(int32_t value)14809   void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
add_exclude_pid()14810   int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
14811 
exclude_cmdline_size() const14812   int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
exclude_cmdline() const14813   const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
mutable_exclude_cmdline()14814   std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
clear_exclude_cmdline()14815   void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
add_exclude_cmdline(std::string value)14816   void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
add_exclude_cmdline()14817   std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
14818 
has_remote_descriptor_timeout_ms() const14819   bool has_remote_descriptor_timeout_ms() const { return _has_field_[9]; }
remote_descriptor_timeout_ms() const14820   uint32_t remote_descriptor_timeout_ms() const { return remote_descriptor_timeout_ms_; }
set_remote_descriptor_timeout_ms(uint32_t value)14821   void set_remote_descriptor_timeout_ms(uint32_t value) { remote_descriptor_timeout_ms_ = value; _has_field_.set(9); }
14822 
has_unwind_state_clear_period_ms() const14823   bool has_unwind_state_clear_period_ms() const { return _has_field_[10]; }
unwind_state_clear_period_ms() const14824   uint32_t unwind_state_clear_period_ms() const { return unwind_state_clear_period_ms_; }
set_unwind_state_clear_period_ms(uint32_t value)14825   void set_unwind_state_clear_period_ms(uint32_t value) { unwind_state_clear_period_ms_ = value; _has_field_.set(10); }
14826 
14827  private:
14828   bool all_cpus_{};
14829   uint32_t sampling_frequency_{};
14830   uint32_t ring_buffer_read_period_ms_{};
14831   uint32_t ring_buffer_pages_{};
14832   std::vector<int32_t> target_pid_;
14833   std::vector<std::string> target_cmdline_;
14834   std::vector<int32_t> exclude_pid_;
14835   std::vector<std::string> exclude_cmdline_;
14836   uint32_t remote_descriptor_timeout_ms_{};
14837   uint32_t unwind_state_clear_period_ms_{};
14838 
14839   // Allows to preserve unknown protobuf fields for compatibility
14840   // with future versions of .proto files.
14841   std::string unknown_fields_;
14842 
14843   std::bitset<11> _has_field_{};
14844 };
14845 
14846 }  // namespace perfetto
14847 }  // namespace protos
14848 }  // namespace gen
14849 
14850 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
14851 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14852 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14853 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14854 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14855 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14856 #pragma GCC diagnostic push
14857 #pragma GCC diagnostic ignored "-Wfloat-equal"
14858 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
14859 
14860 namespace perfetto {
14861 namespace protos {
14862 namespace gen {
14863 
14864 PerfEventConfig::PerfEventConfig() = default;
14865 PerfEventConfig::~PerfEventConfig() = default;
14866 PerfEventConfig::PerfEventConfig(const PerfEventConfig&) = default;
14867 PerfEventConfig& PerfEventConfig::operator=(const PerfEventConfig&) = default;
14868 PerfEventConfig::PerfEventConfig(PerfEventConfig&&) noexcept = default;
14869 PerfEventConfig& PerfEventConfig::operator=(PerfEventConfig&&) = default;
14870 
operator ==(const PerfEventConfig & other) const14871 bool PerfEventConfig::operator==(const PerfEventConfig& other) const {
14872   return unknown_fields_ == other.unknown_fields_
14873    && all_cpus_ == other.all_cpus_
14874    && sampling_frequency_ == other.sampling_frequency_
14875    && ring_buffer_read_period_ms_ == other.ring_buffer_read_period_ms_
14876    && ring_buffer_pages_ == other.ring_buffer_pages_
14877    && target_pid_ == other.target_pid_
14878    && target_cmdline_ == other.target_cmdline_
14879    && exclude_pid_ == other.exclude_pid_
14880    && exclude_cmdline_ == other.exclude_cmdline_
14881    && remote_descriptor_timeout_ms_ == other.remote_descriptor_timeout_ms_
14882    && unwind_state_clear_period_ms_ == other.unwind_state_clear_period_ms_;
14883 }
14884 
ParseFromArray(const void * raw,size_t size)14885 bool PerfEventConfig::ParseFromArray(const void* raw, size_t size) {
14886   target_pid_.clear();
14887   target_cmdline_.clear();
14888   exclude_pid_.clear();
14889   exclude_cmdline_.clear();
14890   unknown_fields_.clear();
14891   bool packed_error = false;
14892 
14893   ::protozero::ProtoDecoder dec(raw, size);
14894   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14895     if (field.id() < _has_field_.size()) {
14896       _has_field_.set(field.id());
14897     }
14898     switch (field.id()) {
14899       case 1 /* all_cpus */:
14900         field.get(&all_cpus_);
14901         break;
14902       case 2 /* sampling_frequency */:
14903         field.get(&sampling_frequency_);
14904         break;
14905       case 8 /* ring_buffer_read_period_ms */:
14906         field.get(&ring_buffer_read_period_ms_);
14907         break;
14908       case 3 /* ring_buffer_pages */:
14909         field.get(&ring_buffer_pages_);
14910         break;
14911       case 4 /* target_pid */:
14912         target_pid_.emplace_back();
14913         field.get(&target_pid_.back());
14914         break;
14915       case 5 /* target_cmdline */:
14916         target_cmdline_.emplace_back();
14917         field.get(&target_cmdline_.back());
14918         break;
14919       case 6 /* exclude_pid */:
14920         exclude_pid_.emplace_back();
14921         field.get(&exclude_pid_.back());
14922         break;
14923       case 7 /* exclude_cmdline */:
14924         exclude_cmdline_.emplace_back();
14925         field.get(&exclude_cmdline_.back());
14926         break;
14927       case 9 /* remote_descriptor_timeout_ms */:
14928         field.get(&remote_descriptor_timeout_ms_);
14929         break;
14930       case 10 /* unwind_state_clear_period_ms */:
14931         field.get(&unwind_state_clear_period_ms_);
14932         break;
14933       default:
14934         field.SerializeAndAppendTo(&unknown_fields_);
14935         break;
14936     }
14937   }
14938   return !packed_error && !dec.bytes_left();
14939 }
14940 
SerializeAsString() const14941 std::string PerfEventConfig::SerializeAsString() const {
14942   ::protozero::HeapBuffered<::protozero::Message> msg;
14943   Serialize(msg.get());
14944   return msg.SerializeAsString();
14945 }
14946 
SerializeAsArray() const14947 std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
14948   ::protozero::HeapBuffered<::protozero::Message> msg;
14949   Serialize(msg.get());
14950   return msg.SerializeAsArray();
14951 }
14952 
Serialize(::protozero::Message * msg) const14953 void PerfEventConfig::Serialize(::protozero::Message* msg) const {
14954   // Field 1: all_cpus
14955   if (_has_field_[1]) {
14956     msg->AppendTinyVarInt(1, all_cpus_);
14957   }
14958 
14959   // Field 2: sampling_frequency
14960   if (_has_field_[2]) {
14961     msg->AppendVarInt(2, sampling_frequency_);
14962   }
14963 
14964   // Field 8: ring_buffer_read_period_ms
14965   if (_has_field_[8]) {
14966     msg->AppendVarInt(8, ring_buffer_read_period_ms_);
14967   }
14968 
14969   // Field 3: ring_buffer_pages
14970   if (_has_field_[3]) {
14971     msg->AppendVarInt(3, ring_buffer_pages_);
14972   }
14973 
14974   // Field 4: target_pid
14975   for (auto& it : target_pid_) {
14976     msg->AppendVarInt(4, it);
14977   }
14978 
14979   // Field 5: target_cmdline
14980   for (auto& it : target_cmdline_) {
14981     msg->AppendString(5, it);
14982   }
14983 
14984   // Field 6: exclude_pid
14985   for (auto& it : exclude_pid_) {
14986     msg->AppendVarInt(6, it);
14987   }
14988 
14989   // Field 7: exclude_cmdline
14990   for (auto& it : exclude_cmdline_) {
14991     msg->AppendString(7, it);
14992   }
14993 
14994   // Field 9: remote_descriptor_timeout_ms
14995   if (_has_field_[9]) {
14996     msg->AppendVarInt(9, remote_descriptor_timeout_ms_);
14997   }
14998 
14999   // Field 10: unwind_state_clear_period_ms
15000   if (_has_field_[10]) {
15001     msg->AppendVarInt(10, unwind_state_clear_period_ms_);
15002   }
15003 
15004   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15005 }
15006 
15007 }  // namespace perfetto
15008 }  // namespace protos
15009 }  // namespace gen
15010 #pragma GCC diagnostic pop
15011 // gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc
15012 // gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.h
15013 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15014 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
15015 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
15016 
15017 #include <stdint.h>
15018 #include <bitset>
15019 #include <vector>
15020 #include <string>
15021 #include <type_traits>
15022 
15023 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15024 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15025 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15026 
15027 namespace perfetto {
15028 namespace protos {
15029 namespace gen {
15030 class SysStatsConfig;
15031 enum SysStatsConfig_StatCounters : int;
15032 enum MeminfoCounters : int;
15033 enum VmstatCounters : int;
15034 }  // namespace perfetto
15035 }  // namespace protos
15036 }  // namespace gen
15037 
15038 namespace protozero {
15039 class Message;
15040 }  // namespace protozero
15041 
15042 namespace perfetto {
15043 namespace protos {
15044 namespace gen {
15045 enum SysStatsConfig_StatCounters : int {
15046   SysStatsConfig_StatCounters_STAT_UNSPECIFIED = 0,
15047   SysStatsConfig_StatCounters_STAT_CPU_TIMES = 1,
15048   SysStatsConfig_StatCounters_STAT_IRQ_COUNTS = 2,
15049   SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS = 3,
15050   SysStatsConfig_StatCounters_STAT_FORK_COUNT = 4,
15051 };
15052 
15053 class PERFETTO_EXPORT SysStatsConfig : public ::protozero::CppMessageObj {
15054  public:
15055   using StatCounters = SysStatsConfig_StatCounters;
15056   static constexpr auto STAT_UNSPECIFIED = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
15057   static constexpr auto STAT_CPU_TIMES = SysStatsConfig_StatCounters_STAT_CPU_TIMES;
15058   static constexpr auto STAT_IRQ_COUNTS = SysStatsConfig_StatCounters_STAT_IRQ_COUNTS;
15059   static constexpr auto STAT_SOFTIRQ_COUNTS = SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS;
15060   static constexpr auto STAT_FORK_COUNT = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
15061   static constexpr auto StatCounters_MIN = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
15062   static constexpr auto StatCounters_MAX = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
15063   enum FieldNumbers {
15064     kMeminfoPeriodMsFieldNumber = 1,
15065     kMeminfoCountersFieldNumber = 2,
15066     kVmstatPeriodMsFieldNumber = 3,
15067     kVmstatCountersFieldNumber = 4,
15068     kStatPeriodMsFieldNumber = 5,
15069     kStatCountersFieldNumber = 6,
15070   };
15071 
15072   SysStatsConfig();
15073   ~SysStatsConfig() override;
15074   SysStatsConfig(SysStatsConfig&&) noexcept;
15075   SysStatsConfig& operator=(SysStatsConfig&&);
15076   SysStatsConfig(const SysStatsConfig&);
15077   SysStatsConfig& operator=(const SysStatsConfig&);
15078   bool operator==(const SysStatsConfig&) const;
operator !=(const SysStatsConfig & other) const15079   bool operator!=(const SysStatsConfig& other) const { return !(*this == other); }
15080 
15081   bool ParseFromArray(const void*, size_t) override;
15082   std::string SerializeAsString() const override;
15083   std::vector<uint8_t> SerializeAsArray() const override;
15084   void Serialize(::protozero::Message*) const;
15085 
has_meminfo_period_ms() const15086   bool has_meminfo_period_ms() const { return _has_field_[1]; }
meminfo_period_ms() const15087   uint32_t meminfo_period_ms() const { return meminfo_period_ms_; }
set_meminfo_period_ms(uint32_t value)15088   void set_meminfo_period_ms(uint32_t value) { meminfo_period_ms_ = value; _has_field_.set(1); }
15089 
meminfo_counters_size() const15090   int meminfo_counters_size() const { return static_cast<int>(meminfo_counters_.size()); }
meminfo_counters() const15091   const std::vector<MeminfoCounters>& meminfo_counters() const { return meminfo_counters_; }
mutable_meminfo_counters()15092   std::vector<MeminfoCounters>* mutable_meminfo_counters() { return &meminfo_counters_; }
clear_meminfo_counters()15093   void clear_meminfo_counters() { meminfo_counters_.clear(); }
add_meminfo_counters(MeminfoCounters value)15094   void add_meminfo_counters(MeminfoCounters value) { meminfo_counters_.emplace_back(value); }
add_meminfo_counters()15095   MeminfoCounters* add_meminfo_counters() { meminfo_counters_.emplace_back(); return &meminfo_counters_.back(); }
15096 
has_vmstat_period_ms() const15097   bool has_vmstat_period_ms() const { return _has_field_[3]; }
vmstat_period_ms() const15098   uint32_t vmstat_period_ms() const { return vmstat_period_ms_; }
set_vmstat_period_ms(uint32_t value)15099   void set_vmstat_period_ms(uint32_t value) { vmstat_period_ms_ = value; _has_field_.set(3); }
15100 
vmstat_counters_size() const15101   int vmstat_counters_size() const { return static_cast<int>(vmstat_counters_.size()); }
vmstat_counters() const15102   const std::vector<VmstatCounters>& vmstat_counters() const { return vmstat_counters_; }
mutable_vmstat_counters()15103   std::vector<VmstatCounters>* mutable_vmstat_counters() { return &vmstat_counters_; }
clear_vmstat_counters()15104   void clear_vmstat_counters() { vmstat_counters_.clear(); }
add_vmstat_counters(VmstatCounters value)15105   void add_vmstat_counters(VmstatCounters value) { vmstat_counters_.emplace_back(value); }
add_vmstat_counters()15106   VmstatCounters* add_vmstat_counters() { vmstat_counters_.emplace_back(); return &vmstat_counters_.back(); }
15107 
has_stat_period_ms() const15108   bool has_stat_period_ms() const { return _has_field_[5]; }
stat_period_ms() const15109   uint32_t stat_period_ms() const { return stat_period_ms_; }
set_stat_period_ms(uint32_t value)15110   void set_stat_period_ms(uint32_t value) { stat_period_ms_ = value; _has_field_.set(5); }
15111 
stat_counters_size() const15112   int stat_counters_size() const { return static_cast<int>(stat_counters_.size()); }
stat_counters() const15113   const std::vector<SysStatsConfig_StatCounters>& stat_counters() const { return stat_counters_; }
mutable_stat_counters()15114   std::vector<SysStatsConfig_StatCounters>* mutable_stat_counters() { return &stat_counters_; }
clear_stat_counters()15115   void clear_stat_counters() { stat_counters_.clear(); }
add_stat_counters(SysStatsConfig_StatCounters value)15116   void add_stat_counters(SysStatsConfig_StatCounters value) { stat_counters_.emplace_back(value); }
add_stat_counters()15117   SysStatsConfig_StatCounters* add_stat_counters() { stat_counters_.emplace_back(); return &stat_counters_.back(); }
15118 
15119  private:
15120   uint32_t meminfo_period_ms_{};
15121   std::vector<MeminfoCounters> meminfo_counters_;
15122   uint32_t vmstat_period_ms_{};
15123   std::vector<VmstatCounters> vmstat_counters_;
15124   uint32_t stat_period_ms_{};
15125   std::vector<SysStatsConfig_StatCounters> stat_counters_;
15126 
15127   // Allows to preserve unknown protobuf fields for compatibility
15128   // with future versions of .proto files.
15129   std::string unknown_fields_;
15130 
15131   std::bitset<7> _has_field_{};
15132 };
15133 
15134 }  // namespace perfetto
15135 }  // namespace protos
15136 }  // namespace gen
15137 
15138 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
15139 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15140 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15141 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15142 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15143 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15144 #pragma GCC diagnostic push
15145 #pragma GCC diagnostic ignored "-Wfloat-equal"
15146 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
15147 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
15148 
15149 namespace perfetto {
15150 namespace protos {
15151 namespace gen {
15152 
15153 SysStatsConfig::SysStatsConfig() = default;
15154 SysStatsConfig::~SysStatsConfig() = default;
15155 SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
15156 SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
15157 SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
15158 SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;
15159 
operator ==(const SysStatsConfig & other) const15160 bool SysStatsConfig::operator==(const SysStatsConfig& other) const {
15161   return unknown_fields_ == other.unknown_fields_
15162    && meminfo_period_ms_ == other.meminfo_period_ms_
15163    && meminfo_counters_ == other.meminfo_counters_
15164    && vmstat_period_ms_ == other.vmstat_period_ms_
15165    && vmstat_counters_ == other.vmstat_counters_
15166    && stat_period_ms_ == other.stat_period_ms_
15167    && stat_counters_ == other.stat_counters_;
15168 }
15169 
ParseFromArray(const void * raw,size_t size)15170 bool SysStatsConfig::ParseFromArray(const void* raw, size_t size) {
15171   meminfo_counters_.clear();
15172   vmstat_counters_.clear();
15173   stat_counters_.clear();
15174   unknown_fields_.clear();
15175   bool packed_error = false;
15176 
15177   ::protozero::ProtoDecoder dec(raw, size);
15178   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15179     if (field.id() < _has_field_.size()) {
15180       _has_field_.set(field.id());
15181     }
15182     switch (field.id()) {
15183       case 1 /* meminfo_period_ms */:
15184         field.get(&meminfo_period_ms_);
15185         break;
15186       case 2 /* meminfo_counters */:
15187         meminfo_counters_.emplace_back();
15188         field.get(&meminfo_counters_.back());
15189         break;
15190       case 3 /* vmstat_period_ms */:
15191         field.get(&vmstat_period_ms_);
15192         break;
15193       case 4 /* vmstat_counters */:
15194         vmstat_counters_.emplace_back();
15195         field.get(&vmstat_counters_.back());
15196         break;
15197       case 5 /* stat_period_ms */:
15198         field.get(&stat_period_ms_);
15199         break;
15200       case 6 /* stat_counters */:
15201         stat_counters_.emplace_back();
15202         field.get(&stat_counters_.back());
15203         break;
15204       default:
15205         field.SerializeAndAppendTo(&unknown_fields_);
15206         break;
15207     }
15208   }
15209   return !packed_error && !dec.bytes_left();
15210 }
15211 
SerializeAsString() const15212 std::string SysStatsConfig::SerializeAsString() const {
15213   ::protozero::HeapBuffered<::protozero::Message> msg;
15214   Serialize(msg.get());
15215   return msg.SerializeAsString();
15216 }
15217 
SerializeAsArray() const15218 std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
15219   ::protozero::HeapBuffered<::protozero::Message> msg;
15220   Serialize(msg.get());
15221   return msg.SerializeAsArray();
15222 }
15223 
Serialize(::protozero::Message * msg) const15224 void SysStatsConfig::Serialize(::protozero::Message* msg) const {
15225   // Field 1: meminfo_period_ms
15226   if (_has_field_[1]) {
15227     msg->AppendVarInt(1, meminfo_period_ms_);
15228   }
15229 
15230   // Field 2: meminfo_counters
15231   for (auto& it : meminfo_counters_) {
15232     msg->AppendVarInt(2, it);
15233   }
15234 
15235   // Field 3: vmstat_period_ms
15236   if (_has_field_[3]) {
15237     msg->AppendVarInt(3, vmstat_period_ms_);
15238   }
15239 
15240   // Field 4: vmstat_counters
15241   for (auto& it : vmstat_counters_) {
15242     msg->AppendVarInt(4, it);
15243   }
15244 
15245   // Field 5: stat_period_ms
15246   if (_has_field_[5]) {
15247     msg->AppendVarInt(5, stat_period_ms_);
15248   }
15249 
15250   // Field 6: stat_counters
15251   for (auto& it : stat_counters_) {
15252     msg->AppendVarInt(6, it);
15253   }
15254 
15255   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15256 }
15257 
15258 }  // namespace perfetto
15259 }  // namespace protos
15260 }  // namespace gen
15261 #pragma GCC diagnostic pop
15262 // gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.gen.cc
15263 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15264 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15265 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15266 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15267 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15268 #pragma GCC diagnostic push
15269 #pragma GCC diagnostic ignored "-Wfloat-equal"
15270 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
15271 
15272 namespace perfetto {
15273 namespace protos {
15274 namespace gen {
15275 
15276 TrackEventConfig::TrackEventConfig() = default;
15277 TrackEventConfig::~TrackEventConfig() = default;
15278 TrackEventConfig::TrackEventConfig(const TrackEventConfig&) = default;
15279 TrackEventConfig& TrackEventConfig::operator=(const TrackEventConfig&) = default;
15280 TrackEventConfig::TrackEventConfig(TrackEventConfig&&) noexcept = default;
15281 TrackEventConfig& TrackEventConfig::operator=(TrackEventConfig&&) = default;
15282 
operator ==(const TrackEventConfig & other) const15283 bool TrackEventConfig::operator==(const TrackEventConfig& other) const {
15284   return unknown_fields_ == other.unknown_fields_
15285    && disabled_categories_ == other.disabled_categories_
15286    && enabled_categories_ == other.enabled_categories_
15287    && disabled_tags_ == other.disabled_tags_
15288    && enabled_tags_ == other.enabled_tags_;
15289 }
15290 
ParseFromArray(const void * raw,size_t size)15291 bool TrackEventConfig::ParseFromArray(const void* raw, size_t size) {
15292   disabled_categories_.clear();
15293   enabled_categories_.clear();
15294   disabled_tags_.clear();
15295   enabled_tags_.clear();
15296   unknown_fields_.clear();
15297   bool packed_error = false;
15298 
15299   ::protozero::ProtoDecoder dec(raw, size);
15300   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15301     if (field.id() < _has_field_.size()) {
15302       _has_field_.set(field.id());
15303     }
15304     switch (field.id()) {
15305       case 1 /* disabled_categories */:
15306         disabled_categories_.emplace_back();
15307         field.get(&disabled_categories_.back());
15308         break;
15309       case 2 /* enabled_categories */:
15310         enabled_categories_.emplace_back();
15311         field.get(&enabled_categories_.back());
15312         break;
15313       case 3 /* disabled_tags */:
15314         disabled_tags_.emplace_back();
15315         field.get(&disabled_tags_.back());
15316         break;
15317       case 4 /* enabled_tags */:
15318         enabled_tags_.emplace_back();
15319         field.get(&enabled_tags_.back());
15320         break;
15321       default:
15322         field.SerializeAndAppendTo(&unknown_fields_);
15323         break;
15324     }
15325   }
15326   return !packed_error && !dec.bytes_left();
15327 }
15328 
SerializeAsString() const15329 std::string TrackEventConfig::SerializeAsString() const {
15330   ::protozero::HeapBuffered<::protozero::Message> msg;
15331   Serialize(msg.get());
15332   return msg.SerializeAsString();
15333 }
15334 
SerializeAsArray() const15335 std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
15336   ::protozero::HeapBuffered<::protozero::Message> msg;
15337   Serialize(msg.get());
15338   return msg.SerializeAsArray();
15339 }
15340 
Serialize(::protozero::Message * msg) const15341 void TrackEventConfig::Serialize(::protozero::Message* msg) const {
15342   // Field 1: disabled_categories
15343   for (auto& it : disabled_categories_) {
15344     msg->AppendString(1, it);
15345   }
15346 
15347   // Field 2: enabled_categories
15348   for (auto& it : enabled_categories_) {
15349     msg->AppendString(2, it);
15350   }
15351 
15352   // Field 3: disabled_tags
15353   for (auto& it : disabled_tags_) {
15354     msg->AppendString(3, it);
15355   }
15356 
15357   // Field 4: enabled_tags
15358   for (auto& it : enabled_tags_) {
15359     msg->AppendString(4, it);
15360   }
15361 
15362   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15363 }
15364 
15365 }  // namespace perfetto
15366 }  // namespace protos
15367 }  // namespace gen
15368 #pragma GCC diagnostic pop
15369 // gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.gen.cc
15370 // gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.gen.h
15371 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15372 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
15373 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
15374 
15375 #include <stdint.h>
15376 #include <bitset>
15377 #include <vector>
15378 #include <string>
15379 #include <type_traits>
15380 
15381 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15382 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15383 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15384 
15385 namespace perfetto {
15386 namespace protos {
15387 namespace gen {
15388 class ChromeConfig;
15389 }  // namespace perfetto
15390 }  // namespace protos
15391 }  // namespace gen
15392 
15393 namespace protozero {
15394 class Message;
15395 }  // namespace protozero
15396 
15397 namespace perfetto {
15398 namespace protos {
15399 namespace gen {
15400 
15401 class PERFETTO_EXPORT ChromeConfig : public ::protozero::CppMessageObj {
15402  public:
15403   enum FieldNumbers {
15404     kTraceConfigFieldNumber = 1,
15405     kPrivacyFilteringEnabledFieldNumber = 2,
15406     kConvertToLegacyJsonFieldNumber = 3,
15407   };
15408 
15409   ChromeConfig();
15410   ~ChromeConfig() override;
15411   ChromeConfig(ChromeConfig&&) noexcept;
15412   ChromeConfig& operator=(ChromeConfig&&);
15413   ChromeConfig(const ChromeConfig&);
15414   ChromeConfig& operator=(const ChromeConfig&);
15415   bool operator==(const ChromeConfig&) const;
operator !=(const ChromeConfig & other) const15416   bool operator!=(const ChromeConfig& other) const { return !(*this == other); }
15417 
15418   bool ParseFromArray(const void*, size_t) override;
15419   std::string SerializeAsString() const override;
15420   std::vector<uint8_t> SerializeAsArray() const override;
15421   void Serialize(::protozero::Message*) const;
15422 
has_trace_config() const15423   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const15424   const std::string& trace_config() const { return trace_config_; }
set_trace_config(const std::string & value)15425   void set_trace_config(const std::string& value) { trace_config_ = value; _has_field_.set(1); }
15426 
has_privacy_filtering_enabled() const15427   bool has_privacy_filtering_enabled() const { return _has_field_[2]; }
privacy_filtering_enabled() const15428   bool privacy_filtering_enabled() const { return privacy_filtering_enabled_; }
set_privacy_filtering_enabled(bool value)15429   void set_privacy_filtering_enabled(bool value) { privacy_filtering_enabled_ = value; _has_field_.set(2); }
15430 
has_convert_to_legacy_json() const15431   bool has_convert_to_legacy_json() const { return _has_field_[3]; }
convert_to_legacy_json() const15432   bool convert_to_legacy_json() const { return convert_to_legacy_json_; }
set_convert_to_legacy_json(bool value)15433   void set_convert_to_legacy_json(bool value) { convert_to_legacy_json_ = value; _has_field_.set(3); }
15434 
15435  private:
15436   std::string trace_config_{};
15437   bool privacy_filtering_enabled_{};
15438   bool convert_to_legacy_json_{};
15439 
15440   // Allows to preserve unknown protobuf fields for compatibility
15441   // with future versions of .proto files.
15442   std::string unknown_fields_;
15443 
15444   std::bitset<4> _has_field_{};
15445 };
15446 
15447 }  // namespace perfetto
15448 }  // namespace protos
15449 }  // namespace gen
15450 
15451 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
15452 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15453 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15454 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15455 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15456 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15457 #pragma GCC diagnostic push
15458 #pragma GCC diagnostic ignored "-Wfloat-equal"
15459 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
15460 
15461 namespace perfetto {
15462 namespace protos {
15463 namespace gen {
15464 
15465 ChromeConfig::ChromeConfig() = default;
15466 ChromeConfig::~ChromeConfig() = default;
15467 ChromeConfig::ChromeConfig(const ChromeConfig&) = default;
15468 ChromeConfig& ChromeConfig::operator=(const ChromeConfig&) = default;
15469 ChromeConfig::ChromeConfig(ChromeConfig&&) noexcept = default;
15470 ChromeConfig& ChromeConfig::operator=(ChromeConfig&&) = default;
15471 
operator ==(const ChromeConfig & other) const15472 bool ChromeConfig::operator==(const ChromeConfig& other) const {
15473   return unknown_fields_ == other.unknown_fields_
15474    && trace_config_ == other.trace_config_
15475    && privacy_filtering_enabled_ == other.privacy_filtering_enabled_
15476    && convert_to_legacy_json_ == other.convert_to_legacy_json_;
15477 }
15478 
ParseFromArray(const void * raw,size_t size)15479 bool ChromeConfig::ParseFromArray(const void* raw, size_t size) {
15480   unknown_fields_.clear();
15481   bool packed_error = false;
15482 
15483   ::protozero::ProtoDecoder dec(raw, size);
15484   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15485     if (field.id() < _has_field_.size()) {
15486       _has_field_.set(field.id());
15487     }
15488     switch (field.id()) {
15489       case 1 /* trace_config */:
15490         field.get(&trace_config_);
15491         break;
15492       case 2 /* privacy_filtering_enabled */:
15493         field.get(&privacy_filtering_enabled_);
15494         break;
15495       case 3 /* convert_to_legacy_json */:
15496         field.get(&convert_to_legacy_json_);
15497         break;
15498       default:
15499         field.SerializeAndAppendTo(&unknown_fields_);
15500         break;
15501     }
15502   }
15503   return !packed_error && !dec.bytes_left();
15504 }
15505 
SerializeAsString() const15506 std::string ChromeConfig::SerializeAsString() const {
15507   ::protozero::HeapBuffered<::protozero::Message> msg;
15508   Serialize(msg.get());
15509   return msg.SerializeAsString();
15510 }
15511 
SerializeAsArray() const15512 std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
15513   ::protozero::HeapBuffered<::protozero::Message> msg;
15514   Serialize(msg.get());
15515   return msg.SerializeAsArray();
15516 }
15517 
Serialize(::protozero::Message * msg) const15518 void ChromeConfig::Serialize(::protozero::Message* msg) const {
15519   // Field 1: trace_config
15520   if (_has_field_[1]) {
15521     msg->AppendString(1, trace_config_);
15522   }
15523 
15524   // Field 2: privacy_filtering_enabled
15525   if (_has_field_[2]) {
15526     msg->AppendTinyVarInt(2, privacy_filtering_enabled_);
15527   }
15528 
15529   // Field 3: convert_to_legacy_json
15530   if (_has_field_[3]) {
15531     msg->AppendTinyVarInt(3, convert_to_legacy_json_);
15532   }
15533 
15534   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15535 }
15536 
15537 }  // namespace perfetto
15538 }  // namespace protos
15539 }  // namespace gen
15540 #pragma GCC diagnostic pop
15541 // gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.gen.cc
15542 // gen_amalgamated begin header: gen/protos/perfetto/config/test_config.gen.h
15543 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15544 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
15545 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
15546 
15547 #include <stdint.h>
15548 #include <bitset>
15549 #include <vector>
15550 #include <string>
15551 #include <type_traits>
15552 
15553 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15554 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15555 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15556 
15557 namespace perfetto {
15558 namespace protos {
15559 namespace gen {
15560 class TestConfig;
15561 class TestConfig_DummyFields;
15562 }  // namespace perfetto
15563 }  // namespace protos
15564 }  // namespace gen
15565 
15566 namespace protozero {
15567 class Message;
15568 }  // namespace protozero
15569 
15570 namespace perfetto {
15571 namespace protos {
15572 namespace gen {
15573 
15574 class PERFETTO_EXPORT TestConfig : public ::protozero::CppMessageObj {
15575  public:
15576   using DummyFields = TestConfig_DummyFields;
15577   enum FieldNumbers {
15578     kMessageCountFieldNumber = 1,
15579     kMaxMessagesPerSecondFieldNumber = 2,
15580     kSeedFieldNumber = 3,
15581     kMessageSizeFieldNumber = 4,
15582     kSendBatchOnRegisterFieldNumber = 5,
15583     kDummyFieldsFieldNumber = 6,
15584   };
15585 
15586   TestConfig();
15587   ~TestConfig() override;
15588   TestConfig(TestConfig&&) noexcept;
15589   TestConfig& operator=(TestConfig&&);
15590   TestConfig(const TestConfig&);
15591   TestConfig& operator=(const TestConfig&);
15592   bool operator==(const TestConfig&) const;
operator !=(const TestConfig & other) const15593   bool operator!=(const TestConfig& other) const { return !(*this == other); }
15594 
15595   bool ParseFromArray(const void*, size_t) override;
15596   std::string SerializeAsString() const override;
15597   std::vector<uint8_t> SerializeAsArray() const override;
15598   void Serialize(::protozero::Message*) const;
15599 
has_message_count() const15600   bool has_message_count() const { return _has_field_[1]; }
message_count() const15601   uint32_t message_count() const { return message_count_; }
set_message_count(uint32_t value)15602   void set_message_count(uint32_t value) { message_count_ = value; _has_field_.set(1); }
15603 
has_max_messages_per_second() const15604   bool has_max_messages_per_second() const { return _has_field_[2]; }
max_messages_per_second() const15605   uint32_t max_messages_per_second() const { return max_messages_per_second_; }
set_max_messages_per_second(uint32_t value)15606   void set_max_messages_per_second(uint32_t value) { max_messages_per_second_ = value; _has_field_.set(2); }
15607 
has_seed() const15608   bool has_seed() const { return _has_field_[3]; }
seed() const15609   uint32_t seed() const { return seed_; }
set_seed(uint32_t value)15610   void set_seed(uint32_t value) { seed_ = value; _has_field_.set(3); }
15611 
has_message_size() const15612   bool has_message_size() const { return _has_field_[4]; }
message_size() const15613   uint32_t message_size() const { return message_size_; }
set_message_size(uint32_t value)15614   void set_message_size(uint32_t value) { message_size_ = value; _has_field_.set(4); }
15615 
has_send_batch_on_register() const15616   bool has_send_batch_on_register() const { return _has_field_[5]; }
send_batch_on_register() const15617   bool send_batch_on_register() const { return send_batch_on_register_; }
set_send_batch_on_register(bool value)15618   void set_send_batch_on_register(bool value) { send_batch_on_register_ = value; _has_field_.set(5); }
15619 
has_dummy_fields() const15620   bool has_dummy_fields() const { return _has_field_[6]; }
dummy_fields() const15621   const TestConfig_DummyFields& dummy_fields() const { return *dummy_fields_; }
mutable_dummy_fields()15622   TestConfig_DummyFields* mutable_dummy_fields() { _has_field_.set(6); return dummy_fields_.get(); }
15623 
15624  private:
15625   uint32_t message_count_{};
15626   uint32_t max_messages_per_second_{};
15627   uint32_t seed_{};
15628   uint32_t message_size_{};
15629   bool send_batch_on_register_{};
15630   ::protozero::CopyablePtr<TestConfig_DummyFields> dummy_fields_;
15631 
15632   // Allows to preserve unknown protobuf fields for compatibility
15633   // with future versions of .proto files.
15634   std::string unknown_fields_;
15635 
15636   std::bitset<7> _has_field_{};
15637 };
15638 
15639 
15640 class PERFETTO_EXPORT TestConfig_DummyFields : public ::protozero::CppMessageObj {
15641  public:
15642   enum FieldNumbers {
15643     kFieldUint32FieldNumber = 1,
15644     kFieldInt32FieldNumber = 2,
15645     kFieldUint64FieldNumber = 3,
15646     kFieldInt64FieldNumber = 4,
15647     kFieldFixed64FieldNumber = 5,
15648     kFieldSfixed64FieldNumber = 6,
15649     kFieldFixed32FieldNumber = 7,
15650     kFieldSfixed32FieldNumber = 8,
15651     kFieldDoubleFieldNumber = 9,
15652     kFieldFloatFieldNumber = 10,
15653     kFieldSint64FieldNumber = 11,
15654     kFieldSint32FieldNumber = 12,
15655     kFieldStringFieldNumber = 13,
15656     kFieldBytesFieldNumber = 14,
15657   };
15658 
15659   TestConfig_DummyFields();
15660   ~TestConfig_DummyFields() override;
15661   TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept;
15662   TestConfig_DummyFields& operator=(TestConfig_DummyFields&&);
15663   TestConfig_DummyFields(const TestConfig_DummyFields&);
15664   TestConfig_DummyFields& operator=(const TestConfig_DummyFields&);
15665   bool operator==(const TestConfig_DummyFields&) const;
operator !=(const TestConfig_DummyFields & other) const15666   bool operator!=(const TestConfig_DummyFields& other) const { return !(*this == other); }
15667 
15668   bool ParseFromArray(const void*, size_t) override;
15669   std::string SerializeAsString() const override;
15670   std::vector<uint8_t> SerializeAsArray() const override;
15671   void Serialize(::protozero::Message*) const;
15672 
has_field_uint32() const15673   bool has_field_uint32() const { return _has_field_[1]; }
field_uint32() const15674   uint32_t field_uint32() const { return field_uint32_; }
set_field_uint32(uint32_t value)15675   void set_field_uint32(uint32_t value) { field_uint32_ = value; _has_field_.set(1); }
15676 
has_field_int32() const15677   bool has_field_int32() const { return _has_field_[2]; }
field_int32() const15678   int32_t field_int32() const { return field_int32_; }
set_field_int32(int32_t value)15679   void set_field_int32(int32_t value) { field_int32_ = value; _has_field_.set(2); }
15680 
has_field_uint64() const15681   bool has_field_uint64() const { return _has_field_[3]; }
field_uint64() const15682   uint64_t field_uint64() const { return field_uint64_; }
set_field_uint64(uint64_t value)15683   void set_field_uint64(uint64_t value) { field_uint64_ = value; _has_field_.set(3); }
15684 
has_field_int64() const15685   bool has_field_int64() const { return _has_field_[4]; }
field_int64() const15686   int64_t field_int64() const { return field_int64_; }
set_field_int64(int64_t value)15687   void set_field_int64(int64_t value) { field_int64_ = value; _has_field_.set(4); }
15688 
has_field_fixed64() const15689   bool has_field_fixed64() const { return _has_field_[5]; }
field_fixed64() const15690   uint64_t field_fixed64() const { return field_fixed64_; }
set_field_fixed64(uint64_t value)15691   void set_field_fixed64(uint64_t value) { field_fixed64_ = value; _has_field_.set(5); }
15692 
has_field_sfixed64() const15693   bool has_field_sfixed64() const { return _has_field_[6]; }
field_sfixed64() const15694   int64_t field_sfixed64() const { return field_sfixed64_; }
set_field_sfixed64(int64_t value)15695   void set_field_sfixed64(int64_t value) { field_sfixed64_ = value; _has_field_.set(6); }
15696 
has_field_fixed32() const15697   bool has_field_fixed32() const { return _has_field_[7]; }
field_fixed32() const15698   uint32_t field_fixed32() const { return field_fixed32_; }
set_field_fixed32(uint32_t value)15699   void set_field_fixed32(uint32_t value) { field_fixed32_ = value; _has_field_.set(7); }
15700 
has_field_sfixed32() const15701   bool has_field_sfixed32() const { return _has_field_[8]; }
field_sfixed32() const15702   int32_t field_sfixed32() const { return field_sfixed32_; }
set_field_sfixed32(int32_t value)15703   void set_field_sfixed32(int32_t value) { field_sfixed32_ = value; _has_field_.set(8); }
15704 
has_field_double() const15705   bool has_field_double() const { return _has_field_[9]; }
field_double() const15706   double field_double() const { return field_double_; }
set_field_double(double value)15707   void set_field_double(double value) { field_double_ = value; _has_field_.set(9); }
15708 
has_field_float() const15709   bool has_field_float() const { return _has_field_[10]; }
field_float() const15710   float field_float() const { return field_float_; }
set_field_float(float value)15711   void set_field_float(float value) { field_float_ = value; _has_field_.set(10); }
15712 
has_field_sint64() const15713   bool has_field_sint64() const { return _has_field_[11]; }
field_sint64() const15714   int64_t field_sint64() const { return field_sint64_; }
set_field_sint64(int64_t value)15715   void set_field_sint64(int64_t value) { field_sint64_ = value; _has_field_.set(11); }
15716 
has_field_sint32() const15717   bool has_field_sint32() const { return _has_field_[12]; }
field_sint32() const15718   int32_t field_sint32() const { return field_sint32_; }
set_field_sint32(int32_t value)15719   void set_field_sint32(int32_t value) { field_sint32_ = value; _has_field_.set(12); }
15720 
has_field_string() const15721   bool has_field_string() const { return _has_field_[13]; }
field_string() const15722   const std::string& field_string() const { return field_string_; }
set_field_string(const std::string & value)15723   void set_field_string(const std::string& value) { field_string_ = value; _has_field_.set(13); }
15724 
has_field_bytes() const15725   bool has_field_bytes() const { return _has_field_[14]; }
field_bytes() const15726   const std::string& field_bytes() const { return field_bytes_; }
set_field_bytes(const std::string & value)15727   void set_field_bytes(const std::string& value) { field_bytes_ = value; _has_field_.set(14); }
set_field_bytes(const void * p,size_t s)15728   void set_field_bytes(const void* p, size_t s) { field_bytes_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
15729 
15730  private:
15731   uint32_t field_uint32_{};
15732   int32_t field_int32_{};
15733   uint64_t field_uint64_{};
15734   int64_t field_int64_{};
15735   uint64_t field_fixed64_{};
15736   int64_t field_sfixed64_{};
15737   uint32_t field_fixed32_{};
15738   int32_t field_sfixed32_{};
15739   double field_double_{};
15740   float field_float_{};
15741   int64_t field_sint64_{};
15742   int32_t field_sint32_{};
15743   std::string field_string_{};
15744   std::string field_bytes_{};
15745 
15746   // Allows to preserve unknown protobuf fields for compatibility
15747   // with future versions of .proto files.
15748   std::string unknown_fields_;
15749 
15750   std::bitset<15> _has_field_{};
15751 };
15752 
15753 }  // namespace perfetto
15754 }  // namespace protos
15755 }  // namespace gen
15756 
15757 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
15758 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15759 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15760 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15761 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15762 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15763 #pragma GCC diagnostic push
15764 #pragma GCC diagnostic ignored "-Wfloat-equal"
15765 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
15766 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
15767 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
15768 
15769 namespace perfetto {
15770 namespace protos {
15771 namespace gen {
15772 
15773 DataSourceConfig::DataSourceConfig() = default;
15774 DataSourceConfig::~DataSourceConfig() = default;
15775 DataSourceConfig::DataSourceConfig(const DataSourceConfig&) = default;
15776 DataSourceConfig& DataSourceConfig::operator=(const DataSourceConfig&) = default;
15777 DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
15778 DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;
15779 
operator ==(const DataSourceConfig & other) const15780 bool DataSourceConfig::operator==(const DataSourceConfig& other) const {
15781   return unknown_fields_ == other.unknown_fields_
15782    && name_ == other.name_
15783    && target_buffer_ == other.target_buffer_
15784    && trace_duration_ms_ == other.trace_duration_ms_
15785    && stop_timeout_ms_ == other.stop_timeout_ms_
15786    && enable_extra_guardrails_ == other.enable_extra_guardrails_
15787    && tracing_session_id_ == other.tracing_session_id_
15788    && ftrace_config_ == other.ftrace_config_
15789    && inode_file_config_ == other.inode_file_config_
15790    && process_stats_config_ == other.process_stats_config_
15791    && sys_stats_config_ == other.sys_stats_config_
15792    && heapprofd_config_ == other.heapprofd_config_
15793    && java_hprof_config_ == other.java_hprof_config_
15794    && android_power_config_ == other.android_power_config_
15795    && android_log_config_ == other.android_log_config_
15796    && gpu_counter_config_ == other.gpu_counter_config_
15797    && packages_list_config_ == other.packages_list_config_
15798    && perf_event_config_ == other.perf_event_config_
15799    && vulkan_memory_config_ == other.vulkan_memory_config_
15800    && track_event_config_ == other.track_event_config_
15801    && android_polled_state_config_ == other.android_polled_state_config_
15802    && chrome_config_ == other.chrome_config_
15803    && legacy_config_ == other.legacy_config_
15804    && for_testing_ == other.for_testing_;
15805 }
15806 
ParseFromArray(const void * raw,size_t size)15807 bool DataSourceConfig::ParseFromArray(const void* raw, size_t size) {
15808   unknown_fields_.clear();
15809   bool packed_error = false;
15810 
15811   ::protozero::ProtoDecoder dec(raw, size);
15812   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15813     if (field.id() < _has_field_.size()) {
15814       _has_field_.set(field.id());
15815     }
15816     switch (field.id()) {
15817       case 1 /* name */:
15818         field.get(&name_);
15819         break;
15820       case 2 /* target_buffer */:
15821         field.get(&target_buffer_);
15822         break;
15823       case 3 /* trace_duration_ms */:
15824         field.get(&trace_duration_ms_);
15825         break;
15826       case 7 /* stop_timeout_ms */:
15827         field.get(&stop_timeout_ms_);
15828         break;
15829       case 6 /* enable_extra_guardrails */:
15830         field.get(&enable_extra_guardrails_);
15831         break;
15832       case 4 /* tracing_session_id */:
15833         field.get(&tracing_session_id_);
15834         break;
15835       case 100 /* ftrace_config */:
15836         ftrace_config_ = field.as_std_string();
15837         break;
15838       case 102 /* inode_file_config */:
15839         inode_file_config_ = field.as_std_string();
15840         break;
15841       case 103 /* process_stats_config */:
15842         process_stats_config_ = field.as_std_string();
15843         break;
15844       case 104 /* sys_stats_config */:
15845         sys_stats_config_ = field.as_std_string();
15846         break;
15847       case 105 /* heapprofd_config */:
15848         heapprofd_config_ = field.as_std_string();
15849         break;
15850       case 110 /* java_hprof_config */:
15851         java_hprof_config_ = field.as_std_string();
15852         break;
15853       case 106 /* android_power_config */:
15854         android_power_config_ = field.as_std_string();
15855         break;
15856       case 107 /* android_log_config */:
15857         android_log_config_ = field.as_std_string();
15858         break;
15859       case 108 /* gpu_counter_config */:
15860         gpu_counter_config_ = field.as_std_string();
15861         break;
15862       case 109 /* packages_list_config */:
15863         packages_list_config_ = field.as_std_string();
15864         break;
15865       case 111 /* perf_event_config */:
15866         perf_event_config_ = field.as_std_string();
15867         break;
15868       case 112 /* vulkan_memory_config */:
15869         vulkan_memory_config_ = field.as_std_string();
15870         break;
15871       case 113 /* track_event_config */:
15872         track_event_config_ = field.as_std_string();
15873         break;
15874       case 114 /* android_polled_state_config */:
15875         android_polled_state_config_ = field.as_std_string();
15876         break;
15877       case 101 /* chrome_config */:
15878         (*chrome_config_).ParseFromString(field.as_std_string());
15879         break;
15880       case 1000 /* legacy_config */:
15881         field.get(&legacy_config_);
15882         break;
15883       case 1001 /* for_testing */:
15884         (*for_testing_).ParseFromString(field.as_std_string());
15885         break;
15886       default:
15887         field.SerializeAndAppendTo(&unknown_fields_);
15888         break;
15889     }
15890   }
15891   return !packed_error && !dec.bytes_left();
15892 }
15893 
SerializeAsString() const15894 std::string DataSourceConfig::SerializeAsString() const {
15895   ::protozero::HeapBuffered<::protozero::Message> msg;
15896   Serialize(msg.get());
15897   return msg.SerializeAsString();
15898 }
15899 
SerializeAsArray() const15900 std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
15901   ::protozero::HeapBuffered<::protozero::Message> msg;
15902   Serialize(msg.get());
15903   return msg.SerializeAsArray();
15904 }
15905 
Serialize(::protozero::Message * msg) const15906 void DataSourceConfig::Serialize(::protozero::Message* msg) const {
15907   // Field 1: name
15908   if (_has_field_[1]) {
15909     msg->AppendString(1, name_);
15910   }
15911 
15912   // Field 2: target_buffer
15913   if (_has_field_[2]) {
15914     msg->AppendVarInt(2, target_buffer_);
15915   }
15916 
15917   // Field 3: trace_duration_ms
15918   if (_has_field_[3]) {
15919     msg->AppendVarInt(3, trace_duration_ms_);
15920   }
15921 
15922   // Field 7: stop_timeout_ms
15923   if (_has_field_[7]) {
15924     msg->AppendVarInt(7, stop_timeout_ms_);
15925   }
15926 
15927   // Field 6: enable_extra_guardrails
15928   if (_has_field_[6]) {
15929     msg->AppendTinyVarInt(6, enable_extra_guardrails_);
15930   }
15931 
15932   // Field 4: tracing_session_id
15933   if (_has_field_[4]) {
15934     msg->AppendVarInt(4, tracing_session_id_);
15935   }
15936 
15937   // Field 100: ftrace_config
15938   if (_has_field_[100]) {
15939     msg->AppendString(100, ftrace_config_);
15940   }
15941 
15942   // Field 102: inode_file_config
15943   if (_has_field_[102]) {
15944     msg->AppendString(102, inode_file_config_);
15945   }
15946 
15947   // Field 103: process_stats_config
15948   if (_has_field_[103]) {
15949     msg->AppendString(103, process_stats_config_);
15950   }
15951 
15952   // Field 104: sys_stats_config
15953   if (_has_field_[104]) {
15954     msg->AppendString(104, sys_stats_config_);
15955   }
15956 
15957   // Field 105: heapprofd_config
15958   if (_has_field_[105]) {
15959     msg->AppendString(105, heapprofd_config_);
15960   }
15961 
15962   // Field 110: java_hprof_config
15963   if (_has_field_[110]) {
15964     msg->AppendString(110, java_hprof_config_);
15965   }
15966 
15967   // Field 106: android_power_config
15968   if (_has_field_[106]) {
15969     msg->AppendString(106, android_power_config_);
15970   }
15971 
15972   // Field 107: android_log_config
15973   if (_has_field_[107]) {
15974     msg->AppendString(107, android_log_config_);
15975   }
15976 
15977   // Field 108: gpu_counter_config
15978   if (_has_field_[108]) {
15979     msg->AppendString(108, gpu_counter_config_);
15980   }
15981 
15982   // Field 109: packages_list_config
15983   if (_has_field_[109]) {
15984     msg->AppendString(109, packages_list_config_);
15985   }
15986 
15987   // Field 111: perf_event_config
15988   if (_has_field_[111]) {
15989     msg->AppendString(111, perf_event_config_);
15990   }
15991 
15992   // Field 112: vulkan_memory_config
15993   if (_has_field_[112]) {
15994     msg->AppendString(112, vulkan_memory_config_);
15995   }
15996 
15997   // Field 113: track_event_config
15998   if (_has_field_[113]) {
15999     msg->AppendString(113, track_event_config_);
16000   }
16001 
16002   // Field 114: android_polled_state_config
16003   if (_has_field_[114]) {
16004     msg->AppendString(114, android_polled_state_config_);
16005   }
16006 
16007   // Field 101: chrome_config
16008   if (_has_field_[101]) {
16009     (*chrome_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(101));
16010   }
16011 
16012   // Field 1000: legacy_config
16013   if (_has_field_[1000]) {
16014     msg->AppendString(1000, legacy_config_);
16015   }
16016 
16017   // Field 1001: for_testing
16018   if (_has_field_[1001]) {
16019     (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
16020   }
16021 
16022   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16023 }
16024 
16025 }  // namespace perfetto
16026 }  // namespace protos
16027 }  // namespace gen
16028 #pragma GCC diagnostic pop
16029 // gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.gen.cc
16030 // gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.gen.h
16031 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16032 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
16033 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
16034 
16035 #include <stdint.h>
16036 #include <bitset>
16037 #include <vector>
16038 #include <string>
16039 #include <type_traits>
16040 
16041 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16042 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16043 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16044 
16045 namespace perfetto {
16046 namespace protos {
16047 namespace gen {
16048 class StressTestConfig;
16049 class StressTestConfig_WriterTiming;
16050 class TraceConfig;
16051 class TraceConfig_IncidentReportConfig;
16052 class TraceConfig_IncrementalStateConfig;
16053 class TraceConfig_TriggerConfig;
16054 class TraceConfig_TriggerConfig_Trigger;
16055 class TraceConfig_GuardrailOverrides;
16056 class TraceConfig_StatsdMetadata;
16057 class TraceConfig_ProducerConfig;
16058 class TraceConfig_BuiltinDataSource;
16059 class TraceConfig_DataSource;
16060 class DataSourceConfig;
16061 class TestConfig;
16062 class TestConfig_DummyFields;
16063 class ChromeConfig;
16064 class TraceConfig_BufferConfig;
16065 enum TraceConfig_LockdownModeOperation : int;
16066 enum TraceConfig_CompressionType : int;
16067 enum TraceConfig_TriggerConfig_TriggerMode : int;
16068 enum BuiltinClock : int;
16069 enum TraceConfig_BufferConfig_FillPolicy : int;
16070 }  // namespace perfetto
16071 }  // namespace protos
16072 }  // namespace gen
16073 
16074 namespace protozero {
16075 class Message;
16076 }  // namespace protozero
16077 
16078 namespace perfetto {
16079 namespace protos {
16080 namespace gen {
16081 
16082 class PERFETTO_EXPORT StressTestConfig : public ::protozero::CppMessageObj {
16083  public:
16084   using WriterTiming = StressTestConfig_WriterTiming;
16085   enum FieldNumbers {
16086     kTraceConfigFieldNumber = 1,
16087     kShmemSizeKbFieldNumber = 2,
16088     kShmemPageSizeKbFieldNumber = 3,
16089     kNumProcessesFieldNumber = 4,
16090     kNumThreadsFieldNumber = 5,
16091     kMaxEventsFieldNumber = 6,
16092     kNestingFieldNumber = 7,
16093     kSteadyStateTimingsFieldNumber = 8,
16094     kBurstPeriodMsFieldNumber = 9,
16095     kBurstDurationMsFieldNumber = 10,
16096     kBurstTimingsFieldNumber = 11,
16097   };
16098 
16099   StressTestConfig();
16100   ~StressTestConfig() override;
16101   StressTestConfig(StressTestConfig&&) noexcept;
16102   StressTestConfig& operator=(StressTestConfig&&);
16103   StressTestConfig(const StressTestConfig&);
16104   StressTestConfig& operator=(const StressTestConfig&);
16105   bool operator==(const StressTestConfig&) const;
operator !=(const StressTestConfig & other) const16106   bool operator!=(const StressTestConfig& other) const { return !(*this == other); }
16107 
16108   bool ParseFromArray(const void*, size_t) override;
16109   std::string SerializeAsString() const override;
16110   std::vector<uint8_t> SerializeAsArray() const override;
16111   void Serialize(::protozero::Message*) const;
16112 
has_trace_config() const16113   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const16114   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()16115   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
16116 
has_shmem_size_kb() const16117   bool has_shmem_size_kb() const { return _has_field_[2]; }
shmem_size_kb() const16118   uint32_t shmem_size_kb() const { return shmem_size_kb_; }
set_shmem_size_kb(uint32_t value)16119   void set_shmem_size_kb(uint32_t value) { shmem_size_kb_ = value; _has_field_.set(2); }
16120 
has_shmem_page_size_kb() const16121   bool has_shmem_page_size_kb() const { return _has_field_[3]; }
shmem_page_size_kb() const16122   uint32_t shmem_page_size_kb() const { return shmem_page_size_kb_; }
set_shmem_page_size_kb(uint32_t value)16123   void set_shmem_page_size_kb(uint32_t value) { shmem_page_size_kb_ = value; _has_field_.set(3); }
16124 
has_num_processes() const16125   bool has_num_processes() const { return _has_field_[4]; }
num_processes() const16126   uint32_t num_processes() const { return num_processes_; }
set_num_processes(uint32_t value)16127   void set_num_processes(uint32_t value) { num_processes_ = value; _has_field_.set(4); }
16128 
has_num_threads() const16129   bool has_num_threads() const { return _has_field_[5]; }
num_threads() const16130   uint32_t num_threads() const { return num_threads_; }
set_num_threads(uint32_t value)16131   void set_num_threads(uint32_t value) { num_threads_ = value; _has_field_.set(5); }
16132 
has_max_events() const16133   bool has_max_events() const { return _has_field_[6]; }
max_events() const16134   uint32_t max_events() const { return max_events_; }
set_max_events(uint32_t value)16135   void set_max_events(uint32_t value) { max_events_ = value; _has_field_.set(6); }
16136 
has_nesting() const16137   bool has_nesting() const { return _has_field_[7]; }
nesting() const16138   uint32_t nesting() const { return nesting_; }
set_nesting(uint32_t value)16139   void set_nesting(uint32_t value) { nesting_ = value; _has_field_.set(7); }
16140 
has_steady_state_timings() const16141   bool has_steady_state_timings() const { return _has_field_[8]; }
steady_state_timings() const16142   const StressTestConfig_WriterTiming& steady_state_timings() const { return *steady_state_timings_; }
mutable_steady_state_timings()16143   StressTestConfig_WriterTiming* mutable_steady_state_timings() { _has_field_.set(8); return steady_state_timings_.get(); }
16144 
has_burst_period_ms() const16145   bool has_burst_period_ms() const { return _has_field_[9]; }
burst_period_ms() const16146   uint32_t burst_period_ms() const { return burst_period_ms_; }
set_burst_period_ms(uint32_t value)16147   void set_burst_period_ms(uint32_t value) { burst_period_ms_ = value; _has_field_.set(9); }
16148 
has_burst_duration_ms() const16149   bool has_burst_duration_ms() const { return _has_field_[10]; }
burst_duration_ms() const16150   uint32_t burst_duration_ms() const { return burst_duration_ms_; }
set_burst_duration_ms(uint32_t value)16151   void set_burst_duration_ms(uint32_t value) { burst_duration_ms_ = value; _has_field_.set(10); }
16152 
has_burst_timings() const16153   bool has_burst_timings() const { return _has_field_[11]; }
burst_timings() const16154   const StressTestConfig_WriterTiming& burst_timings() const { return *burst_timings_; }
mutable_burst_timings()16155   StressTestConfig_WriterTiming* mutable_burst_timings() { _has_field_.set(11); return burst_timings_.get(); }
16156 
16157  private:
16158   ::protozero::CopyablePtr<TraceConfig> trace_config_;
16159   uint32_t shmem_size_kb_{};
16160   uint32_t shmem_page_size_kb_{};
16161   uint32_t num_processes_{};
16162   uint32_t num_threads_{};
16163   uint32_t max_events_{};
16164   uint32_t nesting_{};
16165   ::protozero::CopyablePtr<StressTestConfig_WriterTiming> steady_state_timings_;
16166   uint32_t burst_period_ms_{};
16167   uint32_t burst_duration_ms_{};
16168   ::protozero::CopyablePtr<StressTestConfig_WriterTiming> burst_timings_;
16169 
16170   // Allows to preserve unknown protobuf fields for compatibility
16171   // with future versions of .proto files.
16172   std::string unknown_fields_;
16173 
16174   std::bitset<12> _has_field_{};
16175 };
16176 
16177 
16178 class PERFETTO_EXPORT StressTestConfig_WriterTiming : public ::protozero::CppMessageObj {
16179  public:
16180   enum FieldNumbers {
16181     kPayloadMeanFieldNumber = 1,
16182     kPayloadStddevFieldNumber = 2,
16183     kRateMeanFieldNumber = 3,
16184     kRateStddevFieldNumber = 4,
16185     kPayloadWriteTimeMsFieldNumber = 5,
16186   };
16187 
16188   StressTestConfig_WriterTiming();
16189   ~StressTestConfig_WriterTiming() override;
16190   StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept;
16191   StressTestConfig_WriterTiming& operator=(StressTestConfig_WriterTiming&&);
16192   StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&);
16193   StressTestConfig_WriterTiming& operator=(const StressTestConfig_WriterTiming&);
16194   bool operator==(const StressTestConfig_WriterTiming&) const;
operator !=(const StressTestConfig_WriterTiming & other) const16195   bool operator!=(const StressTestConfig_WriterTiming& other) const { return !(*this == other); }
16196 
16197   bool ParseFromArray(const void*, size_t) override;
16198   std::string SerializeAsString() const override;
16199   std::vector<uint8_t> SerializeAsArray() const override;
16200   void Serialize(::protozero::Message*) const;
16201 
has_payload_mean() const16202   bool has_payload_mean() const { return _has_field_[1]; }
payload_mean() const16203   double payload_mean() const { return payload_mean_; }
set_payload_mean(double value)16204   void set_payload_mean(double value) { payload_mean_ = value; _has_field_.set(1); }
16205 
has_payload_stddev() const16206   bool has_payload_stddev() const { return _has_field_[2]; }
payload_stddev() const16207   double payload_stddev() const { return payload_stddev_; }
set_payload_stddev(double value)16208   void set_payload_stddev(double value) { payload_stddev_ = value; _has_field_.set(2); }
16209 
has_rate_mean() const16210   bool has_rate_mean() const { return _has_field_[3]; }
rate_mean() const16211   double rate_mean() const { return rate_mean_; }
set_rate_mean(double value)16212   void set_rate_mean(double value) { rate_mean_ = value; _has_field_.set(3); }
16213 
has_rate_stddev() const16214   bool has_rate_stddev() const { return _has_field_[4]; }
rate_stddev() const16215   double rate_stddev() const { return rate_stddev_; }
set_rate_stddev(double value)16216   void set_rate_stddev(double value) { rate_stddev_ = value; _has_field_.set(4); }
16217 
has_payload_write_time_ms() const16218   bool has_payload_write_time_ms() const { return _has_field_[5]; }
payload_write_time_ms() const16219   uint32_t payload_write_time_ms() const { return payload_write_time_ms_; }
set_payload_write_time_ms(uint32_t value)16220   void set_payload_write_time_ms(uint32_t value) { payload_write_time_ms_ = value; _has_field_.set(5); }
16221 
16222  private:
16223   double payload_mean_{};
16224   double payload_stddev_{};
16225   double rate_mean_{};
16226   double rate_stddev_{};
16227   uint32_t payload_write_time_ms_{};
16228 
16229   // Allows to preserve unknown protobuf fields for compatibility
16230   // with future versions of .proto files.
16231   std::string unknown_fields_;
16232 
16233   std::bitset<6> _has_field_{};
16234 };
16235 
16236 }  // namespace perfetto
16237 }  // namespace protos
16238 }  // namespace gen
16239 
16240 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
16241 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16242 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16243 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16244 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16245 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16246 #pragma GCC diagnostic push
16247 #pragma GCC diagnostic ignored "-Wfloat-equal"
16248 // gen_amalgamated expanded: #include "protos/perfetto/config/stress_test_config.gen.h"
16249 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
16250 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
16251 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
16252 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
16253 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
16254 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
16255 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
16256 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
16257 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
16258 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
16259 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
16260 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
16261 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
16262 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
16263 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
16264 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
16265 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
16266 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
16267 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
16268 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
16269 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
16270 
16271 namespace perfetto {
16272 namespace protos {
16273 namespace gen {
16274 
16275 StressTestConfig::StressTestConfig() = default;
16276 StressTestConfig::~StressTestConfig() = default;
16277 StressTestConfig::StressTestConfig(const StressTestConfig&) = default;
16278 StressTestConfig& StressTestConfig::operator=(const StressTestConfig&) = default;
16279 StressTestConfig::StressTestConfig(StressTestConfig&&) noexcept = default;
16280 StressTestConfig& StressTestConfig::operator=(StressTestConfig&&) = default;
16281 
operator ==(const StressTestConfig & other) const16282 bool StressTestConfig::operator==(const StressTestConfig& other) const {
16283   return unknown_fields_ == other.unknown_fields_
16284    && trace_config_ == other.trace_config_
16285    && shmem_size_kb_ == other.shmem_size_kb_
16286    && shmem_page_size_kb_ == other.shmem_page_size_kb_
16287    && num_processes_ == other.num_processes_
16288    && num_threads_ == other.num_threads_
16289    && max_events_ == other.max_events_
16290    && nesting_ == other.nesting_
16291    && steady_state_timings_ == other.steady_state_timings_
16292    && burst_period_ms_ == other.burst_period_ms_
16293    && burst_duration_ms_ == other.burst_duration_ms_
16294    && burst_timings_ == other.burst_timings_;
16295 }
16296 
ParseFromArray(const void * raw,size_t size)16297 bool StressTestConfig::ParseFromArray(const void* raw, size_t size) {
16298   unknown_fields_.clear();
16299   bool packed_error = false;
16300 
16301   ::protozero::ProtoDecoder dec(raw, size);
16302   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16303     if (field.id() < _has_field_.size()) {
16304       _has_field_.set(field.id());
16305     }
16306     switch (field.id()) {
16307       case 1 /* trace_config */:
16308         (*trace_config_).ParseFromString(field.as_std_string());
16309         break;
16310       case 2 /* shmem_size_kb */:
16311         field.get(&shmem_size_kb_);
16312         break;
16313       case 3 /* shmem_page_size_kb */:
16314         field.get(&shmem_page_size_kb_);
16315         break;
16316       case 4 /* num_processes */:
16317         field.get(&num_processes_);
16318         break;
16319       case 5 /* num_threads */:
16320         field.get(&num_threads_);
16321         break;
16322       case 6 /* max_events */:
16323         field.get(&max_events_);
16324         break;
16325       case 7 /* nesting */:
16326         field.get(&nesting_);
16327         break;
16328       case 8 /* steady_state_timings */:
16329         (*steady_state_timings_).ParseFromString(field.as_std_string());
16330         break;
16331       case 9 /* burst_period_ms */:
16332         field.get(&burst_period_ms_);
16333         break;
16334       case 10 /* burst_duration_ms */:
16335         field.get(&burst_duration_ms_);
16336         break;
16337       case 11 /* burst_timings */:
16338         (*burst_timings_).ParseFromString(field.as_std_string());
16339         break;
16340       default:
16341         field.SerializeAndAppendTo(&unknown_fields_);
16342         break;
16343     }
16344   }
16345   return !packed_error && !dec.bytes_left();
16346 }
16347 
SerializeAsString() const16348 std::string StressTestConfig::SerializeAsString() const {
16349   ::protozero::HeapBuffered<::protozero::Message> msg;
16350   Serialize(msg.get());
16351   return msg.SerializeAsString();
16352 }
16353 
SerializeAsArray() const16354 std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
16355   ::protozero::HeapBuffered<::protozero::Message> msg;
16356   Serialize(msg.get());
16357   return msg.SerializeAsArray();
16358 }
16359 
Serialize(::protozero::Message * msg) const16360 void StressTestConfig::Serialize(::protozero::Message* msg) const {
16361   // Field 1: trace_config
16362   if (_has_field_[1]) {
16363     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
16364   }
16365 
16366   // Field 2: shmem_size_kb
16367   if (_has_field_[2]) {
16368     msg->AppendVarInt(2, shmem_size_kb_);
16369   }
16370 
16371   // Field 3: shmem_page_size_kb
16372   if (_has_field_[3]) {
16373     msg->AppendVarInt(3, shmem_page_size_kb_);
16374   }
16375 
16376   // Field 4: num_processes
16377   if (_has_field_[4]) {
16378     msg->AppendVarInt(4, num_processes_);
16379   }
16380 
16381   // Field 5: num_threads
16382   if (_has_field_[5]) {
16383     msg->AppendVarInt(5, num_threads_);
16384   }
16385 
16386   // Field 6: max_events
16387   if (_has_field_[6]) {
16388     msg->AppendVarInt(6, max_events_);
16389   }
16390 
16391   // Field 7: nesting
16392   if (_has_field_[7]) {
16393     msg->AppendVarInt(7, nesting_);
16394   }
16395 
16396   // Field 8: steady_state_timings
16397   if (_has_field_[8]) {
16398     (*steady_state_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
16399   }
16400 
16401   // Field 9: burst_period_ms
16402   if (_has_field_[9]) {
16403     msg->AppendVarInt(9, burst_period_ms_);
16404   }
16405 
16406   // Field 10: burst_duration_ms
16407   if (_has_field_[10]) {
16408     msg->AppendVarInt(10, burst_duration_ms_);
16409   }
16410 
16411   // Field 11: burst_timings
16412   if (_has_field_[11]) {
16413     (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
16414   }
16415 
16416   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16417 }
16418 
16419 
16420 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming() = default;
16421 StressTestConfig_WriterTiming::~StressTestConfig_WriterTiming() = default;
16422 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&) = default;
16423 StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(const StressTestConfig_WriterTiming&) = default;
16424 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept = default;
16425 StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(StressTestConfig_WriterTiming&&) = default;
16426 
operator ==(const StressTestConfig_WriterTiming & other) const16427 bool StressTestConfig_WriterTiming::operator==(const StressTestConfig_WriterTiming& other) const {
16428   return unknown_fields_ == other.unknown_fields_
16429    && payload_mean_ == other.payload_mean_
16430    && payload_stddev_ == other.payload_stddev_
16431    && rate_mean_ == other.rate_mean_
16432    && rate_stddev_ == other.rate_stddev_
16433    && payload_write_time_ms_ == other.payload_write_time_ms_;
16434 }
16435 
ParseFromArray(const void * raw,size_t size)16436 bool StressTestConfig_WriterTiming::ParseFromArray(const void* raw, size_t size) {
16437   unknown_fields_.clear();
16438   bool packed_error = false;
16439 
16440   ::protozero::ProtoDecoder dec(raw, size);
16441   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16442     if (field.id() < _has_field_.size()) {
16443       _has_field_.set(field.id());
16444     }
16445     switch (field.id()) {
16446       case 1 /* payload_mean */:
16447         field.get(&payload_mean_);
16448         break;
16449       case 2 /* payload_stddev */:
16450         field.get(&payload_stddev_);
16451         break;
16452       case 3 /* rate_mean */:
16453         field.get(&rate_mean_);
16454         break;
16455       case 4 /* rate_stddev */:
16456         field.get(&rate_stddev_);
16457         break;
16458       case 5 /* payload_write_time_ms */:
16459         field.get(&payload_write_time_ms_);
16460         break;
16461       default:
16462         field.SerializeAndAppendTo(&unknown_fields_);
16463         break;
16464     }
16465   }
16466   return !packed_error && !dec.bytes_left();
16467 }
16468 
SerializeAsString() const16469 std::string StressTestConfig_WriterTiming::SerializeAsString() const {
16470   ::protozero::HeapBuffered<::protozero::Message> msg;
16471   Serialize(msg.get());
16472   return msg.SerializeAsString();
16473 }
16474 
SerializeAsArray() const16475 std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
16476   ::protozero::HeapBuffered<::protozero::Message> msg;
16477   Serialize(msg.get());
16478   return msg.SerializeAsArray();
16479 }
16480 
Serialize(::protozero::Message * msg) const16481 void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
16482   // Field 1: payload_mean
16483   if (_has_field_[1]) {
16484     msg->AppendFixed(1, payload_mean_);
16485   }
16486 
16487   // Field 2: payload_stddev
16488   if (_has_field_[2]) {
16489     msg->AppendFixed(2, payload_stddev_);
16490   }
16491 
16492   // Field 3: rate_mean
16493   if (_has_field_[3]) {
16494     msg->AppendFixed(3, rate_mean_);
16495   }
16496 
16497   // Field 4: rate_stddev
16498   if (_has_field_[4]) {
16499     msg->AppendFixed(4, rate_stddev_);
16500   }
16501 
16502   // Field 5: payload_write_time_ms
16503   if (_has_field_[5]) {
16504     msg->AppendVarInt(5, payload_write_time_ms_);
16505   }
16506 
16507   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16508 }
16509 
16510 }  // namespace perfetto
16511 }  // namespace protos
16512 }  // namespace gen
16513 #pragma GCC diagnostic pop
16514 // gen_amalgamated begin source: gen/protos/perfetto/config/test_config.gen.cc
16515 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16516 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16517 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16518 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16519 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16520 #pragma GCC diagnostic push
16521 #pragma GCC diagnostic ignored "-Wfloat-equal"
16522 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
16523 
16524 namespace perfetto {
16525 namespace protos {
16526 namespace gen {
16527 
16528 TestConfig::TestConfig() = default;
16529 TestConfig::~TestConfig() = default;
16530 TestConfig::TestConfig(const TestConfig&) = default;
16531 TestConfig& TestConfig::operator=(const TestConfig&) = default;
16532 TestConfig::TestConfig(TestConfig&&) noexcept = default;
16533 TestConfig& TestConfig::operator=(TestConfig&&) = default;
16534 
operator ==(const TestConfig & other) const16535 bool TestConfig::operator==(const TestConfig& other) const {
16536   return unknown_fields_ == other.unknown_fields_
16537    && message_count_ == other.message_count_
16538    && max_messages_per_second_ == other.max_messages_per_second_
16539    && seed_ == other.seed_
16540    && message_size_ == other.message_size_
16541    && send_batch_on_register_ == other.send_batch_on_register_
16542    && dummy_fields_ == other.dummy_fields_;
16543 }
16544 
ParseFromArray(const void * raw,size_t size)16545 bool TestConfig::ParseFromArray(const void* raw, size_t size) {
16546   unknown_fields_.clear();
16547   bool packed_error = false;
16548 
16549   ::protozero::ProtoDecoder dec(raw, size);
16550   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16551     if (field.id() < _has_field_.size()) {
16552       _has_field_.set(field.id());
16553     }
16554     switch (field.id()) {
16555       case 1 /* message_count */:
16556         field.get(&message_count_);
16557         break;
16558       case 2 /* max_messages_per_second */:
16559         field.get(&max_messages_per_second_);
16560         break;
16561       case 3 /* seed */:
16562         field.get(&seed_);
16563         break;
16564       case 4 /* message_size */:
16565         field.get(&message_size_);
16566         break;
16567       case 5 /* send_batch_on_register */:
16568         field.get(&send_batch_on_register_);
16569         break;
16570       case 6 /* dummy_fields */:
16571         (*dummy_fields_).ParseFromString(field.as_std_string());
16572         break;
16573       default:
16574         field.SerializeAndAppendTo(&unknown_fields_);
16575         break;
16576     }
16577   }
16578   return !packed_error && !dec.bytes_left();
16579 }
16580 
SerializeAsString() const16581 std::string TestConfig::SerializeAsString() const {
16582   ::protozero::HeapBuffered<::protozero::Message> msg;
16583   Serialize(msg.get());
16584   return msg.SerializeAsString();
16585 }
16586 
SerializeAsArray() const16587 std::vector<uint8_t> TestConfig::SerializeAsArray() const {
16588   ::protozero::HeapBuffered<::protozero::Message> msg;
16589   Serialize(msg.get());
16590   return msg.SerializeAsArray();
16591 }
16592 
Serialize(::protozero::Message * msg) const16593 void TestConfig::Serialize(::protozero::Message* msg) const {
16594   // Field 1: message_count
16595   if (_has_field_[1]) {
16596     msg->AppendVarInt(1, message_count_);
16597   }
16598 
16599   // Field 2: max_messages_per_second
16600   if (_has_field_[2]) {
16601     msg->AppendVarInt(2, max_messages_per_second_);
16602   }
16603 
16604   // Field 3: seed
16605   if (_has_field_[3]) {
16606     msg->AppendVarInt(3, seed_);
16607   }
16608 
16609   // Field 4: message_size
16610   if (_has_field_[4]) {
16611     msg->AppendVarInt(4, message_size_);
16612   }
16613 
16614   // Field 5: send_batch_on_register
16615   if (_has_field_[5]) {
16616     msg->AppendTinyVarInt(5, send_batch_on_register_);
16617   }
16618 
16619   // Field 6: dummy_fields
16620   if (_has_field_[6]) {
16621     (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
16622   }
16623 
16624   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16625 }
16626 
16627 
16628 TestConfig_DummyFields::TestConfig_DummyFields() = default;
16629 TestConfig_DummyFields::~TestConfig_DummyFields() = default;
16630 TestConfig_DummyFields::TestConfig_DummyFields(const TestConfig_DummyFields&) = default;
16631 TestConfig_DummyFields& TestConfig_DummyFields::operator=(const TestConfig_DummyFields&) = default;
16632 TestConfig_DummyFields::TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept = default;
16633 TestConfig_DummyFields& TestConfig_DummyFields::operator=(TestConfig_DummyFields&&) = default;
16634 
operator ==(const TestConfig_DummyFields & other) const16635 bool TestConfig_DummyFields::operator==(const TestConfig_DummyFields& other) const {
16636   return unknown_fields_ == other.unknown_fields_
16637    && field_uint32_ == other.field_uint32_
16638    && field_int32_ == other.field_int32_
16639    && field_uint64_ == other.field_uint64_
16640    && field_int64_ == other.field_int64_
16641    && field_fixed64_ == other.field_fixed64_
16642    && field_sfixed64_ == other.field_sfixed64_
16643    && field_fixed32_ == other.field_fixed32_
16644    && field_sfixed32_ == other.field_sfixed32_
16645    && field_double_ == other.field_double_
16646    && field_float_ == other.field_float_
16647    && field_sint64_ == other.field_sint64_
16648    && field_sint32_ == other.field_sint32_
16649    && field_string_ == other.field_string_
16650    && field_bytes_ == other.field_bytes_;
16651 }
16652 
ParseFromArray(const void * raw,size_t size)16653 bool TestConfig_DummyFields::ParseFromArray(const void* raw, size_t size) {
16654   unknown_fields_.clear();
16655   bool packed_error = false;
16656 
16657   ::protozero::ProtoDecoder dec(raw, size);
16658   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16659     if (field.id() < _has_field_.size()) {
16660       _has_field_.set(field.id());
16661     }
16662     switch (field.id()) {
16663       case 1 /* field_uint32 */:
16664         field.get(&field_uint32_);
16665         break;
16666       case 2 /* field_int32 */:
16667         field.get(&field_int32_);
16668         break;
16669       case 3 /* field_uint64 */:
16670         field.get(&field_uint64_);
16671         break;
16672       case 4 /* field_int64 */:
16673         field.get(&field_int64_);
16674         break;
16675       case 5 /* field_fixed64 */:
16676         field.get(&field_fixed64_);
16677         break;
16678       case 6 /* field_sfixed64 */:
16679         field.get(&field_sfixed64_);
16680         break;
16681       case 7 /* field_fixed32 */:
16682         field.get(&field_fixed32_);
16683         break;
16684       case 8 /* field_sfixed32 */:
16685         field.get(&field_sfixed32_);
16686         break;
16687       case 9 /* field_double */:
16688         field.get(&field_double_);
16689         break;
16690       case 10 /* field_float */:
16691         field.get(&field_float_);
16692         break;
16693       case 11 /* field_sint64 */:
16694         field.get_signed(&field_sint64_);
16695         break;
16696       case 12 /* field_sint32 */:
16697         field.get_signed(&field_sint32_);
16698         break;
16699       case 13 /* field_string */:
16700         field.get(&field_string_);
16701         break;
16702       case 14 /* field_bytes */:
16703         field.get(&field_bytes_);
16704         break;
16705       default:
16706         field.SerializeAndAppendTo(&unknown_fields_);
16707         break;
16708     }
16709   }
16710   return !packed_error && !dec.bytes_left();
16711 }
16712 
SerializeAsString() const16713 std::string TestConfig_DummyFields::SerializeAsString() const {
16714   ::protozero::HeapBuffered<::protozero::Message> msg;
16715   Serialize(msg.get());
16716   return msg.SerializeAsString();
16717 }
16718 
SerializeAsArray() const16719 std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
16720   ::protozero::HeapBuffered<::protozero::Message> msg;
16721   Serialize(msg.get());
16722   return msg.SerializeAsArray();
16723 }
16724 
Serialize(::protozero::Message * msg) const16725 void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
16726   // Field 1: field_uint32
16727   if (_has_field_[1]) {
16728     msg->AppendVarInt(1, field_uint32_);
16729   }
16730 
16731   // Field 2: field_int32
16732   if (_has_field_[2]) {
16733     msg->AppendVarInt(2, field_int32_);
16734   }
16735 
16736   // Field 3: field_uint64
16737   if (_has_field_[3]) {
16738     msg->AppendVarInt(3, field_uint64_);
16739   }
16740 
16741   // Field 4: field_int64
16742   if (_has_field_[4]) {
16743     msg->AppendVarInt(4, field_int64_);
16744   }
16745 
16746   // Field 5: field_fixed64
16747   if (_has_field_[5]) {
16748     msg->AppendFixed(5, field_fixed64_);
16749   }
16750 
16751   // Field 6: field_sfixed64
16752   if (_has_field_[6]) {
16753     msg->AppendFixed(6, field_sfixed64_);
16754   }
16755 
16756   // Field 7: field_fixed32
16757   if (_has_field_[7]) {
16758     msg->AppendFixed(7, field_fixed32_);
16759   }
16760 
16761   // Field 8: field_sfixed32
16762   if (_has_field_[8]) {
16763     msg->AppendFixed(8, field_sfixed32_);
16764   }
16765 
16766   // Field 9: field_double
16767   if (_has_field_[9]) {
16768     msg->AppendFixed(9, field_double_);
16769   }
16770 
16771   // Field 10: field_float
16772   if (_has_field_[10]) {
16773     msg->AppendFixed(10, field_float_);
16774   }
16775 
16776   // Field 11: field_sint64
16777   if (_has_field_[11]) {
16778     msg->AppendSignedVarInt(11, field_sint64_);
16779   }
16780 
16781   // Field 12: field_sint32
16782   if (_has_field_[12]) {
16783     msg->AppendSignedVarInt(12, field_sint32_);
16784   }
16785 
16786   // Field 13: field_string
16787   if (_has_field_[13]) {
16788     msg->AppendString(13, field_string_);
16789   }
16790 
16791   // Field 14: field_bytes
16792   if (_has_field_[14]) {
16793     msg->AppendString(14, field_bytes_);
16794   }
16795 
16796   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16797 }
16798 
16799 }  // namespace perfetto
16800 }  // namespace protos
16801 }  // namespace gen
16802 #pragma GCC diagnostic pop
16803 // gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.gen.cc
16804 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16805 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16806 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16807 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16808 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16809 #pragma GCC diagnostic push
16810 #pragma GCC diagnostic ignored "-Wfloat-equal"
16811 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
16812 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
16813 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
16814 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
16815 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
16816 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
16817 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
16818 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
16819 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
16820 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
16821 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
16822 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
16823 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
16824 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
16825 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
16826 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
16827 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
16828 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
16829 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
16830 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
16831 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
16832 
16833 namespace perfetto {
16834 namespace protos {
16835 namespace gen {
16836 
16837 TraceConfig::TraceConfig() = default;
16838 TraceConfig::~TraceConfig() = default;
16839 TraceConfig::TraceConfig(const TraceConfig&) = default;
16840 TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
16841 TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
16842 TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
16843 
operator ==(const TraceConfig & other) const16844 bool TraceConfig::operator==(const TraceConfig& other) const {
16845   return unknown_fields_ == other.unknown_fields_
16846    && buffers_ == other.buffers_
16847    && data_sources_ == other.data_sources_
16848    && builtin_data_sources_ == other.builtin_data_sources_
16849    && duration_ms_ == other.duration_ms_
16850    && enable_extra_guardrails_ == other.enable_extra_guardrails_
16851    && lockdown_mode_ == other.lockdown_mode_
16852    && producers_ == other.producers_
16853    && statsd_metadata_ == other.statsd_metadata_
16854    && write_into_file_ == other.write_into_file_
16855    && output_path_ == other.output_path_
16856    && file_write_period_ms_ == other.file_write_period_ms_
16857    && max_file_size_bytes_ == other.max_file_size_bytes_
16858    && guardrail_overrides_ == other.guardrail_overrides_
16859    && deferred_start_ == other.deferred_start_
16860    && flush_period_ms_ == other.flush_period_ms_
16861    && flush_timeout_ms_ == other.flush_timeout_ms_
16862    && data_source_stop_timeout_ms_ == other.data_source_stop_timeout_ms_
16863    && notify_traceur_ == other.notify_traceur_
16864    && trigger_config_ == other.trigger_config_
16865    && activate_triggers_ == other.activate_triggers_
16866    && incremental_state_config_ == other.incremental_state_config_
16867    && allow_user_build_tracing_ == other.allow_user_build_tracing_
16868    && unique_session_name_ == other.unique_session_name_
16869    && compression_type_ == other.compression_type_
16870    && incident_report_config_ == other.incident_report_config_
16871    && trace_uuid_msb_ == other.trace_uuid_msb_
16872    && trace_uuid_lsb_ == other.trace_uuid_lsb_;
16873 }
16874 
ParseFromArray(const void * raw,size_t size)16875 bool TraceConfig::ParseFromArray(const void* raw, size_t size) {
16876   buffers_.clear();
16877   data_sources_.clear();
16878   producers_.clear();
16879   activate_triggers_.clear();
16880   unknown_fields_.clear();
16881   bool packed_error = false;
16882 
16883   ::protozero::ProtoDecoder dec(raw, size);
16884   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16885     if (field.id() < _has_field_.size()) {
16886       _has_field_.set(field.id());
16887     }
16888     switch (field.id()) {
16889       case 1 /* buffers */:
16890         buffers_.emplace_back();
16891         buffers_.back().ParseFromString(field.as_std_string());
16892         break;
16893       case 2 /* data_sources */:
16894         data_sources_.emplace_back();
16895         data_sources_.back().ParseFromString(field.as_std_string());
16896         break;
16897       case 20 /* builtin_data_sources */:
16898         (*builtin_data_sources_).ParseFromString(field.as_std_string());
16899         break;
16900       case 3 /* duration_ms */:
16901         field.get(&duration_ms_);
16902         break;
16903       case 4 /* enable_extra_guardrails */:
16904         field.get(&enable_extra_guardrails_);
16905         break;
16906       case 5 /* lockdown_mode */:
16907         field.get(&lockdown_mode_);
16908         break;
16909       case 6 /* producers */:
16910         producers_.emplace_back();
16911         producers_.back().ParseFromString(field.as_std_string());
16912         break;
16913       case 7 /* statsd_metadata */:
16914         (*statsd_metadata_).ParseFromString(field.as_std_string());
16915         break;
16916       case 8 /* write_into_file */:
16917         field.get(&write_into_file_);
16918         break;
16919       case 29 /* output_path */:
16920         field.get(&output_path_);
16921         break;
16922       case 9 /* file_write_period_ms */:
16923         field.get(&file_write_period_ms_);
16924         break;
16925       case 10 /* max_file_size_bytes */:
16926         field.get(&max_file_size_bytes_);
16927         break;
16928       case 11 /* guardrail_overrides */:
16929         (*guardrail_overrides_).ParseFromString(field.as_std_string());
16930         break;
16931       case 12 /* deferred_start */:
16932         field.get(&deferred_start_);
16933         break;
16934       case 13 /* flush_period_ms */:
16935         field.get(&flush_period_ms_);
16936         break;
16937       case 14 /* flush_timeout_ms */:
16938         field.get(&flush_timeout_ms_);
16939         break;
16940       case 23 /* data_source_stop_timeout_ms */:
16941         field.get(&data_source_stop_timeout_ms_);
16942         break;
16943       case 16 /* notify_traceur */:
16944         field.get(&notify_traceur_);
16945         break;
16946       case 17 /* trigger_config */:
16947         (*trigger_config_).ParseFromString(field.as_std_string());
16948         break;
16949       case 18 /* activate_triggers */:
16950         activate_triggers_.emplace_back();
16951         field.get(&activate_triggers_.back());
16952         break;
16953       case 21 /* incremental_state_config */:
16954         (*incremental_state_config_).ParseFromString(field.as_std_string());
16955         break;
16956       case 19 /* allow_user_build_tracing */:
16957         field.get(&allow_user_build_tracing_);
16958         break;
16959       case 22 /* unique_session_name */:
16960         field.get(&unique_session_name_);
16961         break;
16962       case 24 /* compression_type */:
16963         field.get(&compression_type_);
16964         break;
16965       case 25 /* incident_report_config */:
16966         (*incident_report_config_).ParseFromString(field.as_std_string());
16967         break;
16968       case 27 /* trace_uuid_msb */:
16969         field.get(&trace_uuid_msb_);
16970         break;
16971       case 28 /* trace_uuid_lsb */:
16972         field.get(&trace_uuid_lsb_);
16973         break;
16974       default:
16975         field.SerializeAndAppendTo(&unknown_fields_);
16976         break;
16977     }
16978   }
16979   return !packed_error && !dec.bytes_left();
16980 }
16981 
SerializeAsString() const16982 std::string TraceConfig::SerializeAsString() const {
16983   ::protozero::HeapBuffered<::protozero::Message> msg;
16984   Serialize(msg.get());
16985   return msg.SerializeAsString();
16986 }
16987 
SerializeAsArray() const16988 std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
16989   ::protozero::HeapBuffered<::protozero::Message> msg;
16990   Serialize(msg.get());
16991   return msg.SerializeAsArray();
16992 }
16993 
Serialize(::protozero::Message * msg) const16994 void TraceConfig::Serialize(::protozero::Message* msg) const {
16995   // Field 1: buffers
16996   for (auto& it : buffers_) {
16997     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
16998   }
16999 
17000   // Field 2: data_sources
17001   for (auto& it : data_sources_) {
17002     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
17003   }
17004 
17005   // Field 20: builtin_data_sources
17006   if (_has_field_[20]) {
17007     (*builtin_data_sources_).Serialize(msg->BeginNestedMessage<::protozero::Message>(20));
17008   }
17009 
17010   // Field 3: duration_ms
17011   if (_has_field_[3]) {
17012     msg->AppendVarInt(3, duration_ms_);
17013   }
17014 
17015   // Field 4: enable_extra_guardrails
17016   if (_has_field_[4]) {
17017     msg->AppendTinyVarInt(4, enable_extra_guardrails_);
17018   }
17019 
17020   // Field 5: lockdown_mode
17021   if (_has_field_[5]) {
17022     msg->AppendVarInt(5, lockdown_mode_);
17023   }
17024 
17025   // Field 6: producers
17026   for (auto& it : producers_) {
17027     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
17028   }
17029 
17030   // Field 7: statsd_metadata
17031   if (_has_field_[7]) {
17032     (*statsd_metadata_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
17033   }
17034 
17035   // Field 8: write_into_file
17036   if (_has_field_[8]) {
17037     msg->AppendTinyVarInt(8, write_into_file_);
17038   }
17039 
17040   // Field 29: output_path
17041   if (_has_field_[29]) {
17042     msg->AppendString(29, output_path_);
17043   }
17044 
17045   // Field 9: file_write_period_ms
17046   if (_has_field_[9]) {
17047     msg->AppendVarInt(9, file_write_period_ms_);
17048   }
17049 
17050   // Field 10: max_file_size_bytes
17051   if (_has_field_[10]) {
17052     msg->AppendVarInt(10, max_file_size_bytes_);
17053   }
17054 
17055   // Field 11: guardrail_overrides
17056   if (_has_field_[11]) {
17057     (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
17058   }
17059 
17060   // Field 12: deferred_start
17061   if (_has_field_[12]) {
17062     msg->AppendTinyVarInt(12, deferred_start_);
17063   }
17064 
17065   // Field 13: flush_period_ms
17066   if (_has_field_[13]) {
17067     msg->AppendVarInt(13, flush_period_ms_);
17068   }
17069 
17070   // Field 14: flush_timeout_ms
17071   if (_has_field_[14]) {
17072     msg->AppendVarInt(14, flush_timeout_ms_);
17073   }
17074 
17075   // Field 23: data_source_stop_timeout_ms
17076   if (_has_field_[23]) {
17077     msg->AppendVarInt(23, data_source_stop_timeout_ms_);
17078   }
17079 
17080   // Field 16: notify_traceur
17081   if (_has_field_[16]) {
17082     msg->AppendTinyVarInt(16, notify_traceur_);
17083   }
17084 
17085   // Field 17: trigger_config
17086   if (_has_field_[17]) {
17087     (*trigger_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
17088   }
17089 
17090   // Field 18: activate_triggers
17091   for (auto& it : activate_triggers_) {
17092     msg->AppendString(18, it);
17093   }
17094 
17095   // Field 21: incremental_state_config
17096   if (_has_field_[21]) {
17097     (*incremental_state_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
17098   }
17099 
17100   // Field 19: allow_user_build_tracing
17101   if (_has_field_[19]) {
17102     msg->AppendTinyVarInt(19, allow_user_build_tracing_);
17103   }
17104 
17105   // Field 22: unique_session_name
17106   if (_has_field_[22]) {
17107     msg->AppendString(22, unique_session_name_);
17108   }
17109 
17110   // Field 24: compression_type
17111   if (_has_field_[24]) {
17112     msg->AppendVarInt(24, compression_type_);
17113   }
17114 
17115   // Field 25: incident_report_config
17116   if (_has_field_[25]) {
17117     (*incident_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
17118   }
17119 
17120   // Field 27: trace_uuid_msb
17121   if (_has_field_[27]) {
17122     msg->AppendVarInt(27, trace_uuid_msb_);
17123   }
17124 
17125   // Field 28: trace_uuid_lsb
17126   if (_has_field_[28]) {
17127     msg->AppendVarInt(28, trace_uuid_lsb_);
17128   }
17129 
17130   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17131 }
17132 
17133 
17134 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig() = default;
17135 TraceConfig_IncidentReportConfig::~TraceConfig_IncidentReportConfig() = default;
17136 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&) = default;
17137 TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(const TraceConfig_IncidentReportConfig&) = default;
17138 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept = default;
17139 TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(TraceConfig_IncidentReportConfig&&) = default;
17140 
operator ==(const TraceConfig_IncidentReportConfig & other) const17141 bool TraceConfig_IncidentReportConfig::operator==(const TraceConfig_IncidentReportConfig& other) const {
17142   return unknown_fields_ == other.unknown_fields_
17143    && destination_package_ == other.destination_package_
17144    && destination_class_ == other.destination_class_
17145    && privacy_level_ == other.privacy_level_
17146    && skip_dropbox_ == other.skip_dropbox_;
17147 }
17148 
ParseFromArray(const void * raw,size_t size)17149 bool TraceConfig_IncidentReportConfig::ParseFromArray(const void* raw, size_t size) {
17150   unknown_fields_.clear();
17151   bool packed_error = false;
17152 
17153   ::protozero::ProtoDecoder dec(raw, size);
17154   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17155     if (field.id() < _has_field_.size()) {
17156       _has_field_.set(field.id());
17157     }
17158     switch (field.id()) {
17159       case 1 /* destination_package */:
17160         field.get(&destination_package_);
17161         break;
17162       case 2 /* destination_class */:
17163         field.get(&destination_class_);
17164         break;
17165       case 3 /* privacy_level */:
17166         field.get(&privacy_level_);
17167         break;
17168       case 4 /* skip_dropbox */:
17169         field.get(&skip_dropbox_);
17170         break;
17171       default:
17172         field.SerializeAndAppendTo(&unknown_fields_);
17173         break;
17174     }
17175   }
17176   return !packed_error && !dec.bytes_left();
17177 }
17178 
SerializeAsString() const17179 std::string TraceConfig_IncidentReportConfig::SerializeAsString() const {
17180   ::protozero::HeapBuffered<::protozero::Message> msg;
17181   Serialize(msg.get());
17182   return msg.SerializeAsString();
17183 }
17184 
SerializeAsArray() const17185 std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
17186   ::protozero::HeapBuffered<::protozero::Message> msg;
17187   Serialize(msg.get());
17188   return msg.SerializeAsArray();
17189 }
17190 
Serialize(::protozero::Message * msg) const17191 void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
17192   // Field 1: destination_package
17193   if (_has_field_[1]) {
17194     msg->AppendString(1, destination_package_);
17195   }
17196 
17197   // Field 2: destination_class
17198   if (_has_field_[2]) {
17199     msg->AppendString(2, destination_class_);
17200   }
17201 
17202   // Field 3: privacy_level
17203   if (_has_field_[3]) {
17204     msg->AppendVarInt(3, privacy_level_);
17205   }
17206 
17207   // Field 4: skip_dropbox
17208   if (_has_field_[4]) {
17209     msg->AppendTinyVarInt(4, skip_dropbox_);
17210   }
17211 
17212   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17213 }
17214 
17215 
17216 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig() = default;
17217 TraceConfig_IncrementalStateConfig::~TraceConfig_IncrementalStateConfig() = default;
17218 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&) = default;
17219 TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(const TraceConfig_IncrementalStateConfig&) = default;
17220 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept = default;
17221 TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(TraceConfig_IncrementalStateConfig&&) = default;
17222 
operator ==(const TraceConfig_IncrementalStateConfig & other) const17223 bool TraceConfig_IncrementalStateConfig::operator==(const TraceConfig_IncrementalStateConfig& other) const {
17224   return unknown_fields_ == other.unknown_fields_
17225    && clear_period_ms_ == other.clear_period_ms_;
17226 }
17227 
ParseFromArray(const void * raw,size_t size)17228 bool TraceConfig_IncrementalStateConfig::ParseFromArray(const void* raw, size_t size) {
17229   unknown_fields_.clear();
17230   bool packed_error = false;
17231 
17232   ::protozero::ProtoDecoder dec(raw, size);
17233   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17234     if (field.id() < _has_field_.size()) {
17235       _has_field_.set(field.id());
17236     }
17237     switch (field.id()) {
17238       case 1 /* clear_period_ms */:
17239         field.get(&clear_period_ms_);
17240         break;
17241       default:
17242         field.SerializeAndAppendTo(&unknown_fields_);
17243         break;
17244     }
17245   }
17246   return !packed_error && !dec.bytes_left();
17247 }
17248 
SerializeAsString() const17249 std::string TraceConfig_IncrementalStateConfig::SerializeAsString() const {
17250   ::protozero::HeapBuffered<::protozero::Message> msg;
17251   Serialize(msg.get());
17252   return msg.SerializeAsString();
17253 }
17254 
SerializeAsArray() const17255 std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
17256   ::protozero::HeapBuffered<::protozero::Message> msg;
17257   Serialize(msg.get());
17258   return msg.SerializeAsArray();
17259 }
17260 
Serialize(::protozero::Message * msg) const17261 void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
17262   // Field 1: clear_period_ms
17263   if (_has_field_[1]) {
17264     msg->AppendVarInt(1, clear_period_ms_);
17265   }
17266 
17267   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17268 }
17269 
17270 
17271 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig() = default;
17272 TraceConfig_TriggerConfig::~TraceConfig_TriggerConfig() = default;
17273 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&) = default;
17274 TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(const TraceConfig_TriggerConfig&) = default;
17275 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept = default;
17276 TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(TraceConfig_TriggerConfig&&) = default;
17277 
operator ==(const TraceConfig_TriggerConfig & other) const17278 bool TraceConfig_TriggerConfig::operator==(const TraceConfig_TriggerConfig& other) const {
17279   return unknown_fields_ == other.unknown_fields_
17280    && trigger_mode_ == other.trigger_mode_
17281    && triggers_ == other.triggers_
17282    && trigger_timeout_ms_ == other.trigger_timeout_ms_;
17283 }
17284 
ParseFromArray(const void * raw,size_t size)17285 bool TraceConfig_TriggerConfig::ParseFromArray(const void* raw, size_t size) {
17286   triggers_.clear();
17287   unknown_fields_.clear();
17288   bool packed_error = false;
17289 
17290   ::protozero::ProtoDecoder dec(raw, size);
17291   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17292     if (field.id() < _has_field_.size()) {
17293       _has_field_.set(field.id());
17294     }
17295     switch (field.id()) {
17296       case 1 /* trigger_mode */:
17297         field.get(&trigger_mode_);
17298         break;
17299       case 2 /* triggers */:
17300         triggers_.emplace_back();
17301         triggers_.back().ParseFromString(field.as_std_string());
17302         break;
17303       case 3 /* trigger_timeout_ms */:
17304         field.get(&trigger_timeout_ms_);
17305         break;
17306       default:
17307         field.SerializeAndAppendTo(&unknown_fields_);
17308         break;
17309     }
17310   }
17311   return !packed_error && !dec.bytes_left();
17312 }
17313 
SerializeAsString() const17314 std::string TraceConfig_TriggerConfig::SerializeAsString() const {
17315   ::protozero::HeapBuffered<::protozero::Message> msg;
17316   Serialize(msg.get());
17317   return msg.SerializeAsString();
17318 }
17319 
SerializeAsArray() const17320 std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
17321   ::protozero::HeapBuffered<::protozero::Message> msg;
17322   Serialize(msg.get());
17323   return msg.SerializeAsArray();
17324 }
17325 
Serialize(::protozero::Message * msg) const17326 void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
17327   // Field 1: trigger_mode
17328   if (_has_field_[1]) {
17329     msg->AppendVarInt(1, trigger_mode_);
17330   }
17331 
17332   // Field 2: triggers
17333   for (auto& it : triggers_) {
17334     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
17335   }
17336 
17337   // Field 3: trigger_timeout_ms
17338   if (_has_field_[3]) {
17339     msg->AppendVarInt(3, trigger_timeout_ms_);
17340   }
17341 
17342   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17343 }
17344 
17345 
17346 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger() = default;
17347 TraceConfig_TriggerConfig_Trigger::~TraceConfig_TriggerConfig_Trigger() = default;
17348 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&) = default;
17349 TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(const TraceConfig_TriggerConfig_Trigger&) = default;
17350 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept = default;
17351 TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(TraceConfig_TriggerConfig_Trigger&&) = default;
17352 
operator ==(const TraceConfig_TriggerConfig_Trigger & other) const17353 bool TraceConfig_TriggerConfig_Trigger::operator==(const TraceConfig_TriggerConfig_Trigger& other) const {
17354   return unknown_fields_ == other.unknown_fields_
17355    && name_ == other.name_
17356    && producer_name_regex_ == other.producer_name_regex_
17357    && stop_delay_ms_ == other.stop_delay_ms_;
17358 }
17359 
ParseFromArray(const void * raw,size_t size)17360 bool TraceConfig_TriggerConfig_Trigger::ParseFromArray(const void* raw, size_t size) {
17361   unknown_fields_.clear();
17362   bool packed_error = false;
17363 
17364   ::protozero::ProtoDecoder dec(raw, size);
17365   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17366     if (field.id() < _has_field_.size()) {
17367       _has_field_.set(field.id());
17368     }
17369     switch (field.id()) {
17370       case 1 /* name */:
17371         field.get(&name_);
17372         break;
17373       case 2 /* producer_name_regex */:
17374         field.get(&producer_name_regex_);
17375         break;
17376       case 3 /* stop_delay_ms */:
17377         field.get(&stop_delay_ms_);
17378         break;
17379       default:
17380         field.SerializeAndAppendTo(&unknown_fields_);
17381         break;
17382     }
17383   }
17384   return !packed_error && !dec.bytes_left();
17385 }
17386 
SerializeAsString() const17387 std::string TraceConfig_TriggerConfig_Trigger::SerializeAsString() const {
17388   ::protozero::HeapBuffered<::protozero::Message> msg;
17389   Serialize(msg.get());
17390   return msg.SerializeAsString();
17391 }
17392 
SerializeAsArray() const17393 std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
17394   ::protozero::HeapBuffered<::protozero::Message> msg;
17395   Serialize(msg.get());
17396   return msg.SerializeAsArray();
17397 }
17398 
Serialize(::protozero::Message * msg) const17399 void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
17400   // Field 1: name
17401   if (_has_field_[1]) {
17402     msg->AppendString(1, name_);
17403   }
17404 
17405   // Field 2: producer_name_regex
17406   if (_has_field_[2]) {
17407     msg->AppendString(2, producer_name_regex_);
17408   }
17409 
17410   // Field 3: stop_delay_ms
17411   if (_has_field_[3]) {
17412     msg->AppendVarInt(3, stop_delay_ms_);
17413   }
17414 
17415   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17416 }
17417 
17418 
17419 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides() = default;
17420 TraceConfig_GuardrailOverrides::~TraceConfig_GuardrailOverrides() = default;
17421 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&) = default;
17422 TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(const TraceConfig_GuardrailOverrides&) = default;
17423 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept = default;
17424 TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(TraceConfig_GuardrailOverrides&&) = default;
17425 
operator ==(const TraceConfig_GuardrailOverrides & other) const17426 bool TraceConfig_GuardrailOverrides::operator==(const TraceConfig_GuardrailOverrides& other) const {
17427   return unknown_fields_ == other.unknown_fields_
17428    && max_upload_per_day_bytes_ == other.max_upload_per_day_bytes_;
17429 }
17430 
ParseFromArray(const void * raw,size_t size)17431 bool TraceConfig_GuardrailOverrides::ParseFromArray(const void* raw, size_t size) {
17432   unknown_fields_.clear();
17433   bool packed_error = false;
17434 
17435   ::protozero::ProtoDecoder dec(raw, size);
17436   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17437     if (field.id() < _has_field_.size()) {
17438       _has_field_.set(field.id());
17439     }
17440     switch (field.id()) {
17441       case 1 /* max_upload_per_day_bytes */:
17442         field.get(&max_upload_per_day_bytes_);
17443         break;
17444       default:
17445         field.SerializeAndAppendTo(&unknown_fields_);
17446         break;
17447     }
17448   }
17449   return !packed_error && !dec.bytes_left();
17450 }
17451 
SerializeAsString() const17452 std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
17453   ::protozero::HeapBuffered<::protozero::Message> msg;
17454   Serialize(msg.get());
17455   return msg.SerializeAsString();
17456 }
17457 
SerializeAsArray() const17458 std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
17459   ::protozero::HeapBuffered<::protozero::Message> msg;
17460   Serialize(msg.get());
17461   return msg.SerializeAsArray();
17462 }
17463 
Serialize(::protozero::Message * msg) const17464 void TraceConfig_GuardrailOverrides::Serialize(::protozero::Message* msg) const {
17465   // Field 1: max_upload_per_day_bytes
17466   if (_has_field_[1]) {
17467     msg->AppendVarInt(1, max_upload_per_day_bytes_);
17468   }
17469 
17470   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17471 }
17472 
17473 
17474 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata() = default;
17475 TraceConfig_StatsdMetadata::~TraceConfig_StatsdMetadata() = default;
17476 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&) = default;
17477 TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(const TraceConfig_StatsdMetadata&) = default;
17478 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept = default;
17479 TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(TraceConfig_StatsdMetadata&&) = default;
17480 
operator ==(const TraceConfig_StatsdMetadata & other) const17481 bool TraceConfig_StatsdMetadata::operator==(const TraceConfig_StatsdMetadata& other) const {
17482   return unknown_fields_ == other.unknown_fields_
17483    && triggering_alert_id_ == other.triggering_alert_id_
17484    && triggering_config_uid_ == other.triggering_config_uid_
17485    && triggering_config_id_ == other.triggering_config_id_
17486    && triggering_subscription_id_ == other.triggering_subscription_id_;
17487 }
17488 
ParseFromArray(const void * raw,size_t size)17489 bool TraceConfig_StatsdMetadata::ParseFromArray(const void* raw, size_t size) {
17490   unknown_fields_.clear();
17491   bool packed_error = false;
17492 
17493   ::protozero::ProtoDecoder dec(raw, size);
17494   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17495     if (field.id() < _has_field_.size()) {
17496       _has_field_.set(field.id());
17497     }
17498     switch (field.id()) {
17499       case 1 /* triggering_alert_id */:
17500         field.get(&triggering_alert_id_);
17501         break;
17502       case 2 /* triggering_config_uid */:
17503         field.get(&triggering_config_uid_);
17504         break;
17505       case 3 /* triggering_config_id */:
17506         field.get(&triggering_config_id_);
17507         break;
17508       case 4 /* triggering_subscription_id */:
17509         field.get(&triggering_subscription_id_);
17510         break;
17511       default:
17512         field.SerializeAndAppendTo(&unknown_fields_);
17513         break;
17514     }
17515   }
17516   return !packed_error && !dec.bytes_left();
17517 }
17518 
SerializeAsString() const17519 std::string TraceConfig_StatsdMetadata::SerializeAsString() const {
17520   ::protozero::HeapBuffered<::protozero::Message> msg;
17521   Serialize(msg.get());
17522   return msg.SerializeAsString();
17523 }
17524 
SerializeAsArray() const17525 std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
17526   ::protozero::HeapBuffered<::protozero::Message> msg;
17527   Serialize(msg.get());
17528   return msg.SerializeAsArray();
17529 }
17530 
Serialize(::protozero::Message * msg) const17531 void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
17532   // Field 1: triggering_alert_id
17533   if (_has_field_[1]) {
17534     msg->AppendVarInt(1, triggering_alert_id_);
17535   }
17536 
17537   // Field 2: triggering_config_uid
17538   if (_has_field_[2]) {
17539     msg->AppendVarInt(2, triggering_config_uid_);
17540   }
17541 
17542   // Field 3: triggering_config_id
17543   if (_has_field_[3]) {
17544     msg->AppendVarInt(3, triggering_config_id_);
17545   }
17546 
17547   // Field 4: triggering_subscription_id
17548   if (_has_field_[4]) {
17549     msg->AppendVarInt(4, triggering_subscription_id_);
17550   }
17551 
17552   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17553 }
17554 
17555 
17556 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig() = default;
17557 TraceConfig_ProducerConfig::~TraceConfig_ProducerConfig() = default;
17558 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&) = default;
17559 TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(const TraceConfig_ProducerConfig&) = default;
17560 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept = default;
17561 TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(TraceConfig_ProducerConfig&&) = default;
17562 
operator ==(const TraceConfig_ProducerConfig & other) const17563 bool TraceConfig_ProducerConfig::operator==(const TraceConfig_ProducerConfig& other) const {
17564   return unknown_fields_ == other.unknown_fields_
17565    && producer_name_ == other.producer_name_
17566    && shm_size_kb_ == other.shm_size_kb_
17567    && page_size_kb_ == other.page_size_kb_;
17568 }
17569 
ParseFromArray(const void * raw,size_t size)17570 bool TraceConfig_ProducerConfig::ParseFromArray(const void* raw, size_t size) {
17571   unknown_fields_.clear();
17572   bool packed_error = false;
17573 
17574   ::protozero::ProtoDecoder dec(raw, size);
17575   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17576     if (field.id() < _has_field_.size()) {
17577       _has_field_.set(field.id());
17578     }
17579     switch (field.id()) {
17580       case 1 /* producer_name */:
17581         field.get(&producer_name_);
17582         break;
17583       case 2 /* shm_size_kb */:
17584         field.get(&shm_size_kb_);
17585         break;
17586       case 3 /* page_size_kb */:
17587         field.get(&page_size_kb_);
17588         break;
17589       default:
17590         field.SerializeAndAppendTo(&unknown_fields_);
17591         break;
17592     }
17593   }
17594   return !packed_error && !dec.bytes_left();
17595 }
17596 
SerializeAsString() const17597 std::string TraceConfig_ProducerConfig::SerializeAsString() const {
17598   ::protozero::HeapBuffered<::protozero::Message> msg;
17599   Serialize(msg.get());
17600   return msg.SerializeAsString();
17601 }
17602 
SerializeAsArray() const17603 std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
17604   ::protozero::HeapBuffered<::protozero::Message> msg;
17605   Serialize(msg.get());
17606   return msg.SerializeAsArray();
17607 }
17608 
Serialize(::protozero::Message * msg) const17609 void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
17610   // Field 1: producer_name
17611   if (_has_field_[1]) {
17612     msg->AppendString(1, producer_name_);
17613   }
17614 
17615   // Field 2: shm_size_kb
17616   if (_has_field_[2]) {
17617     msg->AppendVarInt(2, shm_size_kb_);
17618   }
17619 
17620   // Field 3: page_size_kb
17621   if (_has_field_[3]) {
17622     msg->AppendVarInt(3, page_size_kb_);
17623   }
17624 
17625   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17626 }
17627 
17628 
17629 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource() = default;
17630 TraceConfig_BuiltinDataSource::~TraceConfig_BuiltinDataSource() = default;
17631 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&) = default;
17632 TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(const TraceConfig_BuiltinDataSource&) = default;
17633 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept = default;
17634 TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(TraceConfig_BuiltinDataSource&&) = default;
17635 
operator ==(const TraceConfig_BuiltinDataSource & other) const17636 bool TraceConfig_BuiltinDataSource::operator==(const TraceConfig_BuiltinDataSource& other) const {
17637   return unknown_fields_ == other.unknown_fields_
17638    && disable_clock_snapshotting_ == other.disable_clock_snapshotting_
17639    && disable_trace_config_ == other.disable_trace_config_
17640    && disable_system_info_ == other.disable_system_info_
17641    && disable_service_events_ == other.disable_service_events_
17642    && primary_trace_clock_ == other.primary_trace_clock_
17643    && snapshot_interval_ms_ == other.snapshot_interval_ms_;
17644 }
17645 
ParseFromArray(const void * raw,size_t size)17646 bool TraceConfig_BuiltinDataSource::ParseFromArray(const void* raw, size_t size) {
17647   unknown_fields_.clear();
17648   bool packed_error = false;
17649 
17650   ::protozero::ProtoDecoder dec(raw, size);
17651   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17652     if (field.id() < _has_field_.size()) {
17653       _has_field_.set(field.id());
17654     }
17655     switch (field.id()) {
17656       case 1 /* disable_clock_snapshotting */:
17657         field.get(&disable_clock_snapshotting_);
17658         break;
17659       case 2 /* disable_trace_config */:
17660         field.get(&disable_trace_config_);
17661         break;
17662       case 3 /* disable_system_info */:
17663         field.get(&disable_system_info_);
17664         break;
17665       case 4 /* disable_service_events */:
17666         field.get(&disable_service_events_);
17667         break;
17668       case 5 /* primary_trace_clock */:
17669         field.get(&primary_trace_clock_);
17670         break;
17671       case 6 /* snapshot_interval_ms */:
17672         field.get(&snapshot_interval_ms_);
17673         break;
17674       default:
17675         field.SerializeAndAppendTo(&unknown_fields_);
17676         break;
17677     }
17678   }
17679   return !packed_error && !dec.bytes_left();
17680 }
17681 
SerializeAsString() const17682 std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
17683   ::protozero::HeapBuffered<::protozero::Message> msg;
17684   Serialize(msg.get());
17685   return msg.SerializeAsString();
17686 }
17687 
SerializeAsArray() const17688 std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
17689   ::protozero::HeapBuffered<::protozero::Message> msg;
17690   Serialize(msg.get());
17691   return msg.SerializeAsArray();
17692 }
17693 
Serialize(::protozero::Message * msg) const17694 void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
17695   // Field 1: disable_clock_snapshotting
17696   if (_has_field_[1]) {
17697     msg->AppendTinyVarInt(1, disable_clock_snapshotting_);
17698   }
17699 
17700   // Field 2: disable_trace_config
17701   if (_has_field_[2]) {
17702     msg->AppendTinyVarInt(2, disable_trace_config_);
17703   }
17704 
17705   // Field 3: disable_system_info
17706   if (_has_field_[3]) {
17707     msg->AppendTinyVarInt(3, disable_system_info_);
17708   }
17709 
17710   // Field 4: disable_service_events
17711   if (_has_field_[4]) {
17712     msg->AppendTinyVarInt(4, disable_service_events_);
17713   }
17714 
17715   // Field 5: primary_trace_clock
17716   if (_has_field_[5]) {
17717     msg->AppendVarInt(5, primary_trace_clock_);
17718   }
17719 
17720   // Field 6: snapshot_interval_ms
17721   if (_has_field_[6]) {
17722     msg->AppendVarInt(6, snapshot_interval_ms_);
17723   }
17724 
17725   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17726 }
17727 
17728 
17729 TraceConfig_DataSource::TraceConfig_DataSource() = default;
17730 TraceConfig_DataSource::~TraceConfig_DataSource() = default;
17731 TraceConfig_DataSource::TraceConfig_DataSource(const TraceConfig_DataSource&) = default;
17732 TraceConfig_DataSource& TraceConfig_DataSource::operator=(const TraceConfig_DataSource&) = default;
17733 TraceConfig_DataSource::TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept = default;
17734 TraceConfig_DataSource& TraceConfig_DataSource::operator=(TraceConfig_DataSource&&) = default;
17735 
operator ==(const TraceConfig_DataSource & other) const17736 bool TraceConfig_DataSource::operator==(const TraceConfig_DataSource& other) const {
17737   return unknown_fields_ == other.unknown_fields_
17738    && config_ == other.config_
17739    && producer_name_filter_ == other.producer_name_filter_
17740    && producer_name_regex_filter_ == other.producer_name_regex_filter_;
17741 }
17742 
ParseFromArray(const void * raw,size_t size)17743 bool TraceConfig_DataSource::ParseFromArray(const void* raw, size_t size) {
17744   producer_name_filter_.clear();
17745   producer_name_regex_filter_.clear();
17746   unknown_fields_.clear();
17747   bool packed_error = false;
17748 
17749   ::protozero::ProtoDecoder dec(raw, size);
17750   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17751     if (field.id() < _has_field_.size()) {
17752       _has_field_.set(field.id());
17753     }
17754     switch (field.id()) {
17755       case 1 /* config */:
17756         (*config_).ParseFromString(field.as_std_string());
17757         break;
17758       case 2 /* producer_name_filter */:
17759         producer_name_filter_.emplace_back();
17760         field.get(&producer_name_filter_.back());
17761         break;
17762       case 3 /* producer_name_regex_filter */:
17763         producer_name_regex_filter_.emplace_back();
17764         field.get(&producer_name_regex_filter_.back());
17765         break;
17766       default:
17767         field.SerializeAndAppendTo(&unknown_fields_);
17768         break;
17769     }
17770   }
17771   return !packed_error && !dec.bytes_left();
17772 }
17773 
SerializeAsString() const17774 std::string TraceConfig_DataSource::SerializeAsString() const {
17775   ::protozero::HeapBuffered<::protozero::Message> msg;
17776   Serialize(msg.get());
17777   return msg.SerializeAsString();
17778 }
17779 
SerializeAsArray() const17780 std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
17781   ::protozero::HeapBuffered<::protozero::Message> msg;
17782   Serialize(msg.get());
17783   return msg.SerializeAsArray();
17784 }
17785 
Serialize(::protozero::Message * msg) const17786 void TraceConfig_DataSource::Serialize(::protozero::Message* msg) const {
17787   // Field 1: config
17788   if (_has_field_[1]) {
17789     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
17790   }
17791 
17792   // Field 2: producer_name_filter
17793   for (auto& it : producer_name_filter_) {
17794     msg->AppendString(2, it);
17795   }
17796 
17797   // Field 3: producer_name_regex_filter
17798   for (auto& it : producer_name_regex_filter_) {
17799     msg->AppendString(3, it);
17800   }
17801 
17802   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17803 }
17804 
17805 
17806 TraceConfig_BufferConfig::TraceConfig_BufferConfig() = default;
17807 TraceConfig_BufferConfig::~TraceConfig_BufferConfig() = default;
17808 TraceConfig_BufferConfig::TraceConfig_BufferConfig(const TraceConfig_BufferConfig&) = default;
17809 TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(const TraceConfig_BufferConfig&) = default;
17810 TraceConfig_BufferConfig::TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept = default;
17811 TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(TraceConfig_BufferConfig&&) = default;
17812 
operator ==(const TraceConfig_BufferConfig & other) const17813 bool TraceConfig_BufferConfig::operator==(const TraceConfig_BufferConfig& other) const {
17814   return unknown_fields_ == other.unknown_fields_
17815    && size_kb_ == other.size_kb_
17816    && fill_policy_ == other.fill_policy_;
17817 }
17818 
ParseFromArray(const void * raw,size_t size)17819 bool TraceConfig_BufferConfig::ParseFromArray(const void* raw, size_t size) {
17820   unknown_fields_.clear();
17821   bool packed_error = false;
17822 
17823   ::protozero::ProtoDecoder dec(raw, size);
17824   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17825     if (field.id() < _has_field_.size()) {
17826       _has_field_.set(field.id());
17827     }
17828     switch (field.id()) {
17829       case 1 /* size_kb */:
17830         field.get(&size_kb_);
17831         break;
17832       case 4 /* fill_policy */:
17833         field.get(&fill_policy_);
17834         break;
17835       default:
17836         field.SerializeAndAppendTo(&unknown_fields_);
17837         break;
17838     }
17839   }
17840   return !packed_error && !dec.bytes_left();
17841 }
17842 
SerializeAsString() const17843 std::string TraceConfig_BufferConfig::SerializeAsString() const {
17844   ::protozero::HeapBuffered<::protozero::Message> msg;
17845   Serialize(msg.get());
17846   return msg.SerializeAsString();
17847 }
17848 
SerializeAsArray() const17849 std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
17850   ::protozero::HeapBuffered<::protozero::Message> msg;
17851   Serialize(msg.get());
17852   return msg.SerializeAsArray();
17853 }
17854 
Serialize(::protozero::Message * msg) const17855 void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
17856   // Field 1: size_kb
17857   if (_has_field_[1]) {
17858     msg->AppendVarInt(1, size_kb_);
17859   }
17860 
17861   // Field 4: fill_policy
17862   if (_has_field_[4]) {
17863     msg->AppendVarInt(4, fill_policy_);
17864   }
17865 
17866   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17867 }
17868 
17869 }  // namespace perfetto
17870 }  // namespace protos
17871 }  // namespace gen
17872 #pragma GCC diagnostic pop
17873 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.pbzero.cc
17874 // Intentionally empty (crbug.com/998165)
17875 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.pbzero.cc
17876 // Intentionally empty (crbug.com/998165)
17877 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.pbzero.cc
17878 // Intentionally empty (crbug.com/998165)
17879 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.pbzero.cc
17880 // Intentionally empty (crbug.com/998165)
17881 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.pbzero.cc
17882 // Intentionally empty (crbug.com/998165)
17883 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc
17884 // Intentionally empty (crbug.com/998165)
17885 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.pbzero.cc
17886 // Intentionally empty (crbug.com/998165)
17887 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.pbzero.cc
17888 // Intentionally empty (crbug.com/998165)
17889 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.pbzero.cc
17890 // Intentionally empty (crbug.com/998165)
17891 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.cc
17892 // Intentionally empty (crbug.com/998165)
17893 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.pbzero.cc
17894 // Intentionally empty (crbug.com/998165)
17895 // gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.pbzero.cc
17896 // Intentionally empty (crbug.com/998165)
17897 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc
17898 // Intentionally empty (crbug.com/998165)
17899 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.cc
17900 // Intentionally empty (crbug.com/998165)
17901 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc
17902 // Intentionally empty (crbug.com/998165)
17903 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc
17904 // Intentionally empty (crbug.com/998165)
17905 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc
17906 // Intentionally empty (crbug.com/998165)
17907 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc
17908 // Intentionally empty (crbug.com/998165)
17909 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.cc
17910 // Intentionally empty (crbug.com/998165)
17911 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_common.pbzero.cc
17912 // Intentionally empty (crbug.com/998165)
17913 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.cc
17914 // Intentionally empty (crbug.com/998165)
17915 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/smaps.pbzero.cc
17916 // Intentionally empty (crbug.com/998165)
17917 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc
17918 // Intentionally empty (crbug.com/998165)
17919 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc
17920 // Intentionally empty (crbug.com/998165)
17921 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc
17922 // Intentionally empty (crbug.com/998165)
17923 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc
17924 // Intentionally empty (crbug.com/998165)
17925 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc
17926 // Intentionally empty (crbug.com/998165)
17927 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc
17928 // Intentionally empty (crbug.com/998165)
17929 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc
17930 // Intentionally empty (crbug.com/998165)
17931 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc
17932 // Intentionally empty (crbug.com/998165)
17933 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc
17934 // Intentionally empty (crbug.com/998165)
17935 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc
17936 // Intentionally empty (crbug.com/998165)
17937 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc
17938 // Intentionally empty (crbug.com/998165)
17939 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.pbzero.cc
17940 // Intentionally empty (crbug.com/998165)
17941 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc
17942 // Intentionally empty (crbug.com/998165)
17943 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.pbzero.cc
17944 // Intentionally empty (crbug.com/998165)
17945 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.pbzero.cc
17946 // Intentionally empty (crbug.com/998165)
17947 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc
17948 // Intentionally empty (crbug.com/998165)
17949 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc
17950 // Intentionally empty (crbug.com/998165)
17951 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.pbzero.cc
17952 // Intentionally empty (crbug.com/998165)
17953 // gen_amalgamated begin source: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.cc
17954 // Intentionally empty (crbug.com/998165)
17955 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc
17956 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h
17957 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17958 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
17959 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
17960 
17961 #include <stdint.h>
17962 #include <bitset>
17963 #include <vector>
17964 #include <string>
17965 #include <type_traits>
17966 
17967 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17968 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17969 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17970 
17971 namespace perfetto {
17972 namespace protos {
17973 namespace gen {
17974 class CompositorTimingHistory;
17975 class BeginFrameSourceState;
17976 class BeginFrameArgs;
17977 class SourceLocation;
17978 class BeginFrameObserverState;
17979 class BeginImplFrameArgs;
17980 class BeginImplFrameArgs_TimestampsInUs;
17981 class ChromeCompositorStateMachine;
17982 class ChromeCompositorStateMachine_MinorState;
17983 class ChromeCompositorStateMachine_MajorState;
17984 class ChromeCompositorSchedulerState;
17985 enum ChromeCompositorSchedulerAction : int;
17986 enum BeginFrameArgs_BeginFrameArgsType : int;
17987 enum BeginImplFrameArgs_State : int;
17988 enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
17989 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
17990 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
17991 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
17992 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
17993 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
17994 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
17995 }  // namespace perfetto
17996 }  // namespace protos
17997 }  // namespace gen
17998 
17999 namespace protozero {
18000 class Message;
18001 }  // namespace protozero
18002 
18003 namespace perfetto {
18004 namespace protos {
18005 namespace gen {
18006 enum ChromeCompositorSchedulerAction : int {
18007   CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
18008   CC_SCHEDULER_ACTION_NONE = 1,
18009   CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
18010   CC_SCHEDULER_ACTION_COMMIT = 3,
18011   CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
18012   CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
18013   CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
18014   CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
18015   CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
18016   CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
18017   CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
18018   CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
18019   CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
18020   CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
18021 };
18022 enum BeginFrameArgs_BeginFrameArgsType : int {
18023   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
18024   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
18025   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
18026   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
18027 };
18028 enum BeginImplFrameArgs_State : int {
18029   BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED = 0,
18030   BeginImplFrameArgs_State_BEGIN_FRAME_USING = 1,
18031 };
18032 enum ChromeCompositorStateMachine_MinorState_TreePriority : int {
18033   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED = 0,
18034   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
18035   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
18036   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
18037 };
18038 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int {
18039   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED = 0,
18040   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER = 1,
18041   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
18042 };
18043 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int {
18044   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
18045   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE = 1,
18046   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
18047   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
18048 };
18049 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int {
18050   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
18051   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE = 1,
18052   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT = 2,
18053   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
18054 };
18055 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int {
18056   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED = 0,
18057   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE = 1,
18058   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE = 2,
18059   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING = 3,
18060   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
18061   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
18062 };
18063 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int {
18064   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED = 0,
18065   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE = 1,
18066   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
18067   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
18068   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW = 4,
18069 };
18070 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int {
18071   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED = 0,
18072   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE = 1,
18073   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE = 2,
18074   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR = 3,
18075   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE = 4,
18076   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED = 5,
18077 };
18078 
18079 class PERFETTO_EXPORT CompositorTimingHistory : public ::protozero::CppMessageObj {
18080  public:
18081   enum FieldNumbers {
18082     kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
18083     kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
18084     kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
18085     kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
18086     kPrepareTilesEstimateDeltaUsFieldNumber = 5,
18087     kActivateEstimateDeltaUsFieldNumber = 6,
18088     kDrawEstimateDeltaUsFieldNumber = 7,
18089   };
18090 
18091   CompositorTimingHistory();
18092   ~CompositorTimingHistory() override;
18093   CompositorTimingHistory(CompositorTimingHistory&&) noexcept;
18094   CompositorTimingHistory& operator=(CompositorTimingHistory&&);
18095   CompositorTimingHistory(const CompositorTimingHistory&);
18096   CompositorTimingHistory& operator=(const CompositorTimingHistory&);
18097   bool operator==(const CompositorTimingHistory&) const;
operator !=(const CompositorTimingHistory & other) const18098   bool operator!=(const CompositorTimingHistory& other) const { return !(*this == other); }
18099 
18100   bool ParseFromArray(const void*, size_t) override;
18101   std::string SerializeAsString() const override;
18102   std::vector<uint8_t> SerializeAsArray() const override;
18103   void Serialize(::protozero::Message*) const;
18104 
has_begin_main_frame_queue_critical_estimate_delta_us() const18105   bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return _has_field_[1]; }
begin_main_frame_queue_critical_estimate_delta_us() const18106   int64_t begin_main_frame_queue_critical_estimate_delta_us() const { return begin_main_frame_queue_critical_estimate_delta_us_; }
set_begin_main_frame_queue_critical_estimate_delta_us(int64_t value)18107   void set_begin_main_frame_queue_critical_estimate_delta_us(int64_t value) { begin_main_frame_queue_critical_estimate_delta_us_ = value; _has_field_.set(1); }
18108 
has_begin_main_frame_queue_not_critical_estimate_delta_us() const18109   bool has_begin_main_frame_queue_not_critical_estimate_delta_us() const { return _has_field_[2]; }
begin_main_frame_queue_not_critical_estimate_delta_us() const18110   int64_t begin_main_frame_queue_not_critical_estimate_delta_us() const { return begin_main_frame_queue_not_critical_estimate_delta_us_; }
set_begin_main_frame_queue_not_critical_estimate_delta_us(int64_t value)18111   void set_begin_main_frame_queue_not_critical_estimate_delta_us(int64_t value) { begin_main_frame_queue_not_critical_estimate_delta_us_ = value; _has_field_.set(2); }
18112 
has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const18113   bool has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return _has_field_[3]; }
begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const18114   int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return begin_main_frame_start_to_ready_to_commit_estimate_delta_us_; }
set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(int64_t value)18115   void set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(int64_t value) { begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ = value; _has_field_.set(3); }
18116 
has_commit_to_ready_to_activate_estimate_delta_us() const18117   bool has_commit_to_ready_to_activate_estimate_delta_us() const { return _has_field_[4]; }
commit_to_ready_to_activate_estimate_delta_us() const18118   int64_t commit_to_ready_to_activate_estimate_delta_us() const { return commit_to_ready_to_activate_estimate_delta_us_; }
set_commit_to_ready_to_activate_estimate_delta_us(int64_t value)18119   void set_commit_to_ready_to_activate_estimate_delta_us(int64_t value) { commit_to_ready_to_activate_estimate_delta_us_ = value; _has_field_.set(4); }
18120 
has_prepare_tiles_estimate_delta_us() const18121   bool has_prepare_tiles_estimate_delta_us() const { return _has_field_[5]; }
prepare_tiles_estimate_delta_us() const18122   int64_t prepare_tiles_estimate_delta_us() const { return prepare_tiles_estimate_delta_us_; }
set_prepare_tiles_estimate_delta_us(int64_t value)18123   void set_prepare_tiles_estimate_delta_us(int64_t value) { prepare_tiles_estimate_delta_us_ = value; _has_field_.set(5); }
18124 
has_activate_estimate_delta_us() const18125   bool has_activate_estimate_delta_us() const { return _has_field_[6]; }
activate_estimate_delta_us() const18126   int64_t activate_estimate_delta_us() const { return activate_estimate_delta_us_; }
set_activate_estimate_delta_us(int64_t value)18127   void set_activate_estimate_delta_us(int64_t value) { activate_estimate_delta_us_ = value; _has_field_.set(6); }
18128 
has_draw_estimate_delta_us() const18129   bool has_draw_estimate_delta_us() const { return _has_field_[7]; }
draw_estimate_delta_us() const18130   int64_t draw_estimate_delta_us() const { return draw_estimate_delta_us_; }
set_draw_estimate_delta_us(int64_t value)18131   void set_draw_estimate_delta_us(int64_t value) { draw_estimate_delta_us_ = value; _has_field_.set(7); }
18132 
18133  private:
18134   int64_t begin_main_frame_queue_critical_estimate_delta_us_{};
18135   int64_t begin_main_frame_queue_not_critical_estimate_delta_us_{};
18136   int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us_{};
18137   int64_t commit_to_ready_to_activate_estimate_delta_us_{};
18138   int64_t prepare_tiles_estimate_delta_us_{};
18139   int64_t activate_estimate_delta_us_{};
18140   int64_t draw_estimate_delta_us_{};
18141 
18142   // Allows to preserve unknown protobuf fields for compatibility
18143   // with future versions of .proto files.
18144   std::string unknown_fields_;
18145 
18146   std::bitset<8> _has_field_{};
18147 };
18148 
18149 
18150 class PERFETTO_EXPORT BeginFrameSourceState : public ::protozero::CppMessageObj {
18151  public:
18152   enum FieldNumbers {
18153     kSourceIdFieldNumber = 1,
18154     kPausedFieldNumber = 2,
18155     kNumObserversFieldNumber = 3,
18156     kLastBeginFrameArgsFieldNumber = 4,
18157   };
18158 
18159   BeginFrameSourceState();
18160   ~BeginFrameSourceState() override;
18161   BeginFrameSourceState(BeginFrameSourceState&&) noexcept;
18162   BeginFrameSourceState& operator=(BeginFrameSourceState&&);
18163   BeginFrameSourceState(const BeginFrameSourceState&);
18164   BeginFrameSourceState& operator=(const BeginFrameSourceState&);
18165   bool operator==(const BeginFrameSourceState&) const;
operator !=(const BeginFrameSourceState & other) const18166   bool operator!=(const BeginFrameSourceState& other) const { return !(*this == other); }
18167 
18168   bool ParseFromArray(const void*, size_t) override;
18169   std::string SerializeAsString() const override;
18170   std::vector<uint8_t> SerializeAsArray() const override;
18171   void Serialize(::protozero::Message*) const;
18172 
has_source_id() const18173   bool has_source_id() const { return _has_field_[1]; }
source_id() const18174   uint32_t source_id() const { return source_id_; }
set_source_id(uint32_t value)18175   void set_source_id(uint32_t value) { source_id_ = value; _has_field_.set(1); }
18176 
has_paused() const18177   bool has_paused() const { return _has_field_[2]; }
paused() const18178   bool paused() const { return paused_; }
set_paused(bool value)18179   void set_paused(bool value) { paused_ = value; _has_field_.set(2); }
18180 
has_num_observers() const18181   bool has_num_observers() const { return _has_field_[3]; }
num_observers() const18182   uint32_t num_observers() const { return num_observers_; }
set_num_observers(uint32_t value)18183   void set_num_observers(uint32_t value) { num_observers_ = value; _has_field_.set(3); }
18184 
has_last_begin_frame_args() const18185   bool has_last_begin_frame_args() const { return _has_field_[4]; }
last_begin_frame_args() const18186   const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
mutable_last_begin_frame_args()18187   BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(4); return last_begin_frame_args_.get(); }
18188 
18189  private:
18190   uint32_t source_id_{};
18191   bool paused_{};
18192   uint32_t num_observers_{};
18193   ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
18194 
18195   // Allows to preserve unknown protobuf fields for compatibility
18196   // with future versions of .proto files.
18197   std::string unknown_fields_;
18198 
18199   std::bitset<5> _has_field_{};
18200 };
18201 
18202 
18203 class PERFETTO_EXPORT BeginFrameArgs : public ::protozero::CppMessageObj {
18204  public:
18205   using BeginFrameArgsType = BeginFrameArgs_BeginFrameArgsType;
18206   static constexpr auto BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
18207   static constexpr auto BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID;
18208   static constexpr auto BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL;
18209   static constexpr auto BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
18210   static constexpr auto BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
18211   static constexpr auto BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
18212   enum FieldNumbers {
18213     kTypeFieldNumber = 1,
18214     kSourceIdFieldNumber = 2,
18215     kSequenceNumberFieldNumber = 3,
18216     kFrameTimeUsFieldNumber = 4,
18217     kDeadlineUsFieldNumber = 5,
18218     kIntervalDeltaUsFieldNumber = 6,
18219     kOnCriticalPathFieldNumber = 7,
18220     kAnimateOnlyFieldNumber = 8,
18221     kSourceLocationIidFieldNumber = 9,
18222     kSourceLocationFieldNumber = 10,
18223   };
18224 
18225   BeginFrameArgs();
18226   ~BeginFrameArgs() override;
18227   BeginFrameArgs(BeginFrameArgs&&) noexcept;
18228   BeginFrameArgs& operator=(BeginFrameArgs&&);
18229   BeginFrameArgs(const BeginFrameArgs&);
18230   BeginFrameArgs& operator=(const BeginFrameArgs&);
18231   bool operator==(const BeginFrameArgs&) const;
operator !=(const BeginFrameArgs & other) const18232   bool operator!=(const BeginFrameArgs& other) const { return !(*this == other); }
18233 
18234   bool ParseFromArray(const void*, size_t) override;
18235   std::string SerializeAsString() const override;
18236   std::vector<uint8_t> SerializeAsArray() const override;
18237   void Serialize(::protozero::Message*) const;
18238 
has_type() const18239   bool has_type() const { return _has_field_[1]; }
type() const18240   BeginFrameArgs_BeginFrameArgsType type() const { return type_; }
set_type(BeginFrameArgs_BeginFrameArgsType value)18241   void set_type(BeginFrameArgs_BeginFrameArgsType value) { type_ = value; _has_field_.set(1); }
18242 
has_source_id() const18243   bool has_source_id() const { return _has_field_[2]; }
source_id() const18244   uint64_t source_id() const { return source_id_; }
set_source_id(uint64_t value)18245   void set_source_id(uint64_t value) { source_id_ = value; _has_field_.set(2); }
18246 
has_sequence_number() const18247   bool has_sequence_number() const { return _has_field_[3]; }
sequence_number() const18248   uint64_t sequence_number() const { return sequence_number_; }
set_sequence_number(uint64_t value)18249   void set_sequence_number(uint64_t value) { sequence_number_ = value; _has_field_.set(3); }
18250 
has_frame_time_us() const18251   bool has_frame_time_us() const { return _has_field_[4]; }
frame_time_us() const18252   int64_t frame_time_us() const { return frame_time_us_; }
set_frame_time_us(int64_t value)18253   void set_frame_time_us(int64_t value) { frame_time_us_ = value; _has_field_.set(4); }
18254 
has_deadline_us() const18255   bool has_deadline_us() const { return _has_field_[5]; }
deadline_us() const18256   int64_t deadline_us() const { return deadline_us_; }
set_deadline_us(int64_t value)18257   void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(5); }
18258 
has_interval_delta_us() const18259   bool has_interval_delta_us() const { return _has_field_[6]; }
interval_delta_us() const18260   int64_t interval_delta_us() const { return interval_delta_us_; }
set_interval_delta_us(int64_t value)18261   void set_interval_delta_us(int64_t value) { interval_delta_us_ = value; _has_field_.set(6); }
18262 
has_on_critical_path() const18263   bool has_on_critical_path() const { return _has_field_[7]; }
on_critical_path() const18264   bool on_critical_path() const { return on_critical_path_; }
set_on_critical_path(bool value)18265   void set_on_critical_path(bool value) { on_critical_path_ = value; _has_field_.set(7); }
18266 
has_animate_only() const18267   bool has_animate_only() const { return _has_field_[8]; }
animate_only() const18268   bool animate_only() const { return animate_only_; }
set_animate_only(bool value)18269   void set_animate_only(bool value) { animate_only_ = value; _has_field_.set(8); }
18270 
has_source_location_iid() const18271   bool has_source_location_iid() const { return _has_field_[9]; }
source_location_iid() const18272   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)18273   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(9); }
18274 
has_source_location() const18275   bool has_source_location() const { return _has_field_[10]; }
source_location() const18276   const SourceLocation& source_location() const { return *source_location_; }
mutable_source_location()18277   SourceLocation* mutable_source_location() { _has_field_.set(10); return source_location_.get(); }
18278 
18279  private:
18280   BeginFrameArgs_BeginFrameArgsType type_{};
18281   uint64_t source_id_{};
18282   uint64_t sequence_number_{};
18283   int64_t frame_time_us_{};
18284   int64_t deadline_us_{};
18285   int64_t interval_delta_us_{};
18286   bool on_critical_path_{};
18287   bool animate_only_{};
18288   uint64_t source_location_iid_{};
18289   ::protozero::CopyablePtr<SourceLocation> source_location_;
18290 
18291   // Allows to preserve unknown protobuf fields for compatibility
18292   // with future versions of .proto files.
18293   std::string unknown_fields_;
18294 
18295   std::bitset<11> _has_field_{};
18296 };
18297 
18298 
18299 class PERFETTO_EXPORT BeginFrameObserverState : public ::protozero::CppMessageObj {
18300  public:
18301   enum FieldNumbers {
18302     kDroppedBeginFrameArgsFieldNumber = 1,
18303     kLastBeginFrameArgsFieldNumber = 2,
18304   };
18305 
18306   BeginFrameObserverState();
18307   ~BeginFrameObserverState() override;
18308   BeginFrameObserverState(BeginFrameObserverState&&) noexcept;
18309   BeginFrameObserverState& operator=(BeginFrameObserverState&&);
18310   BeginFrameObserverState(const BeginFrameObserverState&);
18311   BeginFrameObserverState& operator=(const BeginFrameObserverState&);
18312   bool operator==(const BeginFrameObserverState&) const;
operator !=(const BeginFrameObserverState & other) const18313   bool operator!=(const BeginFrameObserverState& other) const { return !(*this == other); }
18314 
18315   bool ParseFromArray(const void*, size_t) override;
18316   std::string SerializeAsString() const override;
18317   std::vector<uint8_t> SerializeAsArray() const override;
18318   void Serialize(::protozero::Message*) const;
18319 
has_dropped_begin_frame_args() const18320   bool has_dropped_begin_frame_args() const { return _has_field_[1]; }
dropped_begin_frame_args() const18321   int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
set_dropped_begin_frame_args(int64_t value)18322   void set_dropped_begin_frame_args(int64_t value) { dropped_begin_frame_args_ = value; _has_field_.set(1); }
18323 
has_last_begin_frame_args() const18324   bool has_last_begin_frame_args() const { return _has_field_[2]; }
last_begin_frame_args() const18325   const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
mutable_last_begin_frame_args()18326   BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(2); return last_begin_frame_args_.get(); }
18327 
18328  private:
18329   int64_t dropped_begin_frame_args_{};
18330   ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
18331 
18332   // Allows to preserve unknown protobuf fields for compatibility
18333   // with future versions of .proto files.
18334   std::string unknown_fields_;
18335 
18336   std::bitset<3> _has_field_{};
18337 };
18338 
18339 
18340 class PERFETTO_EXPORT BeginImplFrameArgs : public ::protozero::CppMessageObj {
18341  public:
18342   using TimestampsInUs = BeginImplFrameArgs_TimestampsInUs;
18343   using State = BeginImplFrameArgs_State;
18344   static constexpr auto BEGIN_FRAME_FINISHED = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
18345   static constexpr auto BEGIN_FRAME_USING = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
18346   static constexpr auto State_MIN = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
18347   static constexpr auto State_MAX = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
18348   enum FieldNumbers {
18349     kUpdatedAtUsFieldNumber = 1,
18350     kFinishedAtUsFieldNumber = 2,
18351     kStateFieldNumber = 3,
18352     kCurrentArgsFieldNumber = 4,
18353     kLastArgsFieldNumber = 5,
18354     kTimestampsInUsFieldNumber = 6,
18355   };
18356 
18357   BeginImplFrameArgs();
18358   ~BeginImplFrameArgs() override;
18359   BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept;
18360   BeginImplFrameArgs& operator=(BeginImplFrameArgs&&);
18361   BeginImplFrameArgs(const BeginImplFrameArgs&);
18362   BeginImplFrameArgs& operator=(const BeginImplFrameArgs&);
18363   bool operator==(const BeginImplFrameArgs&) const;
operator !=(const BeginImplFrameArgs & other) const18364   bool operator!=(const BeginImplFrameArgs& other) const { return !(*this == other); }
18365 
18366   bool ParseFromArray(const void*, size_t) override;
18367   std::string SerializeAsString() const override;
18368   std::vector<uint8_t> SerializeAsArray() const override;
18369   void Serialize(::protozero::Message*) const;
18370 
has_updated_at_us() const18371   bool has_updated_at_us() const { return _has_field_[1]; }
updated_at_us() const18372   int64_t updated_at_us() const { return updated_at_us_; }
set_updated_at_us(int64_t value)18373   void set_updated_at_us(int64_t value) { updated_at_us_ = value; _has_field_.set(1); }
18374 
has_finished_at_us() const18375   bool has_finished_at_us() const { return _has_field_[2]; }
finished_at_us() const18376   int64_t finished_at_us() const { return finished_at_us_; }
set_finished_at_us(int64_t value)18377   void set_finished_at_us(int64_t value) { finished_at_us_ = value; _has_field_.set(2); }
18378 
has_state() const18379   bool has_state() const { return _has_field_[3]; }
state() const18380   BeginImplFrameArgs_State state() const { return state_; }
set_state(BeginImplFrameArgs_State value)18381   void set_state(BeginImplFrameArgs_State value) { state_ = value; _has_field_.set(3); }
18382 
has_current_args() const18383   bool has_current_args() const { return _has_field_[4]; }
current_args() const18384   const BeginFrameArgs& current_args() const { return *current_args_; }
mutable_current_args()18385   BeginFrameArgs* mutable_current_args() { _has_field_.set(4); return current_args_.get(); }
18386 
has_last_args() const18387   bool has_last_args() const { return _has_field_[5]; }
last_args() const18388   const BeginFrameArgs& last_args() const { return *last_args_; }
mutable_last_args()18389   BeginFrameArgs* mutable_last_args() { _has_field_.set(5); return last_args_.get(); }
18390 
has_timestamps_in_us() const18391   bool has_timestamps_in_us() const { return _has_field_[6]; }
timestamps_in_us() const18392   const BeginImplFrameArgs_TimestampsInUs& timestamps_in_us() const { return *timestamps_in_us_; }
mutable_timestamps_in_us()18393   BeginImplFrameArgs_TimestampsInUs* mutable_timestamps_in_us() { _has_field_.set(6); return timestamps_in_us_.get(); }
18394 
18395  private:
18396   int64_t updated_at_us_{};
18397   int64_t finished_at_us_{};
18398   BeginImplFrameArgs_State state_{};
18399   ::protozero::CopyablePtr<BeginFrameArgs> current_args_;
18400   ::protozero::CopyablePtr<BeginFrameArgs> last_args_;
18401   ::protozero::CopyablePtr<BeginImplFrameArgs_TimestampsInUs> timestamps_in_us_;
18402 
18403   // Allows to preserve unknown protobuf fields for compatibility
18404   // with future versions of .proto files.
18405   std::string unknown_fields_;
18406 
18407   std::bitset<7> _has_field_{};
18408 };
18409 
18410 
18411 class PERFETTO_EXPORT BeginImplFrameArgs_TimestampsInUs : public ::protozero::CppMessageObj {
18412  public:
18413   enum FieldNumbers {
18414     kIntervalDeltaFieldNumber = 1,
18415     kNowToDeadlineDeltaFieldNumber = 2,
18416     kFrameTimeToNowDeltaFieldNumber = 3,
18417     kFrameTimeToDeadlineDeltaFieldNumber = 4,
18418     kNowFieldNumber = 5,
18419     kFrameTimeFieldNumber = 6,
18420     kDeadlineFieldNumber = 7,
18421   };
18422 
18423   BeginImplFrameArgs_TimestampsInUs();
18424   ~BeginImplFrameArgs_TimestampsInUs() override;
18425   BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept;
18426   BeginImplFrameArgs_TimestampsInUs& operator=(BeginImplFrameArgs_TimestampsInUs&&);
18427   BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&);
18428   BeginImplFrameArgs_TimestampsInUs& operator=(const BeginImplFrameArgs_TimestampsInUs&);
18429   bool operator==(const BeginImplFrameArgs_TimestampsInUs&) const;
operator !=(const BeginImplFrameArgs_TimestampsInUs & other) const18430   bool operator!=(const BeginImplFrameArgs_TimestampsInUs& other) const { return !(*this == other); }
18431 
18432   bool ParseFromArray(const void*, size_t) override;
18433   std::string SerializeAsString() const override;
18434   std::vector<uint8_t> SerializeAsArray() const override;
18435   void Serialize(::protozero::Message*) const;
18436 
has_interval_delta() const18437   bool has_interval_delta() const { return _has_field_[1]; }
interval_delta() const18438   int64_t interval_delta() const { return interval_delta_; }
set_interval_delta(int64_t value)18439   void set_interval_delta(int64_t value) { interval_delta_ = value; _has_field_.set(1); }
18440 
has_now_to_deadline_delta() const18441   bool has_now_to_deadline_delta() const { return _has_field_[2]; }
now_to_deadline_delta() const18442   int64_t now_to_deadline_delta() const { return now_to_deadline_delta_; }
set_now_to_deadline_delta(int64_t value)18443   void set_now_to_deadline_delta(int64_t value) { now_to_deadline_delta_ = value; _has_field_.set(2); }
18444 
has_frame_time_to_now_delta() const18445   bool has_frame_time_to_now_delta() const { return _has_field_[3]; }
frame_time_to_now_delta() const18446   int64_t frame_time_to_now_delta() const { return frame_time_to_now_delta_; }
set_frame_time_to_now_delta(int64_t value)18447   void set_frame_time_to_now_delta(int64_t value) { frame_time_to_now_delta_ = value; _has_field_.set(3); }
18448 
has_frame_time_to_deadline_delta() const18449   bool has_frame_time_to_deadline_delta() const { return _has_field_[4]; }
frame_time_to_deadline_delta() const18450   int64_t frame_time_to_deadline_delta() const { return frame_time_to_deadline_delta_; }
set_frame_time_to_deadline_delta(int64_t value)18451   void set_frame_time_to_deadline_delta(int64_t value) { frame_time_to_deadline_delta_ = value; _has_field_.set(4); }
18452 
has_now() const18453   bool has_now() const { return _has_field_[5]; }
now() const18454   int64_t now() const { return now_; }
set_now(int64_t value)18455   void set_now(int64_t value) { now_ = value; _has_field_.set(5); }
18456 
has_frame_time() const18457   bool has_frame_time() const { return _has_field_[6]; }
frame_time() const18458   int64_t frame_time() const { return frame_time_; }
set_frame_time(int64_t value)18459   void set_frame_time(int64_t value) { frame_time_ = value; _has_field_.set(6); }
18460 
has_deadline() const18461   bool has_deadline() const { return _has_field_[7]; }
deadline() const18462   int64_t deadline() const { return deadline_; }
set_deadline(int64_t value)18463   void set_deadline(int64_t value) { deadline_ = value; _has_field_.set(7); }
18464 
18465  private:
18466   int64_t interval_delta_{};
18467   int64_t now_to_deadline_delta_{};
18468   int64_t frame_time_to_now_delta_{};
18469   int64_t frame_time_to_deadline_delta_{};
18470   int64_t now_{};
18471   int64_t frame_time_{};
18472   int64_t deadline_{};
18473 
18474   // Allows to preserve unknown protobuf fields for compatibility
18475   // with future versions of .proto files.
18476   std::string unknown_fields_;
18477 
18478   std::bitset<8> _has_field_{};
18479 };
18480 
18481 
18482 class PERFETTO_EXPORT ChromeCompositorStateMachine : public ::protozero::CppMessageObj {
18483  public:
18484   using MajorState = ChromeCompositorStateMachine_MajorState;
18485   using MinorState = ChromeCompositorStateMachine_MinorState;
18486   enum FieldNumbers {
18487     kMajorStateFieldNumber = 1,
18488     kMinorStateFieldNumber = 2,
18489   };
18490 
18491   ChromeCompositorStateMachine();
18492   ~ChromeCompositorStateMachine() override;
18493   ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept;
18494   ChromeCompositorStateMachine& operator=(ChromeCompositorStateMachine&&);
18495   ChromeCompositorStateMachine(const ChromeCompositorStateMachine&);
18496   ChromeCompositorStateMachine& operator=(const ChromeCompositorStateMachine&);
18497   bool operator==(const ChromeCompositorStateMachine&) const;
operator !=(const ChromeCompositorStateMachine & other) const18498   bool operator!=(const ChromeCompositorStateMachine& other) const { return !(*this == other); }
18499 
18500   bool ParseFromArray(const void*, size_t) override;
18501   std::string SerializeAsString() const override;
18502   std::vector<uint8_t> SerializeAsArray() const override;
18503   void Serialize(::protozero::Message*) const;
18504 
has_major_state() const18505   bool has_major_state() const { return _has_field_[1]; }
major_state() const18506   const ChromeCompositorStateMachine_MajorState& major_state() const { return *major_state_; }
mutable_major_state()18507   ChromeCompositorStateMachine_MajorState* mutable_major_state() { _has_field_.set(1); return major_state_.get(); }
18508 
has_minor_state() const18509   bool has_minor_state() const { return _has_field_[2]; }
minor_state() const18510   const ChromeCompositorStateMachine_MinorState& minor_state() const { return *minor_state_; }
mutable_minor_state()18511   ChromeCompositorStateMachine_MinorState* mutable_minor_state() { _has_field_.set(2); return minor_state_.get(); }
18512 
18513  private:
18514   ::protozero::CopyablePtr<ChromeCompositorStateMachine_MajorState> major_state_;
18515   ::protozero::CopyablePtr<ChromeCompositorStateMachine_MinorState> minor_state_;
18516 
18517   // Allows to preserve unknown protobuf fields for compatibility
18518   // with future versions of .proto files.
18519   std::string unknown_fields_;
18520 
18521   std::bitset<3> _has_field_{};
18522 };
18523 
18524 
18525 class PERFETTO_EXPORT ChromeCompositorStateMachine_MinorState : public ::protozero::CppMessageObj {
18526  public:
18527   using TreePriority = ChromeCompositorStateMachine_MinorState_TreePriority;
18528   static constexpr auto TREE_PRIORITY_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
18529   static constexpr auto TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
18530   static constexpr auto TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
18531   static constexpr auto TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
18532   static constexpr auto TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
18533   static constexpr auto TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
18534   using ScrollHandlerState = ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
18535   static constexpr auto SCROLL_HANDLER_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
18536   static constexpr auto SCROLL_AFFECTS_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER;
18537   static constexpr auto SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
18538   static constexpr auto ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
18539   static constexpr auto ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
18540   enum FieldNumbers {
18541     kCommitCountFieldNumber = 1,
18542     kCurrentFrameNumberFieldNumber = 2,
18543     kLastFrameNumberSubmitPerformedFieldNumber = 3,
18544     kLastFrameNumberDrawPerformedFieldNumber = 4,
18545     kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
18546     kDidDrawFieldNumber = 6,
18547     kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
18548     kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
18549     kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
18550     kWantsBeginMainFrameNotExpectedFieldNumber = 10,
18551     kDidCommitDuringFrameFieldNumber = 11,
18552     kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
18553     kDidPerformImplSideInvalidaionFieldNumber = 13,
18554     kDidPrepareTilesFieldNumber = 14,
18555     kConsecutiveCheckerboardAnimationsFieldNumber = 15,
18556     kPendingSubmitFramesFieldNumber = 16,
18557     kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
18558     kNeedsRedrawFieldNumber = 18,
18559     kNeedsPrepareTilesFieldNumber = 19,
18560     kNeedsBeginMainFrameFieldNumber = 20,
18561     kNeedsOneBeginImplFrameFieldNumber = 21,
18562     kVisibleFieldNumber = 22,
18563     kBeginFrameSourcePausedFieldNumber = 23,
18564     kCanDrawFieldNumber = 24,
18565     kResourcelessDrawFieldNumber = 25,
18566     kHasPendingTreeFieldNumber = 26,
18567     kPendingTreeIsReadyForActivationFieldNumber = 27,
18568     kActiveTreeNeedsFirstDrawFieldNumber = 28,
18569     kActiveTreeIsReadyToDrawFieldNumber = 29,
18570     kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
18571     kTreePriorityFieldNumber = 31,
18572     kScrollHandlerStateFieldNumber = 32,
18573     kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
18574     kMainThreadMissedLastDeadlineFieldNumber = 34,
18575     kSkipNextBeginMainFrameToReduceLatencyFieldNumber = 35,
18576     kVideoNeedsBeginFramesFieldNumber = 36,
18577     kDeferBeginMainFrameFieldNumber = 37,
18578     kLastCommitHadNoUpdatesFieldNumber = 38,
18579     kDidDrawInLastFrameFieldNumber = 39,
18580     kDidSubmitInLastFrameFieldNumber = 40,
18581     kNeedsImplSideInvalidationFieldNumber = 41,
18582     kCurrentPendingTreeIsImplSideFieldNumber = 42,
18583     kPreviousPendingTreeWasImplSideFieldNumber = 43,
18584     kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
18585     kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
18586     kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
18587   };
18588 
18589   ChromeCompositorStateMachine_MinorState();
18590   ~ChromeCompositorStateMachine_MinorState() override;
18591   ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept;
18592   ChromeCompositorStateMachine_MinorState& operator=(ChromeCompositorStateMachine_MinorState&&);
18593   ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&);
18594   ChromeCompositorStateMachine_MinorState& operator=(const ChromeCompositorStateMachine_MinorState&);
18595   bool operator==(const ChromeCompositorStateMachine_MinorState&) const;
operator !=(const ChromeCompositorStateMachine_MinorState & other) const18596   bool operator!=(const ChromeCompositorStateMachine_MinorState& other) const { return !(*this == other); }
18597 
18598   bool ParseFromArray(const void*, size_t) override;
18599   std::string SerializeAsString() const override;
18600   std::vector<uint8_t> SerializeAsArray() const override;
18601   void Serialize(::protozero::Message*) const;
18602 
has_commit_count() const18603   bool has_commit_count() const { return _has_field_[1]; }
commit_count() const18604   int32_t commit_count() const { return commit_count_; }
set_commit_count(int32_t value)18605   void set_commit_count(int32_t value) { commit_count_ = value; _has_field_.set(1); }
18606 
has_current_frame_number() const18607   bool has_current_frame_number() const { return _has_field_[2]; }
current_frame_number() const18608   int32_t current_frame_number() const { return current_frame_number_; }
set_current_frame_number(int32_t value)18609   void set_current_frame_number(int32_t value) { current_frame_number_ = value; _has_field_.set(2); }
18610 
has_last_frame_number_submit_performed() const18611   bool has_last_frame_number_submit_performed() const { return _has_field_[3]; }
last_frame_number_submit_performed() const18612   int32_t last_frame_number_submit_performed() const { return last_frame_number_submit_performed_; }
set_last_frame_number_submit_performed(int32_t value)18613   void set_last_frame_number_submit_performed(int32_t value) { last_frame_number_submit_performed_ = value; _has_field_.set(3); }
18614 
has_last_frame_number_draw_performed() const18615   bool has_last_frame_number_draw_performed() const { return _has_field_[4]; }
last_frame_number_draw_performed() const18616   int32_t last_frame_number_draw_performed() const { return last_frame_number_draw_performed_; }
set_last_frame_number_draw_performed(int32_t value)18617   void set_last_frame_number_draw_performed(int32_t value) { last_frame_number_draw_performed_ = value; _has_field_.set(4); }
18618 
has_last_frame_number_begin_main_frame_sent() const18619   bool has_last_frame_number_begin_main_frame_sent() const { return _has_field_[5]; }
last_frame_number_begin_main_frame_sent() const18620   int32_t last_frame_number_begin_main_frame_sent() const { return last_frame_number_begin_main_frame_sent_; }
set_last_frame_number_begin_main_frame_sent(int32_t value)18621   void set_last_frame_number_begin_main_frame_sent(int32_t value) { last_frame_number_begin_main_frame_sent_ = value; _has_field_.set(5); }
18622 
has_did_draw() const18623   bool has_did_draw() const { return _has_field_[6]; }
did_draw() const18624   bool did_draw() const { return did_draw_; }
set_did_draw(bool value)18625   void set_did_draw(bool value) { did_draw_ = value; _has_field_.set(6); }
18626 
has_did_send_begin_main_frame_for_current_frame() const18627   bool has_did_send_begin_main_frame_for_current_frame() const { return _has_field_[7]; }
did_send_begin_main_frame_for_current_frame() const18628   bool did_send_begin_main_frame_for_current_frame() const { return did_send_begin_main_frame_for_current_frame_; }
set_did_send_begin_main_frame_for_current_frame(bool value)18629   void set_did_send_begin_main_frame_for_current_frame(bool value) { did_send_begin_main_frame_for_current_frame_ = value; _has_field_.set(7); }
18630 
has_did_notify_begin_main_frame_not_expected_until() const18631   bool has_did_notify_begin_main_frame_not_expected_until() const { return _has_field_[8]; }
did_notify_begin_main_frame_not_expected_until() const18632   bool did_notify_begin_main_frame_not_expected_until() const { return did_notify_begin_main_frame_not_expected_until_; }
set_did_notify_begin_main_frame_not_expected_until(bool value)18633   void set_did_notify_begin_main_frame_not_expected_until(bool value) { did_notify_begin_main_frame_not_expected_until_ = value; _has_field_.set(8); }
18634 
has_did_notify_begin_main_frame_not_expected_soon() const18635   bool has_did_notify_begin_main_frame_not_expected_soon() const { return _has_field_[9]; }
did_notify_begin_main_frame_not_expected_soon() const18636   bool did_notify_begin_main_frame_not_expected_soon() const { return did_notify_begin_main_frame_not_expected_soon_; }
set_did_notify_begin_main_frame_not_expected_soon(bool value)18637   void set_did_notify_begin_main_frame_not_expected_soon(bool value) { did_notify_begin_main_frame_not_expected_soon_ = value; _has_field_.set(9); }
18638 
has_wants_begin_main_frame_not_expected() const18639   bool has_wants_begin_main_frame_not_expected() const { return _has_field_[10]; }
wants_begin_main_frame_not_expected() const18640   bool wants_begin_main_frame_not_expected() const { return wants_begin_main_frame_not_expected_; }
set_wants_begin_main_frame_not_expected(bool value)18641   void set_wants_begin_main_frame_not_expected(bool value) { wants_begin_main_frame_not_expected_ = value; _has_field_.set(10); }
18642 
has_did_commit_during_frame() const18643   bool has_did_commit_during_frame() const { return _has_field_[11]; }
did_commit_during_frame() const18644   bool did_commit_during_frame() const { return did_commit_during_frame_; }
set_did_commit_during_frame(bool value)18645   void set_did_commit_during_frame(bool value) { did_commit_during_frame_ = value; _has_field_.set(11); }
18646 
has_did_invalidate_layer_tree_frame_sink() const18647   bool has_did_invalidate_layer_tree_frame_sink() const { return _has_field_[12]; }
did_invalidate_layer_tree_frame_sink() const18648   bool did_invalidate_layer_tree_frame_sink() const { return did_invalidate_layer_tree_frame_sink_; }
set_did_invalidate_layer_tree_frame_sink(bool value)18649   void set_did_invalidate_layer_tree_frame_sink(bool value) { did_invalidate_layer_tree_frame_sink_ = value; _has_field_.set(12); }
18650 
has_did_perform_impl_side_invalidaion() const18651   bool has_did_perform_impl_side_invalidaion() const { return _has_field_[13]; }
did_perform_impl_side_invalidaion() const18652   bool did_perform_impl_side_invalidaion() const { return did_perform_impl_side_invalidaion_; }
set_did_perform_impl_side_invalidaion(bool value)18653   void set_did_perform_impl_side_invalidaion(bool value) { did_perform_impl_side_invalidaion_ = value; _has_field_.set(13); }
18654 
has_did_prepare_tiles() const18655   bool has_did_prepare_tiles() const { return _has_field_[14]; }
did_prepare_tiles() const18656   bool did_prepare_tiles() const { return did_prepare_tiles_; }
set_did_prepare_tiles(bool value)18657   void set_did_prepare_tiles(bool value) { did_prepare_tiles_ = value; _has_field_.set(14); }
18658 
has_consecutive_checkerboard_animations() const18659   bool has_consecutive_checkerboard_animations() const { return _has_field_[15]; }
consecutive_checkerboard_animations() const18660   int32_t consecutive_checkerboard_animations() const { return consecutive_checkerboard_animations_; }
set_consecutive_checkerboard_animations(int32_t value)18661   void set_consecutive_checkerboard_animations(int32_t value) { consecutive_checkerboard_animations_ = value; _has_field_.set(15); }
18662 
has_pending_submit_frames() const18663   bool has_pending_submit_frames() const { return _has_field_[16]; }
pending_submit_frames() const18664   int32_t pending_submit_frames() const { return pending_submit_frames_; }
set_pending_submit_frames(int32_t value)18665   void set_pending_submit_frames(int32_t value) { pending_submit_frames_ = value; _has_field_.set(16); }
18666 
has_submit_frames_with_current_layer_tree_frame_sink() const18667   bool has_submit_frames_with_current_layer_tree_frame_sink() const { return _has_field_[17]; }
submit_frames_with_current_layer_tree_frame_sink() const18668   int32_t submit_frames_with_current_layer_tree_frame_sink() const { return submit_frames_with_current_layer_tree_frame_sink_; }
set_submit_frames_with_current_layer_tree_frame_sink(int32_t value)18669   void set_submit_frames_with_current_layer_tree_frame_sink(int32_t value) { submit_frames_with_current_layer_tree_frame_sink_ = value; _has_field_.set(17); }
18670 
has_needs_redraw() const18671   bool has_needs_redraw() const { return _has_field_[18]; }
needs_redraw() const18672   bool needs_redraw() const { return needs_redraw_; }
set_needs_redraw(bool value)18673   void set_needs_redraw(bool value) { needs_redraw_ = value; _has_field_.set(18); }
18674 
has_needs_prepare_tiles() const18675   bool has_needs_prepare_tiles() const { return _has_field_[19]; }
needs_prepare_tiles() const18676   bool needs_prepare_tiles() const { return needs_prepare_tiles_; }
set_needs_prepare_tiles(bool value)18677   void set_needs_prepare_tiles(bool value) { needs_prepare_tiles_ = value; _has_field_.set(19); }
18678 
has_needs_begin_main_frame() const18679   bool has_needs_begin_main_frame() const { return _has_field_[20]; }
needs_begin_main_frame() const18680   bool needs_begin_main_frame() const { return needs_begin_main_frame_; }
set_needs_begin_main_frame(bool value)18681   void set_needs_begin_main_frame(bool value) { needs_begin_main_frame_ = value; _has_field_.set(20); }
18682 
has_needs_one_begin_impl_frame() const18683   bool has_needs_one_begin_impl_frame() const { return _has_field_[21]; }
needs_one_begin_impl_frame() const18684   bool needs_one_begin_impl_frame() const { return needs_one_begin_impl_frame_; }
set_needs_one_begin_impl_frame(bool value)18685   void set_needs_one_begin_impl_frame(bool value) { needs_one_begin_impl_frame_ = value; _has_field_.set(21); }
18686 
has_visible() const18687   bool has_visible() const { return _has_field_[22]; }
visible() const18688   bool visible() const { return visible_; }
set_visible(bool value)18689   void set_visible(bool value) { visible_ = value; _has_field_.set(22); }
18690 
has_begin_frame_source_paused() const18691   bool has_begin_frame_source_paused() const { return _has_field_[23]; }
begin_frame_source_paused() const18692   bool begin_frame_source_paused() const { return begin_frame_source_paused_; }
set_begin_frame_source_paused(bool value)18693   void set_begin_frame_source_paused(bool value) { begin_frame_source_paused_ = value; _has_field_.set(23); }
18694 
has_can_draw() const18695   bool has_can_draw() const { return _has_field_[24]; }
can_draw() const18696   bool can_draw() const { return can_draw_; }
set_can_draw(bool value)18697   void set_can_draw(bool value) { can_draw_ = value; _has_field_.set(24); }
18698 
has_resourceless_draw() const18699   bool has_resourceless_draw() const { return _has_field_[25]; }
resourceless_draw() const18700   bool resourceless_draw() const { return resourceless_draw_; }
set_resourceless_draw(bool value)18701   void set_resourceless_draw(bool value) { resourceless_draw_ = value; _has_field_.set(25); }
18702 
has_has_pending_tree() const18703   bool has_has_pending_tree() const { return _has_field_[26]; }
has_pending_tree() const18704   bool has_pending_tree() const { return has_pending_tree_; }
set_has_pending_tree(bool value)18705   void set_has_pending_tree(bool value) { has_pending_tree_ = value; _has_field_.set(26); }
18706 
has_pending_tree_is_ready_for_activation() const18707   bool has_pending_tree_is_ready_for_activation() const { return _has_field_[27]; }
pending_tree_is_ready_for_activation() const18708   bool pending_tree_is_ready_for_activation() const { return pending_tree_is_ready_for_activation_; }
set_pending_tree_is_ready_for_activation(bool value)18709   void set_pending_tree_is_ready_for_activation(bool value) { pending_tree_is_ready_for_activation_ = value; _has_field_.set(27); }
18710 
has_active_tree_needs_first_draw() const18711   bool has_active_tree_needs_first_draw() const { return _has_field_[28]; }
active_tree_needs_first_draw() const18712   bool active_tree_needs_first_draw() const { return active_tree_needs_first_draw_; }
set_active_tree_needs_first_draw(bool value)18713   void set_active_tree_needs_first_draw(bool value) { active_tree_needs_first_draw_ = value; _has_field_.set(28); }
18714 
has_active_tree_is_ready_to_draw() const18715   bool has_active_tree_is_ready_to_draw() const { return _has_field_[29]; }
active_tree_is_ready_to_draw() const18716   bool active_tree_is_ready_to_draw() const { return active_tree_is_ready_to_draw_; }
set_active_tree_is_ready_to_draw(bool value)18717   void set_active_tree_is_ready_to_draw(bool value) { active_tree_is_ready_to_draw_ = value; _has_field_.set(29); }
18718 
has_did_create_and_initialize_first_layer_tree_frame_sink() const18719   bool has_did_create_and_initialize_first_layer_tree_frame_sink() const { return _has_field_[30]; }
did_create_and_initialize_first_layer_tree_frame_sink() const18720   bool did_create_and_initialize_first_layer_tree_frame_sink() const { return did_create_and_initialize_first_layer_tree_frame_sink_; }
set_did_create_and_initialize_first_layer_tree_frame_sink(bool value)18721   void set_did_create_and_initialize_first_layer_tree_frame_sink(bool value) { did_create_and_initialize_first_layer_tree_frame_sink_ = value; _has_field_.set(30); }
18722 
has_tree_priority() const18723   bool has_tree_priority() const { return _has_field_[31]; }
tree_priority() const18724   ChromeCompositorStateMachine_MinorState_TreePriority tree_priority() const { return tree_priority_; }
set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value)18725   void set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value) { tree_priority_ = value; _has_field_.set(31); }
18726 
has_scroll_handler_state() const18727   bool has_scroll_handler_state() const { return _has_field_[32]; }
scroll_handler_state() const18728   ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state() const { return scroll_handler_state_; }
set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value)18729   void set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) { scroll_handler_state_ = value; _has_field_.set(32); }
18730 
has_critical_begin_main_frame_to_activate_is_fast() const18731   bool has_critical_begin_main_frame_to_activate_is_fast() const { return _has_field_[33]; }
critical_begin_main_frame_to_activate_is_fast() const18732   bool critical_begin_main_frame_to_activate_is_fast() const { return critical_begin_main_frame_to_activate_is_fast_; }
set_critical_begin_main_frame_to_activate_is_fast(bool value)18733   void set_critical_begin_main_frame_to_activate_is_fast(bool value) { critical_begin_main_frame_to_activate_is_fast_ = value; _has_field_.set(33); }
18734 
has_main_thread_missed_last_deadline() const18735   bool has_main_thread_missed_last_deadline() const { return _has_field_[34]; }
main_thread_missed_last_deadline() const18736   bool main_thread_missed_last_deadline() const { return main_thread_missed_last_deadline_; }
set_main_thread_missed_last_deadline(bool value)18737   void set_main_thread_missed_last_deadline(bool value) { main_thread_missed_last_deadline_ = value; _has_field_.set(34); }
18738 
has_skip_next_begin_main_frame_to_reduce_latency() const18739   bool has_skip_next_begin_main_frame_to_reduce_latency() const { return _has_field_[35]; }
skip_next_begin_main_frame_to_reduce_latency() const18740   bool skip_next_begin_main_frame_to_reduce_latency() const { return skip_next_begin_main_frame_to_reduce_latency_; }
set_skip_next_begin_main_frame_to_reduce_latency(bool value)18741   void set_skip_next_begin_main_frame_to_reduce_latency(bool value) { skip_next_begin_main_frame_to_reduce_latency_ = value; _has_field_.set(35); }
18742 
has_video_needs_begin_frames() const18743   bool has_video_needs_begin_frames() const { return _has_field_[36]; }
video_needs_begin_frames() const18744   bool video_needs_begin_frames() const { return video_needs_begin_frames_; }
set_video_needs_begin_frames(bool value)18745   void set_video_needs_begin_frames(bool value) { video_needs_begin_frames_ = value; _has_field_.set(36); }
18746 
has_defer_begin_main_frame() const18747   bool has_defer_begin_main_frame() const { return _has_field_[37]; }
defer_begin_main_frame() const18748   bool defer_begin_main_frame() const { return defer_begin_main_frame_; }
set_defer_begin_main_frame(bool value)18749   void set_defer_begin_main_frame(bool value) { defer_begin_main_frame_ = value; _has_field_.set(37); }
18750 
has_last_commit_had_no_updates() const18751   bool has_last_commit_had_no_updates() const { return _has_field_[38]; }
last_commit_had_no_updates() const18752   bool last_commit_had_no_updates() const { return last_commit_had_no_updates_; }
set_last_commit_had_no_updates(bool value)18753   void set_last_commit_had_no_updates(bool value) { last_commit_had_no_updates_ = value; _has_field_.set(38); }
18754 
has_did_draw_in_last_frame() const18755   bool has_did_draw_in_last_frame() const { return _has_field_[39]; }
did_draw_in_last_frame() const18756   bool did_draw_in_last_frame() const { return did_draw_in_last_frame_; }
set_did_draw_in_last_frame(bool value)18757   void set_did_draw_in_last_frame(bool value) { did_draw_in_last_frame_ = value; _has_field_.set(39); }
18758 
has_did_submit_in_last_frame() const18759   bool has_did_submit_in_last_frame() const { return _has_field_[40]; }
did_submit_in_last_frame() const18760   bool did_submit_in_last_frame() const { return did_submit_in_last_frame_; }
set_did_submit_in_last_frame(bool value)18761   void set_did_submit_in_last_frame(bool value) { did_submit_in_last_frame_ = value; _has_field_.set(40); }
18762 
has_needs_impl_side_invalidation() const18763   bool has_needs_impl_side_invalidation() const { return _has_field_[41]; }
needs_impl_side_invalidation() const18764   bool needs_impl_side_invalidation() const { return needs_impl_side_invalidation_; }
set_needs_impl_side_invalidation(bool value)18765   void set_needs_impl_side_invalidation(bool value) { needs_impl_side_invalidation_ = value; _has_field_.set(41); }
18766 
has_current_pending_tree_is_impl_side() const18767   bool has_current_pending_tree_is_impl_side() const { return _has_field_[42]; }
current_pending_tree_is_impl_side() const18768   bool current_pending_tree_is_impl_side() const { return current_pending_tree_is_impl_side_; }
set_current_pending_tree_is_impl_side(bool value)18769   void set_current_pending_tree_is_impl_side(bool value) { current_pending_tree_is_impl_side_ = value; _has_field_.set(42); }
18770 
has_previous_pending_tree_was_impl_side() const18771   bool has_previous_pending_tree_was_impl_side() const { return _has_field_[43]; }
previous_pending_tree_was_impl_side() const18772   bool previous_pending_tree_was_impl_side() const { return previous_pending_tree_was_impl_side_; }
set_previous_pending_tree_was_impl_side(bool value)18773   void set_previous_pending_tree_was_impl_side(bool value) { previous_pending_tree_was_impl_side_ = value; _has_field_.set(43); }
18774 
has_processing_animation_worklets_for_active_tree() const18775   bool has_processing_animation_worklets_for_active_tree() const { return _has_field_[44]; }
processing_animation_worklets_for_active_tree() const18776   bool processing_animation_worklets_for_active_tree() const { return processing_animation_worklets_for_active_tree_; }
set_processing_animation_worklets_for_active_tree(bool value)18777   void set_processing_animation_worklets_for_active_tree(bool value) { processing_animation_worklets_for_active_tree_ = value; _has_field_.set(44); }
18778 
has_processing_animation_worklets_for_pending_tree() const18779   bool has_processing_animation_worklets_for_pending_tree() const { return _has_field_[45]; }
processing_animation_worklets_for_pending_tree() const18780   bool processing_animation_worklets_for_pending_tree() const { return processing_animation_worklets_for_pending_tree_; }
set_processing_animation_worklets_for_pending_tree(bool value)18781   void set_processing_animation_worklets_for_pending_tree(bool value) { processing_animation_worklets_for_pending_tree_ = value; _has_field_.set(45); }
18782 
has_processing_paint_worklets_for_pending_tree() const18783   bool has_processing_paint_worklets_for_pending_tree() const { return _has_field_[46]; }
processing_paint_worklets_for_pending_tree() const18784   bool processing_paint_worklets_for_pending_tree() const { return processing_paint_worklets_for_pending_tree_; }
set_processing_paint_worklets_for_pending_tree(bool value)18785   void set_processing_paint_worklets_for_pending_tree(bool value) { processing_paint_worklets_for_pending_tree_ = value; _has_field_.set(46); }
18786 
18787  private:
18788   int32_t commit_count_{};
18789   int32_t current_frame_number_{};
18790   int32_t last_frame_number_submit_performed_{};
18791   int32_t last_frame_number_draw_performed_{};
18792   int32_t last_frame_number_begin_main_frame_sent_{};
18793   bool did_draw_{};
18794   bool did_send_begin_main_frame_for_current_frame_{};
18795   bool did_notify_begin_main_frame_not_expected_until_{};
18796   bool did_notify_begin_main_frame_not_expected_soon_{};
18797   bool wants_begin_main_frame_not_expected_{};
18798   bool did_commit_during_frame_{};
18799   bool did_invalidate_layer_tree_frame_sink_{};
18800   bool did_perform_impl_side_invalidaion_{};
18801   bool did_prepare_tiles_{};
18802   int32_t consecutive_checkerboard_animations_{};
18803   int32_t pending_submit_frames_{};
18804   int32_t submit_frames_with_current_layer_tree_frame_sink_{};
18805   bool needs_redraw_{};
18806   bool needs_prepare_tiles_{};
18807   bool needs_begin_main_frame_{};
18808   bool needs_one_begin_impl_frame_{};
18809   bool visible_{};
18810   bool begin_frame_source_paused_{};
18811   bool can_draw_{};
18812   bool resourceless_draw_{};
18813   bool has_pending_tree_{};
18814   bool pending_tree_is_ready_for_activation_{};
18815   bool active_tree_needs_first_draw_{};
18816   bool active_tree_is_ready_to_draw_{};
18817   bool did_create_and_initialize_first_layer_tree_frame_sink_{};
18818   ChromeCompositorStateMachine_MinorState_TreePriority tree_priority_{};
18819   ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state_{};
18820   bool critical_begin_main_frame_to_activate_is_fast_{};
18821   bool main_thread_missed_last_deadline_{};
18822   bool skip_next_begin_main_frame_to_reduce_latency_{};
18823   bool video_needs_begin_frames_{};
18824   bool defer_begin_main_frame_{};
18825   bool last_commit_had_no_updates_{};
18826   bool did_draw_in_last_frame_{};
18827   bool did_submit_in_last_frame_{};
18828   bool needs_impl_side_invalidation_{};
18829   bool current_pending_tree_is_impl_side_{};
18830   bool previous_pending_tree_was_impl_side_{};
18831   bool processing_animation_worklets_for_active_tree_{};
18832   bool processing_animation_worklets_for_pending_tree_{};
18833   bool processing_paint_worklets_for_pending_tree_{};
18834 
18835   // Allows to preserve unknown protobuf fields for compatibility
18836   // with future versions of .proto files.
18837   std::string unknown_fields_;
18838 
18839   std::bitset<47> _has_field_{};
18840 };
18841 
18842 
18843 class PERFETTO_EXPORT ChromeCompositorStateMachine_MajorState : public ::protozero::CppMessageObj {
18844  public:
18845   using BeginImplFrameState = ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
18846   static constexpr auto BEGIN_IMPL_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
18847   static constexpr auto BEGIN_IMPL_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE;
18848   static constexpr auto BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
18849   static constexpr auto BEGIN_IMPL_FRAME_INSIDE_DEADLINE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
18850   static constexpr auto BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
18851   static constexpr auto BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
18852   using BeginMainFrameState = ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
18853   static constexpr auto BEGIN_MAIN_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
18854   static constexpr auto BEGIN_MAIN_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE;
18855   static constexpr auto BEGIN_MAIN_FRAME_SENT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT;
18856   static constexpr auto BEGIN_MAIN_FRAME_READY_TO_COMMIT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
18857   static constexpr auto BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
18858   static constexpr auto BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
18859   using LayerTreeFrameSinkState = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
18860   static constexpr auto LAYER_TREE_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
18861   static constexpr auto LAYER_TREE_FRAME_NONE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE;
18862   static constexpr auto LAYER_TREE_FRAME_ACTIVE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE;
18863   static constexpr auto LAYER_TREE_FRAME_CREATING = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING;
18864   static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
18865   static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
18866   static constexpr auto LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
18867   static constexpr auto LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
18868   using ForcedRedrawOnTimeoutState = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
18869   static constexpr auto FORCED_REDRAW_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
18870   static constexpr auto FORCED_REDRAW_IDLE = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE;
18871   static constexpr auto FORCED_REDRAW_WAITING_FOR_COMMIT = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT;
18872   static constexpr auto FORCED_REDRAW_WAITING_FOR_ACTIVATION = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION;
18873   static constexpr auto FORCED_REDRAW_WAITING_FOR_DRAW = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
18874   static constexpr auto ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
18875   static constexpr auto ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
18876   enum FieldNumbers {
18877     kNextActionFieldNumber = 1,
18878     kBeginImplFrameStateFieldNumber = 2,
18879     kBeginMainFrameStateFieldNumber = 3,
18880     kLayerTreeFrameSinkStateFieldNumber = 4,
18881     kForcedRedrawStateFieldNumber = 5,
18882   };
18883 
18884   ChromeCompositorStateMachine_MajorState();
18885   ~ChromeCompositorStateMachine_MajorState() override;
18886   ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept;
18887   ChromeCompositorStateMachine_MajorState& operator=(ChromeCompositorStateMachine_MajorState&&);
18888   ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&);
18889   ChromeCompositorStateMachine_MajorState& operator=(const ChromeCompositorStateMachine_MajorState&);
18890   bool operator==(const ChromeCompositorStateMachine_MajorState&) const;
operator !=(const ChromeCompositorStateMachine_MajorState & other) const18891   bool operator!=(const ChromeCompositorStateMachine_MajorState& other) const { return !(*this == other); }
18892 
18893   bool ParseFromArray(const void*, size_t) override;
18894   std::string SerializeAsString() const override;
18895   std::vector<uint8_t> SerializeAsArray() const override;
18896   void Serialize(::protozero::Message*) const;
18897 
has_next_action() const18898   bool has_next_action() const { return _has_field_[1]; }
next_action() const18899   ChromeCompositorSchedulerAction next_action() const { return next_action_; }
set_next_action(ChromeCompositorSchedulerAction value)18900   void set_next_action(ChromeCompositorSchedulerAction value) { next_action_ = value; _has_field_.set(1); }
18901 
has_begin_impl_frame_state() const18902   bool has_begin_impl_frame_state() const { return _has_field_[2]; }
begin_impl_frame_state() const18903   ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state() const { return begin_impl_frame_state_; }
set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value)18904   void set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) { begin_impl_frame_state_ = value; _has_field_.set(2); }
18905 
has_begin_main_frame_state() const18906   bool has_begin_main_frame_state() const { return _has_field_[3]; }
begin_main_frame_state() const18907   ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state() const { return begin_main_frame_state_; }
set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value)18908   void set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) { begin_main_frame_state_ = value; _has_field_.set(3); }
18909 
has_layer_tree_frame_sink_state() const18910   bool has_layer_tree_frame_sink_state() const { return _has_field_[4]; }
layer_tree_frame_sink_state() const18911   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state() const { return layer_tree_frame_sink_state_; }
set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value)18912   void set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) { layer_tree_frame_sink_state_ = value; _has_field_.set(4); }
18913 
has_forced_redraw_state() const18914   bool has_forced_redraw_state() const { return _has_field_[5]; }
forced_redraw_state() const18915   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state() const { return forced_redraw_state_; }
set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value)18916   void set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) { forced_redraw_state_ = value; _has_field_.set(5); }
18917 
18918  private:
18919   ChromeCompositorSchedulerAction next_action_{};
18920   ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state_{};
18921   ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state_{};
18922   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state_{};
18923   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state_{};
18924 
18925   // Allows to preserve unknown protobuf fields for compatibility
18926   // with future versions of .proto files.
18927   std::string unknown_fields_;
18928 
18929   std::bitset<6> _has_field_{};
18930 };
18931 
18932 
18933 class PERFETTO_EXPORT ChromeCompositorSchedulerState : public ::protozero::CppMessageObj {
18934  public:
18935   using BeginImplFrameDeadlineMode = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
18936   static constexpr auto DEADLINE_MODE_UNSPECIFIED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
18937   static constexpr auto DEADLINE_MODE_NONE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE;
18938   static constexpr auto DEADLINE_MODE_IMMEDIATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE;
18939   static constexpr auto DEADLINE_MODE_REGULAR = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR;
18940   static constexpr auto DEADLINE_MODE_LATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE;
18941   static constexpr auto DEADLINE_MODE_BLOCKED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
18942   static constexpr auto BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
18943   static constexpr auto BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
18944   enum FieldNumbers {
18945     kStateMachineFieldNumber = 1,
18946     kObservingBeginFrameSourceFieldNumber = 2,
18947     kBeginImplFrameDeadlineTaskFieldNumber = 3,
18948     kPendingBeginFrameTaskFieldNumber = 4,
18949     kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
18950     kSkippedLastFrameToReduceLatencyFieldNumber = 6,
18951     kInsideActionFieldNumber = 7,
18952     kDeadlineModeFieldNumber = 8,
18953     kDeadlineUsFieldNumber = 9,
18954     kDeadlineScheduledAtUsFieldNumber = 10,
18955     kNowUsFieldNumber = 11,
18956     kNowToDeadlineDeltaUsFieldNumber = 12,
18957     kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
18958     kBeginImplFrameArgsFieldNumber = 14,
18959     kBeginFrameObserverStateFieldNumber = 15,
18960     kBeginFrameSourceStateFieldNumber = 16,
18961     kCompositorTimingHistoryFieldNumber = 17,
18962   };
18963 
18964   ChromeCompositorSchedulerState();
18965   ~ChromeCompositorSchedulerState() override;
18966   ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept;
18967   ChromeCompositorSchedulerState& operator=(ChromeCompositorSchedulerState&&);
18968   ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&);
18969   ChromeCompositorSchedulerState& operator=(const ChromeCompositorSchedulerState&);
18970   bool operator==(const ChromeCompositorSchedulerState&) const;
operator !=(const ChromeCompositorSchedulerState & other) const18971   bool operator!=(const ChromeCompositorSchedulerState& other) const { return !(*this == other); }
18972 
18973   bool ParseFromArray(const void*, size_t) override;
18974   std::string SerializeAsString() const override;
18975   std::vector<uint8_t> SerializeAsArray() const override;
18976   void Serialize(::protozero::Message*) const;
18977 
has_state_machine() const18978   bool has_state_machine() const { return _has_field_[1]; }
state_machine() const18979   const ChromeCompositorStateMachine& state_machine() const { return *state_machine_; }
mutable_state_machine()18980   ChromeCompositorStateMachine* mutable_state_machine() { _has_field_.set(1); return state_machine_.get(); }
18981 
has_observing_begin_frame_source() const18982   bool has_observing_begin_frame_source() const { return _has_field_[2]; }
observing_begin_frame_source() const18983   bool observing_begin_frame_source() const { return observing_begin_frame_source_; }
set_observing_begin_frame_source(bool value)18984   void set_observing_begin_frame_source(bool value) { observing_begin_frame_source_ = value; _has_field_.set(2); }
18985 
has_begin_impl_frame_deadline_task() const18986   bool has_begin_impl_frame_deadline_task() const { return _has_field_[3]; }
begin_impl_frame_deadline_task() const18987   bool begin_impl_frame_deadline_task() const { return begin_impl_frame_deadline_task_; }
set_begin_impl_frame_deadline_task(bool value)18988   void set_begin_impl_frame_deadline_task(bool value) { begin_impl_frame_deadline_task_ = value; _has_field_.set(3); }
18989 
has_pending_begin_frame_task() const18990   bool has_pending_begin_frame_task() const { return _has_field_[4]; }
pending_begin_frame_task() const18991   bool pending_begin_frame_task() const { return pending_begin_frame_task_; }
set_pending_begin_frame_task(bool value)18992   void set_pending_begin_frame_task(bool value) { pending_begin_frame_task_ = value; _has_field_.set(4); }
18993 
has_skipped_last_frame_missed_exceeded_deadline() const18994   bool has_skipped_last_frame_missed_exceeded_deadline() const { return _has_field_[5]; }
skipped_last_frame_missed_exceeded_deadline() const18995   bool skipped_last_frame_missed_exceeded_deadline() const { return skipped_last_frame_missed_exceeded_deadline_; }
set_skipped_last_frame_missed_exceeded_deadline(bool value)18996   void set_skipped_last_frame_missed_exceeded_deadline(bool value) { skipped_last_frame_missed_exceeded_deadline_ = value; _has_field_.set(5); }
18997 
has_skipped_last_frame_to_reduce_latency() const18998   bool has_skipped_last_frame_to_reduce_latency() const { return _has_field_[6]; }
skipped_last_frame_to_reduce_latency() const18999   bool skipped_last_frame_to_reduce_latency() const { return skipped_last_frame_to_reduce_latency_; }
set_skipped_last_frame_to_reduce_latency(bool value)19000   void set_skipped_last_frame_to_reduce_latency(bool value) { skipped_last_frame_to_reduce_latency_ = value; _has_field_.set(6); }
19001 
has_inside_action() const19002   bool has_inside_action() const { return _has_field_[7]; }
inside_action() const19003   ChromeCompositorSchedulerAction inside_action() const { return inside_action_; }
set_inside_action(ChromeCompositorSchedulerAction value)19004   void set_inside_action(ChromeCompositorSchedulerAction value) { inside_action_ = value; _has_field_.set(7); }
19005 
has_deadline_mode() const19006   bool has_deadline_mode() const { return _has_field_[8]; }
deadline_mode() const19007   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode() const { return deadline_mode_; }
set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value)19008   void set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) { deadline_mode_ = value; _has_field_.set(8); }
19009 
has_deadline_us() const19010   bool has_deadline_us() const { return _has_field_[9]; }
deadline_us() const19011   int64_t deadline_us() const { return deadline_us_; }
set_deadline_us(int64_t value)19012   void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(9); }
19013 
has_deadline_scheduled_at_us() const19014   bool has_deadline_scheduled_at_us() const { return _has_field_[10]; }
deadline_scheduled_at_us() const19015   int64_t deadline_scheduled_at_us() const { return deadline_scheduled_at_us_; }
set_deadline_scheduled_at_us(int64_t value)19016   void set_deadline_scheduled_at_us(int64_t value) { deadline_scheduled_at_us_ = value; _has_field_.set(10); }
19017 
has_now_us() const19018   bool has_now_us() const { return _has_field_[11]; }
now_us() const19019   int64_t now_us() const { return now_us_; }
set_now_us(int64_t value)19020   void set_now_us(int64_t value) { now_us_ = value; _has_field_.set(11); }
19021 
has_now_to_deadline_delta_us() const19022   bool has_now_to_deadline_delta_us() const { return _has_field_[12]; }
now_to_deadline_delta_us() const19023   int64_t now_to_deadline_delta_us() const { return now_to_deadline_delta_us_; }
set_now_to_deadline_delta_us(int64_t value)19024   void set_now_to_deadline_delta_us(int64_t value) { now_to_deadline_delta_us_ = value; _has_field_.set(12); }
19025 
has_now_to_deadline_scheduled_at_delta_us() const19026   bool has_now_to_deadline_scheduled_at_delta_us() const { return _has_field_[13]; }
now_to_deadline_scheduled_at_delta_us() const19027   int64_t now_to_deadline_scheduled_at_delta_us() const { return now_to_deadline_scheduled_at_delta_us_; }
set_now_to_deadline_scheduled_at_delta_us(int64_t value)19028   void set_now_to_deadline_scheduled_at_delta_us(int64_t value) { now_to_deadline_scheduled_at_delta_us_ = value; _has_field_.set(13); }
19029 
has_begin_impl_frame_args() const19030   bool has_begin_impl_frame_args() const { return _has_field_[14]; }
begin_impl_frame_args() const19031   const BeginImplFrameArgs& begin_impl_frame_args() const { return *begin_impl_frame_args_; }
mutable_begin_impl_frame_args()19032   BeginImplFrameArgs* mutable_begin_impl_frame_args() { _has_field_.set(14); return begin_impl_frame_args_.get(); }
19033 
has_begin_frame_observer_state() const19034   bool has_begin_frame_observer_state() const { return _has_field_[15]; }
begin_frame_observer_state() const19035   const BeginFrameObserverState& begin_frame_observer_state() const { return *begin_frame_observer_state_; }
mutable_begin_frame_observer_state()19036   BeginFrameObserverState* mutable_begin_frame_observer_state() { _has_field_.set(15); return begin_frame_observer_state_.get(); }
19037 
has_begin_frame_source_state() const19038   bool has_begin_frame_source_state() const { return _has_field_[16]; }
begin_frame_source_state() const19039   const BeginFrameSourceState& begin_frame_source_state() const { return *begin_frame_source_state_; }
mutable_begin_frame_source_state()19040   BeginFrameSourceState* mutable_begin_frame_source_state() { _has_field_.set(16); return begin_frame_source_state_.get(); }
19041 
has_compositor_timing_history() const19042   bool has_compositor_timing_history() const { return _has_field_[17]; }
compositor_timing_history() const19043   const CompositorTimingHistory& compositor_timing_history() const { return *compositor_timing_history_; }
mutable_compositor_timing_history()19044   CompositorTimingHistory* mutable_compositor_timing_history() { _has_field_.set(17); return compositor_timing_history_.get(); }
19045 
19046  private:
19047   ::protozero::CopyablePtr<ChromeCompositorStateMachine> state_machine_;
19048   bool observing_begin_frame_source_{};
19049   bool begin_impl_frame_deadline_task_{};
19050   bool pending_begin_frame_task_{};
19051   bool skipped_last_frame_missed_exceeded_deadline_{};
19052   bool skipped_last_frame_to_reduce_latency_{};
19053   ChromeCompositorSchedulerAction inside_action_{};
19054   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode_{};
19055   int64_t deadline_us_{};
19056   int64_t deadline_scheduled_at_us_{};
19057   int64_t now_us_{};
19058   int64_t now_to_deadline_delta_us_{};
19059   int64_t now_to_deadline_scheduled_at_delta_us_{};
19060   ::protozero::CopyablePtr<BeginImplFrameArgs> begin_impl_frame_args_;
19061   ::protozero::CopyablePtr<BeginFrameObserverState> begin_frame_observer_state_;
19062   ::protozero::CopyablePtr<BeginFrameSourceState> begin_frame_source_state_;
19063   ::protozero::CopyablePtr<CompositorTimingHistory> compositor_timing_history_;
19064 
19065   // Allows to preserve unknown protobuf fields for compatibility
19066   // with future versions of .proto files.
19067   std::string unknown_fields_;
19068 
19069   std::bitset<18> _has_field_{};
19070 };
19071 
19072 }  // namespace perfetto
19073 }  // namespace protos
19074 }  // namespace gen
19075 
19076 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
19077 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.gen.h
19078 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19079 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
19080 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
19081 
19082 #include <stdint.h>
19083 #include <bitset>
19084 #include <vector>
19085 #include <string>
19086 #include <type_traits>
19087 
19088 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19089 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19090 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19091 
19092 namespace perfetto {
19093 namespace protos {
19094 namespace gen {
19095 class SourceLocation;
19096 }  // namespace perfetto
19097 }  // namespace protos
19098 }  // namespace gen
19099 
19100 namespace protozero {
19101 class Message;
19102 }  // namespace protozero
19103 
19104 namespace perfetto {
19105 namespace protos {
19106 namespace gen {
19107 
19108 class PERFETTO_EXPORT SourceLocation : public ::protozero::CppMessageObj {
19109  public:
19110   enum FieldNumbers {
19111     kIidFieldNumber = 1,
19112     kFileNameFieldNumber = 2,
19113     kFunctionNameFieldNumber = 3,
19114     kLineNumberFieldNumber = 4,
19115   };
19116 
19117   SourceLocation();
19118   ~SourceLocation() override;
19119   SourceLocation(SourceLocation&&) noexcept;
19120   SourceLocation& operator=(SourceLocation&&);
19121   SourceLocation(const SourceLocation&);
19122   SourceLocation& operator=(const SourceLocation&);
19123   bool operator==(const SourceLocation&) const;
operator !=(const SourceLocation & other) const19124   bool operator!=(const SourceLocation& other) const { return !(*this == other); }
19125 
19126   bool ParseFromArray(const void*, size_t) override;
19127   std::string SerializeAsString() const override;
19128   std::vector<uint8_t> SerializeAsArray() const override;
19129   void Serialize(::protozero::Message*) const;
19130 
has_iid() const19131   bool has_iid() const { return _has_field_[1]; }
iid() const19132   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)19133   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
19134 
has_file_name() const19135   bool has_file_name() const { return _has_field_[2]; }
file_name() const19136   const std::string& file_name() const { return file_name_; }
set_file_name(const std::string & value)19137   void set_file_name(const std::string& value) { file_name_ = value; _has_field_.set(2); }
19138 
has_function_name() const19139   bool has_function_name() const { return _has_field_[3]; }
function_name() const19140   const std::string& function_name() const { return function_name_; }
set_function_name(const std::string & value)19141   void set_function_name(const std::string& value) { function_name_ = value; _has_field_.set(3); }
19142 
has_line_number() const19143   bool has_line_number() const { return _has_field_[4]; }
line_number() const19144   uint32_t line_number() const { return line_number_; }
set_line_number(uint32_t value)19145   void set_line_number(uint32_t value) { line_number_ = value; _has_field_.set(4); }
19146 
19147  private:
19148   uint64_t iid_{};
19149   std::string file_name_{};
19150   std::string function_name_{};
19151   uint32_t line_number_{};
19152 
19153   // Allows to preserve unknown protobuf fields for compatibility
19154   // with future versions of .proto files.
19155   std::string unknown_fields_;
19156 
19157   std::bitset<5> _has_field_{};
19158 };
19159 
19160 }  // namespace perfetto
19161 }  // namespace protos
19162 }  // namespace gen
19163 
19164 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
19165 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19166 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19167 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19168 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19169 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19170 #pragma GCC diagnostic push
19171 #pragma GCC diagnostic ignored "-Wfloat-equal"
19172 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
19173 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
19174 
19175 namespace perfetto {
19176 namespace protos {
19177 namespace gen {
19178 
19179 CompositorTimingHistory::CompositorTimingHistory() = default;
19180 CompositorTimingHistory::~CompositorTimingHistory() = default;
19181 CompositorTimingHistory::CompositorTimingHistory(const CompositorTimingHistory&) = default;
19182 CompositorTimingHistory& CompositorTimingHistory::operator=(const CompositorTimingHistory&) = default;
19183 CompositorTimingHistory::CompositorTimingHistory(CompositorTimingHistory&&) noexcept = default;
19184 CompositorTimingHistory& CompositorTimingHistory::operator=(CompositorTimingHistory&&) = default;
19185 
operator ==(const CompositorTimingHistory & other) const19186 bool CompositorTimingHistory::operator==(const CompositorTimingHistory& other) const {
19187   return unknown_fields_ == other.unknown_fields_
19188    && begin_main_frame_queue_critical_estimate_delta_us_ == other.begin_main_frame_queue_critical_estimate_delta_us_
19189    && begin_main_frame_queue_not_critical_estimate_delta_us_ == other.begin_main_frame_queue_not_critical_estimate_delta_us_
19190    && begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ == other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_
19191    && commit_to_ready_to_activate_estimate_delta_us_ == other.commit_to_ready_to_activate_estimate_delta_us_
19192    && prepare_tiles_estimate_delta_us_ == other.prepare_tiles_estimate_delta_us_
19193    && activate_estimate_delta_us_ == other.activate_estimate_delta_us_
19194    && draw_estimate_delta_us_ == other.draw_estimate_delta_us_;
19195 }
19196 
ParseFromArray(const void * raw,size_t size)19197 bool CompositorTimingHistory::ParseFromArray(const void* raw, size_t size) {
19198   unknown_fields_.clear();
19199   bool packed_error = false;
19200 
19201   ::protozero::ProtoDecoder dec(raw, size);
19202   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19203     if (field.id() < _has_field_.size()) {
19204       _has_field_.set(field.id());
19205     }
19206     switch (field.id()) {
19207       case 1 /* begin_main_frame_queue_critical_estimate_delta_us */:
19208         field.get(&begin_main_frame_queue_critical_estimate_delta_us_);
19209         break;
19210       case 2 /* begin_main_frame_queue_not_critical_estimate_delta_us */:
19211         field.get(&begin_main_frame_queue_not_critical_estimate_delta_us_);
19212         break;
19213       case 3 /* begin_main_frame_start_to_ready_to_commit_estimate_delta_us */:
19214         field.get(&begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
19215         break;
19216       case 4 /* commit_to_ready_to_activate_estimate_delta_us */:
19217         field.get(&commit_to_ready_to_activate_estimate_delta_us_);
19218         break;
19219       case 5 /* prepare_tiles_estimate_delta_us */:
19220         field.get(&prepare_tiles_estimate_delta_us_);
19221         break;
19222       case 6 /* activate_estimate_delta_us */:
19223         field.get(&activate_estimate_delta_us_);
19224         break;
19225       case 7 /* draw_estimate_delta_us */:
19226         field.get(&draw_estimate_delta_us_);
19227         break;
19228       default:
19229         field.SerializeAndAppendTo(&unknown_fields_);
19230         break;
19231     }
19232   }
19233   return !packed_error && !dec.bytes_left();
19234 }
19235 
SerializeAsString() const19236 std::string CompositorTimingHistory::SerializeAsString() const {
19237   ::protozero::HeapBuffered<::protozero::Message> msg;
19238   Serialize(msg.get());
19239   return msg.SerializeAsString();
19240 }
19241 
SerializeAsArray() const19242 std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
19243   ::protozero::HeapBuffered<::protozero::Message> msg;
19244   Serialize(msg.get());
19245   return msg.SerializeAsArray();
19246 }
19247 
Serialize(::protozero::Message * msg) const19248 void CompositorTimingHistory::Serialize(::protozero::Message* msg) const {
19249   // Field 1: begin_main_frame_queue_critical_estimate_delta_us
19250   if (_has_field_[1]) {
19251     msg->AppendVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_);
19252   }
19253 
19254   // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
19255   if (_has_field_[2]) {
19256     msg->AppendVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_);
19257   }
19258 
19259   // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
19260   if (_has_field_[3]) {
19261     msg->AppendVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
19262   }
19263 
19264   // Field 4: commit_to_ready_to_activate_estimate_delta_us
19265   if (_has_field_[4]) {
19266     msg->AppendVarInt(4, commit_to_ready_to_activate_estimate_delta_us_);
19267   }
19268 
19269   // Field 5: prepare_tiles_estimate_delta_us
19270   if (_has_field_[5]) {
19271     msg->AppendVarInt(5, prepare_tiles_estimate_delta_us_);
19272   }
19273 
19274   // Field 6: activate_estimate_delta_us
19275   if (_has_field_[6]) {
19276     msg->AppendVarInt(6, activate_estimate_delta_us_);
19277   }
19278 
19279   // Field 7: draw_estimate_delta_us
19280   if (_has_field_[7]) {
19281     msg->AppendVarInt(7, draw_estimate_delta_us_);
19282   }
19283 
19284   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19285 }
19286 
19287 
19288 BeginFrameSourceState::BeginFrameSourceState() = default;
19289 BeginFrameSourceState::~BeginFrameSourceState() = default;
19290 BeginFrameSourceState::BeginFrameSourceState(const BeginFrameSourceState&) = default;
19291 BeginFrameSourceState& BeginFrameSourceState::operator=(const BeginFrameSourceState&) = default;
19292 BeginFrameSourceState::BeginFrameSourceState(BeginFrameSourceState&&) noexcept = default;
19293 BeginFrameSourceState& BeginFrameSourceState::operator=(BeginFrameSourceState&&) = default;
19294 
operator ==(const BeginFrameSourceState & other) const19295 bool BeginFrameSourceState::operator==(const BeginFrameSourceState& other) const {
19296   return unknown_fields_ == other.unknown_fields_
19297    && source_id_ == other.source_id_
19298    && paused_ == other.paused_
19299    && num_observers_ == other.num_observers_
19300    && last_begin_frame_args_ == other.last_begin_frame_args_;
19301 }
19302 
ParseFromArray(const void * raw,size_t size)19303 bool BeginFrameSourceState::ParseFromArray(const void* raw, size_t size) {
19304   unknown_fields_.clear();
19305   bool packed_error = false;
19306 
19307   ::protozero::ProtoDecoder dec(raw, size);
19308   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19309     if (field.id() < _has_field_.size()) {
19310       _has_field_.set(field.id());
19311     }
19312     switch (field.id()) {
19313       case 1 /* source_id */:
19314         field.get(&source_id_);
19315         break;
19316       case 2 /* paused */:
19317         field.get(&paused_);
19318         break;
19319       case 3 /* num_observers */:
19320         field.get(&num_observers_);
19321         break;
19322       case 4 /* last_begin_frame_args */:
19323         (*last_begin_frame_args_).ParseFromString(field.as_std_string());
19324         break;
19325       default:
19326         field.SerializeAndAppendTo(&unknown_fields_);
19327         break;
19328     }
19329   }
19330   return !packed_error && !dec.bytes_left();
19331 }
19332 
SerializeAsString() const19333 std::string BeginFrameSourceState::SerializeAsString() const {
19334   ::protozero::HeapBuffered<::protozero::Message> msg;
19335   Serialize(msg.get());
19336   return msg.SerializeAsString();
19337 }
19338 
SerializeAsArray() const19339 std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
19340   ::protozero::HeapBuffered<::protozero::Message> msg;
19341   Serialize(msg.get());
19342   return msg.SerializeAsArray();
19343 }
19344 
Serialize(::protozero::Message * msg) const19345 void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
19346   // Field 1: source_id
19347   if (_has_field_[1]) {
19348     msg->AppendVarInt(1, source_id_);
19349   }
19350 
19351   // Field 2: paused
19352   if (_has_field_[2]) {
19353     msg->AppendTinyVarInt(2, paused_);
19354   }
19355 
19356   // Field 3: num_observers
19357   if (_has_field_[3]) {
19358     msg->AppendVarInt(3, num_observers_);
19359   }
19360 
19361   // Field 4: last_begin_frame_args
19362   if (_has_field_[4]) {
19363     (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
19364   }
19365 
19366   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19367 }
19368 
19369 
19370 BeginFrameArgs::BeginFrameArgs() = default;
19371 BeginFrameArgs::~BeginFrameArgs() = default;
19372 BeginFrameArgs::BeginFrameArgs(const BeginFrameArgs&) = default;
19373 BeginFrameArgs& BeginFrameArgs::operator=(const BeginFrameArgs&) = default;
19374 BeginFrameArgs::BeginFrameArgs(BeginFrameArgs&&) noexcept = default;
19375 BeginFrameArgs& BeginFrameArgs::operator=(BeginFrameArgs&&) = default;
19376 
operator ==(const BeginFrameArgs & other) const19377 bool BeginFrameArgs::operator==(const BeginFrameArgs& other) const {
19378   return unknown_fields_ == other.unknown_fields_
19379    && type_ == other.type_
19380    && source_id_ == other.source_id_
19381    && sequence_number_ == other.sequence_number_
19382    && frame_time_us_ == other.frame_time_us_
19383    && deadline_us_ == other.deadline_us_
19384    && interval_delta_us_ == other.interval_delta_us_
19385    && on_critical_path_ == other.on_critical_path_
19386    && animate_only_ == other.animate_only_
19387    && source_location_iid_ == other.source_location_iid_
19388    && source_location_ == other.source_location_;
19389 }
19390 
ParseFromArray(const void * raw,size_t size)19391 bool BeginFrameArgs::ParseFromArray(const void* raw, size_t size) {
19392   unknown_fields_.clear();
19393   bool packed_error = false;
19394 
19395   ::protozero::ProtoDecoder dec(raw, size);
19396   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19397     if (field.id() < _has_field_.size()) {
19398       _has_field_.set(field.id());
19399     }
19400     switch (field.id()) {
19401       case 1 /* type */:
19402         field.get(&type_);
19403         break;
19404       case 2 /* source_id */:
19405         field.get(&source_id_);
19406         break;
19407       case 3 /* sequence_number */:
19408         field.get(&sequence_number_);
19409         break;
19410       case 4 /* frame_time_us */:
19411         field.get(&frame_time_us_);
19412         break;
19413       case 5 /* deadline_us */:
19414         field.get(&deadline_us_);
19415         break;
19416       case 6 /* interval_delta_us */:
19417         field.get(&interval_delta_us_);
19418         break;
19419       case 7 /* on_critical_path */:
19420         field.get(&on_critical_path_);
19421         break;
19422       case 8 /* animate_only */:
19423         field.get(&animate_only_);
19424         break;
19425       case 9 /* source_location_iid */:
19426         field.get(&source_location_iid_);
19427         break;
19428       case 10 /* source_location */:
19429         (*source_location_).ParseFromString(field.as_std_string());
19430         break;
19431       default:
19432         field.SerializeAndAppendTo(&unknown_fields_);
19433         break;
19434     }
19435   }
19436   return !packed_error && !dec.bytes_left();
19437 }
19438 
SerializeAsString() const19439 std::string BeginFrameArgs::SerializeAsString() const {
19440   ::protozero::HeapBuffered<::protozero::Message> msg;
19441   Serialize(msg.get());
19442   return msg.SerializeAsString();
19443 }
19444 
SerializeAsArray() const19445 std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
19446   ::protozero::HeapBuffered<::protozero::Message> msg;
19447   Serialize(msg.get());
19448   return msg.SerializeAsArray();
19449 }
19450 
Serialize(::protozero::Message * msg) const19451 void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
19452   // Field 1: type
19453   if (_has_field_[1]) {
19454     msg->AppendVarInt(1, type_);
19455   }
19456 
19457   // Field 2: source_id
19458   if (_has_field_[2]) {
19459     msg->AppendVarInt(2, source_id_);
19460   }
19461 
19462   // Field 3: sequence_number
19463   if (_has_field_[3]) {
19464     msg->AppendVarInt(3, sequence_number_);
19465   }
19466 
19467   // Field 4: frame_time_us
19468   if (_has_field_[4]) {
19469     msg->AppendVarInt(4, frame_time_us_);
19470   }
19471 
19472   // Field 5: deadline_us
19473   if (_has_field_[5]) {
19474     msg->AppendVarInt(5, deadline_us_);
19475   }
19476 
19477   // Field 6: interval_delta_us
19478   if (_has_field_[6]) {
19479     msg->AppendVarInt(6, interval_delta_us_);
19480   }
19481 
19482   // Field 7: on_critical_path
19483   if (_has_field_[7]) {
19484     msg->AppendTinyVarInt(7, on_critical_path_);
19485   }
19486 
19487   // Field 8: animate_only
19488   if (_has_field_[8]) {
19489     msg->AppendTinyVarInt(8, animate_only_);
19490   }
19491 
19492   // Field 9: source_location_iid
19493   if (_has_field_[9]) {
19494     msg->AppendVarInt(9, source_location_iid_);
19495   }
19496 
19497   // Field 10: source_location
19498   if (_has_field_[10]) {
19499     (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(10));
19500   }
19501 
19502   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19503 }
19504 
19505 
19506 BeginFrameObserverState::BeginFrameObserverState() = default;
19507 BeginFrameObserverState::~BeginFrameObserverState() = default;
19508 BeginFrameObserverState::BeginFrameObserverState(const BeginFrameObserverState&) = default;
19509 BeginFrameObserverState& BeginFrameObserverState::operator=(const BeginFrameObserverState&) = default;
19510 BeginFrameObserverState::BeginFrameObserverState(BeginFrameObserverState&&) noexcept = default;
19511 BeginFrameObserverState& BeginFrameObserverState::operator=(BeginFrameObserverState&&) = default;
19512 
operator ==(const BeginFrameObserverState & other) const19513 bool BeginFrameObserverState::operator==(const BeginFrameObserverState& other) const {
19514   return unknown_fields_ == other.unknown_fields_
19515    && dropped_begin_frame_args_ == other.dropped_begin_frame_args_
19516    && last_begin_frame_args_ == other.last_begin_frame_args_;
19517 }
19518 
ParseFromArray(const void * raw,size_t size)19519 bool BeginFrameObserverState::ParseFromArray(const void* raw, size_t size) {
19520   unknown_fields_.clear();
19521   bool packed_error = false;
19522 
19523   ::protozero::ProtoDecoder dec(raw, size);
19524   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19525     if (field.id() < _has_field_.size()) {
19526       _has_field_.set(field.id());
19527     }
19528     switch (field.id()) {
19529       case 1 /* dropped_begin_frame_args */:
19530         field.get(&dropped_begin_frame_args_);
19531         break;
19532       case 2 /* last_begin_frame_args */:
19533         (*last_begin_frame_args_).ParseFromString(field.as_std_string());
19534         break;
19535       default:
19536         field.SerializeAndAppendTo(&unknown_fields_);
19537         break;
19538     }
19539   }
19540   return !packed_error && !dec.bytes_left();
19541 }
19542 
SerializeAsString() const19543 std::string BeginFrameObserverState::SerializeAsString() const {
19544   ::protozero::HeapBuffered<::protozero::Message> msg;
19545   Serialize(msg.get());
19546   return msg.SerializeAsString();
19547 }
19548 
SerializeAsArray() const19549 std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
19550   ::protozero::HeapBuffered<::protozero::Message> msg;
19551   Serialize(msg.get());
19552   return msg.SerializeAsArray();
19553 }
19554 
Serialize(::protozero::Message * msg) const19555 void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
19556   // Field 1: dropped_begin_frame_args
19557   if (_has_field_[1]) {
19558     msg->AppendVarInt(1, dropped_begin_frame_args_);
19559   }
19560 
19561   // Field 2: last_begin_frame_args
19562   if (_has_field_[2]) {
19563     (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
19564   }
19565 
19566   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19567 }
19568 
19569 
19570 BeginImplFrameArgs::BeginImplFrameArgs() = default;
19571 BeginImplFrameArgs::~BeginImplFrameArgs() = default;
19572 BeginImplFrameArgs::BeginImplFrameArgs(const BeginImplFrameArgs&) = default;
19573 BeginImplFrameArgs& BeginImplFrameArgs::operator=(const BeginImplFrameArgs&) = default;
19574 BeginImplFrameArgs::BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept = default;
19575 BeginImplFrameArgs& BeginImplFrameArgs::operator=(BeginImplFrameArgs&&) = default;
19576 
operator ==(const BeginImplFrameArgs & other) const19577 bool BeginImplFrameArgs::operator==(const BeginImplFrameArgs& other) const {
19578   return unknown_fields_ == other.unknown_fields_
19579    && updated_at_us_ == other.updated_at_us_
19580    && finished_at_us_ == other.finished_at_us_
19581    && state_ == other.state_
19582    && current_args_ == other.current_args_
19583    && last_args_ == other.last_args_
19584    && timestamps_in_us_ == other.timestamps_in_us_;
19585 }
19586 
ParseFromArray(const void * raw,size_t size)19587 bool BeginImplFrameArgs::ParseFromArray(const void* raw, size_t size) {
19588   unknown_fields_.clear();
19589   bool packed_error = false;
19590 
19591   ::protozero::ProtoDecoder dec(raw, size);
19592   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19593     if (field.id() < _has_field_.size()) {
19594       _has_field_.set(field.id());
19595     }
19596     switch (field.id()) {
19597       case 1 /* updated_at_us */:
19598         field.get(&updated_at_us_);
19599         break;
19600       case 2 /* finished_at_us */:
19601         field.get(&finished_at_us_);
19602         break;
19603       case 3 /* state */:
19604         field.get(&state_);
19605         break;
19606       case 4 /* current_args */:
19607         (*current_args_).ParseFromString(field.as_std_string());
19608         break;
19609       case 5 /* last_args */:
19610         (*last_args_).ParseFromString(field.as_std_string());
19611         break;
19612       case 6 /* timestamps_in_us */:
19613         (*timestamps_in_us_).ParseFromString(field.as_std_string());
19614         break;
19615       default:
19616         field.SerializeAndAppendTo(&unknown_fields_);
19617         break;
19618     }
19619   }
19620   return !packed_error && !dec.bytes_left();
19621 }
19622 
SerializeAsString() const19623 std::string BeginImplFrameArgs::SerializeAsString() const {
19624   ::protozero::HeapBuffered<::protozero::Message> msg;
19625   Serialize(msg.get());
19626   return msg.SerializeAsString();
19627 }
19628 
SerializeAsArray() const19629 std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
19630   ::protozero::HeapBuffered<::protozero::Message> msg;
19631   Serialize(msg.get());
19632   return msg.SerializeAsArray();
19633 }
19634 
Serialize(::protozero::Message * msg) const19635 void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
19636   // Field 1: updated_at_us
19637   if (_has_field_[1]) {
19638     msg->AppendVarInt(1, updated_at_us_);
19639   }
19640 
19641   // Field 2: finished_at_us
19642   if (_has_field_[2]) {
19643     msg->AppendVarInt(2, finished_at_us_);
19644   }
19645 
19646   // Field 3: state
19647   if (_has_field_[3]) {
19648     msg->AppendVarInt(3, state_);
19649   }
19650 
19651   // Field 4: current_args
19652   if (_has_field_[4]) {
19653     (*current_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
19654   }
19655 
19656   // Field 5: last_args
19657   if (_has_field_[5]) {
19658     (*last_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
19659   }
19660 
19661   // Field 6: timestamps_in_us
19662   if (_has_field_[6]) {
19663     (*timestamps_in_us_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
19664   }
19665 
19666   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19667 }
19668 
19669 
19670 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs() = default;
19671 BeginImplFrameArgs_TimestampsInUs::~BeginImplFrameArgs_TimestampsInUs() = default;
19672 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&) = default;
19673 BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(const BeginImplFrameArgs_TimestampsInUs&) = default;
19674 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept = default;
19675 BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(BeginImplFrameArgs_TimestampsInUs&&) = default;
19676 
operator ==(const BeginImplFrameArgs_TimestampsInUs & other) const19677 bool BeginImplFrameArgs_TimestampsInUs::operator==(const BeginImplFrameArgs_TimestampsInUs& other) const {
19678   return unknown_fields_ == other.unknown_fields_
19679    && interval_delta_ == other.interval_delta_
19680    && now_to_deadline_delta_ == other.now_to_deadline_delta_
19681    && frame_time_to_now_delta_ == other.frame_time_to_now_delta_
19682    && frame_time_to_deadline_delta_ == other.frame_time_to_deadline_delta_
19683    && now_ == other.now_
19684    && frame_time_ == other.frame_time_
19685    && deadline_ == other.deadline_;
19686 }
19687 
ParseFromArray(const void * raw,size_t size)19688 bool BeginImplFrameArgs_TimestampsInUs::ParseFromArray(const void* raw, size_t size) {
19689   unknown_fields_.clear();
19690   bool packed_error = false;
19691 
19692   ::protozero::ProtoDecoder dec(raw, size);
19693   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19694     if (field.id() < _has_field_.size()) {
19695       _has_field_.set(field.id());
19696     }
19697     switch (field.id()) {
19698       case 1 /* interval_delta */:
19699         field.get(&interval_delta_);
19700         break;
19701       case 2 /* now_to_deadline_delta */:
19702         field.get(&now_to_deadline_delta_);
19703         break;
19704       case 3 /* frame_time_to_now_delta */:
19705         field.get(&frame_time_to_now_delta_);
19706         break;
19707       case 4 /* frame_time_to_deadline_delta */:
19708         field.get(&frame_time_to_deadline_delta_);
19709         break;
19710       case 5 /* now */:
19711         field.get(&now_);
19712         break;
19713       case 6 /* frame_time */:
19714         field.get(&frame_time_);
19715         break;
19716       case 7 /* deadline */:
19717         field.get(&deadline_);
19718         break;
19719       default:
19720         field.SerializeAndAppendTo(&unknown_fields_);
19721         break;
19722     }
19723   }
19724   return !packed_error && !dec.bytes_left();
19725 }
19726 
SerializeAsString() const19727 std::string BeginImplFrameArgs_TimestampsInUs::SerializeAsString() const {
19728   ::protozero::HeapBuffered<::protozero::Message> msg;
19729   Serialize(msg.get());
19730   return msg.SerializeAsString();
19731 }
19732 
SerializeAsArray() const19733 std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
19734   ::protozero::HeapBuffered<::protozero::Message> msg;
19735   Serialize(msg.get());
19736   return msg.SerializeAsArray();
19737 }
19738 
Serialize(::protozero::Message * msg) const19739 void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
19740   // Field 1: interval_delta
19741   if (_has_field_[1]) {
19742     msg->AppendVarInt(1, interval_delta_);
19743   }
19744 
19745   // Field 2: now_to_deadline_delta
19746   if (_has_field_[2]) {
19747     msg->AppendVarInt(2, now_to_deadline_delta_);
19748   }
19749 
19750   // Field 3: frame_time_to_now_delta
19751   if (_has_field_[3]) {
19752     msg->AppendVarInt(3, frame_time_to_now_delta_);
19753   }
19754 
19755   // Field 4: frame_time_to_deadline_delta
19756   if (_has_field_[4]) {
19757     msg->AppendVarInt(4, frame_time_to_deadline_delta_);
19758   }
19759 
19760   // Field 5: now
19761   if (_has_field_[5]) {
19762     msg->AppendVarInt(5, now_);
19763   }
19764 
19765   // Field 6: frame_time
19766   if (_has_field_[6]) {
19767     msg->AppendVarInt(6, frame_time_);
19768   }
19769 
19770   // Field 7: deadline
19771   if (_has_field_[7]) {
19772     msg->AppendVarInt(7, deadline_);
19773   }
19774 
19775   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19776 }
19777 
19778 
19779 ChromeCompositorStateMachine::ChromeCompositorStateMachine() = default;
19780 ChromeCompositorStateMachine::~ChromeCompositorStateMachine() = default;
19781 ChromeCompositorStateMachine::ChromeCompositorStateMachine(const ChromeCompositorStateMachine&) = default;
19782 ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(const ChromeCompositorStateMachine&) = default;
19783 ChromeCompositorStateMachine::ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept = default;
19784 ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(ChromeCompositorStateMachine&&) = default;
19785 
operator ==(const ChromeCompositorStateMachine & other) const19786 bool ChromeCompositorStateMachine::operator==(const ChromeCompositorStateMachine& other) const {
19787   return unknown_fields_ == other.unknown_fields_
19788    && major_state_ == other.major_state_
19789    && minor_state_ == other.minor_state_;
19790 }
19791 
ParseFromArray(const void * raw,size_t size)19792 bool ChromeCompositorStateMachine::ParseFromArray(const void* raw, size_t size) {
19793   unknown_fields_.clear();
19794   bool packed_error = false;
19795 
19796   ::protozero::ProtoDecoder dec(raw, size);
19797   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19798     if (field.id() < _has_field_.size()) {
19799       _has_field_.set(field.id());
19800     }
19801     switch (field.id()) {
19802       case 1 /* major_state */:
19803         (*major_state_).ParseFromString(field.as_std_string());
19804         break;
19805       case 2 /* minor_state */:
19806         (*minor_state_).ParseFromString(field.as_std_string());
19807         break;
19808       default:
19809         field.SerializeAndAppendTo(&unknown_fields_);
19810         break;
19811     }
19812   }
19813   return !packed_error && !dec.bytes_left();
19814 }
19815 
SerializeAsString() const19816 std::string ChromeCompositorStateMachine::SerializeAsString() const {
19817   ::protozero::HeapBuffered<::protozero::Message> msg;
19818   Serialize(msg.get());
19819   return msg.SerializeAsString();
19820 }
19821 
SerializeAsArray() const19822 std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
19823   ::protozero::HeapBuffered<::protozero::Message> msg;
19824   Serialize(msg.get());
19825   return msg.SerializeAsArray();
19826 }
19827 
Serialize(::protozero::Message * msg) const19828 void ChromeCompositorStateMachine::Serialize(::protozero::Message* msg) const {
19829   // Field 1: major_state
19830   if (_has_field_[1]) {
19831     (*major_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
19832   }
19833 
19834   // Field 2: minor_state
19835   if (_has_field_[2]) {
19836     (*minor_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
19837   }
19838 
19839   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19840 }
19841 
19842 
19843 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState() = default;
19844 ChromeCompositorStateMachine_MinorState::~ChromeCompositorStateMachine_MinorState() = default;
19845 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&) = default;
19846 ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(const ChromeCompositorStateMachine_MinorState&) = default;
19847 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept = default;
19848 ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(ChromeCompositorStateMachine_MinorState&&) = default;
19849 
operator ==(const ChromeCompositorStateMachine_MinorState & other) const19850 bool ChromeCompositorStateMachine_MinorState::operator==(const ChromeCompositorStateMachine_MinorState& other) const {
19851   return unknown_fields_ == other.unknown_fields_
19852    && commit_count_ == other.commit_count_
19853    && current_frame_number_ == other.current_frame_number_
19854    && last_frame_number_submit_performed_ == other.last_frame_number_submit_performed_
19855    && last_frame_number_draw_performed_ == other.last_frame_number_draw_performed_
19856    && last_frame_number_begin_main_frame_sent_ == other.last_frame_number_begin_main_frame_sent_
19857    && did_draw_ == other.did_draw_
19858    && did_send_begin_main_frame_for_current_frame_ == other.did_send_begin_main_frame_for_current_frame_
19859    && did_notify_begin_main_frame_not_expected_until_ == other.did_notify_begin_main_frame_not_expected_until_
19860    && did_notify_begin_main_frame_not_expected_soon_ == other.did_notify_begin_main_frame_not_expected_soon_
19861    && wants_begin_main_frame_not_expected_ == other.wants_begin_main_frame_not_expected_
19862    && did_commit_during_frame_ == other.did_commit_during_frame_
19863    && did_invalidate_layer_tree_frame_sink_ == other.did_invalidate_layer_tree_frame_sink_
19864    && did_perform_impl_side_invalidaion_ == other.did_perform_impl_side_invalidaion_
19865    && did_prepare_tiles_ == other.did_prepare_tiles_
19866    && consecutive_checkerboard_animations_ == other.consecutive_checkerboard_animations_
19867    && pending_submit_frames_ == other.pending_submit_frames_
19868    && submit_frames_with_current_layer_tree_frame_sink_ == other.submit_frames_with_current_layer_tree_frame_sink_
19869    && needs_redraw_ == other.needs_redraw_
19870    && needs_prepare_tiles_ == other.needs_prepare_tiles_
19871    && needs_begin_main_frame_ == other.needs_begin_main_frame_
19872    && needs_one_begin_impl_frame_ == other.needs_one_begin_impl_frame_
19873    && visible_ == other.visible_
19874    && begin_frame_source_paused_ == other.begin_frame_source_paused_
19875    && can_draw_ == other.can_draw_
19876    && resourceless_draw_ == other.resourceless_draw_
19877    && has_pending_tree_ == other.has_pending_tree_
19878    && pending_tree_is_ready_for_activation_ == other.pending_tree_is_ready_for_activation_
19879    && active_tree_needs_first_draw_ == other.active_tree_needs_first_draw_
19880    && active_tree_is_ready_to_draw_ == other.active_tree_is_ready_to_draw_
19881    && did_create_and_initialize_first_layer_tree_frame_sink_ == other.did_create_and_initialize_first_layer_tree_frame_sink_
19882    && tree_priority_ == other.tree_priority_
19883    && scroll_handler_state_ == other.scroll_handler_state_
19884    && critical_begin_main_frame_to_activate_is_fast_ == other.critical_begin_main_frame_to_activate_is_fast_
19885    && main_thread_missed_last_deadline_ == other.main_thread_missed_last_deadline_
19886    && skip_next_begin_main_frame_to_reduce_latency_ == other.skip_next_begin_main_frame_to_reduce_latency_
19887    && video_needs_begin_frames_ == other.video_needs_begin_frames_
19888    && defer_begin_main_frame_ == other.defer_begin_main_frame_
19889    && last_commit_had_no_updates_ == other.last_commit_had_no_updates_
19890    && did_draw_in_last_frame_ == other.did_draw_in_last_frame_
19891    && did_submit_in_last_frame_ == other.did_submit_in_last_frame_
19892    && needs_impl_side_invalidation_ == other.needs_impl_side_invalidation_
19893    && current_pending_tree_is_impl_side_ == other.current_pending_tree_is_impl_side_
19894    && previous_pending_tree_was_impl_side_ == other.previous_pending_tree_was_impl_side_
19895    && processing_animation_worklets_for_active_tree_ == other.processing_animation_worklets_for_active_tree_
19896    && processing_animation_worklets_for_pending_tree_ == other.processing_animation_worklets_for_pending_tree_
19897    && processing_paint_worklets_for_pending_tree_ == other.processing_paint_worklets_for_pending_tree_;
19898 }
19899 
ParseFromArray(const void * raw,size_t size)19900 bool ChromeCompositorStateMachine_MinorState::ParseFromArray(const void* raw, size_t size) {
19901   unknown_fields_.clear();
19902   bool packed_error = false;
19903 
19904   ::protozero::ProtoDecoder dec(raw, size);
19905   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19906     if (field.id() < _has_field_.size()) {
19907       _has_field_.set(field.id());
19908     }
19909     switch (field.id()) {
19910       case 1 /* commit_count */:
19911         field.get(&commit_count_);
19912         break;
19913       case 2 /* current_frame_number */:
19914         field.get(&current_frame_number_);
19915         break;
19916       case 3 /* last_frame_number_submit_performed */:
19917         field.get(&last_frame_number_submit_performed_);
19918         break;
19919       case 4 /* last_frame_number_draw_performed */:
19920         field.get(&last_frame_number_draw_performed_);
19921         break;
19922       case 5 /* last_frame_number_begin_main_frame_sent */:
19923         field.get(&last_frame_number_begin_main_frame_sent_);
19924         break;
19925       case 6 /* did_draw */:
19926         field.get(&did_draw_);
19927         break;
19928       case 7 /* did_send_begin_main_frame_for_current_frame */:
19929         field.get(&did_send_begin_main_frame_for_current_frame_);
19930         break;
19931       case 8 /* did_notify_begin_main_frame_not_expected_until */:
19932         field.get(&did_notify_begin_main_frame_not_expected_until_);
19933         break;
19934       case 9 /* did_notify_begin_main_frame_not_expected_soon */:
19935         field.get(&did_notify_begin_main_frame_not_expected_soon_);
19936         break;
19937       case 10 /* wants_begin_main_frame_not_expected */:
19938         field.get(&wants_begin_main_frame_not_expected_);
19939         break;
19940       case 11 /* did_commit_during_frame */:
19941         field.get(&did_commit_during_frame_);
19942         break;
19943       case 12 /* did_invalidate_layer_tree_frame_sink */:
19944         field.get(&did_invalidate_layer_tree_frame_sink_);
19945         break;
19946       case 13 /* did_perform_impl_side_invalidaion */:
19947         field.get(&did_perform_impl_side_invalidaion_);
19948         break;
19949       case 14 /* did_prepare_tiles */:
19950         field.get(&did_prepare_tiles_);
19951         break;
19952       case 15 /* consecutive_checkerboard_animations */:
19953         field.get(&consecutive_checkerboard_animations_);
19954         break;
19955       case 16 /* pending_submit_frames */:
19956         field.get(&pending_submit_frames_);
19957         break;
19958       case 17 /* submit_frames_with_current_layer_tree_frame_sink */:
19959         field.get(&submit_frames_with_current_layer_tree_frame_sink_);
19960         break;
19961       case 18 /* needs_redraw */:
19962         field.get(&needs_redraw_);
19963         break;
19964       case 19 /* needs_prepare_tiles */:
19965         field.get(&needs_prepare_tiles_);
19966         break;
19967       case 20 /* needs_begin_main_frame */:
19968         field.get(&needs_begin_main_frame_);
19969         break;
19970       case 21 /* needs_one_begin_impl_frame */:
19971         field.get(&needs_one_begin_impl_frame_);
19972         break;
19973       case 22 /* visible */:
19974         field.get(&visible_);
19975         break;
19976       case 23 /* begin_frame_source_paused */:
19977         field.get(&begin_frame_source_paused_);
19978         break;
19979       case 24 /* can_draw */:
19980         field.get(&can_draw_);
19981         break;
19982       case 25 /* resourceless_draw */:
19983         field.get(&resourceless_draw_);
19984         break;
19985       case 26 /* has_pending_tree */:
19986         field.get(&has_pending_tree_);
19987         break;
19988       case 27 /* pending_tree_is_ready_for_activation */:
19989         field.get(&pending_tree_is_ready_for_activation_);
19990         break;
19991       case 28 /* active_tree_needs_first_draw */:
19992         field.get(&active_tree_needs_first_draw_);
19993         break;
19994       case 29 /* active_tree_is_ready_to_draw */:
19995         field.get(&active_tree_is_ready_to_draw_);
19996         break;
19997       case 30 /* did_create_and_initialize_first_layer_tree_frame_sink */:
19998         field.get(&did_create_and_initialize_first_layer_tree_frame_sink_);
19999         break;
20000       case 31 /* tree_priority */:
20001         field.get(&tree_priority_);
20002         break;
20003       case 32 /* scroll_handler_state */:
20004         field.get(&scroll_handler_state_);
20005         break;
20006       case 33 /* critical_begin_main_frame_to_activate_is_fast */:
20007         field.get(&critical_begin_main_frame_to_activate_is_fast_);
20008         break;
20009       case 34 /* main_thread_missed_last_deadline */:
20010         field.get(&main_thread_missed_last_deadline_);
20011         break;
20012       case 35 /* skip_next_begin_main_frame_to_reduce_latency */:
20013         field.get(&skip_next_begin_main_frame_to_reduce_latency_);
20014         break;
20015       case 36 /* video_needs_begin_frames */:
20016         field.get(&video_needs_begin_frames_);
20017         break;
20018       case 37 /* defer_begin_main_frame */:
20019         field.get(&defer_begin_main_frame_);
20020         break;
20021       case 38 /* last_commit_had_no_updates */:
20022         field.get(&last_commit_had_no_updates_);
20023         break;
20024       case 39 /* did_draw_in_last_frame */:
20025         field.get(&did_draw_in_last_frame_);
20026         break;
20027       case 40 /* did_submit_in_last_frame */:
20028         field.get(&did_submit_in_last_frame_);
20029         break;
20030       case 41 /* needs_impl_side_invalidation */:
20031         field.get(&needs_impl_side_invalidation_);
20032         break;
20033       case 42 /* current_pending_tree_is_impl_side */:
20034         field.get(&current_pending_tree_is_impl_side_);
20035         break;
20036       case 43 /* previous_pending_tree_was_impl_side */:
20037         field.get(&previous_pending_tree_was_impl_side_);
20038         break;
20039       case 44 /* processing_animation_worklets_for_active_tree */:
20040         field.get(&processing_animation_worklets_for_active_tree_);
20041         break;
20042       case 45 /* processing_animation_worklets_for_pending_tree */:
20043         field.get(&processing_animation_worklets_for_pending_tree_);
20044         break;
20045       case 46 /* processing_paint_worklets_for_pending_tree */:
20046         field.get(&processing_paint_worklets_for_pending_tree_);
20047         break;
20048       default:
20049         field.SerializeAndAppendTo(&unknown_fields_);
20050         break;
20051     }
20052   }
20053   return !packed_error && !dec.bytes_left();
20054 }
20055 
SerializeAsString() const20056 std::string ChromeCompositorStateMachine_MinorState::SerializeAsString() const {
20057   ::protozero::HeapBuffered<::protozero::Message> msg;
20058   Serialize(msg.get());
20059   return msg.SerializeAsString();
20060 }
20061 
SerializeAsArray() const20062 std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
20063   ::protozero::HeapBuffered<::protozero::Message> msg;
20064   Serialize(msg.get());
20065   return msg.SerializeAsArray();
20066 }
20067 
Serialize(::protozero::Message * msg) const20068 void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
20069   // Field 1: commit_count
20070   if (_has_field_[1]) {
20071     msg->AppendVarInt(1, commit_count_);
20072   }
20073 
20074   // Field 2: current_frame_number
20075   if (_has_field_[2]) {
20076     msg->AppendVarInt(2, current_frame_number_);
20077   }
20078 
20079   // Field 3: last_frame_number_submit_performed
20080   if (_has_field_[3]) {
20081     msg->AppendVarInt(3, last_frame_number_submit_performed_);
20082   }
20083 
20084   // Field 4: last_frame_number_draw_performed
20085   if (_has_field_[4]) {
20086     msg->AppendVarInt(4, last_frame_number_draw_performed_);
20087   }
20088 
20089   // Field 5: last_frame_number_begin_main_frame_sent
20090   if (_has_field_[5]) {
20091     msg->AppendVarInt(5, last_frame_number_begin_main_frame_sent_);
20092   }
20093 
20094   // Field 6: did_draw
20095   if (_has_field_[6]) {
20096     msg->AppendTinyVarInt(6, did_draw_);
20097   }
20098 
20099   // Field 7: did_send_begin_main_frame_for_current_frame
20100   if (_has_field_[7]) {
20101     msg->AppendTinyVarInt(7, did_send_begin_main_frame_for_current_frame_);
20102   }
20103 
20104   // Field 8: did_notify_begin_main_frame_not_expected_until
20105   if (_has_field_[8]) {
20106     msg->AppendTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_);
20107   }
20108 
20109   // Field 9: did_notify_begin_main_frame_not_expected_soon
20110   if (_has_field_[9]) {
20111     msg->AppendTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_);
20112   }
20113 
20114   // Field 10: wants_begin_main_frame_not_expected
20115   if (_has_field_[10]) {
20116     msg->AppendTinyVarInt(10, wants_begin_main_frame_not_expected_);
20117   }
20118 
20119   // Field 11: did_commit_during_frame
20120   if (_has_field_[11]) {
20121     msg->AppendTinyVarInt(11, did_commit_during_frame_);
20122   }
20123 
20124   // Field 12: did_invalidate_layer_tree_frame_sink
20125   if (_has_field_[12]) {
20126     msg->AppendTinyVarInt(12, did_invalidate_layer_tree_frame_sink_);
20127   }
20128 
20129   // Field 13: did_perform_impl_side_invalidaion
20130   if (_has_field_[13]) {
20131     msg->AppendTinyVarInt(13, did_perform_impl_side_invalidaion_);
20132   }
20133 
20134   // Field 14: did_prepare_tiles
20135   if (_has_field_[14]) {
20136     msg->AppendTinyVarInt(14, did_prepare_tiles_);
20137   }
20138 
20139   // Field 15: consecutive_checkerboard_animations
20140   if (_has_field_[15]) {
20141     msg->AppendVarInt(15, consecutive_checkerboard_animations_);
20142   }
20143 
20144   // Field 16: pending_submit_frames
20145   if (_has_field_[16]) {
20146     msg->AppendVarInt(16, pending_submit_frames_);
20147   }
20148 
20149   // Field 17: submit_frames_with_current_layer_tree_frame_sink
20150   if (_has_field_[17]) {
20151     msg->AppendVarInt(17, submit_frames_with_current_layer_tree_frame_sink_);
20152   }
20153 
20154   // Field 18: needs_redraw
20155   if (_has_field_[18]) {
20156     msg->AppendTinyVarInt(18, needs_redraw_);
20157   }
20158 
20159   // Field 19: needs_prepare_tiles
20160   if (_has_field_[19]) {
20161     msg->AppendTinyVarInt(19, needs_prepare_tiles_);
20162   }
20163 
20164   // Field 20: needs_begin_main_frame
20165   if (_has_field_[20]) {
20166     msg->AppendTinyVarInt(20, needs_begin_main_frame_);
20167   }
20168 
20169   // Field 21: needs_one_begin_impl_frame
20170   if (_has_field_[21]) {
20171     msg->AppendTinyVarInt(21, needs_one_begin_impl_frame_);
20172   }
20173 
20174   // Field 22: visible
20175   if (_has_field_[22]) {
20176     msg->AppendTinyVarInt(22, visible_);
20177   }
20178 
20179   // Field 23: begin_frame_source_paused
20180   if (_has_field_[23]) {
20181     msg->AppendTinyVarInt(23, begin_frame_source_paused_);
20182   }
20183 
20184   // Field 24: can_draw
20185   if (_has_field_[24]) {
20186     msg->AppendTinyVarInt(24, can_draw_);
20187   }
20188 
20189   // Field 25: resourceless_draw
20190   if (_has_field_[25]) {
20191     msg->AppendTinyVarInt(25, resourceless_draw_);
20192   }
20193 
20194   // Field 26: has_pending_tree
20195   if (_has_field_[26]) {
20196     msg->AppendTinyVarInt(26, has_pending_tree_);
20197   }
20198 
20199   // Field 27: pending_tree_is_ready_for_activation
20200   if (_has_field_[27]) {
20201     msg->AppendTinyVarInt(27, pending_tree_is_ready_for_activation_);
20202   }
20203 
20204   // Field 28: active_tree_needs_first_draw
20205   if (_has_field_[28]) {
20206     msg->AppendTinyVarInt(28, active_tree_needs_first_draw_);
20207   }
20208 
20209   // Field 29: active_tree_is_ready_to_draw
20210   if (_has_field_[29]) {
20211     msg->AppendTinyVarInt(29, active_tree_is_ready_to_draw_);
20212   }
20213 
20214   // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
20215   if (_has_field_[30]) {
20216     msg->AppendTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_);
20217   }
20218 
20219   // Field 31: tree_priority
20220   if (_has_field_[31]) {
20221     msg->AppendVarInt(31, tree_priority_);
20222   }
20223 
20224   // Field 32: scroll_handler_state
20225   if (_has_field_[32]) {
20226     msg->AppendVarInt(32, scroll_handler_state_);
20227   }
20228 
20229   // Field 33: critical_begin_main_frame_to_activate_is_fast
20230   if (_has_field_[33]) {
20231     msg->AppendTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_);
20232   }
20233 
20234   // Field 34: main_thread_missed_last_deadline
20235   if (_has_field_[34]) {
20236     msg->AppendTinyVarInt(34, main_thread_missed_last_deadline_);
20237   }
20238 
20239   // Field 35: skip_next_begin_main_frame_to_reduce_latency
20240   if (_has_field_[35]) {
20241     msg->AppendTinyVarInt(35, skip_next_begin_main_frame_to_reduce_latency_);
20242   }
20243 
20244   // Field 36: video_needs_begin_frames
20245   if (_has_field_[36]) {
20246     msg->AppendTinyVarInt(36, video_needs_begin_frames_);
20247   }
20248 
20249   // Field 37: defer_begin_main_frame
20250   if (_has_field_[37]) {
20251     msg->AppendTinyVarInt(37, defer_begin_main_frame_);
20252   }
20253 
20254   // Field 38: last_commit_had_no_updates
20255   if (_has_field_[38]) {
20256     msg->AppendTinyVarInt(38, last_commit_had_no_updates_);
20257   }
20258 
20259   // Field 39: did_draw_in_last_frame
20260   if (_has_field_[39]) {
20261     msg->AppendTinyVarInt(39, did_draw_in_last_frame_);
20262   }
20263 
20264   // Field 40: did_submit_in_last_frame
20265   if (_has_field_[40]) {
20266     msg->AppendTinyVarInt(40, did_submit_in_last_frame_);
20267   }
20268 
20269   // Field 41: needs_impl_side_invalidation
20270   if (_has_field_[41]) {
20271     msg->AppendTinyVarInt(41, needs_impl_side_invalidation_);
20272   }
20273 
20274   // Field 42: current_pending_tree_is_impl_side
20275   if (_has_field_[42]) {
20276     msg->AppendTinyVarInt(42, current_pending_tree_is_impl_side_);
20277   }
20278 
20279   // Field 43: previous_pending_tree_was_impl_side
20280   if (_has_field_[43]) {
20281     msg->AppendTinyVarInt(43, previous_pending_tree_was_impl_side_);
20282   }
20283 
20284   // Field 44: processing_animation_worklets_for_active_tree
20285   if (_has_field_[44]) {
20286     msg->AppendTinyVarInt(44, processing_animation_worklets_for_active_tree_);
20287   }
20288 
20289   // Field 45: processing_animation_worklets_for_pending_tree
20290   if (_has_field_[45]) {
20291     msg->AppendTinyVarInt(45, processing_animation_worklets_for_pending_tree_);
20292   }
20293 
20294   // Field 46: processing_paint_worklets_for_pending_tree
20295   if (_has_field_[46]) {
20296     msg->AppendTinyVarInt(46, processing_paint_worklets_for_pending_tree_);
20297   }
20298 
20299   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20300 }
20301 
20302 
20303 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState() = default;
20304 ChromeCompositorStateMachine_MajorState::~ChromeCompositorStateMachine_MajorState() = default;
20305 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&) = default;
20306 ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(const ChromeCompositorStateMachine_MajorState&) = default;
20307 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept = default;
20308 ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(ChromeCompositorStateMachine_MajorState&&) = default;
20309 
operator ==(const ChromeCompositorStateMachine_MajorState & other) const20310 bool ChromeCompositorStateMachine_MajorState::operator==(const ChromeCompositorStateMachine_MajorState& other) const {
20311   return unknown_fields_ == other.unknown_fields_
20312    && next_action_ == other.next_action_
20313    && begin_impl_frame_state_ == other.begin_impl_frame_state_
20314    && begin_main_frame_state_ == other.begin_main_frame_state_
20315    && layer_tree_frame_sink_state_ == other.layer_tree_frame_sink_state_
20316    && forced_redraw_state_ == other.forced_redraw_state_;
20317 }
20318 
ParseFromArray(const void * raw,size_t size)20319 bool ChromeCompositorStateMachine_MajorState::ParseFromArray(const void* raw, size_t size) {
20320   unknown_fields_.clear();
20321   bool packed_error = false;
20322 
20323   ::protozero::ProtoDecoder dec(raw, size);
20324   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20325     if (field.id() < _has_field_.size()) {
20326       _has_field_.set(field.id());
20327     }
20328     switch (field.id()) {
20329       case 1 /* next_action */:
20330         field.get(&next_action_);
20331         break;
20332       case 2 /* begin_impl_frame_state */:
20333         field.get(&begin_impl_frame_state_);
20334         break;
20335       case 3 /* begin_main_frame_state */:
20336         field.get(&begin_main_frame_state_);
20337         break;
20338       case 4 /* layer_tree_frame_sink_state */:
20339         field.get(&layer_tree_frame_sink_state_);
20340         break;
20341       case 5 /* forced_redraw_state */:
20342         field.get(&forced_redraw_state_);
20343         break;
20344       default:
20345         field.SerializeAndAppendTo(&unknown_fields_);
20346         break;
20347     }
20348   }
20349   return !packed_error && !dec.bytes_left();
20350 }
20351 
SerializeAsString() const20352 std::string ChromeCompositorStateMachine_MajorState::SerializeAsString() const {
20353   ::protozero::HeapBuffered<::protozero::Message> msg;
20354   Serialize(msg.get());
20355   return msg.SerializeAsString();
20356 }
20357 
SerializeAsArray() const20358 std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
20359   ::protozero::HeapBuffered<::protozero::Message> msg;
20360   Serialize(msg.get());
20361   return msg.SerializeAsArray();
20362 }
20363 
Serialize(::protozero::Message * msg) const20364 void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
20365   // Field 1: next_action
20366   if (_has_field_[1]) {
20367     msg->AppendVarInt(1, next_action_);
20368   }
20369 
20370   // Field 2: begin_impl_frame_state
20371   if (_has_field_[2]) {
20372     msg->AppendVarInt(2, begin_impl_frame_state_);
20373   }
20374 
20375   // Field 3: begin_main_frame_state
20376   if (_has_field_[3]) {
20377     msg->AppendVarInt(3, begin_main_frame_state_);
20378   }
20379 
20380   // Field 4: layer_tree_frame_sink_state
20381   if (_has_field_[4]) {
20382     msg->AppendVarInt(4, layer_tree_frame_sink_state_);
20383   }
20384 
20385   // Field 5: forced_redraw_state
20386   if (_has_field_[5]) {
20387     msg->AppendVarInt(5, forced_redraw_state_);
20388   }
20389 
20390   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20391 }
20392 
20393 
20394 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState() = default;
20395 ChromeCompositorSchedulerState::~ChromeCompositorSchedulerState() = default;
20396 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&) = default;
20397 ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(const ChromeCompositorSchedulerState&) = default;
20398 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept = default;
20399 ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(ChromeCompositorSchedulerState&&) = default;
20400 
operator ==(const ChromeCompositorSchedulerState & other) const20401 bool ChromeCompositorSchedulerState::operator==(const ChromeCompositorSchedulerState& other) const {
20402   return unknown_fields_ == other.unknown_fields_
20403    && state_machine_ == other.state_machine_
20404    && observing_begin_frame_source_ == other.observing_begin_frame_source_
20405    && begin_impl_frame_deadline_task_ == other.begin_impl_frame_deadline_task_
20406    && pending_begin_frame_task_ == other.pending_begin_frame_task_
20407    && skipped_last_frame_missed_exceeded_deadline_ == other.skipped_last_frame_missed_exceeded_deadline_
20408    && skipped_last_frame_to_reduce_latency_ == other.skipped_last_frame_to_reduce_latency_
20409    && inside_action_ == other.inside_action_
20410    && deadline_mode_ == other.deadline_mode_
20411    && deadline_us_ == other.deadline_us_
20412    && deadline_scheduled_at_us_ == other.deadline_scheduled_at_us_
20413    && now_us_ == other.now_us_
20414    && now_to_deadline_delta_us_ == other.now_to_deadline_delta_us_
20415    && now_to_deadline_scheduled_at_delta_us_ == other.now_to_deadline_scheduled_at_delta_us_
20416    && begin_impl_frame_args_ == other.begin_impl_frame_args_
20417    && begin_frame_observer_state_ == other.begin_frame_observer_state_
20418    && begin_frame_source_state_ == other.begin_frame_source_state_
20419    && compositor_timing_history_ == other.compositor_timing_history_;
20420 }
20421 
ParseFromArray(const void * raw,size_t size)20422 bool ChromeCompositorSchedulerState::ParseFromArray(const void* raw, size_t size) {
20423   unknown_fields_.clear();
20424   bool packed_error = false;
20425 
20426   ::protozero::ProtoDecoder dec(raw, size);
20427   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20428     if (field.id() < _has_field_.size()) {
20429       _has_field_.set(field.id());
20430     }
20431     switch (field.id()) {
20432       case 1 /* state_machine */:
20433         (*state_machine_).ParseFromString(field.as_std_string());
20434         break;
20435       case 2 /* observing_begin_frame_source */:
20436         field.get(&observing_begin_frame_source_);
20437         break;
20438       case 3 /* begin_impl_frame_deadline_task */:
20439         field.get(&begin_impl_frame_deadline_task_);
20440         break;
20441       case 4 /* pending_begin_frame_task */:
20442         field.get(&pending_begin_frame_task_);
20443         break;
20444       case 5 /* skipped_last_frame_missed_exceeded_deadline */:
20445         field.get(&skipped_last_frame_missed_exceeded_deadline_);
20446         break;
20447       case 6 /* skipped_last_frame_to_reduce_latency */:
20448         field.get(&skipped_last_frame_to_reduce_latency_);
20449         break;
20450       case 7 /* inside_action */:
20451         field.get(&inside_action_);
20452         break;
20453       case 8 /* deadline_mode */:
20454         field.get(&deadline_mode_);
20455         break;
20456       case 9 /* deadline_us */:
20457         field.get(&deadline_us_);
20458         break;
20459       case 10 /* deadline_scheduled_at_us */:
20460         field.get(&deadline_scheduled_at_us_);
20461         break;
20462       case 11 /* now_us */:
20463         field.get(&now_us_);
20464         break;
20465       case 12 /* now_to_deadline_delta_us */:
20466         field.get(&now_to_deadline_delta_us_);
20467         break;
20468       case 13 /* now_to_deadline_scheduled_at_delta_us */:
20469         field.get(&now_to_deadline_scheduled_at_delta_us_);
20470         break;
20471       case 14 /* begin_impl_frame_args */:
20472         (*begin_impl_frame_args_).ParseFromString(field.as_std_string());
20473         break;
20474       case 15 /* begin_frame_observer_state */:
20475         (*begin_frame_observer_state_).ParseFromString(field.as_std_string());
20476         break;
20477       case 16 /* begin_frame_source_state */:
20478         (*begin_frame_source_state_).ParseFromString(field.as_std_string());
20479         break;
20480       case 17 /* compositor_timing_history */:
20481         (*compositor_timing_history_).ParseFromString(field.as_std_string());
20482         break;
20483       default:
20484         field.SerializeAndAppendTo(&unknown_fields_);
20485         break;
20486     }
20487   }
20488   return !packed_error && !dec.bytes_left();
20489 }
20490 
SerializeAsString() const20491 std::string ChromeCompositorSchedulerState::SerializeAsString() const {
20492   ::protozero::HeapBuffered<::protozero::Message> msg;
20493   Serialize(msg.get());
20494   return msg.SerializeAsString();
20495 }
20496 
SerializeAsArray() const20497 std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
20498   ::protozero::HeapBuffered<::protozero::Message> msg;
20499   Serialize(msg.get());
20500   return msg.SerializeAsArray();
20501 }
20502 
Serialize(::protozero::Message * msg) const20503 void ChromeCompositorSchedulerState::Serialize(::protozero::Message* msg) const {
20504   // Field 1: state_machine
20505   if (_has_field_[1]) {
20506     (*state_machine_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
20507   }
20508 
20509   // Field 2: observing_begin_frame_source
20510   if (_has_field_[2]) {
20511     msg->AppendTinyVarInt(2, observing_begin_frame_source_);
20512   }
20513 
20514   // Field 3: begin_impl_frame_deadline_task
20515   if (_has_field_[3]) {
20516     msg->AppendTinyVarInt(3, begin_impl_frame_deadline_task_);
20517   }
20518 
20519   // Field 4: pending_begin_frame_task
20520   if (_has_field_[4]) {
20521     msg->AppendTinyVarInt(4, pending_begin_frame_task_);
20522   }
20523 
20524   // Field 5: skipped_last_frame_missed_exceeded_deadline
20525   if (_has_field_[5]) {
20526     msg->AppendTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_);
20527   }
20528 
20529   // Field 6: skipped_last_frame_to_reduce_latency
20530   if (_has_field_[6]) {
20531     msg->AppendTinyVarInt(6, skipped_last_frame_to_reduce_latency_);
20532   }
20533 
20534   // Field 7: inside_action
20535   if (_has_field_[7]) {
20536     msg->AppendVarInt(7, inside_action_);
20537   }
20538 
20539   // Field 8: deadline_mode
20540   if (_has_field_[8]) {
20541     msg->AppendVarInt(8, deadline_mode_);
20542   }
20543 
20544   // Field 9: deadline_us
20545   if (_has_field_[9]) {
20546     msg->AppendVarInt(9, deadline_us_);
20547   }
20548 
20549   // Field 10: deadline_scheduled_at_us
20550   if (_has_field_[10]) {
20551     msg->AppendVarInt(10, deadline_scheduled_at_us_);
20552   }
20553 
20554   // Field 11: now_us
20555   if (_has_field_[11]) {
20556     msg->AppendVarInt(11, now_us_);
20557   }
20558 
20559   // Field 12: now_to_deadline_delta_us
20560   if (_has_field_[12]) {
20561     msg->AppendVarInt(12, now_to_deadline_delta_us_);
20562   }
20563 
20564   // Field 13: now_to_deadline_scheduled_at_delta_us
20565   if (_has_field_[13]) {
20566     msg->AppendVarInt(13, now_to_deadline_scheduled_at_delta_us_);
20567   }
20568 
20569   // Field 14: begin_impl_frame_args
20570   if (_has_field_[14]) {
20571     (*begin_impl_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(14));
20572   }
20573 
20574   // Field 15: begin_frame_observer_state
20575   if (_has_field_[15]) {
20576     (*begin_frame_observer_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
20577   }
20578 
20579   // Field 16: begin_frame_source_state
20580   if (_has_field_[16]) {
20581     (*begin_frame_source_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
20582   }
20583 
20584   // Field 17: compositor_timing_history
20585   if (_has_field_[17]) {
20586     (*compositor_timing_history_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
20587   }
20588 
20589   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20590 }
20591 
20592 }  // namespace perfetto
20593 }  // namespace protos
20594 }  // namespace gen
20595 #pragma GCC diagnostic pop
20596 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc
20597 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h
20598 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20599 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
20600 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
20601 
20602 #include <stdint.h>
20603 #include <bitset>
20604 #include <vector>
20605 #include <string>
20606 #include <type_traits>
20607 
20608 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
20609 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
20610 // gen_amalgamated expanded: #include "perfetto/base/export.h"
20611 
20612 namespace perfetto {
20613 namespace protos {
20614 namespace gen {
20615 class ChromeFrameReporter;
20616 enum ChromeFrameReporter_State : int;
20617 enum ChromeFrameReporter_FrameDropReason : int;
20618 }  // namespace perfetto
20619 }  // namespace protos
20620 }  // namespace gen
20621 
20622 namespace protozero {
20623 class Message;
20624 }  // namespace protozero
20625 
20626 namespace perfetto {
20627 namespace protos {
20628 namespace gen {
20629 enum ChromeFrameReporter_State : int {
20630   ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED = 0,
20631   ChromeFrameReporter_State_STATE_PRESENTED_ALL = 1,
20632   ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL = 2,
20633   ChromeFrameReporter_State_STATE_DROPPED = 3,
20634 };
20635 enum ChromeFrameReporter_FrameDropReason : int {
20636   ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED = 0,
20637   ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR = 1,
20638   ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD = 2,
20639   ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR = 3,
20640 };
20641 
20642 class PERFETTO_EXPORT ChromeFrameReporter : public ::protozero::CppMessageObj {
20643  public:
20644   using State = ChromeFrameReporter_State;
20645   static constexpr auto STATE_NO_UPDATE_DESIRED = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
20646   static constexpr auto STATE_PRESENTED_ALL = ChromeFrameReporter_State_STATE_PRESENTED_ALL;
20647   static constexpr auto STATE_PRESENTED_PARTIAL = ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL;
20648   static constexpr auto STATE_DROPPED = ChromeFrameReporter_State_STATE_DROPPED;
20649   static constexpr auto State_MIN = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
20650   static constexpr auto State_MAX = ChromeFrameReporter_State_STATE_DROPPED;
20651   using FrameDropReason = ChromeFrameReporter_FrameDropReason;
20652   static constexpr auto REASON_UNSPECIFIED = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
20653   static constexpr auto REASON_DISPLAY_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR;
20654   static constexpr auto REASON_MAIN_THREAD = ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD;
20655   static constexpr auto REASON_CLIENT_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
20656   static constexpr auto FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
20657   static constexpr auto FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
20658   enum FieldNumbers {
20659     kStateFieldNumber = 1,
20660     kReasonFieldNumber = 2,
20661     kFrameSourceFieldNumber = 3,
20662     kFrameSequenceFieldNumber = 4,
20663   };
20664 
20665   ChromeFrameReporter();
20666   ~ChromeFrameReporter() override;
20667   ChromeFrameReporter(ChromeFrameReporter&&) noexcept;
20668   ChromeFrameReporter& operator=(ChromeFrameReporter&&);
20669   ChromeFrameReporter(const ChromeFrameReporter&);
20670   ChromeFrameReporter& operator=(const ChromeFrameReporter&);
20671   bool operator==(const ChromeFrameReporter&) const;
operator !=(const ChromeFrameReporter & other) const20672   bool operator!=(const ChromeFrameReporter& other) const { return !(*this == other); }
20673 
20674   bool ParseFromArray(const void*, size_t) override;
20675   std::string SerializeAsString() const override;
20676   std::vector<uint8_t> SerializeAsArray() const override;
20677   void Serialize(::protozero::Message*) const;
20678 
has_state() const20679   bool has_state() const { return _has_field_[1]; }
state() const20680   ChromeFrameReporter_State state() const { return state_; }
set_state(ChromeFrameReporter_State value)20681   void set_state(ChromeFrameReporter_State value) { state_ = value; _has_field_.set(1); }
20682 
has_reason() const20683   bool has_reason() const { return _has_field_[2]; }
reason() const20684   ChromeFrameReporter_FrameDropReason reason() const { return reason_; }
set_reason(ChromeFrameReporter_FrameDropReason value)20685   void set_reason(ChromeFrameReporter_FrameDropReason value) { reason_ = value; _has_field_.set(2); }
20686 
has_frame_source() const20687   bool has_frame_source() const { return _has_field_[3]; }
frame_source() const20688   uint64_t frame_source() const { return frame_source_; }
set_frame_source(uint64_t value)20689   void set_frame_source(uint64_t value) { frame_source_ = value; _has_field_.set(3); }
20690 
has_frame_sequence() const20691   bool has_frame_sequence() const { return _has_field_[4]; }
frame_sequence() const20692   uint64_t frame_sequence() const { return frame_sequence_; }
set_frame_sequence(uint64_t value)20693   void set_frame_sequence(uint64_t value) { frame_sequence_ = value; _has_field_.set(4); }
20694 
20695  private:
20696   ChromeFrameReporter_State state_{};
20697   ChromeFrameReporter_FrameDropReason reason_{};
20698   uint64_t frame_source_{};
20699   uint64_t frame_sequence_{};
20700 
20701   // Allows to preserve unknown protobuf fields for compatibility
20702   // with future versions of .proto files.
20703   std::string unknown_fields_;
20704 
20705   std::bitset<5> _has_field_{};
20706 };
20707 
20708 }  // namespace perfetto
20709 }  // namespace protos
20710 }  // namespace gen
20711 
20712 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
20713 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20714 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20715 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20716 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20717 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20718 #pragma GCC diagnostic push
20719 #pragma GCC diagnostic ignored "-Wfloat-equal"
20720 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
20721 
20722 namespace perfetto {
20723 namespace protos {
20724 namespace gen {
20725 
20726 ChromeFrameReporter::ChromeFrameReporter() = default;
20727 ChromeFrameReporter::~ChromeFrameReporter() = default;
20728 ChromeFrameReporter::ChromeFrameReporter(const ChromeFrameReporter&) = default;
20729 ChromeFrameReporter& ChromeFrameReporter::operator=(const ChromeFrameReporter&) = default;
20730 ChromeFrameReporter::ChromeFrameReporter(ChromeFrameReporter&&) noexcept = default;
20731 ChromeFrameReporter& ChromeFrameReporter::operator=(ChromeFrameReporter&&) = default;
20732 
operator ==(const ChromeFrameReporter & other) const20733 bool ChromeFrameReporter::operator==(const ChromeFrameReporter& other) const {
20734   return unknown_fields_ == other.unknown_fields_
20735    && state_ == other.state_
20736    && reason_ == other.reason_
20737    && frame_source_ == other.frame_source_
20738    && frame_sequence_ == other.frame_sequence_;
20739 }
20740 
ParseFromArray(const void * raw,size_t size)20741 bool ChromeFrameReporter::ParseFromArray(const void* raw, size_t size) {
20742   unknown_fields_.clear();
20743   bool packed_error = false;
20744 
20745   ::protozero::ProtoDecoder dec(raw, size);
20746   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20747     if (field.id() < _has_field_.size()) {
20748       _has_field_.set(field.id());
20749     }
20750     switch (field.id()) {
20751       case 1 /* state */:
20752         field.get(&state_);
20753         break;
20754       case 2 /* reason */:
20755         field.get(&reason_);
20756         break;
20757       case 3 /* frame_source */:
20758         field.get(&frame_source_);
20759         break;
20760       case 4 /* frame_sequence */:
20761         field.get(&frame_sequence_);
20762         break;
20763       default:
20764         field.SerializeAndAppendTo(&unknown_fields_);
20765         break;
20766     }
20767   }
20768   return !packed_error && !dec.bytes_left();
20769 }
20770 
SerializeAsString() const20771 std::string ChromeFrameReporter::SerializeAsString() const {
20772   ::protozero::HeapBuffered<::protozero::Message> msg;
20773   Serialize(msg.get());
20774   return msg.SerializeAsString();
20775 }
20776 
SerializeAsArray() const20777 std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
20778   ::protozero::HeapBuffered<::protozero::Message> msg;
20779   Serialize(msg.get());
20780   return msg.SerializeAsArray();
20781 }
20782 
Serialize(::protozero::Message * msg) const20783 void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
20784   // Field 1: state
20785   if (_has_field_[1]) {
20786     msg->AppendVarInt(1, state_);
20787   }
20788 
20789   // Field 2: reason
20790   if (_has_field_[2]) {
20791     msg->AppendVarInt(2, reason_);
20792   }
20793 
20794   // Field 3: frame_source
20795   if (_has_field_[3]) {
20796     msg->AppendVarInt(3, frame_source_);
20797   }
20798 
20799   // Field 4: frame_sequence
20800   if (_has_field_[4]) {
20801     msg->AppendVarInt(4, frame_sequence_);
20802   }
20803 
20804   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20805 }
20806 
20807 }  // namespace perfetto
20808 }  // namespace protos
20809 }  // namespace gen
20810 #pragma GCC diagnostic pop
20811 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc
20812 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h
20813 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20814 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
20815 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
20816 
20817 #include <stdint.h>
20818 #include <bitset>
20819 #include <vector>
20820 #include <string>
20821 #include <type_traits>
20822 
20823 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
20824 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
20825 // gen_amalgamated expanded: #include "perfetto/base/export.h"
20826 
20827 namespace perfetto {
20828 namespace protos {
20829 namespace gen {
20830 class ChromeHistogramSample;
20831 }  // namespace perfetto
20832 }  // namespace protos
20833 }  // namespace gen
20834 
20835 namespace protozero {
20836 class Message;
20837 }  // namespace protozero
20838 
20839 namespace perfetto {
20840 namespace protos {
20841 namespace gen {
20842 
20843 class PERFETTO_EXPORT ChromeHistogramSample : public ::protozero::CppMessageObj {
20844  public:
20845   enum FieldNumbers {
20846     kNameHashFieldNumber = 1,
20847     kNameFieldNumber = 2,
20848     kSampleFieldNumber = 3,
20849   };
20850 
20851   ChromeHistogramSample();
20852   ~ChromeHistogramSample() override;
20853   ChromeHistogramSample(ChromeHistogramSample&&) noexcept;
20854   ChromeHistogramSample& operator=(ChromeHistogramSample&&);
20855   ChromeHistogramSample(const ChromeHistogramSample&);
20856   ChromeHistogramSample& operator=(const ChromeHistogramSample&);
20857   bool operator==(const ChromeHistogramSample&) const;
operator !=(const ChromeHistogramSample & other) const20858   bool operator!=(const ChromeHistogramSample& other) const { return !(*this == other); }
20859 
20860   bool ParseFromArray(const void*, size_t) override;
20861   std::string SerializeAsString() const override;
20862   std::vector<uint8_t> SerializeAsArray() const override;
20863   void Serialize(::protozero::Message*) const;
20864 
has_name_hash() const20865   bool has_name_hash() const { return _has_field_[1]; }
name_hash() const20866   uint64_t name_hash() const { return name_hash_; }
set_name_hash(uint64_t value)20867   void set_name_hash(uint64_t value) { name_hash_ = value; _has_field_.set(1); }
20868 
has_name() const20869   bool has_name() const { return _has_field_[2]; }
name() const20870   const std::string& name() const { return name_; }
set_name(const std::string & value)20871   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
20872 
has_sample() const20873   bool has_sample() const { return _has_field_[3]; }
sample() const20874   int64_t sample() const { return sample_; }
set_sample(int64_t value)20875   void set_sample(int64_t value) { sample_ = value; _has_field_.set(3); }
20876 
20877  private:
20878   uint64_t name_hash_{};
20879   std::string name_{};
20880   int64_t sample_{};
20881 
20882   // Allows to preserve unknown protobuf fields for compatibility
20883   // with future versions of .proto files.
20884   std::string unknown_fields_;
20885 
20886   std::bitset<4> _has_field_{};
20887 };
20888 
20889 }  // namespace perfetto
20890 }  // namespace protos
20891 }  // namespace gen
20892 
20893 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
20894 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20895 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20896 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20897 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20898 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20899 #pragma GCC diagnostic push
20900 #pragma GCC diagnostic ignored "-Wfloat-equal"
20901 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
20902 
20903 namespace perfetto {
20904 namespace protos {
20905 namespace gen {
20906 
20907 ChromeHistogramSample::ChromeHistogramSample() = default;
20908 ChromeHistogramSample::~ChromeHistogramSample() = default;
20909 ChromeHistogramSample::ChromeHistogramSample(const ChromeHistogramSample&) = default;
20910 ChromeHistogramSample& ChromeHistogramSample::operator=(const ChromeHistogramSample&) = default;
20911 ChromeHistogramSample::ChromeHistogramSample(ChromeHistogramSample&&) noexcept = default;
20912 ChromeHistogramSample& ChromeHistogramSample::operator=(ChromeHistogramSample&&) = default;
20913 
operator ==(const ChromeHistogramSample & other) const20914 bool ChromeHistogramSample::operator==(const ChromeHistogramSample& other) const {
20915   return unknown_fields_ == other.unknown_fields_
20916    && name_hash_ == other.name_hash_
20917    && name_ == other.name_
20918    && sample_ == other.sample_;
20919 }
20920 
ParseFromArray(const void * raw,size_t size)20921 bool ChromeHistogramSample::ParseFromArray(const void* raw, size_t size) {
20922   unknown_fields_.clear();
20923   bool packed_error = false;
20924 
20925   ::protozero::ProtoDecoder dec(raw, size);
20926   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20927     if (field.id() < _has_field_.size()) {
20928       _has_field_.set(field.id());
20929     }
20930     switch (field.id()) {
20931       case 1 /* name_hash */:
20932         field.get(&name_hash_);
20933         break;
20934       case 2 /* name */:
20935         field.get(&name_);
20936         break;
20937       case 3 /* sample */:
20938         field.get(&sample_);
20939         break;
20940       default:
20941         field.SerializeAndAppendTo(&unknown_fields_);
20942         break;
20943     }
20944   }
20945   return !packed_error && !dec.bytes_left();
20946 }
20947 
SerializeAsString() const20948 std::string ChromeHistogramSample::SerializeAsString() const {
20949   ::protozero::HeapBuffered<::protozero::Message> msg;
20950   Serialize(msg.get());
20951   return msg.SerializeAsString();
20952 }
20953 
SerializeAsArray() const20954 std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
20955   ::protozero::HeapBuffered<::protozero::Message> msg;
20956   Serialize(msg.get());
20957   return msg.SerializeAsArray();
20958 }
20959 
Serialize(::protozero::Message * msg) const20960 void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
20961   // Field 1: name_hash
20962   if (_has_field_[1]) {
20963     msg->AppendVarInt(1, name_hash_);
20964   }
20965 
20966   // Field 2: name
20967   if (_has_field_[2]) {
20968     msg->AppendString(2, name_);
20969   }
20970 
20971   // Field 3: sample
20972   if (_has_field_[3]) {
20973     msg->AppendVarInt(3, sample_);
20974   }
20975 
20976   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20977 }
20978 
20979 }  // namespace perfetto
20980 }  // namespace protos
20981 }  // namespace gen
20982 #pragma GCC diagnostic pop
20983 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc
20984 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h
20985 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20986 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
20987 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
20988 
20989 #include <stdint.h>
20990 #include <bitset>
20991 #include <vector>
20992 #include <string>
20993 #include <type_traits>
20994 
20995 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
20996 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
20997 // gen_amalgamated expanded: #include "perfetto/base/export.h"
20998 
20999 namespace perfetto {
21000 namespace protos {
21001 namespace gen {
21002 class ChromeKeyedService;
21003 }  // namespace perfetto
21004 }  // namespace protos
21005 }  // namespace gen
21006 
21007 namespace protozero {
21008 class Message;
21009 }  // namespace protozero
21010 
21011 namespace perfetto {
21012 namespace protos {
21013 namespace gen {
21014 
21015 class PERFETTO_EXPORT ChromeKeyedService : public ::protozero::CppMessageObj {
21016  public:
21017   enum FieldNumbers {
21018     kNameFieldNumber = 1,
21019   };
21020 
21021   ChromeKeyedService();
21022   ~ChromeKeyedService() override;
21023   ChromeKeyedService(ChromeKeyedService&&) noexcept;
21024   ChromeKeyedService& operator=(ChromeKeyedService&&);
21025   ChromeKeyedService(const ChromeKeyedService&);
21026   ChromeKeyedService& operator=(const ChromeKeyedService&);
21027   bool operator==(const ChromeKeyedService&) const;
operator !=(const ChromeKeyedService & other) const21028   bool operator!=(const ChromeKeyedService& other) const { return !(*this == other); }
21029 
21030   bool ParseFromArray(const void*, size_t) override;
21031   std::string SerializeAsString() const override;
21032   std::vector<uint8_t> SerializeAsArray() const override;
21033   void Serialize(::protozero::Message*) const;
21034 
has_name() const21035   bool has_name() const { return _has_field_[1]; }
name() const21036   const std::string& name() const { return name_; }
set_name(const std::string & value)21037   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
21038 
21039  private:
21040   std::string name_{};
21041 
21042   // Allows to preserve unknown protobuf fields for compatibility
21043   // with future versions of .proto files.
21044   std::string unknown_fields_;
21045 
21046   std::bitset<2> _has_field_{};
21047 };
21048 
21049 }  // namespace perfetto
21050 }  // namespace protos
21051 }  // namespace gen
21052 
21053 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
21054 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21055 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21056 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21057 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21058 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21059 #pragma GCC diagnostic push
21060 #pragma GCC diagnostic ignored "-Wfloat-equal"
21061 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
21062 
21063 namespace perfetto {
21064 namespace protos {
21065 namespace gen {
21066 
21067 ChromeKeyedService::ChromeKeyedService() = default;
21068 ChromeKeyedService::~ChromeKeyedService() = default;
21069 ChromeKeyedService::ChromeKeyedService(const ChromeKeyedService&) = default;
21070 ChromeKeyedService& ChromeKeyedService::operator=(const ChromeKeyedService&) = default;
21071 ChromeKeyedService::ChromeKeyedService(ChromeKeyedService&&) noexcept = default;
21072 ChromeKeyedService& ChromeKeyedService::operator=(ChromeKeyedService&&) = default;
21073 
operator ==(const ChromeKeyedService & other) const21074 bool ChromeKeyedService::operator==(const ChromeKeyedService& other) const {
21075   return unknown_fields_ == other.unknown_fields_
21076    && name_ == other.name_;
21077 }
21078 
ParseFromArray(const void * raw,size_t size)21079 bool ChromeKeyedService::ParseFromArray(const void* raw, size_t size) {
21080   unknown_fields_.clear();
21081   bool packed_error = false;
21082 
21083   ::protozero::ProtoDecoder dec(raw, size);
21084   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21085     if (field.id() < _has_field_.size()) {
21086       _has_field_.set(field.id());
21087     }
21088     switch (field.id()) {
21089       case 1 /* name */:
21090         field.get(&name_);
21091         break;
21092       default:
21093         field.SerializeAndAppendTo(&unknown_fields_);
21094         break;
21095     }
21096   }
21097   return !packed_error && !dec.bytes_left();
21098 }
21099 
SerializeAsString() const21100 std::string ChromeKeyedService::SerializeAsString() const {
21101   ::protozero::HeapBuffered<::protozero::Message> msg;
21102   Serialize(msg.get());
21103   return msg.SerializeAsString();
21104 }
21105 
SerializeAsArray() const21106 std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
21107   ::protozero::HeapBuffered<::protozero::Message> msg;
21108   Serialize(msg.get());
21109   return msg.SerializeAsArray();
21110 }
21111 
Serialize(::protozero::Message * msg) const21112 void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
21113   // Field 1: name
21114   if (_has_field_[1]) {
21115     msg->AppendString(1, name_);
21116   }
21117 
21118   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21119 }
21120 
21121 }  // namespace perfetto
21122 }  // namespace protos
21123 }  // namespace gen
21124 #pragma GCC diagnostic pop
21125 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc
21126 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.h
21127 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21128 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
21129 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
21130 
21131 #include <stdint.h>
21132 #include <bitset>
21133 #include <vector>
21134 #include <string>
21135 #include <type_traits>
21136 
21137 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21138 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21139 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21140 
21141 namespace perfetto {
21142 namespace protos {
21143 namespace gen {
21144 class ChromeLatencyInfo;
21145 class ChromeLatencyInfo_ComponentInfo;
21146 enum ChromeLatencyInfo_Step : int;
21147 enum ChromeLatencyInfo_LatencyComponentType : int;
21148 }  // namespace perfetto
21149 }  // namespace protos
21150 }  // namespace gen
21151 
21152 namespace protozero {
21153 class Message;
21154 }  // namespace protozero
21155 
21156 namespace perfetto {
21157 namespace protos {
21158 namespace gen {
21159 enum ChromeLatencyInfo_Step : int {
21160   ChromeLatencyInfo_Step_STEP_UNSPECIFIED = 0,
21161   ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI = 3,
21162   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL = 5,
21163   ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
21164   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN = 4,
21165   ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
21166   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
21167   ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
21168   ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL = 10,
21169   ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS = 6,
21170   ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP = 7,
21171 };
21172 enum ChromeLatencyInfo_LatencyComponentType : int {
21173   ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED = 0,
21174   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
21175   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
21176   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
21177   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
21178   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
21179   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
21180   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
21181   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
21182   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
21183   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
21184   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
21185   ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
21186   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
21187   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
21188 };
21189 
21190 class PERFETTO_EXPORT ChromeLatencyInfo : public ::protozero::CppMessageObj {
21191  public:
21192   using ComponentInfo = ChromeLatencyInfo_ComponentInfo;
21193   using Step = ChromeLatencyInfo_Step;
21194   static constexpr auto STEP_UNSPECIFIED = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
21195   static constexpr auto STEP_SEND_INPUT_EVENT_UI = ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI;
21196   static constexpr auto STEP_HANDLE_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL;
21197   static constexpr auto STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
21198   static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN;
21199   static constexpr auto STEP_MAIN_THREAD_SCROLL_UPDATE = ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE;
21200   static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
21201   static constexpr auto STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
21202   static constexpr auto STEP_HANDLED_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
21203   static constexpr auto STEP_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS;
21204   static constexpr auto STEP_DRAW_AND_SWAP = ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP;
21205   static constexpr auto Step_MIN = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
21206   static constexpr auto Step_MAX = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
21207   using LatencyComponentType = ChromeLatencyInfo_LatencyComponentType;
21208   static constexpr auto COMPONENT_UNSPECIFIED = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
21209   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
21210   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
21211   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
21212   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
21213   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_UI = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI;
21214   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
21215   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
21216   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
21217   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
21218   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
21219   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
21220   static constexpr auto COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
21221   static constexpr auto COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
21222   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
21223   static constexpr auto LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
21224   static constexpr auto LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
21225   enum FieldNumbers {
21226     kTraceIdFieldNumber = 1,
21227     kStepFieldNumber = 2,
21228     kFrameTreeNodeIdFieldNumber = 3,
21229     kComponentInfoFieldNumber = 4,
21230     kIsCoalescedFieldNumber = 5,
21231     kGestureScrollIdFieldNumber = 6,
21232   };
21233 
21234   ChromeLatencyInfo();
21235   ~ChromeLatencyInfo() override;
21236   ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept;
21237   ChromeLatencyInfo& operator=(ChromeLatencyInfo&&);
21238   ChromeLatencyInfo(const ChromeLatencyInfo&);
21239   ChromeLatencyInfo& operator=(const ChromeLatencyInfo&);
21240   bool operator==(const ChromeLatencyInfo&) const;
operator !=(const ChromeLatencyInfo & other) const21241   bool operator!=(const ChromeLatencyInfo& other) const { return !(*this == other); }
21242 
21243   bool ParseFromArray(const void*, size_t) override;
21244   std::string SerializeAsString() const override;
21245   std::vector<uint8_t> SerializeAsArray() const override;
21246   void Serialize(::protozero::Message*) const;
21247 
has_trace_id() const21248   bool has_trace_id() const { return _has_field_[1]; }
trace_id() const21249   int64_t trace_id() const { return trace_id_; }
set_trace_id(int64_t value)21250   void set_trace_id(int64_t value) { trace_id_ = value; _has_field_.set(1); }
21251 
has_step() const21252   bool has_step() const { return _has_field_[2]; }
step() const21253   ChromeLatencyInfo_Step step() const { return step_; }
set_step(ChromeLatencyInfo_Step value)21254   void set_step(ChromeLatencyInfo_Step value) { step_ = value; _has_field_.set(2); }
21255 
has_frame_tree_node_id() const21256   bool has_frame_tree_node_id() const { return _has_field_[3]; }
frame_tree_node_id() const21257   int32_t frame_tree_node_id() const { return frame_tree_node_id_; }
set_frame_tree_node_id(int32_t value)21258   void set_frame_tree_node_id(int32_t value) { frame_tree_node_id_ = value; _has_field_.set(3); }
21259 
component_info_size() const21260   int component_info_size() const { return static_cast<int>(component_info_.size()); }
component_info() const21261   const std::vector<ChromeLatencyInfo_ComponentInfo>& component_info() const { return component_info_; }
mutable_component_info()21262   std::vector<ChromeLatencyInfo_ComponentInfo>* mutable_component_info() { return &component_info_; }
clear_component_info()21263   void clear_component_info() { component_info_.clear(); }
add_component_info()21264   ChromeLatencyInfo_ComponentInfo* add_component_info() { component_info_.emplace_back(); return &component_info_.back(); }
21265 
has_is_coalesced() const21266   bool has_is_coalesced() const { return _has_field_[5]; }
is_coalesced() const21267   bool is_coalesced() const { return is_coalesced_; }
set_is_coalesced(bool value)21268   void set_is_coalesced(bool value) { is_coalesced_ = value; _has_field_.set(5); }
21269 
has_gesture_scroll_id() const21270   bool has_gesture_scroll_id() const { return _has_field_[6]; }
gesture_scroll_id() const21271   int64_t gesture_scroll_id() const { return gesture_scroll_id_; }
set_gesture_scroll_id(int64_t value)21272   void set_gesture_scroll_id(int64_t value) { gesture_scroll_id_ = value; _has_field_.set(6); }
21273 
21274  private:
21275   int64_t trace_id_{};
21276   ChromeLatencyInfo_Step step_{};
21277   int32_t frame_tree_node_id_{};
21278   std::vector<ChromeLatencyInfo_ComponentInfo> component_info_;
21279   bool is_coalesced_{};
21280   int64_t gesture_scroll_id_{};
21281 
21282   // Allows to preserve unknown protobuf fields for compatibility
21283   // with future versions of .proto files.
21284   std::string unknown_fields_;
21285 
21286   std::bitset<7> _has_field_{};
21287 };
21288 
21289 
21290 class PERFETTO_EXPORT ChromeLatencyInfo_ComponentInfo : public ::protozero::CppMessageObj {
21291  public:
21292   enum FieldNumbers {
21293     kComponentTypeFieldNumber = 1,
21294     kTimeUsFieldNumber = 2,
21295   };
21296 
21297   ChromeLatencyInfo_ComponentInfo();
21298   ~ChromeLatencyInfo_ComponentInfo() override;
21299   ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept;
21300   ChromeLatencyInfo_ComponentInfo& operator=(ChromeLatencyInfo_ComponentInfo&&);
21301   ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&);
21302   ChromeLatencyInfo_ComponentInfo& operator=(const ChromeLatencyInfo_ComponentInfo&);
21303   bool operator==(const ChromeLatencyInfo_ComponentInfo&) const;
operator !=(const ChromeLatencyInfo_ComponentInfo & other) const21304   bool operator!=(const ChromeLatencyInfo_ComponentInfo& other) const { return !(*this == other); }
21305 
21306   bool ParseFromArray(const void*, size_t) override;
21307   std::string SerializeAsString() const override;
21308   std::vector<uint8_t> SerializeAsArray() const override;
21309   void Serialize(::protozero::Message*) const;
21310 
has_component_type() const21311   bool has_component_type() const { return _has_field_[1]; }
component_type() const21312   ChromeLatencyInfo_LatencyComponentType component_type() const { return component_type_; }
set_component_type(ChromeLatencyInfo_LatencyComponentType value)21313   void set_component_type(ChromeLatencyInfo_LatencyComponentType value) { component_type_ = value; _has_field_.set(1); }
21314 
has_time_us() const21315   bool has_time_us() const { return _has_field_[2]; }
time_us() const21316   uint64_t time_us() const { return time_us_; }
set_time_us(uint64_t value)21317   void set_time_us(uint64_t value) { time_us_ = value; _has_field_.set(2); }
21318 
21319  private:
21320   ChromeLatencyInfo_LatencyComponentType component_type_{};
21321   uint64_t time_us_{};
21322 
21323   // Allows to preserve unknown protobuf fields for compatibility
21324   // with future versions of .proto files.
21325   std::string unknown_fields_;
21326 
21327   std::bitset<3> _has_field_{};
21328 };
21329 
21330 }  // namespace perfetto
21331 }  // namespace protos
21332 }  // namespace gen
21333 
21334 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
21335 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21336 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21337 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21338 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21339 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21340 #pragma GCC diagnostic push
21341 #pragma GCC diagnostic ignored "-Wfloat-equal"
21342 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
21343 
21344 namespace perfetto {
21345 namespace protos {
21346 namespace gen {
21347 
21348 ChromeLatencyInfo::ChromeLatencyInfo() = default;
21349 ChromeLatencyInfo::~ChromeLatencyInfo() = default;
21350 ChromeLatencyInfo::ChromeLatencyInfo(const ChromeLatencyInfo&) = default;
21351 ChromeLatencyInfo& ChromeLatencyInfo::operator=(const ChromeLatencyInfo&) = default;
21352 ChromeLatencyInfo::ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept = default;
21353 ChromeLatencyInfo& ChromeLatencyInfo::operator=(ChromeLatencyInfo&&) = default;
21354 
operator ==(const ChromeLatencyInfo & other) const21355 bool ChromeLatencyInfo::operator==(const ChromeLatencyInfo& other) const {
21356   return unknown_fields_ == other.unknown_fields_
21357    && trace_id_ == other.trace_id_
21358    && step_ == other.step_
21359    && frame_tree_node_id_ == other.frame_tree_node_id_
21360    && component_info_ == other.component_info_
21361    && is_coalesced_ == other.is_coalesced_
21362    && gesture_scroll_id_ == other.gesture_scroll_id_;
21363 }
21364 
ParseFromArray(const void * raw,size_t size)21365 bool ChromeLatencyInfo::ParseFromArray(const void* raw, size_t size) {
21366   component_info_.clear();
21367   unknown_fields_.clear();
21368   bool packed_error = false;
21369 
21370   ::protozero::ProtoDecoder dec(raw, size);
21371   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21372     if (field.id() < _has_field_.size()) {
21373       _has_field_.set(field.id());
21374     }
21375     switch (field.id()) {
21376       case 1 /* trace_id */:
21377         field.get(&trace_id_);
21378         break;
21379       case 2 /* step */:
21380         field.get(&step_);
21381         break;
21382       case 3 /* frame_tree_node_id */:
21383         field.get(&frame_tree_node_id_);
21384         break;
21385       case 4 /* component_info */:
21386         component_info_.emplace_back();
21387         component_info_.back().ParseFromString(field.as_std_string());
21388         break;
21389       case 5 /* is_coalesced */:
21390         field.get(&is_coalesced_);
21391         break;
21392       case 6 /* gesture_scroll_id */:
21393         field.get(&gesture_scroll_id_);
21394         break;
21395       default:
21396         field.SerializeAndAppendTo(&unknown_fields_);
21397         break;
21398     }
21399   }
21400   return !packed_error && !dec.bytes_left();
21401 }
21402 
SerializeAsString() const21403 std::string ChromeLatencyInfo::SerializeAsString() const {
21404   ::protozero::HeapBuffered<::protozero::Message> msg;
21405   Serialize(msg.get());
21406   return msg.SerializeAsString();
21407 }
21408 
SerializeAsArray() const21409 std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
21410   ::protozero::HeapBuffered<::protozero::Message> msg;
21411   Serialize(msg.get());
21412   return msg.SerializeAsArray();
21413 }
21414 
Serialize(::protozero::Message * msg) const21415 void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
21416   // Field 1: trace_id
21417   if (_has_field_[1]) {
21418     msg->AppendVarInt(1, trace_id_);
21419   }
21420 
21421   // Field 2: step
21422   if (_has_field_[2]) {
21423     msg->AppendVarInt(2, step_);
21424   }
21425 
21426   // Field 3: frame_tree_node_id
21427   if (_has_field_[3]) {
21428     msg->AppendVarInt(3, frame_tree_node_id_);
21429   }
21430 
21431   // Field 4: component_info
21432   for (auto& it : component_info_) {
21433     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
21434   }
21435 
21436   // Field 5: is_coalesced
21437   if (_has_field_[5]) {
21438     msg->AppendTinyVarInt(5, is_coalesced_);
21439   }
21440 
21441   // Field 6: gesture_scroll_id
21442   if (_has_field_[6]) {
21443     msg->AppendVarInt(6, gesture_scroll_id_);
21444   }
21445 
21446   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21447 }
21448 
21449 
21450 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo() = default;
21451 ChromeLatencyInfo_ComponentInfo::~ChromeLatencyInfo_ComponentInfo() = default;
21452 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&) = default;
21453 ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(const ChromeLatencyInfo_ComponentInfo&) = default;
21454 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept = default;
21455 ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(ChromeLatencyInfo_ComponentInfo&&) = default;
21456 
operator ==(const ChromeLatencyInfo_ComponentInfo & other) const21457 bool ChromeLatencyInfo_ComponentInfo::operator==(const ChromeLatencyInfo_ComponentInfo& other) const {
21458   return unknown_fields_ == other.unknown_fields_
21459    && component_type_ == other.component_type_
21460    && time_us_ == other.time_us_;
21461 }
21462 
ParseFromArray(const void * raw,size_t size)21463 bool ChromeLatencyInfo_ComponentInfo::ParseFromArray(const void* raw, size_t size) {
21464   unknown_fields_.clear();
21465   bool packed_error = false;
21466 
21467   ::protozero::ProtoDecoder dec(raw, size);
21468   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21469     if (field.id() < _has_field_.size()) {
21470       _has_field_.set(field.id());
21471     }
21472     switch (field.id()) {
21473       case 1 /* component_type */:
21474         field.get(&component_type_);
21475         break;
21476       case 2 /* time_us */:
21477         field.get(&time_us_);
21478         break;
21479       default:
21480         field.SerializeAndAppendTo(&unknown_fields_);
21481         break;
21482     }
21483   }
21484   return !packed_error && !dec.bytes_left();
21485 }
21486 
SerializeAsString() const21487 std::string ChromeLatencyInfo_ComponentInfo::SerializeAsString() const {
21488   ::protozero::HeapBuffered<::protozero::Message> msg;
21489   Serialize(msg.get());
21490   return msg.SerializeAsString();
21491 }
21492 
SerializeAsArray() const21493 std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
21494   ::protozero::HeapBuffered<::protozero::Message> msg;
21495   Serialize(msg.get());
21496   return msg.SerializeAsArray();
21497 }
21498 
Serialize(::protozero::Message * msg) const21499 void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
21500   // Field 1: component_type
21501   if (_has_field_[1]) {
21502     msg->AppendVarInt(1, component_type_);
21503   }
21504 
21505   // Field 2: time_us
21506   if (_has_field_[2]) {
21507     msg->AppendVarInt(2, time_us_);
21508   }
21509 
21510   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21511 }
21512 
21513 }  // namespace perfetto
21514 }  // namespace protos
21515 }  // namespace gen
21516 #pragma GCC diagnostic pop
21517 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc
21518 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h
21519 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21520 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
21521 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
21522 
21523 #include <stdint.h>
21524 #include <bitset>
21525 #include <vector>
21526 #include <string>
21527 #include <type_traits>
21528 
21529 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21530 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21531 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21532 
21533 namespace perfetto {
21534 namespace protos {
21535 namespace gen {
21536 class ChromeLegacyIpc;
21537 enum ChromeLegacyIpc_MessageClass : int;
21538 }  // namespace perfetto
21539 }  // namespace protos
21540 }  // namespace gen
21541 
21542 namespace protozero {
21543 class Message;
21544 }  // namespace protozero
21545 
21546 namespace perfetto {
21547 namespace protos {
21548 namespace gen {
21549 enum ChromeLegacyIpc_MessageClass : int {
21550   ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED = 0,
21551   ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION = 1,
21552   ChromeLegacyIpc_MessageClass_CLASS_FRAME = 2,
21553   ChromeLegacyIpc_MessageClass_CLASS_PAGE = 3,
21554   ChromeLegacyIpc_MessageClass_CLASS_VIEW = 4,
21555   ChromeLegacyIpc_MessageClass_CLASS_WIDGET = 5,
21556   ChromeLegacyIpc_MessageClass_CLASS_INPUT = 6,
21557   ChromeLegacyIpc_MessageClass_CLASS_TEST = 7,
21558   ChromeLegacyIpc_MessageClass_CLASS_WORKER = 8,
21559   ChromeLegacyIpc_MessageClass_CLASS_NACL = 9,
21560   ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL = 10,
21561   ChromeLegacyIpc_MessageClass_CLASS_MEDIA = 11,
21562   ChromeLegacyIpc_MessageClass_CLASS_PPAPI = 12,
21563   ChromeLegacyIpc_MessageClass_CLASS_CHROME = 13,
21564   ChromeLegacyIpc_MessageClass_CLASS_DRAG = 14,
21565   ChromeLegacyIpc_MessageClass_CLASS_PRINT = 15,
21566   ChromeLegacyIpc_MessageClass_CLASS_EXTENSION = 16,
21567   ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT = 17,
21568   ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST = 18,
21569   ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY = 19,
21570   ChromeLegacyIpc_MessageClass_CLASS_PRERENDER = 20,
21571   ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING = 21,
21572   ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN = 22,
21573   ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW = 23,
21574   ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST = 24,
21575   ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA = 25,
21576   ChromeLegacyIpc_MessageClass_CLASS_CAST = 26,
21577   ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE = 27,
21578   ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING = 28,
21579   ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU = 29,
21580   ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST = 30,
21581   ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS = 31,
21582   ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW = 32,
21583   ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW = 33,
21584   ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE = 34,
21585   ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER = 35,
21586   ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER = 36,
21587   ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME = 37,
21588 };
21589 
21590 class PERFETTO_EXPORT ChromeLegacyIpc : public ::protozero::CppMessageObj {
21591  public:
21592   using MessageClass = ChromeLegacyIpc_MessageClass;
21593   static constexpr auto CLASS_UNSPECIFIED = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
21594   static constexpr auto CLASS_AUTOMATION = ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION;
21595   static constexpr auto CLASS_FRAME = ChromeLegacyIpc_MessageClass_CLASS_FRAME;
21596   static constexpr auto CLASS_PAGE = ChromeLegacyIpc_MessageClass_CLASS_PAGE;
21597   static constexpr auto CLASS_VIEW = ChromeLegacyIpc_MessageClass_CLASS_VIEW;
21598   static constexpr auto CLASS_WIDGET = ChromeLegacyIpc_MessageClass_CLASS_WIDGET;
21599   static constexpr auto CLASS_INPUT = ChromeLegacyIpc_MessageClass_CLASS_INPUT;
21600   static constexpr auto CLASS_TEST = ChromeLegacyIpc_MessageClass_CLASS_TEST;
21601   static constexpr auto CLASS_WORKER = ChromeLegacyIpc_MessageClass_CLASS_WORKER;
21602   static constexpr auto CLASS_NACL = ChromeLegacyIpc_MessageClass_CLASS_NACL;
21603   static constexpr auto CLASS_GPU_CHANNEL = ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL;
21604   static constexpr auto CLASS_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_MEDIA;
21605   static constexpr auto CLASS_PPAPI = ChromeLegacyIpc_MessageClass_CLASS_PPAPI;
21606   static constexpr auto CLASS_CHROME = ChromeLegacyIpc_MessageClass_CLASS_CHROME;
21607   static constexpr auto CLASS_DRAG = ChromeLegacyIpc_MessageClass_CLASS_DRAG;
21608   static constexpr auto CLASS_PRINT = ChromeLegacyIpc_MessageClass_CLASS_PRINT;
21609   static constexpr auto CLASS_EXTENSION = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION;
21610   static constexpr auto CLASS_TEXT_INPUT_CLIENT = ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT;
21611   static constexpr auto CLASS_BLINK_TEST = ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST;
21612   static constexpr auto CLASS_ACCESSIBILITY = ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY;
21613   static constexpr auto CLASS_PRERENDER = ChromeLegacyIpc_MessageClass_CLASS_PRERENDER;
21614   static constexpr auto CLASS_CHROMOTING = ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING;
21615   static constexpr auto CLASS_BROWSER_PLUGIN = ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN;
21616   static constexpr auto CLASS_ANDROID_WEB_VIEW = ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW;
21617   static constexpr auto CLASS_NACL_HOST = ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST;
21618   static constexpr auto CLASS_ENCRYPTED_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA;
21619   static constexpr auto CLASS_CAST = ChromeLegacyIpc_MessageClass_CLASS_CAST;
21620   static constexpr auto CLASS_GIN_JAVA_BRIDGE = ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE;
21621   static constexpr auto CLASS_CHROME_UTILITY_PRINTING = ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING;
21622   static constexpr auto CLASS_OZONE_GPU = ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU;
21623   static constexpr auto CLASS_WEB_TEST = ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST;
21624   static constexpr auto CLASS_NETWORK_HINTS = ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS;
21625   static constexpr auto CLASS_EXTENSIONS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW;
21626   static constexpr auto CLASS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW;
21627   static constexpr auto CLASS_MEDIA_PLAYER_DELEGATE = ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE;
21628   static constexpr auto CLASS_EXTENSION_WORKER = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER;
21629   static constexpr auto CLASS_SUBRESOURCE_FILTER = ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER;
21630   static constexpr auto CLASS_UNFREEZABLE_FRAME = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
21631   static constexpr auto MessageClass_MIN = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
21632   static constexpr auto MessageClass_MAX = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
21633   enum FieldNumbers {
21634     kMessageClassFieldNumber = 1,
21635     kMessageLineFieldNumber = 2,
21636   };
21637 
21638   ChromeLegacyIpc();
21639   ~ChromeLegacyIpc() override;
21640   ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept;
21641   ChromeLegacyIpc& operator=(ChromeLegacyIpc&&);
21642   ChromeLegacyIpc(const ChromeLegacyIpc&);
21643   ChromeLegacyIpc& operator=(const ChromeLegacyIpc&);
21644   bool operator==(const ChromeLegacyIpc&) const;
operator !=(const ChromeLegacyIpc & other) const21645   bool operator!=(const ChromeLegacyIpc& other) const { return !(*this == other); }
21646 
21647   bool ParseFromArray(const void*, size_t) override;
21648   std::string SerializeAsString() const override;
21649   std::vector<uint8_t> SerializeAsArray() const override;
21650   void Serialize(::protozero::Message*) const;
21651 
has_message_class() const21652   bool has_message_class() const { return _has_field_[1]; }
message_class() const21653   ChromeLegacyIpc_MessageClass message_class() const { return message_class_; }
set_message_class(ChromeLegacyIpc_MessageClass value)21654   void set_message_class(ChromeLegacyIpc_MessageClass value) { message_class_ = value; _has_field_.set(1); }
21655 
has_message_line() const21656   bool has_message_line() const { return _has_field_[2]; }
message_line() const21657   uint32_t message_line() const { return message_line_; }
set_message_line(uint32_t value)21658   void set_message_line(uint32_t value) { message_line_ = value; _has_field_.set(2); }
21659 
21660  private:
21661   ChromeLegacyIpc_MessageClass message_class_{};
21662   uint32_t message_line_{};
21663 
21664   // Allows to preserve unknown protobuf fields for compatibility
21665   // with future versions of .proto files.
21666   std::string unknown_fields_;
21667 
21668   std::bitset<3> _has_field_{};
21669 };
21670 
21671 }  // namespace perfetto
21672 }  // namespace protos
21673 }  // namespace gen
21674 
21675 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
21676 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21677 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21678 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21679 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21680 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21681 #pragma GCC diagnostic push
21682 #pragma GCC diagnostic ignored "-Wfloat-equal"
21683 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
21684 
21685 namespace perfetto {
21686 namespace protos {
21687 namespace gen {
21688 
21689 ChromeLegacyIpc::ChromeLegacyIpc() = default;
21690 ChromeLegacyIpc::~ChromeLegacyIpc() = default;
21691 ChromeLegacyIpc::ChromeLegacyIpc(const ChromeLegacyIpc&) = default;
21692 ChromeLegacyIpc& ChromeLegacyIpc::operator=(const ChromeLegacyIpc&) = default;
21693 ChromeLegacyIpc::ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept = default;
21694 ChromeLegacyIpc& ChromeLegacyIpc::operator=(ChromeLegacyIpc&&) = default;
21695 
operator ==(const ChromeLegacyIpc & other) const21696 bool ChromeLegacyIpc::operator==(const ChromeLegacyIpc& other) const {
21697   return unknown_fields_ == other.unknown_fields_
21698    && message_class_ == other.message_class_
21699    && message_line_ == other.message_line_;
21700 }
21701 
ParseFromArray(const void * raw,size_t size)21702 bool ChromeLegacyIpc::ParseFromArray(const void* raw, size_t size) {
21703   unknown_fields_.clear();
21704   bool packed_error = false;
21705 
21706   ::protozero::ProtoDecoder dec(raw, size);
21707   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21708     if (field.id() < _has_field_.size()) {
21709       _has_field_.set(field.id());
21710     }
21711     switch (field.id()) {
21712       case 1 /* message_class */:
21713         field.get(&message_class_);
21714         break;
21715       case 2 /* message_line */:
21716         field.get(&message_line_);
21717         break;
21718       default:
21719         field.SerializeAndAppendTo(&unknown_fields_);
21720         break;
21721     }
21722   }
21723   return !packed_error && !dec.bytes_left();
21724 }
21725 
SerializeAsString() const21726 std::string ChromeLegacyIpc::SerializeAsString() const {
21727   ::protozero::HeapBuffered<::protozero::Message> msg;
21728   Serialize(msg.get());
21729   return msg.SerializeAsString();
21730 }
21731 
SerializeAsArray() const21732 std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
21733   ::protozero::HeapBuffered<::protozero::Message> msg;
21734   Serialize(msg.get());
21735   return msg.SerializeAsArray();
21736 }
21737 
Serialize(::protozero::Message * msg) const21738 void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
21739   // Field 1: message_class
21740   if (_has_field_[1]) {
21741     msg->AppendVarInt(1, message_class_);
21742   }
21743 
21744   // Field 2: message_line
21745   if (_has_field_[2]) {
21746     msg->AppendVarInt(2, message_line_);
21747   }
21748 
21749   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21750 }
21751 
21752 }  // namespace perfetto
21753 }  // namespace protos
21754 }  // namespace gen
21755 #pragma GCC diagnostic pop
21756 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc
21757 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h
21758 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21759 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
21760 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
21761 
21762 #include <stdint.h>
21763 #include <bitset>
21764 #include <vector>
21765 #include <string>
21766 #include <type_traits>
21767 
21768 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21769 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21770 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21771 
21772 namespace perfetto {
21773 namespace protos {
21774 namespace gen {
21775 class ChromeProcessDescriptor;
21776 enum ChromeProcessDescriptor_ProcessType : int;
21777 }  // namespace perfetto
21778 }  // namespace protos
21779 }  // namespace gen
21780 
21781 namespace protozero {
21782 class Message;
21783 }  // namespace protozero
21784 
21785 namespace perfetto {
21786 namespace protos {
21787 namespace gen {
21788 enum ChromeProcessDescriptor_ProcessType : int {
21789   ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED = 0,
21790   ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER = 1,
21791   ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER = 2,
21792   ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY = 3,
21793   ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE = 4,
21794   ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER = 5,
21795   ChromeProcessDescriptor_ProcessType_PROCESS_GPU = 6,
21796   ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN = 7,
21797   ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER = 8,
21798 };
21799 
21800 class PERFETTO_EXPORT ChromeProcessDescriptor : public ::protozero::CppMessageObj {
21801  public:
21802   using ProcessType = ChromeProcessDescriptor_ProcessType;
21803   static constexpr auto PROCESS_UNSPECIFIED = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
21804   static constexpr auto PROCESS_BROWSER = ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER;
21805   static constexpr auto PROCESS_RENDERER = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER;
21806   static constexpr auto PROCESS_UTILITY = ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY;
21807   static constexpr auto PROCESS_ZYGOTE = ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE;
21808   static constexpr auto PROCESS_SANDBOX_HELPER = ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER;
21809   static constexpr auto PROCESS_GPU = ChromeProcessDescriptor_ProcessType_PROCESS_GPU;
21810   static constexpr auto PROCESS_PPAPI_PLUGIN = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN;
21811   static constexpr auto PROCESS_PPAPI_BROKER = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
21812   static constexpr auto ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
21813   static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
21814   enum FieldNumbers {
21815     kProcessTypeFieldNumber = 1,
21816     kProcessPriorityFieldNumber = 2,
21817     kLegacySortIndexFieldNumber = 3,
21818     kHostAppPackageNameFieldNumber = 4,
21819   };
21820 
21821   ChromeProcessDescriptor();
21822   ~ChromeProcessDescriptor() override;
21823   ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept;
21824   ChromeProcessDescriptor& operator=(ChromeProcessDescriptor&&);
21825   ChromeProcessDescriptor(const ChromeProcessDescriptor&);
21826   ChromeProcessDescriptor& operator=(const ChromeProcessDescriptor&);
21827   bool operator==(const ChromeProcessDescriptor&) const;
operator !=(const ChromeProcessDescriptor & other) const21828   bool operator!=(const ChromeProcessDescriptor& other) const { return !(*this == other); }
21829 
21830   bool ParseFromArray(const void*, size_t) override;
21831   std::string SerializeAsString() const override;
21832   std::vector<uint8_t> SerializeAsArray() const override;
21833   void Serialize(::protozero::Message*) const;
21834 
has_process_type() const21835   bool has_process_type() const { return _has_field_[1]; }
process_type() const21836   ChromeProcessDescriptor_ProcessType process_type() const { return process_type_; }
set_process_type(ChromeProcessDescriptor_ProcessType value)21837   void set_process_type(ChromeProcessDescriptor_ProcessType value) { process_type_ = value; _has_field_.set(1); }
21838 
has_process_priority() const21839   bool has_process_priority() const { return _has_field_[2]; }
process_priority() const21840   int32_t process_priority() const { return process_priority_; }
set_process_priority(int32_t value)21841   void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(2); }
21842 
has_legacy_sort_index() const21843   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const21844   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)21845   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
21846 
has_host_app_package_name() const21847   bool has_host_app_package_name() const { return _has_field_[4]; }
host_app_package_name() const21848   const std::string& host_app_package_name() const { return host_app_package_name_; }
set_host_app_package_name(const std::string & value)21849   void set_host_app_package_name(const std::string& value) { host_app_package_name_ = value; _has_field_.set(4); }
21850 
21851  private:
21852   ChromeProcessDescriptor_ProcessType process_type_{};
21853   int32_t process_priority_{};
21854   int32_t legacy_sort_index_{};
21855   std::string host_app_package_name_{};
21856 
21857   // Allows to preserve unknown protobuf fields for compatibility
21858   // with future versions of .proto files.
21859   std::string unknown_fields_;
21860 
21861   std::bitset<5> _has_field_{};
21862 };
21863 
21864 }  // namespace perfetto
21865 }  // namespace protos
21866 }  // namespace gen
21867 
21868 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
21869 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21870 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21871 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21872 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21873 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21874 #pragma GCC diagnostic push
21875 #pragma GCC diagnostic ignored "-Wfloat-equal"
21876 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
21877 
21878 namespace perfetto {
21879 namespace protos {
21880 namespace gen {
21881 
21882 ChromeProcessDescriptor::ChromeProcessDescriptor() = default;
21883 ChromeProcessDescriptor::~ChromeProcessDescriptor() = default;
21884 ChromeProcessDescriptor::ChromeProcessDescriptor(const ChromeProcessDescriptor&) = default;
21885 ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(const ChromeProcessDescriptor&) = default;
21886 ChromeProcessDescriptor::ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept = default;
21887 ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(ChromeProcessDescriptor&&) = default;
21888 
operator ==(const ChromeProcessDescriptor & other) const21889 bool ChromeProcessDescriptor::operator==(const ChromeProcessDescriptor& other) const {
21890   return unknown_fields_ == other.unknown_fields_
21891    && process_type_ == other.process_type_
21892    && process_priority_ == other.process_priority_
21893    && legacy_sort_index_ == other.legacy_sort_index_
21894    && host_app_package_name_ == other.host_app_package_name_;
21895 }
21896 
ParseFromArray(const void * raw,size_t size)21897 bool ChromeProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
21898   unknown_fields_.clear();
21899   bool packed_error = false;
21900 
21901   ::protozero::ProtoDecoder dec(raw, size);
21902   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21903     if (field.id() < _has_field_.size()) {
21904       _has_field_.set(field.id());
21905     }
21906     switch (field.id()) {
21907       case 1 /* process_type */:
21908         field.get(&process_type_);
21909         break;
21910       case 2 /* process_priority */:
21911         field.get(&process_priority_);
21912         break;
21913       case 3 /* legacy_sort_index */:
21914         field.get(&legacy_sort_index_);
21915         break;
21916       case 4 /* host_app_package_name */:
21917         field.get(&host_app_package_name_);
21918         break;
21919       default:
21920         field.SerializeAndAppendTo(&unknown_fields_);
21921         break;
21922     }
21923   }
21924   return !packed_error && !dec.bytes_left();
21925 }
21926 
SerializeAsString() const21927 std::string ChromeProcessDescriptor::SerializeAsString() const {
21928   ::protozero::HeapBuffered<::protozero::Message> msg;
21929   Serialize(msg.get());
21930   return msg.SerializeAsString();
21931 }
21932 
SerializeAsArray() const21933 std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
21934   ::protozero::HeapBuffered<::protozero::Message> msg;
21935   Serialize(msg.get());
21936   return msg.SerializeAsArray();
21937 }
21938 
Serialize(::protozero::Message * msg) const21939 void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
21940   // Field 1: process_type
21941   if (_has_field_[1]) {
21942     msg->AppendVarInt(1, process_type_);
21943   }
21944 
21945   // Field 2: process_priority
21946   if (_has_field_[2]) {
21947     msg->AppendVarInt(2, process_priority_);
21948   }
21949 
21950   // Field 3: legacy_sort_index
21951   if (_has_field_[3]) {
21952     msg->AppendVarInt(3, legacy_sort_index_);
21953   }
21954 
21955   // Field 4: host_app_package_name
21956   if (_has_field_[4]) {
21957     msg->AppendString(4, host_app_package_name_);
21958   }
21959 
21960   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21961 }
21962 
21963 }  // namespace perfetto
21964 }  // namespace protos
21965 }  // namespace gen
21966 #pragma GCC diagnostic pop
21967 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc
21968 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h
21969 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21970 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
21971 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
21972 
21973 #include <stdint.h>
21974 #include <bitset>
21975 #include <vector>
21976 #include <string>
21977 #include <type_traits>
21978 
21979 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21980 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21981 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21982 
21983 namespace perfetto {
21984 namespace protos {
21985 namespace gen {
21986 class ChromeThreadDescriptor;
21987 enum ChromeThreadDescriptor_ThreadType : int;
21988 }  // namespace perfetto
21989 }  // namespace protos
21990 }  // namespace gen
21991 
21992 namespace protozero {
21993 class Message;
21994 }  // namespace protozero
21995 
21996 namespace perfetto {
21997 namespace protos {
21998 namespace gen {
21999 enum ChromeThreadDescriptor_ThreadType : int {
22000   ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED = 0,
22001   ChromeThreadDescriptor_ThreadType_THREAD_MAIN = 1,
22002   ChromeThreadDescriptor_ThreadType_THREAD_IO = 2,
22003   ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER = 3,
22004   ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER = 4,
22005   ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING = 6,
22006   ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING = 5,
22007   ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE = 7,
22008   ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR = 8,
22009   ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR = 9,
22010   ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER = 10,
22011   ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER = 11,
22012   ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA = 50,
22013   ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
22014 };
22015 
22016 class PERFETTO_EXPORT ChromeThreadDescriptor : public ::protozero::CppMessageObj {
22017  public:
22018   using ThreadType = ChromeThreadDescriptor_ThreadType;
22019   static constexpr auto THREAD_UNSPECIFIED = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
22020   static constexpr auto THREAD_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_MAIN;
22021   static constexpr auto THREAD_IO = ChromeThreadDescriptor_ThreadType_THREAD_IO;
22022   static constexpr auto THREAD_POOL_BG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER;
22023   static constexpr auto THREAD_POOL_FG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER;
22024   static constexpr auto THREAD_POOL_BG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING;
22025   static constexpr auto THREAD_POOL_FG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING;
22026   static constexpr auto THREAD_POOL_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE;
22027   static constexpr auto THREAD_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR;
22028   static constexpr auto THREAD_VIZ_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR;
22029   static constexpr auto THREAD_COMPOSITOR_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER;
22030   static constexpr auto THREAD_SERVICE_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER;
22031   static constexpr auto THREAD_MEMORY_INFRA = ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA;
22032   static constexpr auto THREAD_SAMPLING_PROFILER = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
22033   static constexpr auto ThreadType_MIN = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
22034   static constexpr auto ThreadType_MAX = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
22035   enum FieldNumbers {
22036     kThreadTypeFieldNumber = 1,
22037     kLegacySortIndexFieldNumber = 2,
22038   };
22039 
22040   ChromeThreadDescriptor();
22041   ~ChromeThreadDescriptor() override;
22042   ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept;
22043   ChromeThreadDescriptor& operator=(ChromeThreadDescriptor&&);
22044   ChromeThreadDescriptor(const ChromeThreadDescriptor&);
22045   ChromeThreadDescriptor& operator=(const ChromeThreadDescriptor&);
22046   bool operator==(const ChromeThreadDescriptor&) const;
operator !=(const ChromeThreadDescriptor & other) const22047   bool operator!=(const ChromeThreadDescriptor& other) const { return !(*this == other); }
22048 
22049   bool ParseFromArray(const void*, size_t) override;
22050   std::string SerializeAsString() const override;
22051   std::vector<uint8_t> SerializeAsArray() const override;
22052   void Serialize(::protozero::Message*) const;
22053 
has_thread_type() const22054   bool has_thread_type() const { return _has_field_[1]; }
thread_type() const22055   ChromeThreadDescriptor_ThreadType thread_type() const { return thread_type_; }
set_thread_type(ChromeThreadDescriptor_ThreadType value)22056   void set_thread_type(ChromeThreadDescriptor_ThreadType value) { thread_type_ = value; _has_field_.set(1); }
22057 
has_legacy_sort_index() const22058   bool has_legacy_sort_index() const { return _has_field_[2]; }
legacy_sort_index() const22059   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)22060   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(2); }
22061 
22062  private:
22063   ChromeThreadDescriptor_ThreadType thread_type_{};
22064   int32_t legacy_sort_index_{};
22065 
22066   // Allows to preserve unknown protobuf fields for compatibility
22067   // with future versions of .proto files.
22068   std::string unknown_fields_;
22069 
22070   std::bitset<3> _has_field_{};
22071 };
22072 
22073 }  // namespace perfetto
22074 }  // namespace protos
22075 }  // namespace gen
22076 
22077 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
22078 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22079 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22080 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22081 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22082 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22083 #pragma GCC diagnostic push
22084 #pragma GCC diagnostic ignored "-Wfloat-equal"
22085 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
22086 
22087 namespace perfetto {
22088 namespace protos {
22089 namespace gen {
22090 
22091 ChromeThreadDescriptor::ChromeThreadDescriptor() = default;
22092 ChromeThreadDescriptor::~ChromeThreadDescriptor() = default;
22093 ChromeThreadDescriptor::ChromeThreadDescriptor(const ChromeThreadDescriptor&) = default;
22094 ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(const ChromeThreadDescriptor&) = default;
22095 ChromeThreadDescriptor::ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept = default;
22096 ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(ChromeThreadDescriptor&&) = default;
22097 
operator ==(const ChromeThreadDescriptor & other) const22098 bool ChromeThreadDescriptor::operator==(const ChromeThreadDescriptor& other) const {
22099   return unknown_fields_ == other.unknown_fields_
22100    && thread_type_ == other.thread_type_
22101    && legacy_sort_index_ == other.legacy_sort_index_;
22102 }
22103 
ParseFromArray(const void * raw,size_t size)22104 bool ChromeThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
22105   unknown_fields_.clear();
22106   bool packed_error = false;
22107 
22108   ::protozero::ProtoDecoder dec(raw, size);
22109   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22110     if (field.id() < _has_field_.size()) {
22111       _has_field_.set(field.id());
22112     }
22113     switch (field.id()) {
22114       case 1 /* thread_type */:
22115         field.get(&thread_type_);
22116         break;
22117       case 2 /* legacy_sort_index */:
22118         field.get(&legacy_sort_index_);
22119         break;
22120       default:
22121         field.SerializeAndAppendTo(&unknown_fields_);
22122         break;
22123     }
22124   }
22125   return !packed_error && !dec.bytes_left();
22126 }
22127 
SerializeAsString() const22128 std::string ChromeThreadDescriptor::SerializeAsString() const {
22129   ::protozero::HeapBuffered<::protozero::Message> msg;
22130   Serialize(msg.get());
22131   return msg.SerializeAsString();
22132 }
22133 
SerializeAsArray() const22134 std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
22135   ::protozero::HeapBuffered<::protozero::Message> msg;
22136   Serialize(msg.get());
22137   return msg.SerializeAsArray();
22138 }
22139 
Serialize(::protozero::Message * msg) const22140 void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
22141   // Field 1: thread_type
22142   if (_has_field_[1]) {
22143     msg->AppendVarInt(1, thread_type_);
22144   }
22145 
22146   // Field 2: legacy_sort_index
22147   if (_has_field_[2]) {
22148     msg->AppendVarInt(2, legacy_sort_index_);
22149   }
22150 
22151   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22152 }
22153 
22154 }  // namespace perfetto
22155 }  // namespace protos
22156 }  // namespace gen
22157 #pragma GCC diagnostic pop
22158 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.cc
22159 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.h
22160 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22161 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
22162 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
22163 
22164 #include <stdint.h>
22165 #include <bitset>
22166 #include <vector>
22167 #include <string>
22168 #include <type_traits>
22169 
22170 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
22171 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
22172 // gen_amalgamated expanded: #include "perfetto/base/export.h"
22173 
22174 namespace perfetto {
22175 namespace protos {
22176 namespace gen {
22177 class ChromeUserEvent;
22178 }  // namespace perfetto
22179 }  // namespace protos
22180 }  // namespace gen
22181 
22182 namespace protozero {
22183 class Message;
22184 }  // namespace protozero
22185 
22186 namespace perfetto {
22187 namespace protos {
22188 namespace gen {
22189 
22190 class PERFETTO_EXPORT ChromeUserEvent : public ::protozero::CppMessageObj {
22191  public:
22192   enum FieldNumbers {
22193     kActionFieldNumber = 1,
22194     kActionHashFieldNumber = 2,
22195   };
22196 
22197   ChromeUserEvent();
22198   ~ChromeUserEvent() override;
22199   ChromeUserEvent(ChromeUserEvent&&) noexcept;
22200   ChromeUserEvent& operator=(ChromeUserEvent&&);
22201   ChromeUserEvent(const ChromeUserEvent&);
22202   ChromeUserEvent& operator=(const ChromeUserEvent&);
22203   bool operator==(const ChromeUserEvent&) const;
operator !=(const ChromeUserEvent & other) const22204   bool operator!=(const ChromeUserEvent& other) const { return !(*this == other); }
22205 
22206   bool ParseFromArray(const void*, size_t) override;
22207   std::string SerializeAsString() const override;
22208   std::vector<uint8_t> SerializeAsArray() const override;
22209   void Serialize(::protozero::Message*) const;
22210 
has_action() const22211   bool has_action() const { return _has_field_[1]; }
action() const22212   const std::string& action() const { return action_; }
set_action(const std::string & value)22213   void set_action(const std::string& value) { action_ = value; _has_field_.set(1); }
22214 
has_action_hash() const22215   bool has_action_hash() const { return _has_field_[2]; }
action_hash() const22216   uint64_t action_hash() const { return action_hash_; }
set_action_hash(uint64_t value)22217   void set_action_hash(uint64_t value) { action_hash_ = value; _has_field_.set(2); }
22218 
22219  private:
22220   std::string action_{};
22221   uint64_t action_hash_{};
22222 
22223   // Allows to preserve unknown protobuf fields for compatibility
22224   // with future versions of .proto files.
22225   std::string unknown_fields_;
22226 
22227   std::bitset<3> _has_field_{};
22228 };
22229 
22230 }  // namespace perfetto
22231 }  // namespace protos
22232 }  // namespace gen
22233 
22234 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
22235 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22236 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22237 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22238 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22239 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22240 #pragma GCC diagnostic push
22241 #pragma GCC diagnostic ignored "-Wfloat-equal"
22242 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
22243 
22244 namespace perfetto {
22245 namespace protos {
22246 namespace gen {
22247 
22248 ChromeUserEvent::ChromeUserEvent() = default;
22249 ChromeUserEvent::~ChromeUserEvent() = default;
22250 ChromeUserEvent::ChromeUserEvent(const ChromeUserEvent&) = default;
22251 ChromeUserEvent& ChromeUserEvent::operator=(const ChromeUserEvent&) = default;
22252 ChromeUserEvent::ChromeUserEvent(ChromeUserEvent&&) noexcept = default;
22253 ChromeUserEvent& ChromeUserEvent::operator=(ChromeUserEvent&&) = default;
22254 
operator ==(const ChromeUserEvent & other) const22255 bool ChromeUserEvent::operator==(const ChromeUserEvent& other) const {
22256   return unknown_fields_ == other.unknown_fields_
22257    && action_ == other.action_
22258    && action_hash_ == other.action_hash_;
22259 }
22260 
ParseFromArray(const void * raw,size_t size)22261 bool ChromeUserEvent::ParseFromArray(const void* raw, size_t size) {
22262   unknown_fields_.clear();
22263   bool packed_error = false;
22264 
22265   ::protozero::ProtoDecoder dec(raw, size);
22266   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22267     if (field.id() < _has_field_.size()) {
22268       _has_field_.set(field.id());
22269     }
22270     switch (field.id()) {
22271       case 1 /* action */:
22272         field.get(&action_);
22273         break;
22274       case 2 /* action_hash */:
22275         field.get(&action_hash_);
22276         break;
22277       default:
22278         field.SerializeAndAppendTo(&unknown_fields_);
22279         break;
22280     }
22281   }
22282   return !packed_error && !dec.bytes_left();
22283 }
22284 
SerializeAsString() const22285 std::string ChromeUserEvent::SerializeAsString() const {
22286   ::protozero::HeapBuffered<::protozero::Message> msg;
22287   Serialize(msg.get());
22288   return msg.SerializeAsString();
22289 }
22290 
SerializeAsArray() const22291 std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
22292   ::protozero::HeapBuffered<::protozero::Message> msg;
22293   Serialize(msg.get());
22294   return msg.SerializeAsArray();
22295 }
22296 
Serialize(::protozero::Message * msg) const22297 void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
22298   // Field 1: action
22299   if (_has_field_[1]) {
22300     msg->AppendString(1, action_);
22301   }
22302 
22303   // Field 2: action_hash
22304   if (_has_field_[2]) {
22305     msg->AppendVarInt(2, action_hash_);
22306   }
22307 
22308   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22309 }
22310 
22311 }  // namespace perfetto
22312 }  // namespace protos
22313 }  // namespace gen
22314 #pragma GCC diagnostic pop
22315 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.cc
22316 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.h
22317 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22318 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
22319 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
22320 
22321 #include <stdint.h>
22322 #include <bitset>
22323 #include <vector>
22324 #include <string>
22325 #include <type_traits>
22326 
22327 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
22328 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
22329 // gen_amalgamated expanded: #include "perfetto/base/export.h"
22330 
22331 namespace perfetto {
22332 namespace protos {
22333 namespace gen {
22334 class CounterDescriptor;
22335 enum CounterDescriptor_BuiltinCounterType : int;
22336 enum CounterDescriptor_Unit : int;
22337 }  // namespace perfetto
22338 }  // namespace protos
22339 }  // namespace gen
22340 
22341 namespace protozero {
22342 class Message;
22343 }  // namespace protozero
22344 
22345 namespace perfetto {
22346 namespace protos {
22347 namespace gen {
22348 enum CounterDescriptor_BuiltinCounterType : int {
22349   CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
22350   CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
22351   CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
22352 };
22353 enum CounterDescriptor_Unit : int {
22354   CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
22355   CounterDescriptor_Unit_UNIT_TIME_NS = 1,
22356   CounterDescriptor_Unit_UNIT_COUNT = 2,
22357   CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
22358 };
22359 
22360 class PERFETTO_EXPORT CounterDescriptor : public ::protozero::CppMessageObj {
22361  public:
22362   using BuiltinCounterType = CounterDescriptor_BuiltinCounterType;
22363   static constexpr auto COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
22364   static constexpr auto COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
22365   static constexpr auto COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
22366   static constexpr auto BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
22367   static constexpr auto BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
22368   using Unit = CounterDescriptor_Unit;
22369   static constexpr auto UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
22370   static constexpr auto UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
22371   static constexpr auto UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
22372   static constexpr auto UNIT_SIZE_BYTES = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
22373   static constexpr auto Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
22374   static constexpr auto Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
22375   enum FieldNumbers {
22376     kTypeFieldNumber = 1,
22377     kCategoriesFieldNumber = 2,
22378     kUnitFieldNumber = 3,
22379     kUnitMultiplierFieldNumber = 4,
22380     kIsIncrementalFieldNumber = 5,
22381   };
22382 
22383   CounterDescriptor();
22384   ~CounterDescriptor() override;
22385   CounterDescriptor(CounterDescriptor&&) noexcept;
22386   CounterDescriptor& operator=(CounterDescriptor&&);
22387   CounterDescriptor(const CounterDescriptor&);
22388   CounterDescriptor& operator=(const CounterDescriptor&);
22389   bool operator==(const CounterDescriptor&) const;
operator !=(const CounterDescriptor & other) const22390   bool operator!=(const CounterDescriptor& other) const { return !(*this == other); }
22391 
22392   bool ParseFromArray(const void*, size_t) override;
22393   std::string SerializeAsString() const override;
22394   std::vector<uint8_t> SerializeAsArray() const override;
22395   void Serialize(::protozero::Message*) const;
22396 
has_type() const22397   bool has_type() const { return _has_field_[1]; }
type() const22398   CounterDescriptor_BuiltinCounterType type() const { return type_; }
set_type(CounterDescriptor_BuiltinCounterType value)22399   void set_type(CounterDescriptor_BuiltinCounterType value) { type_ = value; _has_field_.set(1); }
22400 
categories_size() const22401   int categories_size() const { return static_cast<int>(categories_.size()); }
categories() const22402   const std::vector<std::string>& categories() const { return categories_; }
mutable_categories()22403   std::vector<std::string>* mutable_categories() { return &categories_; }
clear_categories()22404   void clear_categories() { categories_.clear(); }
add_categories(std::string value)22405   void add_categories(std::string value) { categories_.emplace_back(value); }
add_categories()22406   std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
22407 
has_unit() const22408   bool has_unit() const { return _has_field_[3]; }
unit() const22409   CounterDescriptor_Unit unit() const { return unit_; }
set_unit(CounterDescriptor_Unit value)22410   void set_unit(CounterDescriptor_Unit value) { unit_ = value; _has_field_.set(3); }
22411 
has_unit_multiplier() const22412   bool has_unit_multiplier() const { return _has_field_[4]; }
unit_multiplier() const22413   int64_t unit_multiplier() const { return unit_multiplier_; }
set_unit_multiplier(int64_t value)22414   void set_unit_multiplier(int64_t value) { unit_multiplier_ = value; _has_field_.set(4); }
22415 
has_is_incremental() const22416   bool has_is_incremental() const { return _has_field_[5]; }
is_incremental() const22417   bool is_incremental() const { return is_incremental_; }
set_is_incremental(bool value)22418   void set_is_incremental(bool value) { is_incremental_ = value; _has_field_.set(5); }
22419 
22420  private:
22421   CounterDescriptor_BuiltinCounterType type_{};
22422   std::vector<std::string> categories_;
22423   CounterDescriptor_Unit unit_{};
22424   int64_t unit_multiplier_{};
22425   bool is_incremental_{};
22426 
22427   // Allows to preserve unknown protobuf fields for compatibility
22428   // with future versions of .proto files.
22429   std::string unknown_fields_;
22430 
22431   std::bitset<6> _has_field_{};
22432 };
22433 
22434 }  // namespace perfetto
22435 }  // namespace protos
22436 }  // namespace gen
22437 
22438 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
22439 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22440 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22441 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22442 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22443 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22444 #pragma GCC diagnostic push
22445 #pragma GCC diagnostic ignored "-Wfloat-equal"
22446 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
22447 
22448 namespace perfetto {
22449 namespace protos {
22450 namespace gen {
22451 
22452 CounterDescriptor::CounterDescriptor() = default;
22453 CounterDescriptor::~CounterDescriptor() = default;
22454 CounterDescriptor::CounterDescriptor(const CounterDescriptor&) = default;
22455 CounterDescriptor& CounterDescriptor::operator=(const CounterDescriptor&) = default;
22456 CounterDescriptor::CounterDescriptor(CounterDescriptor&&) noexcept = default;
22457 CounterDescriptor& CounterDescriptor::operator=(CounterDescriptor&&) = default;
22458 
operator ==(const CounterDescriptor & other) const22459 bool CounterDescriptor::operator==(const CounterDescriptor& other) const {
22460   return unknown_fields_ == other.unknown_fields_
22461    && type_ == other.type_
22462    && categories_ == other.categories_
22463    && unit_ == other.unit_
22464    && unit_multiplier_ == other.unit_multiplier_
22465    && is_incremental_ == other.is_incremental_;
22466 }
22467 
ParseFromArray(const void * raw,size_t size)22468 bool CounterDescriptor::ParseFromArray(const void* raw, size_t size) {
22469   categories_.clear();
22470   unknown_fields_.clear();
22471   bool packed_error = false;
22472 
22473   ::protozero::ProtoDecoder dec(raw, size);
22474   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22475     if (field.id() < _has_field_.size()) {
22476       _has_field_.set(field.id());
22477     }
22478     switch (field.id()) {
22479       case 1 /* type */:
22480         field.get(&type_);
22481         break;
22482       case 2 /* categories */:
22483         categories_.emplace_back();
22484         field.get(&categories_.back());
22485         break;
22486       case 3 /* unit */:
22487         field.get(&unit_);
22488         break;
22489       case 4 /* unit_multiplier */:
22490         field.get(&unit_multiplier_);
22491         break;
22492       case 5 /* is_incremental */:
22493         field.get(&is_incremental_);
22494         break;
22495       default:
22496         field.SerializeAndAppendTo(&unknown_fields_);
22497         break;
22498     }
22499   }
22500   return !packed_error && !dec.bytes_left();
22501 }
22502 
SerializeAsString() const22503 std::string CounterDescriptor::SerializeAsString() const {
22504   ::protozero::HeapBuffered<::protozero::Message> msg;
22505   Serialize(msg.get());
22506   return msg.SerializeAsString();
22507 }
22508 
SerializeAsArray() const22509 std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
22510   ::protozero::HeapBuffered<::protozero::Message> msg;
22511   Serialize(msg.get());
22512   return msg.SerializeAsArray();
22513 }
22514 
Serialize(::protozero::Message * msg) const22515 void CounterDescriptor::Serialize(::protozero::Message* msg) const {
22516   // Field 1: type
22517   if (_has_field_[1]) {
22518     msg->AppendVarInt(1, type_);
22519   }
22520 
22521   // Field 2: categories
22522   for (auto& it : categories_) {
22523     msg->AppendString(2, it);
22524   }
22525 
22526   // Field 3: unit
22527   if (_has_field_[3]) {
22528     msg->AppendVarInt(3, unit_);
22529   }
22530 
22531   // Field 4: unit_multiplier
22532   if (_has_field_[4]) {
22533     msg->AppendVarInt(4, unit_multiplier_);
22534   }
22535 
22536   // Field 5: is_incremental
22537   if (_has_field_[5]) {
22538     msg->AppendTinyVarInt(5, is_incremental_);
22539   }
22540 
22541   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22542 }
22543 
22544 }  // namespace perfetto
22545 }  // namespace protos
22546 }  // namespace gen
22547 #pragma GCC diagnostic pop
22548 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.gen.cc
22549 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.gen.h
22550 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22551 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
22552 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
22553 
22554 #include <stdint.h>
22555 #include <bitset>
22556 #include <vector>
22557 #include <string>
22558 #include <type_traits>
22559 
22560 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
22561 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
22562 // gen_amalgamated expanded: #include "perfetto/base/export.h"
22563 
22564 namespace perfetto {
22565 namespace protos {
22566 namespace gen {
22567 class DebugAnnotationName;
22568 class DebugAnnotation;
22569 class DebugAnnotation_NestedValue;
22570 enum DebugAnnotation_NestedValue_NestedType : int;
22571 }  // namespace perfetto
22572 }  // namespace protos
22573 }  // namespace gen
22574 
22575 namespace protozero {
22576 class Message;
22577 }  // namespace protozero
22578 
22579 namespace perfetto {
22580 namespace protos {
22581 namespace gen {
22582 enum DebugAnnotation_NestedValue_NestedType : int {
22583   DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
22584   DebugAnnotation_NestedValue_NestedType_DICT = 1,
22585   DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
22586 };
22587 
22588 class PERFETTO_EXPORT DebugAnnotationName : public ::protozero::CppMessageObj {
22589  public:
22590   enum FieldNumbers {
22591     kIidFieldNumber = 1,
22592     kNameFieldNumber = 2,
22593   };
22594 
22595   DebugAnnotationName();
22596   ~DebugAnnotationName() override;
22597   DebugAnnotationName(DebugAnnotationName&&) noexcept;
22598   DebugAnnotationName& operator=(DebugAnnotationName&&);
22599   DebugAnnotationName(const DebugAnnotationName&);
22600   DebugAnnotationName& operator=(const DebugAnnotationName&);
22601   bool operator==(const DebugAnnotationName&) const;
operator !=(const DebugAnnotationName & other) const22602   bool operator!=(const DebugAnnotationName& other) const { return !(*this == other); }
22603 
22604   bool ParseFromArray(const void*, size_t) override;
22605   std::string SerializeAsString() const override;
22606   std::vector<uint8_t> SerializeAsArray() const override;
22607   void Serialize(::protozero::Message*) const;
22608 
has_iid() const22609   bool has_iid() const { return _has_field_[1]; }
iid() const22610   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)22611   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
22612 
has_name() const22613   bool has_name() const { return _has_field_[2]; }
name() const22614   const std::string& name() const { return name_; }
set_name(const std::string & value)22615   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
22616 
22617  private:
22618   uint64_t iid_{};
22619   std::string name_{};
22620 
22621   // Allows to preserve unknown protobuf fields for compatibility
22622   // with future versions of .proto files.
22623   std::string unknown_fields_;
22624 
22625   std::bitset<3> _has_field_{};
22626 };
22627 
22628 
22629 class PERFETTO_EXPORT DebugAnnotation : public ::protozero::CppMessageObj {
22630  public:
22631   using NestedValue = DebugAnnotation_NestedValue;
22632   enum FieldNumbers {
22633     kNameIidFieldNumber = 1,
22634     kNameFieldNumber = 10,
22635     kBoolValueFieldNumber = 2,
22636     kUintValueFieldNumber = 3,
22637     kIntValueFieldNumber = 4,
22638     kDoubleValueFieldNumber = 5,
22639     kStringValueFieldNumber = 6,
22640     kPointerValueFieldNumber = 7,
22641     kNestedValueFieldNumber = 8,
22642     kLegacyJsonValueFieldNumber = 9,
22643   };
22644 
22645   DebugAnnotation();
22646   ~DebugAnnotation() override;
22647   DebugAnnotation(DebugAnnotation&&) noexcept;
22648   DebugAnnotation& operator=(DebugAnnotation&&);
22649   DebugAnnotation(const DebugAnnotation&);
22650   DebugAnnotation& operator=(const DebugAnnotation&);
22651   bool operator==(const DebugAnnotation&) const;
operator !=(const DebugAnnotation & other) const22652   bool operator!=(const DebugAnnotation& other) const { return !(*this == other); }
22653 
22654   bool ParseFromArray(const void*, size_t) override;
22655   std::string SerializeAsString() const override;
22656   std::vector<uint8_t> SerializeAsArray() const override;
22657   void Serialize(::protozero::Message*) const;
22658 
has_name_iid() const22659   bool has_name_iid() const { return _has_field_[1]; }
name_iid() const22660   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)22661   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
22662 
has_name() const22663   bool has_name() const { return _has_field_[10]; }
name() const22664   const std::string& name() const { return name_; }
set_name(const std::string & value)22665   void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
22666 
has_bool_value() const22667   bool has_bool_value() const { return _has_field_[2]; }
bool_value() const22668   bool bool_value() const { return bool_value_; }
set_bool_value(bool value)22669   void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(2); }
22670 
has_uint_value() const22671   bool has_uint_value() const { return _has_field_[3]; }
uint_value() const22672   uint64_t uint_value() const { return uint_value_; }
set_uint_value(uint64_t value)22673   void set_uint_value(uint64_t value) { uint_value_ = value; _has_field_.set(3); }
22674 
has_int_value() const22675   bool has_int_value() const { return _has_field_[4]; }
int_value() const22676   int64_t int_value() const { return int_value_; }
set_int_value(int64_t value)22677   void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(4); }
22678 
has_double_value() const22679   bool has_double_value() const { return _has_field_[5]; }
double_value() const22680   double double_value() const { return double_value_; }
set_double_value(double value)22681   void set_double_value(double value) { double_value_ = value; _has_field_.set(5); }
22682 
has_string_value() const22683   bool has_string_value() const { return _has_field_[6]; }
string_value() const22684   const std::string& string_value() const { return string_value_; }
set_string_value(const std::string & value)22685   void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(6); }
22686 
has_pointer_value() const22687   bool has_pointer_value() const { return _has_field_[7]; }
pointer_value() const22688   uint64_t pointer_value() const { return pointer_value_; }
set_pointer_value(uint64_t value)22689   void set_pointer_value(uint64_t value) { pointer_value_ = value; _has_field_.set(7); }
22690 
has_nested_value() const22691   bool has_nested_value() const { return _has_field_[8]; }
nested_value() const22692   const DebugAnnotation_NestedValue& nested_value() const { return *nested_value_; }
mutable_nested_value()22693   DebugAnnotation_NestedValue* mutable_nested_value() { _has_field_.set(8); return nested_value_.get(); }
22694 
has_legacy_json_value() const22695   bool has_legacy_json_value() const { return _has_field_[9]; }
legacy_json_value() const22696   const std::string& legacy_json_value() const { return legacy_json_value_; }
set_legacy_json_value(const std::string & value)22697   void set_legacy_json_value(const std::string& value) { legacy_json_value_ = value; _has_field_.set(9); }
22698 
22699  private:
22700   uint64_t name_iid_{};
22701   std::string name_{};
22702   bool bool_value_{};
22703   uint64_t uint_value_{};
22704   int64_t int_value_{};
22705   double double_value_{};
22706   std::string string_value_{};
22707   uint64_t pointer_value_{};
22708   ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
22709   std::string legacy_json_value_{};
22710 
22711   // Allows to preserve unknown protobuf fields for compatibility
22712   // with future versions of .proto files.
22713   std::string unknown_fields_;
22714 
22715   std::bitset<11> _has_field_{};
22716 };
22717 
22718 
22719 class PERFETTO_EXPORT DebugAnnotation_NestedValue : public ::protozero::CppMessageObj {
22720  public:
22721   using NestedType = DebugAnnotation_NestedValue_NestedType;
22722   static constexpr auto UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
22723   static constexpr auto DICT = DebugAnnotation_NestedValue_NestedType_DICT;
22724   static constexpr auto ARRAY = DebugAnnotation_NestedValue_NestedType_ARRAY;
22725   static constexpr auto NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
22726   static constexpr auto NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
22727   enum FieldNumbers {
22728     kNestedTypeFieldNumber = 1,
22729     kDictKeysFieldNumber = 2,
22730     kDictValuesFieldNumber = 3,
22731     kArrayValuesFieldNumber = 4,
22732     kIntValueFieldNumber = 5,
22733     kDoubleValueFieldNumber = 6,
22734     kBoolValueFieldNumber = 7,
22735     kStringValueFieldNumber = 8,
22736   };
22737 
22738   DebugAnnotation_NestedValue();
22739   ~DebugAnnotation_NestedValue() override;
22740   DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept;
22741   DebugAnnotation_NestedValue& operator=(DebugAnnotation_NestedValue&&);
22742   DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&);
22743   DebugAnnotation_NestedValue& operator=(const DebugAnnotation_NestedValue&);
22744   bool operator==(const DebugAnnotation_NestedValue&) const;
operator !=(const DebugAnnotation_NestedValue & other) const22745   bool operator!=(const DebugAnnotation_NestedValue& other) const { return !(*this == other); }
22746 
22747   bool ParseFromArray(const void*, size_t) override;
22748   std::string SerializeAsString() const override;
22749   std::vector<uint8_t> SerializeAsArray() const override;
22750   void Serialize(::protozero::Message*) const;
22751 
has_nested_type() const22752   bool has_nested_type() const { return _has_field_[1]; }
nested_type() const22753   DebugAnnotation_NestedValue_NestedType nested_type() const { return nested_type_; }
set_nested_type(DebugAnnotation_NestedValue_NestedType value)22754   void set_nested_type(DebugAnnotation_NestedValue_NestedType value) { nested_type_ = value; _has_field_.set(1); }
22755 
dict_keys_size() const22756   int dict_keys_size() const { return static_cast<int>(dict_keys_.size()); }
dict_keys() const22757   const std::vector<std::string>& dict_keys() const { return dict_keys_; }
mutable_dict_keys()22758   std::vector<std::string>* mutable_dict_keys() { return &dict_keys_; }
clear_dict_keys()22759   void clear_dict_keys() { dict_keys_.clear(); }
add_dict_keys(std::string value)22760   void add_dict_keys(std::string value) { dict_keys_.emplace_back(value); }
add_dict_keys()22761   std::string* add_dict_keys() { dict_keys_.emplace_back(); return &dict_keys_.back(); }
22762 
dict_values_size() const22763   int dict_values_size() const { return static_cast<int>(dict_values_.size()); }
dict_values() const22764   const std::vector<DebugAnnotation_NestedValue>& dict_values() const { return dict_values_; }
mutable_dict_values()22765   std::vector<DebugAnnotation_NestedValue>* mutable_dict_values() { return &dict_values_; }
clear_dict_values()22766   void clear_dict_values() { dict_values_.clear(); }
add_dict_values()22767   DebugAnnotation_NestedValue* add_dict_values() { dict_values_.emplace_back(); return &dict_values_.back(); }
22768 
array_values_size() const22769   int array_values_size() const { return static_cast<int>(array_values_.size()); }
array_values() const22770   const std::vector<DebugAnnotation_NestedValue>& array_values() const { return array_values_; }
mutable_array_values()22771   std::vector<DebugAnnotation_NestedValue>* mutable_array_values() { return &array_values_; }
clear_array_values()22772   void clear_array_values() { array_values_.clear(); }
add_array_values()22773   DebugAnnotation_NestedValue* add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
22774 
has_int_value() const22775   bool has_int_value() const { return _has_field_[5]; }
int_value() const22776   int64_t int_value() const { return int_value_; }
set_int_value(int64_t value)22777   void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(5); }
22778 
has_double_value() const22779   bool has_double_value() const { return _has_field_[6]; }
double_value() const22780   double double_value() const { return double_value_; }
set_double_value(double value)22781   void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
22782 
has_bool_value() const22783   bool has_bool_value() const { return _has_field_[7]; }
bool_value() const22784   bool bool_value() const { return bool_value_; }
set_bool_value(bool value)22785   void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(7); }
22786 
has_string_value() const22787   bool has_string_value() const { return _has_field_[8]; }
string_value() const22788   const std::string& string_value() const { return string_value_; }
set_string_value(const std::string & value)22789   void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(8); }
22790 
22791  private:
22792   DebugAnnotation_NestedValue_NestedType nested_type_{};
22793   std::vector<std::string> dict_keys_;
22794   std::vector<DebugAnnotation_NestedValue> dict_values_;
22795   std::vector<DebugAnnotation_NestedValue> array_values_;
22796   int64_t int_value_{};
22797   double double_value_{};
22798   bool bool_value_{};
22799   std::string string_value_{};
22800 
22801   // Allows to preserve unknown protobuf fields for compatibility
22802   // with future versions of .proto files.
22803   std::string unknown_fields_;
22804 
22805   std::bitset<9> _has_field_{};
22806 };
22807 
22808 }  // namespace perfetto
22809 }  // namespace protos
22810 }  // namespace gen
22811 
22812 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
22813 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22814 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22815 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22816 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22817 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22818 #pragma GCC diagnostic push
22819 #pragma GCC diagnostic ignored "-Wfloat-equal"
22820 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
22821 
22822 namespace perfetto {
22823 namespace protos {
22824 namespace gen {
22825 
22826 DebugAnnotationName::DebugAnnotationName() = default;
22827 DebugAnnotationName::~DebugAnnotationName() = default;
22828 DebugAnnotationName::DebugAnnotationName(const DebugAnnotationName&) = default;
22829 DebugAnnotationName& DebugAnnotationName::operator=(const DebugAnnotationName&) = default;
22830 DebugAnnotationName::DebugAnnotationName(DebugAnnotationName&&) noexcept = default;
22831 DebugAnnotationName& DebugAnnotationName::operator=(DebugAnnotationName&&) = default;
22832 
operator ==(const DebugAnnotationName & other) const22833 bool DebugAnnotationName::operator==(const DebugAnnotationName& other) const {
22834   return unknown_fields_ == other.unknown_fields_
22835    && iid_ == other.iid_
22836    && name_ == other.name_;
22837 }
22838 
ParseFromArray(const void * raw,size_t size)22839 bool DebugAnnotationName::ParseFromArray(const void* raw, size_t size) {
22840   unknown_fields_.clear();
22841   bool packed_error = false;
22842 
22843   ::protozero::ProtoDecoder dec(raw, size);
22844   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22845     if (field.id() < _has_field_.size()) {
22846       _has_field_.set(field.id());
22847     }
22848     switch (field.id()) {
22849       case 1 /* iid */:
22850         field.get(&iid_);
22851         break;
22852       case 2 /* name */:
22853         field.get(&name_);
22854         break;
22855       default:
22856         field.SerializeAndAppendTo(&unknown_fields_);
22857         break;
22858     }
22859   }
22860   return !packed_error && !dec.bytes_left();
22861 }
22862 
SerializeAsString() const22863 std::string DebugAnnotationName::SerializeAsString() const {
22864   ::protozero::HeapBuffered<::protozero::Message> msg;
22865   Serialize(msg.get());
22866   return msg.SerializeAsString();
22867 }
22868 
SerializeAsArray() const22869 std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
22870   ::protozero::HeapBuffered<::protozero::Message> msg;
22871   Serialize(msg.get());
22872   return msg.SerializeAsArray();
22873 }
22874 
Serialize(::protozero::Message * msg) const22875 void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
22876   // Field 1: iid
22877   if (_has_field_[1]) {
22878     msg->AppendVarInt(1, iid_);
22879   }
22880 
22881   // Field 2: name
22882   if (_has_field_[2]) {
22883     msg->AppendString(2, name_);
22884   }
22885 
22886   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22887 }
22888 
22889 
22890 DebugAnnotation::DebugAnnotation() = default;
22891 DebugAnnotation::~DebugAnnotation() = default;
22892 DebugAnnotation::DebugAnnotation(const DebugAnnotation&) = default;
22893 DebugAnnotation& DebugAnnotation::operator=(const DebugAnnotation&) = default;
22894 DebugAnnotation::DebugAnnotation(DebugAnnotation&&) noexcept = default;
22895 DebugAnnotation& DebugAnnotation::operator=(DebugAnnotation&&) = default;
22896 
operator ==(const DebugAnnotation & other) const22897 bool DebugAnnotation::operator==(const DebugAnnotation& other) const {
22898   return unknown_fields_ == other.unknown_fields_
22899    && name_iid_ == other.name_iid_
22900    && name_ == other.name_
22901    && bool_value_ == other.bool_value_
22902    && uint_value_ == other.uint_value_
22903    && int_value_ == other.int_value_
22904    && double_value_ == other.double_value_
22905    && string_value_ == other.string_value_
22906    && pointer_value_ == other.pointer_value_
22907    && nested_value_ == other.nested_value_
22908    && legacy_json_value_ == other.legacy_json_value_;
22909 }
22910 
ParseFromArray(const void * raw,size_t size)22911 bool DebugAnnotation::ParseFromArray(const void* raw, size_t size) {
22912   unknown_fields_.clear();
22913   bool packed_error = false;
22914 
22915   ::protozero::ProtoDecoder dec(raw, size);
22916   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22917     if (field.id() < _has_field_.size()) {
22918       _has_field_.set(field.id());
22919     }
22920     switch (field.id()) {
22921       case 1 /* name_iid */:
22922         field.get(&name_iid_);
22923         break;
22924       case 10 /* name */:
22925         field.get(&name_);
22926         break;
22927       case 2 /* bool_value */:
22928         field.get(&bool_value_);
22929         break;
22930       case 3 /* uint_value */:
22931         field.get(&uint_value_);
22932         break;
22933       case 4 /* int_value */:
22934         field.get(&int_value_);
22935         break;
22936       case 5 /* double_value */:
22937         field.get(&double_value_);
22938         break;
22939       case 6 /* string_value */:
22940         field.get(&string_value_);
22941         break;
22942       case 7 /* pointer_value */:
22943         field.get(&pointer_value_);
22944         break;
22945       case 8 /* nested_value */:
22946         (*nested_value_).ParseFromString(field.as_std_string());
22947         break;
22948       case 9 /* legacy_json_value */:
22949         field.get(&legacy_json_value_);
22950         break;
22951       default:
22952         field.SerializeAndAppendTo(&unknown_fields_);
22953         break;
22954     }
22955   }
22956   return !packed_error && !dec.bytes_left();
22957 }
22958 
SerializeAsString() const22959 std::string DebugAnnotation::SerializeAsString() const {
22960   ::protozero::HeapBuffered<::protozero::Message> msg;
22961   Serialize(msg.get());
22962   return msg.SerializeAsString();
22963 }
22964 
SerializeAsArray() const22965 std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
22966   ::protozero::HeapBuffered<::protozero::Message> msg;
22967   Serialize(msg.get());
22968   return msg.SerializeAsArray();
22969 }
22970 
Serialize(::protozero::Message * msg) const22971 void DebugAnnotation::Serialize(::protozero::Message* msg) const {
22972   // Field 1: name_iid
22973   if (_has_field_[1]) {
22974     msg->AppendVarInt(1, name_iid_);
22975   }
22976 
22977   // Field 10: name
22978   if (_has_field_[10]) {
22979     msg->AppendString(10, name_);
22980   }
22981 
22982   // Field 2: bool_value
22983   if (_has_field_[2]) {
22984     msg->AppendTinyVarInt(2, bool_value_);
22985   }
22986 
22987   // Field 3: uint_value
22988   if (_has_field_[3]) {
22989     msg->AppendVarInt(3, uint_value_);
22990   }
22991 
22992   // Field 4: int_value
22993   if (_has_field_[4]) {
22994     msg->AppendVarInt(4, int_value_);
22995   }
22996 
22997   // Field 5: double_value
22998   if (_has_field_[5]) {
22999     msg->AppendFixed(5, double_value_);
23000   }
23001 
23002   // Field 6: string_value
23003   if (_has_field_[6]) {
23004     msg->AppendString(6, string_value_);
23005   }
23006 
23007   // Field 7: pointer_value
23008   if (_has_field_[7]) {
23009     msg->AppendVarInt(7, pointer_value_);
23010   }
23011 
23012   // Field 8: nested_value
23013   if (_has_field_[8]) {
23014     (*nested_value_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
23015   }
23016 
23017   // Field 9: legacy_json_value
23018   if (_has_field_[9]) {
23019     msg->AppendString(9, legacy_json_value_);
23020   }
23021 
23022   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23023 }
23024 
23025 
23026 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue() = default;
23027 DebugAnnotation_NestedValue::~DebugAnnotation_NestedValue() = default;
23028 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&) = default;
23029 DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(const DebugAnnotation_NestedValue&) = default;
23030 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept = default;
23031 DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(DebugAnnotation_NestedValue&&) = default;
23032 
operator ==(const DebugAnnotation_NestedValue & other) const23033 bool DebugAnnotation_NestedValue::operator==(const DebugAnnotation_NestedValue& other) const {
23034   return unknown_fields_ == other.unknown_fields_
23035    && nested_type_ == other.nested_type_
23036    && dict_keys_ == other.dict_keys_
23037    && dict_values_ == other.dict_values_
23038    && array_values_ == other.array_values_
23039    && int_value_ == other.int_value_
23040    && double_value_ == other.double_value_
23041    && bool_value_ == other.bool_value_
23042    && string_value_ == other.string_value_;
23043 }
23044 
ParseFromArray(const void * raw,size_t size)23045 bool DebugAnnotation_NestedValue::ParseFromArray(const void* raw, size_t size) {
23046   dict_keys_.clear();
23047   dict_values_.clear();
23048   array_values_.clear();
23049   unknown_fields_.clear();
23050   bool packed_error = false;
23051 
23052   ::protozero::ProtoDecoder dec(raw, size);
23053   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23054     if (field.id() < _has_field_.size()) {
23055       _has_field_.set(field.id());
23056     }
23057     switch (field.id()) {
23058       case 1 /* nested_type */:
23059         field.get(&nested_type_);
23060         break;
23061       case 2 /* dict_keys */:
23062         dict_keys_.emplace_back();
23063         field.get(&dict_keys_.back());
23064         break;
23065       case 3 /* dict_values */:
23066         dict_values_.emplace_back();
23067         dict_values_.back().ParseFromString(field.as_std_string());
23068         break;
23069       case 4 /* array_values */:
23070         array_values_.emplace_back();
23071         array_values_.back().ParseFromString(field.as_std_string());
23072         break;
23073       case 5 /* int_value */:
23074         field.get(&int_value_);
23075         break;
23076       case 6 /* double_value */:
23077         field.get(&double_value_);
23078         break;
23079       case 7 /* bool_value */:
23080         field.get(&bool_value_);
23081         break;
23082       case 8 /* string_value */:
23083         field.get(&string_value_);
23084         break;
23085       default:
23086         field.SerializeAndAppendTo(&unknown_fields_);
23087         break;
23088     }
23089   }
23090   return !packed_error && !dec.bytes_left();
23091 }
23092 
SerializeAsString() const23093 std::string DebugAnnotation_NestedValue::SerializeAsString() const {
23094   ::protozero::HeapBuffered<::protozero::Message> msg;
23095   Serialize(msg.get());
23096   return msg.SerializeAsString();
23097 }
23098 
SerializeAsArray() const23099 std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
23100   ::protozero::HeapBuffered<::protozero::Message> msg;
23101   Serialize(msg.get());
23102   return msg.SerializeAsArray();
23103 }
23104 
Serialize(::protozero::Message * msg) const23105 void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
23106   // Field 1: nested_type
23107   if (_has_field_[1]) {
23108     msg->AppendVarInt(1, nested_type_);
23109   }
23110 
23111   // Field 2: dict_keys
23112   for (auto& it : dict_keys_) {
23113     msg->AppendString(2, it);
23114   }
23115 
23116   // Field 3: dict_values
23117   for (auto& it : dict_values_) {
23118     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
23119   }
23120 
23121   // Field 4: array_values
23122   for (auto& it : array_values_) {
23123     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
23124   }
23125 
23126   // Field 5: int_value
23127   if (_has_field_[5]) {
23128     msg->AppendVarInt(5, int_value_);
23129   }
23130 
23131   // Field 6: double_value
23132   if (_has_field_[6]) {
23133     msg->AppendFixed(6, double_value_);
23134   }
23135 
23136   // Field 7: bool_value
23137   if (_has_field_[7]) {
23138     msg->AppendTinyVarInt(7, bool_value_);
23139   }
23140 
23141   // Field 8: string_value
23142   if (_has_field_[8]) {
23143     msg->AppendString(8, string_value_);
23144   }
23145 
23146   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23147 }
23148 
23149 }  // namespace perfetto
23150 }  // namespace protos
23151 }  // namespace gen
23152 #pragma GCC diagnostic pop
23153 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.gen.cc
23154 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.gen.h
23155 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23156 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
23157 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
23158 
23159 #include <stdint.h>
23160 #include <bitset>
23161 #include <vector>
23162 #include <string>
23163 #include <type_traits>
23164 
23165 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
23166 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
23167 // gen_amalgamated expanded: #include "perfetto/base/export.h"
23168 
23169 namespace perfetto {
23170 namespace protos {
23171 namespace gen {
23172 class LogMessageBody;
23173 class LogMessage;
23174 }  // namespace perfetto
23175 }  // namespace protos
23176 }  // namespace gen
23177 
23178 namespace protozero {
23179 class Message;
23180 }  // namespace protozero
23181 
23182 namespace perfetto {
23183 namespace protos {
23184 namespace gen {
23185 
23186 class PERFETTO_EXPORT LogMessageBody : public ::protozero::CppMessageObj {
23187  public:
23188   enum FieldNumbers {
23189     kIidFieldNumber = 1,
23190     kBodyFieldNumber = 2,
23191   };
23192 
23193   LogMessageBody();
23194   ~LogMessageBody() override;
23195   LogMessageBody(LogMessageBody&&) noexcept;
23196   LogMessageBody& operator=(LogMessageBody&&);
23197   LogMessageBody(const LogMessageBody&);
23198   LogMessageBody& operator=(const LogMessageBody&);
23199   bool operator==(const LogMessageBody&) const;
operator !=(const LogMessageBody & other) const23200   bool operator!=(const LogMessageBody& other) const { return !(*this == other); }
23201 
23202   bool ParseFromArray(const void*, size_t) override;
23203   std::string SerializeAsString() const override;
23204   std::vector<uint8_t> SerializeAsArray() const override;
23205   void Serialize(::protozero::Message*) const;
23206 
has_iid() const23207   bool has_iid() const { return _has_field_[1]; }
iid() const23208   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)23209   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
23210 
has_body() const23211   bool has_body() const { return _has_field_[2]; }
body() const23212   const std::string& body() const { return body_; }
set_body(const std::string & value)23213   void set_body(const std::string& value) { body_ = value; _has_field_.set(2); }
23214 
23215  private:
23216   uint64_t iid_{};
23217   std::string body_{};
23218 
23219   // Allows to preserve unknown protobuf fields for compatibility
23220   // with future versions of .proto files.
23221   std::string unknown_fields_;
23222 
23223   std::bitset<3> _has_field_{};
23224 };
23225 
23226 
23227 class PERFETTO_EXPORT LogMessage : public ::protozero::CppMessageObj {
23228  public:
23229   enum FieldNumbers {
23230     kSourceLocationIidFieldNumber = 1,
23231     kBodyIidFieldNumber = 2,
23232   };
23233 
23234   LogMessage();
23235   ~LogMessage() override;
23236   LogMessage(LogMessage&&) noexcept;
23237   LogMessage& operator=(LogMessage&&);
23238   LogMessage(const LogMessage&);
23239   LogMessage& operator=(const LogMessage&);
23240   bool operator==(const LogMessage&) const;
operator !=(const LogMessage & other) const23241   bool operator!=(const LogMessage& other) const { return !(*this == other); }
23242 
23243   bool ParseFromArray(const void*, size_t) override;
23244   std::string SerializeAsString() const override;
23245   std::vector<uint8_t> SerializeAsArray() const override;
23246   void Serialize(::protozero::Message*) const;
23247 
has_source_location_iid() const23248   bool has_source_location_iid() const { return _has_field_[1]; }
source_location_iid() const23249   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)23250   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(1); }
23251 
has_body_iid() const23252   bool has_body_iid() const { return _has_field_[2]; }
body_iid() const23253   uint64_t body_iid() const { return body_iid_; }
set_body_iid(uint64_t value)23254   void set_body_iid(uint64_t value) { body_iid_ = value; _has_field_.set(2); }
23255 
23256  private:
23257   uint64_t source_location_iid_{};
23258   uint64_t body_iid_{};
23259 
23260   // Allows to preserve unknown protobuf fields for compatibility
23261   // with future versions of .proto files.
23262   std::string unknown_fields_;
23263 
23264   std::bitset<3> _has_field_{};
23265 };
23266 
23267 }  // namespace perfetto
23268 }  // namespace protos
23269 }  // namespace gen
23270 
23271 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
23272 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
23273 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
23274 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
23275 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
23276 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23277 #pragma GCC diagnostic push
23278 #pragma GCC diagnostic ignored "-Wfloat-equal"
23279 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
23280 
23281 namespace perfetto {
23282 namespace protos {
23283 namespace gen {
23284 
23285 LogMessageBody::LogMessageBody() = default;
23286 LogMessageBody::~LogMessageBody() = default;
23287 LogMessageBody::LogMessageBody(const LogMessageBody&) = default;
23288 LogMessageBody& LogMessageBody::operator=(const LogMessageBody&) = default;
23289 LogMessageBody::LogMessageBody(LogMessageBody&&) noexcept = default;
23290 LogMessageBody& LogMessageBody::operator=(LogMessageBody&&) = default;
23291 
operator ==(const LogMessageBody & other) const23292 bool LogMessageBody::operator==(const LogMessageBody& other) const {
23293   return unknown_fields_ == other.unknown_fields_
23294    && iid_ == other.iid_
23295    && body_ == other.body_;
23296 }
23297 
ParseFromArray(const void * raw,size_t size)23298 bool LogMessageBody::ParseFromArray(const void* raw, size_t size) {
23299   unknown_fields_.clear();
23300   bool packed_error = false;
23301 
23302   ::protozero::ProtoDecoder dec(raw, size);
23303   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23304     if (field.id() < _has_field_.size()) {
23305       _has_field_.set(field.id());
23306     }
23307     switch (field.id()) {
23308       case 1 /* iid */:
23309         field.get(&iid_);
23310         break;
23311       case 2 /* body */:
23312         field.get(&body_);
23313         break;
23314       default:
23315         field.SerializeAndAppendTo(&unknown_fields_);
23316         break;
23317     }
23318   }
23319   return !packed_error && !dec.bytes_left();
23320 }
23321 
SerializeAsString() const23322 std::string LogMessageBody::SerializeAsString() const {
23323   ::protozero::HeapBuffered<::protozero::Message> msg;
23324   Serialize(msg.get());
23325   return msg.SerializeAsString();
23326 }
23327 
SerializeAsArray() const23328 std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
23329   ::protozero::HeapBuffered<::protozero::Message> msg;
23330   Serialize(msg.get());
23331   return msg.SerializeAsArray();
23332 }
23333 
Serialize(::protozero::Message * msg) const23334 void LogMessageBody::Serialize(::protozero::Message* msg) const {
23335   // Field 1: iid
23336   if (_has_field_[1]) {
23337     msg->AppendVarInt(1, iid_);
23338   }
23339 
23340   // Field 2: body
23341   if (_has_field_[2]) {
23342     msg->AppendString(2, body_);
23343   }
23344 
23345   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23346 }
23347 
23348 
23349 LogMessage::LogMessage() = default;
23350 LogMessage::~LogMessage() = default;
23351 LogMessage::LogMessage(const LogMessage&) = default;
23352 LogMessage& LogMessage::operator=(const LogMessage&) = default;
23353 LogMessage::LogMessage(LogMessage&&) noexcept = default;
23354 LogMessage& LogMessage::operator=(LogMessage&&) = default;
23355 
operator ==(const LogMessage & other) const23356 bool LogMessage::operator==(const LogMessage& other) const {
23357   return unknown_fields_ == other.unknown_fields_
23358    && source_location_iid_ == other.source_location_iid_
23359    && body_iid_ == other.body_iid_;
23360 }
23361 
ParseFromArray(const void * raw,size_t size)23362 bool LogMessage::ParseFromArray(const void* raw, size_t size) {
23363   unknown_fields_.clear();
23364   bool packed_error = false;
23365 
23366   ::protozero::ProtoDecoder dec(raw, size);
23367   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23368     if (field.id() < _has_field_.size()) {
23369       _has_field_.set(field.id());
23370     }
23371     switch (field.id()) {
23372       case 1 /* source_location_iid */:
23373         field.get(&source_location_iid_);
23374         break;
23375       case 2 /* body_iid */:
23376         field.get(&body_iid_);
23377         break;
23378       default:
23379         field.SerializeAndAppendTo(&unknown_fields_);
23380         break;
23381     }
23382   }
23383   return !packed_error && !dec.bytes_left();
23384 }
23385 
SerializeAsString() const23386 std::string LogMessage::SerializeAsString() const {
23387   ::protozero::HeapBuffered<::protozero::Message> msg;
23388   Serialize(msg.get());
23389   return msg.SerializeAsString();
23390 }
23391 
SerializeAsArray() const23392 std::vector<uint8_t> LogMessage::SerializeAsArray() const {
23393   ::protozero::HeapBuffered<::protozero::Message> msg;
23394   Serialize(msg.get());
23395   return msg.SerializeAsArray();
23396 }
23397 
Serialize(::protozero::Message * msg) const23398 void LogMessage::Serialize(::protozero::Message* msg) const {
23399   // Field 1: source_location_iid
23400   if (_has_field_[1]) {
23401     msg->AppendVarInt(1, source_location_iid_);
23402   }
23403 
23404   // Field 2: body_iid
23405   if (_has_field_[2]) {
23406     msg->AppendVarInt(2, body_iid_);
23407   }
23408 
23409   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23410 }
23411 
23412 }  // namespace perfetto
23413 }  // namespace protos
23414 }  // namespace gen
23415 #pragma GCC diagnostic pop
23416 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.gen.cc
23417 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.gen.h
23418 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23419 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
23420 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
23421 
23422 #include <stdint.h>
23423 #include <bitset>
23424 #include <vector>
23425 #include <string>
23426 #include <type_traits>
23427 
23428 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
23429 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
23430 // gen_amalgamated expanded: #include "perfetto/base/export.h"
23431 
23432 namespace perfetto {
23433 namespace protos {
23434 namespace gen {
23435 class ProcessDescriptor;
23436 enum ProcessDescriptor_ChromeProcessType : int;
23437 }  // namespace perfetto
23438 }  // namespace protos
23439 }  // namespace gen
23440 
23441 namespace protozero {
23442 class Message;
23443 }  // namespace protozero
23444 
23445 namespace perfetto {
23446 namespace protos {
23447 namespace gen {
23448 enum ProcessDescriptor_ChromeProcessType : int {
23449   ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
23450   ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
23451   ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
23452   ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
23453   ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
23454   ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
23455   ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
23456   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
23457   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
23458 };
23459 
23460 class PERFETTO_EXPORT ProcessDescriptor : public ::protozero::CppMessageObj {
23461  public:
23462   using ChromeProcessType = ProcessDescriptor_ChromeProcessType;
23463   static constexpr auto PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
23464   static constexpr auto PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
23465   static constexpr auto PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
23466   static constexpr auto PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
23467   static constexpr auto PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
23468   static constexpr auto PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
23469   static constexpr auto PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
23470   static constexpr auto PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
23471   static constexpr auto PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
23472   static constexpr auto ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
23473   static constexpr auto ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
23474   enum FieldNumbers {
23475     kPidFieldNumber = 1,
23476     kCmdlineFieldNumber = 2,
23477     kProcessNameFieldNumber = 6,
23478     kProcessPriorityFieldNumber = 5,
23479     kChromeProcessTypeFieldNumber = 4,
23480     kLegacySortIndexFieldNumber = 3,
23481   };
23482 
23483   ProcessDescriptor();
23484   ~ProcessDescriptor() override;
23485   ProcessDescriptor(ProcessDescriptor&&) noexcept;
23486   ProcessDescriptor& operator=(ProcessDescriptor&&);
23487   ProcessDescriptor(const ProcessDescriptor&);
23488   ProcessDescriptor& operator=(const ProcessDescriptor&);
23489   bool operator==(const ProcessDescriptor&) const;
operator !=(const ProcessDescriptor & other) const23490   bool operator!=(const ProcessDescriptor& other) const { return !(*this == other); }
23491 
23492   bool ParseFromArray(const void*, size_t) override;
23493   std::string SerializeAsString() const override;
23494   std::vector<uint8_t> SerializeAsArray() const override;
23495   void Serialize(::protozero::Message*) const;
23496 
has_pid() const23497   bool has_pid() const { return _has_field_[1]; }
pid() const23498   int32_t pid() const { return pid_; }
set_pid(int32_t value)23499   void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
23500 
cmdline_size() const23501   int cmdline_size() const { return static_cast<int>(cmdline_.size()); }
cmdline() const23502   const std::vector<std::string>& cmdline() const { return cmdline_; }
mutable_cmdline()23503   std::vector<std::string>* mutable_cmdline() { return &cmdline_; }
clear_cmdline()23504   void clear_cmdline() { cmdline_.clear(); }
add_cmdline(std::string value)23505   void add_cmdline(std::string value) { cmdline_.emplace_back(value); }
add_cmdline()23506   std::string* add_cmdline() { cmdline_.emplace_back(); return &cmdline_.back(); }
23507 
has_process_name() const23508   bool has_process_name() const { return _has_field_[6]; }
process_name() const23509   const std::string& process_name() const { return process_name_; }
set_process_name(const std::string & value)23510   void set_process_name(const std::string& value) { process_name_ = value; _has_field_.set(6); }
23511 
has_process_priority() const23512   bool has_process_priority() const { return _has_field_[5]; }
process_priority() const23513   int32_t process_priority() const { return process_priority_; }
set_process_priority(int32_t value)23514   void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(5); }
23515 
has_chrome_process_type() const23516   bool has_chrome_process_type() const { return _has_field_[4]; }
chrome_process_type() const23517   ProcessDescriptor_ChromeProcessType chrome_process_type() const { return chrome_process_type_; }
set_chrome_process_type(ProcessDescriptor_ChromeProcessType value)23518   void set_chrome_process_type(ProcessDescriptor_ChromeProcessType value) { chrome_process_type_ = value; _has_field_.set(4); }
23519 
has_legacy_sort_index() const23520   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const23521   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)23522   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
23523 
23524  private:
23525   int32_t pid_{};
23526   std::vector<std::string> cmdline_;
23527   std::string process_name_{};
23528   int32_t process_priority_{};
23529   ProcessDescriptor_ChromeProcessType chrome_process_type_{};
23530   int32_t legacy_sort_index_{};
23531 
23532   // Allows to preserve unknown protobuf fields for compatibility
23533   // with future versions of .proto files.
23534   std::string unknown_fields_;
23535 
23536   std::bitset<7> _has_field_{};
23537 };
23538 
23539 }  // namespace perfetto
23540 }  // namespace protos
23541 }  // namespace gen
23542 
23543 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
23544 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
23545 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
23546 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
23547 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
23548 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23549 #pragma GCC diagnostic push
23550 #pragma GCC diagnostic ignored "-Wfloat-equal"
23551 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
23552 
23553 namespace perfetto {
23554 namespace protos {
23555 namespace gen {
23556 
23557 ProcessDescriptor::ProcessDescriptor() = default;
23558 ProcessDescriptor::~ProcessDescriptor() = default;
23559 ProcessDescriptor::ProcessDescriptor(const ProcessDescriptor&) = default;
23560 ProcessDescriptor& ProcessDescriptor::operator=(const ProcessDescriptor&) = default;
23561 ProcessDescriptor::ProcessDescriptor(ProcessDescriptor&&) noexcept = default;
23562 ProcessDescriptor& ProcessDescriptor::operator=(ProcessDescriptor&&) = default;
23563 
operator ==(const ProcessDescriptor & other) const23564 bool ProcessDescriptor::operator==(const ProcessDescriptor& other) const {
23565   return unknown_fields_ == other.unknown_fields_
23566    && pid_ == other.pid_
23567    && cmdline_ == other.cmdline_
23568    && process_name_ == other.process_name_
23569    && process_priority_ == other.process_priority_
23570    && chrome_process_type_ == other.chrome_process_type_
23571    && legacy_sort_index_ == other.legacy_sort_index_;
23572 }
23573 
ParseFromArray(const void * raw,size_t size)23574 bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
23575   cmdline_.clear();
23576   unknown_fields_.clear();
23577   bool packed_error = false;
23578 
23579   ::protozero::ProtoDecoder dec(raw, size);
23580   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23581     if (field.id() < _has_field_.size()) {
23582       _has_field_.set(field.id());
23583     }
23584     switch (field.id()) {
23585       case 1 /* pid */:
23586         field.get(&pid_);
23587         break;
23588       case 2 /* cmdline */:
23589         cmdline_.emplace_back();
23590         field.get(&cmdline_.back());
23591         break;
23592       case 6 /* process_name */:
23593         field.get(&process_name_);
23594         break;
23595       case 5 /* process_priority */:
23596         field.get(&process_priority_);
23597         break;
23598       case 4 /* chrome_process_type */:
23599         field.get(&chrome_process_type_);
23600         break;
23601       case 3 /* legacy_sort_index */:
23602         field.get(&legacy_sort_index_);
23603         break;
23604       default:
23605         field.SerializeAndAppendTo(&unknown_fields_);
23606         break;
23607     }
23608   }
23609   return !packed_error && !dec.bytes_left();
23610 }
23611 
SerializeAsString() const23612 std::string ProcessDescriptor::SerializeAsString() const {
23613   ::protozero::HeapBuffered<::protozero::Message> msg;
23614   Serialize(msg.get());
23615   return msg.SerializeAsString();
23616 }
23617 
SerializeAsArray() const23618 std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
23619   ::protozero::HeapBuffered<::protozero::Message> msg;
23620   Serialize(msg.get());
23621   return msg.SerializeAsArray();
23622 }
23623 
Serialize(::protozero::Message * msg) const23624 void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
23625   // Field 1: pid
23626   if (_has_field_[1]) {
23627     msg->AppendVarInt(1, pid_);
23628   }
23629 
23630   // Field 2: cmdline
23631   for (auto& it : cmdline_) {
23632     msg->AppendString(2, it);
23633   }
23634 
23635   // Field 6: process_name
23636   if (_has_field_[6]) {
23637     msg->AppendString(6, process_name_);
23638   }
23639 
23640   // Field 5: process_priority
23641   if (_has_field_[5]) {
23642     msg->AppendVarInt(5, process_priority_);
23643   }
23644 
23645   // Field 4: chrome_process_type
23646   if (_has_field_[4]) {
23647     msg->AppendVarInt(4, chrome_process_type_);
23648   }
23649 
23650   // Field 3: legacy_sort_index
23651   if (_has_field_[3]) {
23652     msg->AppendVarInt(3, legacy_sort_index_);
23653   }
23654 
23655   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23656 }
23657 
23658 }  // namespace perfetto
23659 }  // namespace protos
23660 }  // namespace gen
23661 #pragma GCC diagnostic pop
23662 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.gen.cc
23663 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
23664 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
23665 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
23666 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
23667 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23668 #pragma GCC diagnostic push
23669 #pragma GCC diagnostic ignored "-Wfloat-equal"
23670 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
23671 
23672 namespace perfetto {
23673 namespace protos {
23674 namespace gen {
23675 
23676 SourceLocation::SourceLocation() = default;
23677 SourceLocation::~SourceLocation() = default;
23678 SourceLocation::SourceLocation(const SourceLocation&) = default;
23679 SourceLocation& SourceLocation::operator=(const SourceLocation&) = default;
23680 SourceLocation::SourceLocation(SourceLocation&&) noexcept = default;
23681 SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;
23682 
operator ==(const SourceLocation & other) const23683 bool SourceLocation::operator==(const SourceLocation& other) const {
23684   return unknown_fields_ == other.unknown_fields_
23685    && iid_ == other.iid_
23686    && file_name_ == other.file_name_
23687    && function_name_ == other.function_name_
23688    && line_number_ == other.line_number_;
23689 }
23690 
ParseFromArray(const void * raw,size_t size)23691 bool SourceLocation::ParseFromArray(const void* raw, size_t size) {
23692   unknown_fields_.clear();
23693   bool packed_error = false;
23694 
23695   ::protozero::ProtoDecoder dec(raw, size);
23696   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23697     if (field.id() < _has_field_.size()) {
23698       _has_field_.set(field.id());
23699     }
23700     switch (field.id()) {
23701       case 1 /* iid */:
23702         field.get(&iid_);
23703         break;
23704       case 2 /* file_name */:
23705         field.get(&file_name_);
23706         break;
23707       case 3 /* function_name */:
23708         field.get(&function_name_);
23709         break;
23710       case 4 /* line_number */:
23711         field.get(&line_number_);
23712         break;
23713       default:
23714         field.SerializeAndAppendTo(&unknown_fields_);
23715         break;
23716     }
23717   }
23718   return !packed_error && !dec.bytes_left();
23719 }
23720 
SerializeAsString() const23721 std::string SourceLocation::SerializeAsString() const {
23722   ::protozero::HeapBuffered<::protozero::Message> msg;
23723   Serialize(msg.get());
23724   return msg.SerializeAsString();
23725 }
23726 
SerializeAsArray() const23727 std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
23728   ::protozero::HeapBuffered<::protozero::Message> msg;
23729   Serialize(msg.get());
23730   return msg.SerializeAsArray();
23731 }
23732 
Serialize(::protozero::Message * msg) const23733 void SourceLocation::Serialize(::protozero::Message* msg) const {
23734   // Field 1: iid
23735   if (_has_field_[1]) {
23736     msg->AppendVarInt(1, iid_);
23737   }
23738 
23739   // Field 2: file_name
23740   if (_has_field_[2]) {
23741     msg->AppendString(2, file_name_);
23742   }
23743 
23744   // Field 3: function_name
23745   if (_has_field_[3]) {
23746     msg->AppendString(3, function_name_);
23747   }
23748 
23749   // Field 4: line_number
23750   if (_has_field_[4]) {
23751     msg->AppendVarInt(4, line_number_);
23752   }
23753 
23754   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23755 }
23756 
23757 }  // namespace perfetto
23758 }  // namespace protos
23759 }  // namespace gen
23760 #pragma GCC diagnostic pop
23761 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.gen.cc
23762 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.gen.h
23763 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23764 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
23765 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
23766 
23767 #include <stdint.h>
23768 #include <bitset>
23769 #include <vector>
23770 #include <string>
23771 #include <type_traits>
23772 
23773 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
23774 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
23775 // gen_amalgamated expanded: #include "perfetto/base/export.h"
23776 
23777 namespace perfetto {
23778 namespace protos {
23779 namespace gen {
23780 class TaskExecution;
23781 }  // namespace perfetto
23782 }  // namespace protos
23783 }  // namespace gen
23784 
23785 namespace protozero {
23786 class Message;
23787 }  // namespace protozero
23788 
23789 namespace perfetto {
23790 namespace protos {
23791 namespace gen {
23792 
23793 class PERFETTO_EXPORT TaskExecution : public ::protozero::CppMessageObj {
23794  public:
23795   enum FieldNumbers {
23796     kPostedFromIidFieldNumber = 1,
23797   };
23798 
23799   TaskExecution();
23800   ~TaskExecution() override;
23801   TaskExecution(TaskExecution&&) noexcept;
23802   TaskExecution& operator=(TaskExecution&&);
23803   TaskExecution(const TaskExecution&);
23804   TaskExecution& operator=(const TaskExecution&);
23805   bool operator==(const TaskExecution&) const;
operator !=(const TaskExecution & other) const23806   bool operator!=(const TaskExecution& other) const { return !(*this == other); }
23807 
23808   bool ParseFromArray(const void*, size_t) override;
23809   std::string SerializeAsString() const override;
23810   std::vector<uint8_t> SerializeAsArray() const override;
23811   void Serialize(::protozero::Message*) const;
23812 
has_posted_from_iid() const23813   bool has_posted_from_iid() const { return _has_field_[1]; }
posted_from_iid() const23814   uint64_t posted_from_iid() const { return posted_from_iid_; }
set_posted_from_iid(uint64_t value)23815   void set_posted_from_iid(uint64_t value) { posted_from_iid_ = value; _has_field_.set(1); }
23816 
23817  private:
23818   uint64_t posted_from_iid_{};
23819 
23820   // Allows to preserve unknown protobuf fields for compatibility
23821   // with future versions of .proto files.
23822   std::string unknown_fields_;
23823 
23824   std::bitset<2> _has_field_{};
23825 };
23826 
23827 }  // namespace perfetto
23828 }  // namespace protos
23829 }  // namespace gen
23830 
23831 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
23832 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
23833 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
23834 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
23835 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
23836 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23837 #pragma GCC diagnostic push
23838 #pragma GCC diagnostic ignored "-Wfloat-equal"
23839 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
23840 
23841 namespace perfetto {
23842 namespace protos {
23843 namespace gen {
23844 
23845 TaskExecution::TaskExecution() = default;
23846 TaskExecution::~TaskExecution() = default;
23847 TaskExecution::TaskExecution(const TaskExecution&) = default;
23848 TaskExecution& TaskExecution::operator=(const TaskExecution&) = default;
23849 TaskExecution::TaskExecution(TaskExecution&&) noexcept = default;
23850 TaskExecution& TaskExecution::operator=(TaskExecution&&) = default;
23851 
operator ==(const TaskExecution & other) const23852 bool TaskExecution::operator==(const TaskExecution& other) const {
23853   return unknown_fields_ == other.unknown_fields_
23854    && posted_from_iid_ == other.posted_from_iid_;
23855 }
23856 
ParseFromArray(const void * raw,size_t size)23857 bool TaskExecution::ParseFromArray(const void* raw, size_t size) {
23858   unknown_fields_.clear();
23859   bool packed_error = false;
23860 
23861   ::protozero::ProtoDecoder dec(raw, size);
23862   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23863     if (field.id() < _has_field_.size()) {
23864       _has_field_.set(field.id());
23865     }
23866     switch (field.id()) {
23867       case 1 /* posted_from_iid */:
23868         field.get(&posted_from_iid_);
23869         break;
23870       default:
23871         field.SerializeAndAppendTo(&unknown_fields_);
23872         break;
23873     }
23874   }
23875   return !packed_error && !dec.bytes_left();
23876 }
23877 
SerializeAsString() const23878 std::string TaskExecution::SerializeAsString() const {
23879   ::protozero::HeapBuffered<::protozero::Message> msg;
23880   Serialize(msg.get());
23881   return msg.SerializeAsString();
23882 }
23883 
SerializeAsArray() const23884 std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
23885   ::protozero::HeapBuffered<::protozero::Message> msg;
23886   Serialize(msg.get());
23887   return msg.SerializeAsArray();
23888 }
23889 
Serialize(::protozero::Message * msg) const23890 void TaskExecution::Serialize(::protozero::Message* msg) const {
23891   // Field 1: posted_from_iid
23892   if (_has_field_[1]) {
23893     msg->AppendVarInt(1, posted_from_iid_);
23894   }
23895 
23896   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23897 }
23898 
23899 }  // namespace perfetto
23900 }  // namespace protos
23901 }  // namespace gen
23902 #pragma GCC diagnostic pop
23903 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.cc
23904 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.h
23905 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
23906 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
23907 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
23908 
23909 #include <stdint.h>
23910 #include <bitset>
23911 #include <vector>
23912 #include <string>
23913 #include <type_traits>
23914 
23915 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
23916 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
23917 // gen_amalgamated expanded: #include "perfetto/base/export.h"
23918 
23919 namespace perfetto {
23920 namespace protos {
23921 namespace gen {
23922 class ThreadDescriptor;
23923 enum ThreadDescriptor_ChromeThreadType : int;
23924 }  // namespace perfetto
23925 }  // namespace protos
23926 }  // namespace gen
23927 
23928 namespace protozero {
23929 class Message;
23930 }  // namespace protozero
23931 
23932 namespace perfetto {
23933 namespace protos {
23934 namespace gen {
23935 enum ThreadDescriptor_ChromeThreadType : int {
23936   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
23937   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
23938   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
23939   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
23940   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
23941   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
23942   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
23943   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
23944   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
23945   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
23946   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
23947   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
23948   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
23949   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
23950 };
23951 
23952 class PERFETTO_EXPORT ThreadDescriptor : public ::protozero::CppMessageObj {
23953  public:
23954   using ChromeThreadType = ThreadDescriptor_ChromeThreadType;
23955   static constexpr auto CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
23956   static constexpr auto CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
23957   static constexpr auto CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
23958   static constexpr auto CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
23959   static constexpr auto CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
23960   static constexpr auto CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
23961   static constexpr auto CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
23962   static constexpr auto CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
23963   static constexpr auto CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
23964   static constexpr auto CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
23965   static constexpr auto CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
23966   static constexpr auto CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
23967   static constexpr auto CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
23968   static constexpr auto CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
23969   static constexpr auto ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
23970   static constexpr auto ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
23971   enum FieldNumbers {
23972     kPidFieldNumber = 1,
23973     kTidFieldNumber = 2,
23974     kThreadNameFieldNumber = 5,
23975     kChromeThreadTypeFieldNumber = 4,
23976     kReferenceTimestampUsFieldNumber = 6,
23977     kReferenceThreadTimeUsFieldNumber = 7,
23978     kReferenceThreadInstructionCountFieldNumber = 8,
23979     kLegacySortIndexFieldNumber = 3,
23980   };
23981 
23982   ThreadDescriptor();
23983   ~ThreadDescriptor() override;
23984   ThreadDescriptor(ThreadDescriptor&&) noexcept;
23985   ThreadDescriptor& operator=(ThreadDescriptor&&);
23986   ThreadDescriptor(const ThreadDescriptor&);
23987   ThreadDescriptor& operator=(const ThreadDescriptor&);
23988   bool operator==(const ThreadDescriptor&) const;
operator !=(const ThreadDescriptor & other) const23989   bool operator!=(const ThreadDescriptor& other) const { return !(*this == other); }
23990 
23991   bool ParseFromArray(const void*, size_t) override;
23992   std::string SerializeAsString() const override;
23993   std::vector<uint8_t> SerializeAsArray() const override;
23994   void Serialize(::protozero::Message*) const;
23995 
has_pid() const23996   bool has_pid() const { return _has_field_[1]; }
pid() const23997   int32_t pid() const { return pid_; }
set_pid(int32_t value)23998   void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
23999 
has_tid() const24000   bool has_tid() const { return _has_field_[2]; }
tid() const24001   int32_t tid() const { return tid_; }
set_tid(int32_t value)24002   void set_tid(int32_t value) { tid_ = value; _has_field_.set(2); }
24003 
has_thread_name() const24004   bool has_thread_name() const { return _has_field_[5]; }
thread_name() const24005   const std::string& thread_name() const { return thread_name_; }
set_thread_name(const std::string & value)24006   void set_thread_name(const std::string& value) { thread_name_ = value; _has_field_.set(5); }
24007 
has_chrome_thread_type() const24008   bool has_chrome_thread_type() const { return _has_field_[4]; }
chrome_thread_type() const24009   ThreadDescriptor_ChromeThreadType chrome_thread_type() const { return chrome_thread_type_; }
set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value)24010   void set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value) { chrome_thread_type_ = value; _has_field_.set(4); }
24011 
has_reference_timestamp_us() const24012   bool has_reference_timestamp_us() const { return _has_field_[6]; }
reference_timestamp_us() const24013   int64_t reference_timestamp_us() const { return reference_timestamp_us_; }
set_reference_timestamp_us(int64_t value)24014   void set_reference_timestamp_us(int64_t value) { reference_timestamp_us_ = value; _has_field_.set(6); }
24015 
has_reference_thread_time_us() const24016   bool has_reference_thread_time_us() const { return _has_field_[7]; }
reference_thread_time_us() const24017   int64_t reference_thread_time_us() const { return reference_thread_time_us_; }
set_reference_thread_time_us(int64_t value)24018   void set_reference_thread_time_us(int64_t value) { reference_thread_time_us_ = value; _has_field_.set(7); }
24019 
has_reference_thread_instruction_count() const24020   bool has_reference_thread_instruction_count() const { return _has_field_[8]; }
reference_thread_instruction_count() const24021   int64_t reference_thread_instruction_count() const { return reference_thread_instruction_count_; }
set_reference_thread_instruction_count(int64_t value)24022   void set_reference_thread_instruction_count(int64_t value) { reference_thread_instruction_count_ = value; _has_field_.set(8); }
24023 
has_legacy_sort_index() const24024   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const24025   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)24026   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
24027 
24028  private:
24029   int32_t pid_{};
24030   int32_t tid_{};
24031   std::string thread_name_{};
24032   ThreadDescriptor_ChromeThreadType chrome_thread_type_{};
24033   int64_t reference_timestamp_us_{};
24034   int64_t reference_thread_time_us_{};
24035   int64_t reference_thread_instruction_count_{};
24036   int32_t legacy_sort_index_{};
24037 
24038   // Allows to preserve unknown protobuf fields for compatibility
24039   // with future versions of .proto files.
24040   std::string unknown_fields_;
24041 
24042   std::bitset<9> _has_field_{};
24043 };
24044 
24045 }  // namespace perfetto
24046 }  // namespace protos
24047 }  // namespace gen
24048 
24049 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
24050 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
24051 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
24052 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
24053 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
24054 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24055 #pragma GCC diagnostic push
24056 #pragma GCC diagnostic ignored "-Wfloat-equal"
24057 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
24058 
24059 namespace perfetto {
24060 namespace protos {
24061 namespace gen {
24062 
24063 ThreadDescriptor::ThreadDescriptor() = default;
24064 ThreadDescriptor::~ThreadDescriptor() = default;
24065 ThreadDescriptor::ThreadDescriptor(const ThreadDescriptor&) = default;
24066 ThreadDescriptor& ThreadDescriptor::operator=(const ThreadDescriptor&) = default;
24067 ThreadDescriptor::ThreadDescriptor(ThreadDescriptor&&) noexcept = default;
24068 ThreadDescriptor& ThreadDescriptor::operator=(ThreadDescriptor&&) = default;
24069 
operator ==(const ThreadDescriptor & other) const24070 bool ThreadDescriptor::operator==(const ThreadDescriptor& other) const {
24071   return unknown_fields_ == other.unknown_fields_
24072    && pid_ == other.pid_
24073    && tid_ == other.tid_
24074    && thread_name_ == other.thread_name_
24075    && chrome_thread_type_ == other.chrome_thread_type_
24076    && reference_timestamp_us_ == other.reference_timestamp_us_
24077    && reference_thread_time_us_ == other.reference_thread_time_us_
24078    && reference_thread_instruction_count_ == other.reference_thread_instruction_count_
24079    && legacy_sort_index_ == other.legacy_sort_index_;
24080 }
24081 
ParseFromArray(const void * raw,size_t size)24082 bool ThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
24083   unknown_fields_.clear();
24084   bool packed_error = false;
24085 
24086   ::protozero::ProtoDecoder dec(raw, size);
24087   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24088     if (field.id() < _has_field_.size()) {
24089       _has_field_.set(field.id());
24090     }
24091     switch (field.id()) {
24092       case 1 /* pid */:
24093         field.get(&pid_);
24094         break;
24095       case 2 /* tid */:
24096         field.get(&tid_);
24097         break;
24098       case 5 /* thread_name */:
24099         field.get(&thread_name_);
24100         break;
24101       case 4 /* chrome_thread_type */:
24102         field.get(&chrome_thread_type_);
24103         break;
24104       case 6 /* reference_timestamp_us */:
24105         field.get(&reference_timestamp_us_);
24106         break;
24107       case 7 /* reference_thread_time_us */:
24108         field.get(&reference_thread_time_us_);
24109         break;
24110       case 8 /* reference_thread_instruction_count */:
24111         field.get(&reference_thread_instruction_count_);
24112         break;
24113       case 3 /* legacy_sort_index */:
24114         field.get(&legacy_sort_index_);
24115         break;
24116       default:
24117         field.SerializeAndAppendTo(&unknown_fields_);
24118         break;
24119     }
24120   }
24121   return !packed_error && !dec.bytes_left();
24122 }
24123 
SerializeAsString() const24124 std::string ThreadDescriptor::SerializeAsString() const {
24125   ::protozero::HeapBuffered<::protozero::Message> msg;
24126   Serialize(msg.get());
24127   return msg.SerializeAsString();
24128 }
24129 
SerializeAsArray() const24130 std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
24131   ::protozero::HeapBuffered<::protozero::Message> msg;
24132   Serialize(msg.get());
24133   return msg.SerializeAsArray();
24134 }
24135 
Serialize(::protozero::Message * msg) const24136 void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
24137   // Field 1: pid
24138   if (_has_field_[1]) {
24139     msg->AppendVarInt(1, pid_);
24140   }
24141 
24142   // Field 2: tid
24143   if (_has_field_[2]) {
24144     msg->AppendVarInt(2, tid_);
24145   }
24146 
24147   // Field 5: thread_name
24148   if (_has_field_[5]) {
24149     msg->AppendString(5, thread_name_);
24150   }
24151 
24152   // Field 4: chrome_thread_type
24153   if (_has_field_[4]) {
24154     msg->AppendVarInt(4, chrome_thread_type_);
24155   }
24156 
24157   // Field 6: reference_timestamp_us
24158   if (_has_field_[6]) {
24159     msg->AppendVarInt(6, reference_timestamp_us_);
24160   }
24161 
24162   // Field 7: reference_thread_time_us
24163   if (_has_field_[7]) {
24164     msg->AppendVarInt(7, reference_thread_time_us_);
24165   }
24166 
24167   // Field 8: reference_thread_instruction_count
24168   if (_has_field_[8]) {
24169     msg->AppendVarInt(8, reference_thread_instruction_count_);
24170   }
24171 
24172   // Field 3: legacy_sort_index
24173   if (_has_field_[3]) {
24174     msg->AppendVarInt(3, legacy_sort_index_);
24175   }
24176 
24177   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24178 }
24179 
24180 }  // namespace perfetto
24181 }  // namespace protos
24182 }  // namespace gen
24183 #pragma GCC diagnostic pop
24184 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.gen.cc
24185 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
24186 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
24187 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
24188 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
24189 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24190 #pragma GCC diagnostic push
24191 #pragma GCC diagnostic ignored "-Wfloat-equal"
24192 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
24193 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
24194 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
24195 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
24196 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
24197 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
24198 
24199 namespace perfetto {
24200 namespace protos {
24201 namespace gen {
24202 
24203 TrackDescriptor::TrackDescriptor() = default;
24204 TrackDescriptor::~TrackDescriptor() = default;
24205 TrackDescriptor::TrackDescriptor(const TrackDescriptor&) = default;
24206 TrackDescriptor& TrackDescriptor::operator=(const TrackDescriptor&) = default;
24207 TrackDescriptor::TrackDescriptor(TrackDescriptor&&) noexcept = default;
24208 TrackDescriptor& TrackDescriptor::operator=(TrackDescriptor&&) = default;
24209 
operator ==(const TrackDescriptor & other) const24210 bool TrackDescriptor::operator==(const TrackDescriptor& other) const {
24211   return unknown_fields_ == other.unknown_fields_
24212    && uuid_ == other.uuid_
24213    && parent_uuid_ == other.parent_uuid_
24214    && name_ == other.name_
24215    && process_ == other.process_
24216    && chrome_process_ == other.chrome_process_
24217    && thread_ == other.thread_
24218    && chrome_thread_ == other.chrome_thread_
24219    && counter_ == other.counter_;
24220 }
24221 
ParseFromArray(const void * raw,size_t size)24222 bool TrackDescriptor::ParseFromArray(const void* raw, size_t size) {
24223   unknown_fields_.clear();
24224   bool packed_error = false;
24225 
24226   ::protozero::ProtoDecoder dec(raw, size);
24227   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24228     if (field.id() < _has_field_.size()) {
24229       _has_field_.set(field.id());
24230     }
24231     switch (field.id()) {
24232       case 1 /* uuid */:
24233         field.get(&uuid_);
24234         break;
24235       case 5 /* parent_uuid */:
24236         field.get(&parent_uuid_);
24237         break;
24238       case 2 /* name */:
24239         field.get(&name_);
24240         break;
24241       case 3 /* process */:
24242         (*process_).ParseFromString(field.as_std_string());
24243         break;
24244       case 6 /* chrome_process */:
24245         (*chrome_process_).ParseFromString(field.as_std_string());
24246         break;
24247       case 4 /* thread */:
24248         (*thread_).ParseFromString(field.as_std_string());
24249         break;
24250       case 7 /* chrome_thread */:
24251         (*chrome_thread_).ParseFromString(field.as_std_string());
24252         break;
24253       case 8 /* counter */:
24254         (*counter_).ParseFromString(field.as_std_string());
24255         break;
24256       default:
24257         field.SerializeAndAppendTo(&unknown_fields_);
24258         break;
24259     }
24260   }
24261   return !packed_error && !dec.bytes_left();
24262 }
24263 
SerializeAsString() const24264 std::string TrackDescriptor::SerializeAsString() const {
24265   ::protozero::HeapBuffered<::protozero::Message> msg;
24266   Serialize(msg.get());
24267   return msg.SerializeAsString();
24268 }
24269 
SerializeAsArray() const24270 std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
24271   ::protozero::HeapBuffered<::protozero::Message> msg;
24272   Serialize(msg.get());
24273   return msg.SerializeAsArray();
24274 }
24275 
Serialize(::protozero::Message * msg) const24276 void TrackDescriptor::Serialize(::protozero::Message* msg) const {
24277   // Field 1: uuid
24278   if (_has_field_[1]) {
24279     msg->AppendVarInt(1, uuid_);
24280   }
24281 
24282   // Field 5: parent_uuid
24283   if (_has_field_[5]) {
24284     msg->AppendVarInt(5, parent_uuid_);
24285   }
24286 
24287   // Field 2: name
24288   if (_has_field_[2]) {
24289     msg->AppendString(2, name_);
24290   }
24291 
24292   // Field 3: process
24293   if (_has_field_[3]) {
24294     (*process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
24295   }
24296 
24297   // Field 6: chrome_process
24298   if (_has_field_[6]) {
24299     (*chrome_process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
24300   }
24301 
24302   // Field 4: thread
24303   if (_has_field_[4]) {
24304     (*thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
24305   }
24306 
24307   // Field 7: chrome_thread
24308   if (_has_field_[7]) {
24309     (*chrome_thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
24310   }
24311 
24312   // Field 8: counter
24313   if (_has_field_[8]) {
24314     (*counter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
24315   }
24316 
24317   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24318 }
24319 
24320 }  // namespace perfetto
24321 }  // namespace protos
24322 }  // namespace gen
24323 #pragma GCC diagnostic pop
24324 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.gen.cc
24325 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.gen.h
24326 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24327 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
24328 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
24329 
24330 #include <stdint.h>
24331 #include <bitset>
24332 #include <vector>
24333 #include <string>
24334 #include <type_traits>
24335 
24336 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
24337 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
24338 // gen_amalgamated expanded: #include "perfetto/base/export.h"
24339 
24340 namespace perfetto {
24341 namespace protos {
24342 namespace gen {
24343 class EventName;
24344 class EventCategory;
24345 class TrackEventDefaults;
24346 class TrackEvent;
24347 class TrackEvent_LegacyEvent;
24348 class ChromeFrameReporter;
24349 class ChromeLatencyInfo;
24350 class ChromeLatencyInfo_ComponentInfo;
24351 class ChromeHistogramSample;
24352 class ChromeLegacyIpc;
24353 class ChromeKeyedService;
24354 class ChromeUserEvent;
24355 class ChromeCompositorSchedulerState;
24356 class CompositorTimingHistory;
24357 class BeginFrameSourceState;
24358 class BeginFrameArgs;
24359 class SourceLocation;
24360 class BeginFrameObserverState;
24361 class BeginImplFrameArgs;
24362 class BeginImplFrameArgs_TimestampsInUs;
24363 class ChromeCompositorStateMachine;
24364 class ChromeCompositorStateMachine_MinorState;
24365 class ChromeCompositorStateMachine_MajorState;
24366 class LogMessage;
24367 class TaskExecution;
24368 class DebugAnnotation;
24369 class DebugAnnotation_NestedValue;
24370 enum TrackEvent_Type : int;
24371 enum TrackEvent_LegacyEvent_FlowDirection : int;
24372 enum TrackEvent_LegacyEvent_InstantEventScope : int;
24373 enum ChromeFrameReporter_State : int;
24374 enum ChromeFrameReporter_FrameDropReason : int;
24375 enum ChromeLatencyInfo_Step : int;
24376 enum ChromeLatencyInfo_LatencyComponentType : int;
24377 enum ChromeLegacyIpc_MessageClass : int;
24378 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
24379 enum ChromeCompositorSchedulerAction : int;
24380 enum BeginFrameArgs_BeginFrameArgsType : int;
24381 enum BeginImplFrameArgs_State : int;
24382 enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
24383 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
24384 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
24385 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
24386 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
24387 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
24388 enum DebugAnnotation_NestedValue_NestedType : int;
24389 }  // namespace perfetto
24390 }  // namespace protos
24391 }  // namespace gen
24392 
24393 namespace protozero {
24394 class Message;
24395 }  // namespace protozero
24396 
24397 namespace perfetto {
24398 namespace protos {
24399 namespace gen {
24400 enum TrackEvent_Type : int {
24401   TrackEvent_Type_TYPE_UNSPECIFIED = 0,
24402   TrackEvent_Type_TYPE_SLICE_BEGIN = 1,
24403   TrackEvent_Type_TYPE_SLICE_END = 2,
24404   TrackEvent_Type_TYPE_INSTANT = 3,
24405   TrackEvent_Type_TYPE_COUNTER = 4,
24406 };
24407 enum TrackEvent_LegacyEvent_FlowDirection : int {
24408   TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
24409   TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
24410   TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
24411   TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
24412 };
24413 enum TrackEvent_LegacyEvent_InstantEventScope : int {
24414   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
24415   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
24416   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
24417   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
24418 };
24419 
24420 class PERFETTO_EXPORT EventName : public ::protozero::CppMessageObj {
24421  public:
24422   enum FieldNumbers {
24423     kIidFieldNumber = 1,
24424     kNameFieldNumber = 2,
24425   };
24426 
24427   EventName();
24428   ~EventName() override;
24429   EventName(EventName&&) noexcept;
24430   EventName& operator=(EventName&&);
24431   EventName(const EventName&);
24432   EventName& operator=(const EventName&);
24433   bool operator==(const EventName&) const;
operator !=(const EventName & other) const24434   bool operator!=(const EventName& other) const { return !(*this == other); }
24435 
24436   bool ParseFromArray(const void*, size_t) override;
24437   std::string SerializeAsString() const override;
24438   std::vector<uint8_t> SerializeAsArray() const override;
24439   void Serialize(::protozero::Message*) const;
24440 
has_iid() const24441   bool has_iid() const { return _has_field_[1]; }
iid() const24442   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)24443   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
24444 
has_name() const24445   bool has_name() const { return _has_field_[2]; }
name() const24446   const std::string& name() const { return name_; }
set_name(const std::string & value)24447   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
24448 
24449  private:
24450   uint64_t iid_{};
24451   std::string name_{};
24452 
24453   // Allows to preserve unknown protobuf fields for compatibility
24454   // with future versions of .proto files.
24455   std::string unknown_fields_;
24456 
24457   std::bitset<3> _has_field_{};
24458 };
24459 
24460 
24461 class PERFETTO_EXPORT EventCategory : public ::protozero::CppMessageObj {
24462  public:
24463   enum FieldNumbers {
24464     kIidFieldNumber = 1,
24465     kNameFieldNumber = 2,
24466   };
24467 
24468   EventCategory();
24469   ~EventCategory() override;
24470   EventCategory(EventCategory&&) noexcept;
24471   EventCategory& operator=(EventCategory&&);
24472   EventCategory(const EventCategory&);
24473   EventCategory& operator=(const EventCategory&);
24474   bool operator==(const EventCategory&) const;
operator !=(const EventCategory & other) const24475   bool operator!=(const EventCategory& other) const { return !(*this == other); }
24476 
24477   bool ParseFromArray(const void*, size_t) override;
24478   std::string SerializeAsString() const override;
24479   std::vector<uint8_t> SerializeAsArray() const override;
24480   void Serialize(::protozero::Message*) const;
24481 
has_iid() const24482   bool has_iid() const { return _has_field_[1]; }
iid() const24483   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)24484   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
24485 
has_name() const24486   bool has_name() const { return _has_field_[2]; }
name() const24487   const std::string& name() const { return name_; }
set_name(const std::string & value)24488   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
24489 
24490  private:
24491   uint64_t iid_{};
24492   std::string name_{};
24493 
24494   // Allows to preserve unknown protobuf fields for compatibility
24495   // with future versions of .proto files.
24496   std::string unknown_fields_;
24497 
24498   std::bitset<3> _has_field_{};
24499 };
24500 
24501 
24502 class PERFETTO_EXPORT TrackEventDefaults : public ::protozero::CppMessageObj {
24503  public:
24504   enum FieldNumbers {
24505     kTrackUuidFieldNumber = 11,
24506     kExtraCounterTrackUuidsFieldNumber = 31,
24507   };
24508 
24509   TrackEventDefaults();
24510   ~TrackEventDefaults() override;
24511   TrackEventDefaults(TrackEventDefaults&&) noexcept;
24512   TrackEventDefaults& operator=(TrackEventDefaults&&);
24513   TrackEventDefaults(const TrackEventDefaults&);
24514   TrackEventDefaults& operator=(const TrackEventDefaults&);
24515   bool operator==(const TrackEventDefaults&) const;
operator !=(const TrackEventDefaults & other) const24516   bool operator!=(const TrackEventDefaults& other) const { return !(*this == other); }
24517 
24518   bool ParseFromArray(const void*, size_t) override;
24519   std::string SerializeAsString() const override;
24520   std::vector<uint8_t> SerializeAsArray() const override;
24521   void Serialize(::protozero::Message*) const;
24522 
has_track_uuid() const24523   bool has_track_uuid() const { return _has_field_[11]; }
track_uuid() const24524   uint64_t track_uuid() const { return track_uuid_; }
set_track_uuid(uint64_t value)24525   void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
24526 
extra_counter_track_uuids_size() const24527   int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
extra_counter_track_uuids() const24528   const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
mutable_extra_counter_track_uuids()24529   std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
clear_extra_counter_track_uuids()24530   void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
add_extra_counter_track_uuids(uint64_t value)24531   void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
add_extra_counter_track_uuids()24532   uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
24533 
24534  private:
24535   uint64_t track_uuid_{};
24536   std::vector<uint64_t> extra_counter_track_uuids_;
24537 
24538   // Allows to preserve unknown protobuf fields for compatibility
24539   // with future versions of .proto files.
24540   std::string unknown_fields_;
24541 
24542   std::bitset<32> _has_field_{};
24543 };
24544 
24545 
24546 class PERFETTO_EXPORT TrackEvent : public ::protozero::CppMessageObj {
24547  public:
24548   using LegacyEvent = TrackEvent_LegacyEvent;
24549   using Type = TrackEvent_Type;
24550   static constexpr auto TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
24551   static constexpr auto TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
24552   static constexpr auto TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
24553   static constexpr auto TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
24554   static constexpr auto TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
24555   static constexpr auto Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
24556   static constexpr auto Type_MAX = TrackEvent_Type_TYPE_COUNTER;
24557   enum FieldNumbers {
24558     kCategoryIidsFieldNumber = 3,
24559     kCategoriesFieldNumber = 22,
24560     kNameIidFieldNumber = 10,
24561     kNameFieldNumber = 23,
24562     kTypeFieldNumber = 9,
24563     kTrackUuidFieldNumber = 11,
24564     kCounterValueFieldNumber = 30,
24565     kExtraCounterTrackUuidsFieldNumber = 31,
24566     kExtraCounterValuesFieldNumber = 12,
24567     kDebugAnnotationsFieldNumber = 4,
24568     kTaskExecutionFieldNumber = 5,
24569     kLogMessageFieldNumber = 21,
24570     kCcSchedulerStateFieldNumber = 24,
24571     kChromeUserEventFieldNumber = 25,
24572     kChromeKeyedServiceFieldNumber = 26,
24573     kChromeLegacyIpcFieldNumber = 27,
24574     kChromeHistogramSampleFieldNumber = 28,
24575     kChromeLatencyInfoFieldNumber = 29,
24576     kChromeFrameReporterFieldNumber = 32,
24577     kTimestampDeltaUsFieldNumber = 1,
24578     kTimestampAbsoluteUsFieldNumber = 16,
24579     kThreadTimeDeltaUsFieldNumber = 2,
24580     kThreadTimeAbsoluteUsFieldNumber = 17,
24581     kThreadInstructionCountDeltaFieldNumber = 8,
24582     kThreadInstructionCountAbsoluteFieldNumber = 20,
24583     kLegacyEventFieldNumber = 6,
24584   };
24585 
24586   TrackEvent();
24587   ~TrackEvent() override;
24588   TrackEvent(TrackEvent&&) noexcept;
24589   TrackEvent& operator=(TrackEvent&&);
24590   TrackEvent(const TrackEvent&);
24591   TrackEvent& operator=(const TrackEvent&);
24592   bool operator==(const TrackEvent&) const;
operator !=(const TrackEvent & other) const24593   bool operator!=(const TrackEvent& other) const { return !(*this == other); }
24594 
24595   bool ParseFromArray(const void*, size_t) override;
24596   std::string SerializeAsString() const override;
24597   std::vector<uint8_t> SerializeAsArray() const override;
24598   void Serialize(::protozero::Message*) const;
24599 
category_iids_size() const24600   int category_iids_size() const { return static_cast<int>(category_iids_.size()); }
category_iids() const24601   const std::vector<uint64_t>& category_iids() const { return category_iids_; }
mutable_category_iids()24602   std::vector<uint64_t>* mutable_category_iids() { return &category_iids_; }
clear_category_iids()24603   void clear_category_iids() { category_iids_.clear(); }
add_category_iids(uint64_t value)24604   void add_category_iids(uint64_t value) { category_iids_.emplace_back(value); }
add_category_iids()24605   uint64_t* add_category_iids() { category_iids_.emplace_back(); return &category_iids_.back(); }
24606 
categories_size() const24607   int categories_size() const { return static_cast<int>(categories_.size()); }
categories() const24608   const std::vector<std::string>& categories() const { return categories_; }
mutable_categories()24609   std::vector<std::string>* mutable_categories() { return &categories_; }
clear_categories()24610   void clear_categories() { categories_.clear(); }
add_categories(std::string value)24611   void add_categories(std::string value) { categories_.emplace_back(value); }
add_categories()24612   std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
24613 
has_name_iid() const24614   bool has_name_iid() const { return _has_field_[10]; }
name_iid() const24615   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)24616   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(10); }
24617 
has_name() const24618   bool has_name() const { return _has_field_[23]; }
name() const24619   const std::string& name() const { return name_; }
set_name(const std::string & value)24620   void set_name(const std::string& value) { name_ = value; _has_field_.set(23); }
24621 
has_type() const24622   bool has_type() const { return _has_field_[9]; }
type() const24623   TrackEvent_Type type() const { return type_; }
set_type(TrackEvent_Type value)24624   void set_type(TrackEvent_Type value) { type_ = value; _has_field_.set(9); }
24625 
has_track_uuid() const24626   bool has_track_uuid() const { return _has_field_[11]; }
track_uuid() const24627   uint64_t track_uuid() const { return track_uuid_; }
set_track_uuid(uint64_t value)24628   void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
24629 
has_counter_value() const24630   bool has_counter_value() const { return _has_field_[30]; }
counter_value() const24631   int64_t counter_value() const { return counter_value_; }
set_counter_value(int64_t value)24632   void set_counter_value(int64_t value) { counter_value_ = value; _has_field_.set(30); }
24633 
extra_counter_track_uuids_size() const24634   int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
extra_counter_track_uuids() const24635   const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
mutable_extra_counter_track_uuids()24636   std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
clear_extra_counter_track_uuids()24637   void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
add_extra_counter_track_uuids(uint64_t value)24638   void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
add_extra_counter_track_uuids()24639   uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
24640 
extra_counter_values_size() const24641   int extra_counter_values_size() const { return static_cast<int>(extra_counter_values_.size()); }
extra_counter_values() const24642   const std::vector<int64_t>& extra_counter_values() const { return extra_counter_values_; }
mutable_extra_counter_values()24643   std::vector<int64_t>* mutable_extra_counter_values() { return &extra_counter_values_; }
clear_extra_counter_values()24644   void clear_extra_counter_values() { extra_counter_values_.clear(); }
add_extra_counter_values(int64_t value)24645   void add_extra_counter_values(int64_t value) { extra_counter_values_.emplace_back(value); }
add_extra_counter_values()24646   int64_t* add_extra_counter_values() { extra_counter_values_.emplace_back(); return &extra_counter_values_.back(); }
24647 
debug_annotations_size() const24648   int debug_annotations_size() const { return static_cast<int>(debug_annotations_.size()); }
debug_annotations() const24649   const std::vector<DebugAnnotation>& debug_annotations() const { return debug_annotations_; }
mutable_debug_annotations()24650   std::vector<DebugAnnotation>* mutable_debug_annotations() { return &debug_annotations_; }
clear_debug_annotations()24651   void clear_debug_annotations() { debug_annotations_.clear(); }
add_debug_annotations()24652   DebugAnnotation* add_debug_annotations() { debug_annotations_.emplace_back(); return &debug_annotations_.back(); }
24653 
has_task_execution() const24654   bool has_task_execution() const { return _has_field_[5]; }
task_execution() const24655   const TaskExecution& task_execution() const { return *task_execution_; }
mutable_task_execution()24656   TaskExecution* mutable_task_execution() { _has_field_.set(5); return task_execution_.get(); }
24657 
has_log_message() const24658   bool has_log_message() const { return _has_field_[21]; }
log_message() const24659   const LogMessage& log_message() const { return *log_message_; }
mutable_log_message()24660   LogMessage* mutable_log_message() { _has_field_.set(21); return log_message_.get(); }
24661 
has_cc_scheduler_state() const24662   bool has_cc_scheduler_state() const { return _has_field_[24]; }
cc_scheduler_state() const24663   const ChromeCompositorSchedulerState& cc_scheduler_state() const { return *cc_scheduler_state_; }
mutable_cc_scheduler_state()24664   ChromeCompositorSchedulerState* mutable_cc_scheduler_state() { _has_field_.set(24); return cc_scheduler_state_.get(); }
24665 
has_chrome_user_event() const24666   bool has_chrome_user_event() const { return _has_field_[25]; }
chrome_user_event() const24667   const ChromeUserEvent& chrome_user_event() const { return *chrome_user_event_; }
mutable_chrome_user_event()24668   ChromeUserEvent* mutable_chrome_user_event() { _has_field_.set(25); return chrome_user_event_.get(); }
24669 
has_chrome_keyed_service() const24670   bool has_chrome_keyed_service() const { return _has_field_[26]; }
chrome_keyed_service() const24671   const ChromeKeyedService& chrome_keyed_service() const { return *chrome_keyed_service_; }
mutable_chrome_keyed_service()24672   ChromeKeyedService* mutable_chrome_keyed_service() { _has_field_.set(26); return chrome_keyed_service_.get(); }
24673 
has_chrome_legacy_ipc() const24674   bool has_chrome_legacy_ipc() const { return _has_field_[27]; }
chrome_legacy_ipc() const24675   const ChromeLegacyIpc& chrome_legacy_ipc() const { return *chrome_legacy_ipc_; }
mutable_chrome_legacy_ipc()24676   ChromeLegacyIpc* mutable_chrome_legacy_ipc() { _has_field_.set(27); return chrome_legacy_ipc_.get(); }
24677 
has_chrome_histogram_sample() const24678   bool has_chrome_histogram_sample() const { return _has_field_[28]; }
chrome_histogram_sample() const24679   const ChromeHistogramSample& chrome_histogram_sample() const { return *chrome_histogram_sample_; }
mutable_chrome_histogram_sample()24680   ChromeHistogramSample* mutable_chrome_histogram_sample() { _has_field_.set(28); return chrome_histogram_sample_.get(); }
24681 
has_chrome_latency_info() const24682   bool has_chrome_latency_info() const { return _has_field_[29]; }
chrome_latency_info() const24683   const ChromeLatencyInfo& chrome_latency_info() const { return *chrome_latency_info_; }
mutable_chrome_latency_info()24684   ChromeLatencyInfo* mutable_chrome_latency_info() { _has_field_.set(29); return chrome_latency_info_.get(); }
24685 
has_chrome_frame_reporter() const24686   bool has_chrome_frame_reporter() const { return _has_field_[32]; }
chrome_frame_reporter() const24687   const ChromeFrameReporter& chrome_frame_reporter() const { return *chrome_frame_reporter_; }
mutable_chrome_frame_reporter()24688   ChromeFrameReporter* mutable_chrome_frame_reporter() { _has_field_.set(32); return chrome_frame_reporter_.get(); }
24689 
has_timestamp_delta_us() const24690   bool has_timestamp_delta_us() const { return _has_field_[1]; }
timestamp_delta_us() const24691   int64_t timestamp_delta_us() const { return timestamp_delta_us_; }
set_timestamp_delta_us(int64_t value)24692   void set_timestamp_delta_us(int64_t value) { timestamp_delta_us_ = value; _has_field_.set(1); }
24693 
has_timestamp_absolute_us() const24694   bool has_timestamp_absolute_us() const { return _has_field_[16]; }
timestamp_absolute_us() const24695   int64_t timestamp_absolute_us() const { return timestamp_absolute_us_; }
set_timestamp_absolute_us(int64_t value)24696   void set_timestamp_absolute_us(int64_t value) { timestamp_absolute_us_ = value; _has_field_.set(16); }
24697 
has_thread_time_delta_us() const24698   bool has_thread_time_delta_us() const { return _has_field_[2]; }
thread_time_delta_us() const24699   int64_t thread_time_delta_us() const { return thread_time_delta_us_; }
set_thread_time_delta_us(int64_t value)24700   void set_thread_time_delta_us(int64_t value) { thread_time_delta_us_ = value; _has_field_.set(2); }
24701 
has_thread_time_absolute_us() const24702   bool has_thread_time_absolute_us() const { return _has_field_[17]; }
thread_time_absolute_us() const24703   int64_t thread_time_absolute_us() const { return thread_time_absolute_us_; }
set_thread_time_absolute_us(int64_t value)24704   void set_thread_time_absolute_us(int64_t value) { thread_time_absolute_us_ = value; _has_field_.set(17); }
24705 
has_thread_instruction_count_delta() const24706   bool has_thread_instruction_count_delta() const { return _has_field_[8]; }
thread_instruction_count_delta() const24707   int64_t thread_instruction_count_delta() const { return thread_instruction_count_delta_; }
set_thread_instruction_count_delta(int64_t value)24708   void set_thread_instruction_count_delta(int64_t value) { thread_instruction_count_delta_ = value; _has_field_.set(8); }
24709 
has_thread_instruction_count_absolute() const24710   bool has_thread_instruction_count_absolute() const { return _has_field_[20]; }
thread_instruction_count_absolute() const24711   int64_t thread_instruction_count_absolute() const { return thread_instruction_count_absolute_; }
set_thread_instruction_count_absolute(int64_t value)24712   void set_thread_instruction_count_absolute(int64_t value) { thread_instruction_count_absolute_ = value; _has_field_.set(20); }
24713 
has_legacy_event() const24714   bool has_legacy_event() const { return _has_field_[6]; }
legacy_event() const24715   const TrackEvent_LegacyEvent& legacy_event() const { return *legacy_event_; }
mutable_legacy_event()24716   TrackEvent_LegacyEvent* mutable_legacy_event() { _has_field_.set(6); return legacy_event_.get(); }
24717 
24718  private:
24719   std::vector<uint64_t> category_iids_;
24720   std::vector<std::string> categories_;
24721   uint64_t name_iid_{};
24722   std::string name_{};
24723   TrackEvent_Type type_{};
24724   uint64_t track_uuid_{};
24725   int64_t counter_value_{};
24726   std::vector<uint64_t> extra_counter_track_uuids_;
24727   std::vector<int64_t> extra_counter_values_;
24728   std::vector<DebugAnnotation> debug_annotations_;
24729   ::protozero::CopyablePtr<TaskExecution> task_execution_;
24730   ::protozero::CopyablePtr<LogMessage> log_message_;
24731   ::protozero::CopyablePtr<ChromeCompositorSchedulerState> cc_scheduler_state_;
24732   ::protozero::CopyablePtr<ChromeUserEvent> chrome_user_event_;
24733   ::protozero::CopyablePtr<ChromeKeyedService> chrome_keyed_service_;
24734   ::protozero::CopyablePtr<ChromeLegacyIpc> chrome_legacy_ipc_;
24735   ::protozero::CopyablePtr<ChromeHistogramSample> chrome_histogram_sample_;
24736   ::protozero::CopyablePtr<ChromeLatencyInfo> chrome_latency_info_;
24737   ::protozero::CopyablePtr<ChromeFrameReporter> chrome_frame_reporter_;
24738   int64_t timestamp_delta_us_{};
24739   int64_t timestamp_absolute_us_{};
24740   int64_t thread_time_delta_us_{};
24741   int64_t thread_time_absolute_us_{};
24742   int64_t thread_instruction_count_delta_{};
24743   int64_t thread_instruction_count_absolute_{};
24744   ::protozero::CopyablePtr<TrackEvent_LegacyEvent> legacy_event_;
24745 
24746   // Allows to preserve unknown protobuf fields for compatibility
24747   // with future versions of .proto files.
24748   std::string unknown_fields_;
24749 
24750   std::bitset<33> _has_field_{};
24751 };
24752 
24753 
24754 class PERFETTO_EXPORT TrackEvent_LegacyEvent : public ::protozero::CppMessageObj {
24755  public:
24756   using FlowDirection = TrackEvent_LegacyEvent_FlowDirection;
24757   static constexpr auto FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
24758   static constexpr auto FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
24759   static constexpr auto FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
24760   static constexpr auto FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
24761   static constexpr auto FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
24762   static constexpr auto FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
24763   using InstantEventScope = TrackEvent_LegacyEvent_InstantEventScope;
24764   static constexpr auto SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
24765   static constexpr auto SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
24766   static constexpr auto SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
24767   static constexpr auto SCOPE_THREAD = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
24768   static constexpr auto InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
24769   static constexpr auto InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
24770   enum FieldNumbers {
24771     kNameIidFieldNumber = 1,
24772     kPhaseFieldNumber = 2,
24773     kDurationUsFieldNumber = 3,
24774     kThreadDurationUsFieldNumber = 4,
24775     kThreadInstructionDeltaFieldNumber = 15,
24776     kUnscopedIdFieldNumber = 6,
24777     kLocalIdFieldNumber = 10,
24778     kGlobalIdFieldNumber = 11,
24779     kIdScopeFieldNumber = 7,
24780     kUseAsyncTtsFieldNumber = 9,
24781     kBindIdFieldNumber = 8,
24782     kBindToEnclosingFieldNumber = 12,
24783     kFlowDirectionFieldNumber = 13,
24784     kInstantEventScopeFieldNumber = 14,
24785     kPidOverrideFieldNumber = 18,
24786     kTidOverrideFieldNumber = 19,
24787   };
24788 
24789   TrackEvent_LegacyEvent();
24790   ~TrackEvent_LegacyEvent() override;
24791   TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept;
24792   TrackEvent_LegacyEvent& operator=(TrackEvent_LegacyEvent&&);
24793   TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&);
24794   TrackEvent_LegacyEvent& operator=(const TrackEvent_LegacyEvent&);
24795   bool operator==(const TrackEvent_LegacyEvent&) const;
operator !=(const TrackEvent_LegacyEvent & other) const24796   bool operator!=(const TrackEvent_LegacyEvent& other) const { return !(*this == other); }
24797 
24798   bool ParseFromArray(const void*, size_t) override;
24799   std::string SerializeAsString() const override;
24800   std::vector<uint8_t> SerializeAsArray() const override;
24801   void Serialize(::protozero::Message*) const;
24802 
has_name_iid() const24803   bool has_name_iid() const { return _has_field_[1]; }
name_iid() const24804   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)24805   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
24806 
has_phase() const24807   bool has_phase() const { return _has_field_[2]; }
phase() const24808   int32_t phase() const { return phase_; }
set_phase(int32_t value)24809   void set_phase(int32_t value) { phase_ = value; _has_field_.set(2); }
24810 
has_duration_us() const24811   bool has_duration_us() const { return _has_field_[3]; }
duration_us() const24812   int64_t duration_us() const { return duration_us_; }
set_duration_us(int64_t value)24813   void set_duration_us(int64_t value) { duration_us_ = value; _has_field_.set(3); }
24814 
has_thread_duration_us() const24815   bool has_thread_duration_us() const { return _has_field_[4]; }
thread_duration_us() const24816   int64_t thread_duration_us() const { return thread_duration_us_; }
set_thread_duration_us(int64_t value)24817   void set_thread_duration_us(int64_t value) { thread_duration_us_ = value; _has_field_.set(4); }
24818 
has_thread_instruction_delta() const24819   bool has_thread_instruction_delta() const { return _has_field_[15]; }
thread_instruction_delta() const24820   int64_t thread_instruction_delta() const { return thread_instruction_delta_; }
set_thread_instruction_delta(int64_t value)24821   void set_thread_instruction_delta(int64_t value) { thread_instruction_delta_ = value; _has_field_.set(15); }
24822 
has_unscoped_id() const24823   bool has_unscoped_id() const { return _has_field_[6]; }
unscoped_id() const24824   uint64_t unscoped_id() const { return unscoped_id_; }
set_unscoped_id(uint64_t value)24825   void set_unscoped_id(uint64_t value) { unscoped_id_ = value; _has_field_.set(6); }
24826 
has_local_id() const24827   bool has_local_id() const { return _has_field_[10]; }
local_id() const24828   uint64_t local_id() const { return local_id_; }
set_local_id(uint64_t value)24829   void set_local_id(uint64_t value) { local_id_ = value; _has_field_.set(10); }
24830 
has_global_id() const24831   bool has_global_id() const { return _has_field_[11]; }
global_id() const24832   uint64_t global_id() const { return global_id_; }
set_global_id(uint64_t value)24833   void set_global_id(uint64_t value) { global_id_ = value; _has_field_.set(11); }
24834 
has_id_scope() const24835   bool has_id_scope() const { return _has_field_[7]; }
id_scope() const24836   const std::string& id_scope() const { return id_scope_; }
set_id_scope(const std::string & value)24837   void set_id_scope(const std::string& value) { id_scope_ = value; _has_field_.set(7); }
24838 
has_use_async_tts() const24839   bool has_use_async_tts() const { return _has_field_[9]; }
use_async_tts() const24840   bool use_async_tts() const { return use_async_tts_; }
set_use_async_tts(bool value)24841   void set_use_async_tts(bool value) { use_async_tts_ = value; _has_field_.set(9); }
24842 
has_bind_id() const24843   bool has_bind_id() const { return _has_field_[8]; }
bind_id() const24844   uint64_t bind_id() const { return bind_id_; }
set_bind_id(uint64_t value)24845   void set_bind_id(uint64_t value) { bind_id_ = value; _has_field_.set(8); }
24846 
has_bind_to_enclosing() const24847   bool has_bind_to_enclosing() const { return _has_field_[12]; }
bind_to_enclosing() const24848   bool bind_to_enclosing() const { return bind_to_enclosing_; }
set_bind_to_enclosing(bool value)24849   void set_bind_to_enclosing(bool value) { bind_to_enclosing_ = value; _has_field_.set(12); }
24850 
has_flow_direction() const24851   bool has_flow_direction() const { return _has_field_[13]; }
flow_direction() const24852   TrackEvent_LegacyEvent_FlowDirection flow_direction() const { return flow_direction_; }
set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value)24853   void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) { flow_direction_ = value; _has_field_.set(13); }
24854 
has_instant_event_scope() const24855   bool has_instant_event_scope() const { return _has_field_[14]; }
instant_event_scope() const24856   TrackEvent_LegacyEvent_InstantEventScope instant_event_scope() const { return instant_event_scope_; }
set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value)24857   void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) { instant_event_scope_ = value; _has_field_.set(14); }
24858 
has_pid_override() const24859   bool has_pid_override() const { return _has_field_[18]; }
pid_override() const24860   int32_t pid_override() const { return pid_override_; }
set_pid_override(int32_t value)24861   void set_pid_override(int32_t value) { pid_override_ = value; _has_field_.set(18); }
24862 
has_tid_override() const24863   bool has_tid_override() const { return _has_field_[19]; }
tid_override() const24864   int32_t tid_override() const { return tid_override_; }
set_tid_override(int32_t value)24865   void set_tid_override(int32_t value) { tid_override_ = value; _has_field_.set(19); }
24866 
24867  private:
24868   uint64_t name_iid_{};
24869   int32_t phase_{};
24870   int64_t duration_us_{};
24871   int64_t thread_duration_us_{};
24872   int64_t thread_instruction_delta_{};
24873   uint64_t unscoped_id_{};
24874   uint64_t local_id_{};
24875   uint64_t global_id_{};
24876   std::string id_scope_{};
24877   bool use_async_tts_{};
24878   uint64_t bind_id_{};
24879   bool bind_to_enclosing_{};
24880   TrackEvent_LegacyEvent_FlowDirection flow_direction_{};
24881   TrackEvent_LegacyEvent_InstantEventScope instant_event_scope_{};
24882   int32_t pid_override_{};
24883   int32_t tid_override_{};
24884 
24885   // Allows to preserve unknown protobuf fields for compatibility
24886   // with future versions of .proto files.
24887   std::string unknown_fields_;
24888 
24889   std::bitset<20> _has_field_{};
24890 };
24891 
24892 }  // namespace perfetto
24893 }  // namespace protos
24894 }  // namespace gen
24895 
24896 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
24897 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
24898 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
24899 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
24900 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
24901 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24902 #pragma GCC diagnostic push
24903 #pragma GCC diagnostic ignored "-Wfloat-equal"
24904 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.gen.h"
24905 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
24906 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
24907 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
24908 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
24909 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
24910 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
24911 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
24912 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
24913 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
24914 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
24915 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
24916 
24917 namespace perfetto {
24918 namespace protos {
24919 namespace gen {
24920 
24921 EventName::EventName() = default;
24922 EventName::~EventName() = default;
24923 EventName::EventName(const EventName&) = default;
24924 EventName& EventName::operator=(const EventName&) = default;
24925 EventName::EventName(EventName&&) noexcept = default;
24926 EventName& EventName::operator=(EventName&&) = default;
24927 
operator ==(const EventName & other) const24928 bool EventName::operator==(const EventName& other) const {
24929   return unknown_fields_ == other.unknown_fields_
24930    && iid_ == other.iid_
24931    && name_ == other.name_;
24932 }
24933 
ParseFromArray(const void * raw,size_t size)24934 bool EventName::ParseFromArray(const void* raw, size_t size) {
24935   unknown_fields_.clear();
24936   bool packed_error = false;
24937 
24938   ::protozero::ProtoDecoder dec(raw, size);
24939   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24940     if (field.id() < _has_field_.size()) {
24941       _has_field_.set(field.id());
24942     }
24943     switch (field.id()) {
24944       case 1 /* iid */:
24945         field.get(&iid_);
24946         break;
24947       case 2 /* name */:
24948         field.get(&name_);
24949         break;
24950       default:
24951         field.SerializeAndAppendTo(&unknown_fields_);
24952         break;
24953     }
24954   }
24955   return !packed_error && !dec.bytes_left();
24956 }
24957 
SerializeAsString() const24958 std::string EventName::SerializeAsString() const {
24959   ::protozero::HeapBuffered<::protozero::Message> msg;
24960   Serialize(msg.get());
24961   return msg.SerializeAsString();
24962 }
24963 
SerializeAsArray() const24964 std::vector<uint8_t> EventName::SerializeAsArray() const {
24965   ::protozero::HeapBuffered<::protozero::Message> msg;
24966   Serialize(msg.get());
24967   return msg.SerializeAsArray();
24968 }
24969 
Serialize(::protozero::Message * msg) const24970 void EventName::Serialize(::protozero::Message* msg) const {
24971   // Field 1: iid
24972   if (_has_field_[1]) {
24973     msg->AppendVarInt(1, iid_);
24974   }
24975 
24976   // Field 2: name
24977   if (_has_field_[2]) {
24978     msg->AppendString(2, name_);
24979   }
24980 
24981   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24982 }
24983 
24984 
24985 EventCategory::EventCategory() = default;
24986 EventCategory::~EventCategory() = default;
24987 EventCategory::EventCategory(const EventCategory&) = default;
24988 EventCategory& EventCategory::operator=(const EventCategory&) = default;
24989 EventCategory::EventCategory(EventCategory&&) noexcept = default;
24990 EventCategory& EventCategory::operator=(EventCategory&&) = default;
24991 
operator ==(const EventCategory & other) const24992 bool EventCategory::operator==(const EventCategory& other) const {
24993   return unknown_fields_ == other.unknown_fields_
24994    && iid_ == other.iid_
24995    && name_ == other.name_;
24996 }
24997 
ParseFromArray(const void * raw,size_t size)24998 bool EventCategory::ParseFromArray(const void* raw, size_t size) {
24999   unknown_fields_.clear();
25000   bool packed_error = false;
25001 
25002   ::protozero::ProtoDecoder dec(raw, size);
25003   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25004     if (field.id() < _has_field_.size()) {
25005       _has_field_.set(field.id());
25006     }
25007     switch (field.id()) {
25008       case 1 /* iid */:
25009         field.get(&iid_);
25010         break;
25011       case 2 /* name */:
25012         field.get(&name_);
25013         break;
25014       default:
25015         field.SerializeAndAppendTo(&unknown_fields_);
25016         break;
25017     }
25018   }
25019   return !packed_error && !dec.bytes_left();
25020 }
25021 
SerializeAsString() const25022 std::string EventCategory::SerializeAsString() const {
25023   ::protozero::HeapBuffered<::protozero::Message> msg;
25024   Serialize(msg.get());
25025   return msg.SerializeAsString();
25026 }
25027 
SerializeAsArray() const25028 std::vector<uint8_t> EventCategory::SerializeAsArray() const {
25029   ::protozero::HeapBuffered<::protozero::Message> msg;
25030   Serialize(msg.get());
25031   return msg.SerializeAsArray();
25032 }
25033 
Serialize(::protozero::Message * msg) const25034 void EventCategory::Serialize(::protozero::Message* msg) const {
25035   // Field 1: iid
25036   if (_has_field_[1]) {
25037     msg->AppendVarInt(1, iid_);
25038   }
25039 
25040   // Field 2: name
25041   if (_has_field_[2]) {
25042     msg->AppendString(2, name_);
25043   }
25044 
25045   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25046 }
25047 
25048 
25049 TrackEventDefaults::TrackEventDefaults() = default;
25050 TrackEventDefaults::~TrackEventDefaults() = default;
25051 TrackEventDefaults::TrackEventDefaults(const TrackEventDefaults&) = default;
25052 TrackEventDefaults& TrackEventDefaults::operator=(const TrackEventDefaults&) = default;
25053 TrackEventDefaults::TrackEventDefaults(TrackEventDefaults&&) noexcept = default;
25054 TrackEventDefaults& TrackEventDefaults::operator=(TrackEventDefaults&&) = default;
25055 
operator ==(const TrackEventDefaults & other) const25056 bool TrackEventDefaults::operator==(const TrackEventDefaults& other) const {
25057   return unknown_fields_ == other.unknown_fields_
25058    && track_uuid_ == other.track_uuid_
25059    && extra_counter_track_uuids_ == other.extra_counter_track_uuids_;
25060 }
25061 
ParseFromArray(const void * raw,size_t size)25062 bool TrackEventDefaults::ParseFromArray(const void* raw, size_t size) {
25063   extra_counter_track_uuids_.clear();
25064   unknown_fields_.clear();
25065   bool packed_error = false;
25066 
25067   ::protozero::ProtoDecoder dec(raw, size);
25068   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25069     if (field.id() < _has_field_.size()) {
25070       _has_field_.set(field.id());
25071     }
25072     switch (field.id()) {
25073       case 11 /* track_uuid */:
25074         field.get(&track_uuid_);
25075         break;
25076       case 31 /* extra_counter_track_uuids */:
25077         extra_counter_track_uuids_.emplace_back();
25078         field.get(&extra_counter_track_uuids_.back());
25079         break;
25080       default:
25081         field.SerializeAndAppendTo(&unknown_fields_);
25082         break;
25083     }
25084   }
25085   return !packed_error && !dec.bytes_left();
25086 }
25087 
SerializeAsString() const25088 std::string TrackEventDefaults::SerializeAsString() const {
25089   ::protozero::HeapBuffered<::protozero::Message> msg;
25090   Serialize(msg.get());
25091   return msg.SerializeAsString();
25092 }
25093 
SerializeAsArray() const25094 std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
25095   ::protozero::HeapBuffered<::protozero::Message> msg;
25096   Serialize(msg.get());
25097   return msg.SerializeAsArray();
25098 }
25099 
Serialize(::protozero::Message * msg) const25100 void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
25101   // Field 11: track_uuid
25102   if (_has_field_[11]) {
25103     msg->AppendVarInt(11, track_uuid_);
25104   }
25105 
25106   // Field 31: extra_counter_track_uuids
25107   for (auto& it : extra_counter_track_uuids_) {
25108     msg->AppendVarInt(31, it);
25109   }
25110 
25111   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25112 }
25113 
25114 
25115 TrackEvent::TrackEvent() = default;
25116 TrackEvent::~TrackEvent() = default;
25117 TrackEvent::TrackEvent(const TrackEvent&) = default;
25118 TrackEvent& TrackEvent::operator=(const TrackEvent&) = default;
25119 TrackEvent::TrackEvent(TrackEvent&&) noexcept = default;
25120 TrackEvent& TrackEvent::operator=(TrackEvent&&) = default;
25121 
operator ==(const TrackEvent & other) const25122 bool TrackEvent::operator==(const TrackEvent& other) const {
25123   return unknown_fields_ == other.unknown_fields_
25124    && category_iids_ == other.category_iids_
25125    && categories_ == other.categories_
25126    && name_iid_ == other.name_iid_
25127    && name_ == other.name_
25128    && type_ == other.type_
25129    && track_uuid_ == other.track_uuid_
25130    && counter_value_ == other.counter_value_
25131    && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
25132    && extra_counter_values_ == other.extra_counter_values_
25133    && debug_annotations_ == other.debug_annotations_
25134    && task_execution_ == other.task_execution_
25135    && log_message_ == other.log_message_
25136    && cc_scheduler_state_ == other.cc_scheduler_state_
25137    && chrome_user_event_ == other.chrome_user_event_
25138    && chrome_keyed_service_ == other.chrome_keyed_service_
25139    && chrome_legacy_ipc_ == other.chrome_legacy_ipc_
25140    && chrome_histogram_sample_ == other.chrome_histogram_sample_
25141    && chrome_latency_info_ == other.chrome_latency_info_
25142    && chrome_frame_reporter_ == other.chrome_frame_reporter_
25143    && timestamp_delta_us_ == other.timestamp_delta_us_
25144    && timestamp_absolute_us_ == other.timestamp_absolute_us_
25145    && thread_time_delta_us_ == other.thread_time_delta_us_
25146    && thread_time_absolute_us_ == other.thread_time_absolute_us_
25147    && thread_instruction_count_delta_ == other.thread_instruction_count_delta_
25148    && thread_instruction_count_absolute_ == other.thread_instruction_count_absolute_
25149    && legacy_event_ == other.legacy_event_;
25150 }
25151 
ParseFromArray(const void * raw,size_t size)25152 bool TrackEvent::ParseFromArray(const void* raw, size_t size) {
25153   category_iids_.clear();
25154   categories_.clear();
25155   extra_counter_track_uuids_.clear();
25156   extra_counter_values_.clear();
25157   debug_annotations_.clear();
25158   unknown_fields_.clear();
25159   bool packed_error = false;
25160 
25161   ::protozero::ProtoDecoder dec(raw, size);
25162   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25163     if (field.id() < _has_field_.size()) {
25164       _has_field_.set(field.id());
25165     }
25166     switch (field.id()) {
25167       case 3 /* category_iids */:
25168         category_iids_.emplace_back();
25169         field.get(&category_iids_.back());
25170         break;
25171       case 22 /* categories */:
25172         categories_.emplace_back();
25173         field.get(&categories_.back());
25174         break;
25175       case 10 /* name_iid */:
25176         field.get(&name_iid_);
25177         break;
25178       case 23 /* name */:
25179         field.get(&name_);
25180         break;
25181       case 9 /* type */:
25182         field.get(&type_);
25183         break;
25184       case 11 /* track_uuid */:
25185         field.get(&track_uuid_);
25186         break;
25187       case 30 /* counter_value */:
25188         field.get(&counter_value_);
25189         break;
25190       case 31 /* extra_counter_track_uuids */:
25191         extra_counter_track_uuids_.emplace_back();
25192         field.get(&extra_counter_track_uuids_.back());
25193         break;
25194       case 12 /* extra_counter_values */:
25195         extra_counter_values_.emplace_back();
25196         field.get(&extra_counter_values_.back());
25197         break;
25198       case 4 /* debug_annotations */:
25199         debug_annotations_.emplace_back();
25200         debug_annotations_.back().ParseFromString(field.as_std_string());
25201         break;
25202       case 5 /* task_execution */:
25203         (*task_execution_).ParseFromString(field.as_std_string());
25204         break;
25205       case 21 /* log_message */:
25206         (*log_message_).ParseFromString(field.as_std_string());
25207         break;
25208       case 24 /* cc_scheduler_state */:
25209         (*cc_scheduler_state_).ParseFromString(field.as_std_string());
25210         break;
25211       case 25 /* chrome_user_event */:
25212         (*chrome_user_event_).ParseFromString(field.as_std_string());
25213         break;
25214       case 26 /* chrome_keyed_service */:
25215         (*chrome_keyed_service_).ParseFromString(field.as_std_string());
25216         break;
25217       case 27 /* chrome_legacy_ipc */:
25218         (*chrome_legacy_ipc_).ParseFromString(field.as_std_string());
25219         break;
25220       case 28 /* chrome_histogram_sample */:
25221         (*chrome_histogram_sample_).ParseFromString(field.as_std_string());
25222         break;
25223       case 29 /* chrome_latency_info */:
25224         (*chrome_latency_info_).ParseFromString(field.as_std_string());
25225         break;
25226       case 32 /* chrome_frame_reporter */:
25227         (*chrome_frame_reporter_).ParseFromString(field.as_std_string());
25228         break;
25229       case 1 /* timestamp_delta_us */:
25230         field.get(&timestamp_delta_us_);
25231         break;
25232       case 16 /* timestamp_absolute_us */:
25233         field.get(&timestamp_absolute_us_);
25234         break;
25235       case 2 /* thread_time_delta_us */:
25236         field.get(&thread_time_delta_us_);
25237         break;
25238       case 17 /* thread_time_absolute_us */:
25239         field.get(&thread_time_absolute_us_);
25240         break;
25241       case 8 /* thread_instruction_count_delta */:
25242         field.get(&thread_instruction_count_delta_);
25243         break;
25244       case 20 /* thread_instruction_count_absolute */:
25245         field.get(&thread_instruction_count_absolute_);
25246         break;
25247       case 6 /* legacy_event */:
25248         (*legacy_event_).ParseFromString(field.as_std_string());
25249         break;
25250       default:
25251         field.SerializeAndAppendTo(&unknown_fields_);
25252         break;
25253     }
25254   }
25255   return !packed_error && !dec.bytes_left();
25256 }
25257 
SerializeAsString() const25258 std::string TrackEvent::SerializeAsString() const {
25259   ::protozero::HeapBuffered<::protozero::Message> msg;
25260   Serialize(msg.get());
25261   return msg.SerializeAsString();
25262 }
25263 
SerializeAsArray() const25264 std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
25265   ::protozero::HeapBuffered<::protozero::Message> msg;
25266   Serialize(msg.get());
25267   return msg.SerializeAsArray();
25268 }
25269 
Serialize(::protozero::Message * msg) const25270 void TrackEvent::Serialize(::protozero::Message* msg) const {
25271   // Field 3: category_iids
25272   for (auto& it : category_iids_) {
25273     msg->AppendVarInt(3, it);
25274   }
25275 
25276   // Field 22: categories
25277   for (auto& it : categories_) {
25278     msg->AppendString(22, it);
25279   }
25280 
25281   // Field 10: name_iid
25282   if (_has_field_[10]) {
25283     msg->AppendVarInt(10, name_iid_);
25284   }
25285 
25286   // Field 23: name
25287   if (_has_field_[23]) {
25288     msg->AppendString(23, name_);
25289   }
25290 
25291   // Field 9: type
25292   if (_has_field_[9]) {
25293     msg->AppendVarInt(9, type_);
25294   }
25295 
25296   // Field 11: track_uuid
25297   if (_has_field_[11]) {
25298     msg->AppendVarInt(11, track_uuid_);
25299   }
25300 
25301   // Field 30: counter_value
25302   if (_has_field_[30]) {
25303     msg->AppendVarInt(30, counter_value_);
25304   }
25305 
25306   // Field 31: extra_counter_track_uuids
25307   for (auto& it : extra_counter_track_uuids_) {
25308     msg->AppendVarInt(31, it);
25309   }
25310 
25311   // Field 12: extra_counter_values
25312   for (auto& it : extra_counter_values_) {
25313     msg->AppendVarInt(12, it);
25314   }
25315 
25316   // Field 4: debug_annotations
25317   for (auto& it : debug_annotations_) {
25318     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
25319   }
25320 
25321   // Field 5: task_execution
25322   if (_has_field_[5]) {
25323     (*task_execution_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
25324   }
25325 
25326   // Field 21: log_message
25327   if (_has_field_[21]) {
25328     (*log_message_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
25329   }
25330 
25331   // Field 24: cc_scheduler_state
25332   if (_has_field_[24]) {
25333     (*cc_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(24));
25334   }
25335 
25336   // Field 25: chrome_user_event
25337   if (_has_field_[25]) {
25338     (*chrome_user_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
25339   }
25340 
25341   // Field 26: chrome_keyed_service
25342   if (_has_field_[26]) {
25343     (*chrome_keyed_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(26));
25344   }
25345 
25346   // Field 27: chrome_legacy_ipc
25347   if (_has_field_[27]) {
25348     (*chrome_legacy_ipc_).Serialize(msg->BeginNestedMessage<::protozero::Message>(27));
25349   }
25350 
25351   // Field 28: chrome_histogram_sample
25352   if (_has_field_[28]) {
25353     (*chrome_histogram_sample_).Serialize(msg->BeginNestedMessage<::protozero::Message>(28));
25354   }
25355 
25356   // Field 29: chrome_latency_info
25357   if (_has_field_[29]) {
25358     (*chrome_latency_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(29));
25359   }
25360 
25361   // Field 32: chrome_frame_reporter
25362   if (_has_field_[32]) {
25363     (*chrome_frame_reporter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
25364   }
25365 
25366   // Field 1: timestamp_delta_us
25367   if (_has_field_[1]) {
25368     msg->AppendVarInt(1, timestamp_delta_us_);
25369   }
25370 
25371   // Field 16: timestamp_absolute_us
25372   if (_has_field_[16]) {
25373     msg->AppendVarInt(16, timestamp_absolute_us_);
25374   }
25375 
25376   // Field 2: thread_time_delta_us
25377   if (_has_field_[2]) {
25378     msg->AppendVarInt(2, thread_time_delta_us_);
25379   }
25380 
25381   // Field 17: thread_time_absolute_us
25382   if (_has_field_[17]) {
25383     msg->AppendVarInt(17, thread_time_absolute_us_);
25384   }
25385 
25386   // Field 8: thread_instruction_count_delta
25387   if (_has_field_[8]) {
25388     msg->AppendVarInt(8, thread_instruction_count_delta_);
25389   }
25390 
25391   // Field 20: thread_instruction_count_absolute
25392   if (_has_field_[20]) {
25393     msg->AppendVarInt(20, thread_instruction_count_absolute_);
25394   }
25395 
25396   // Field 6: legacy_event
25397   if (_has_field_[6]) {
25398     (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
25399   }
25400 
25401   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25402 }
25403 
25404 
25405 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent() = default;
25406 TrackEvent_LegacyEvent::~TrackEvent_LegacyEvent() = default;
25407 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&) = default;
25408 TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(const TrackEvent_LegacyEvent&) = default;
25409 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept = default;
25410 TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(TrackEvent_LegacyEvent&&) = default;
25411 
operator ==(const TrackEvent_LegacyEvent & other) const25412 bool TrackEvent_LegacyEvent::operator==(const TrackEvent_LegacyEvent& other) const {
25413   return unknown_fields_ == other.unknown_fields_
25414    && name_iid_ == other.name_iid_
25415    && phase_ == other.phase_
25416    && duration_us_ == other.duration_us_
25417    && thread_duration_us_ == other.thread_duration_us_
25418    && thread_instruction_delta_ == other.thread_instruction_delta_
25419    && unscoped_id_ == other.unscoped_id_
25420    && local_id_ == other.local_id_
25421    && global_id_ == other.global_id_
25422    && id_scope_ == other.id_scope_
25423    && use_async_tts_ == other.use_async_tts_
25424    && bind_id_ == other.bind_id_
25425    && bind_to_enclosing_ == other.bind_to_enclosing_
25426    && flow_direction_ == other.flow_direction_
25427    && instant_event_scope_ == other.instant_event_scope_
25428    && pid_override_ == other.pid_override_
25429    && tid_override_ == other.tid_override_;
25430 }
25431 
ParseFromArray(const void * raw,size_t size)25432 bool TrackEvent_LegacyEvent::ParseFromArray(const void* raw, size_t size) {
25433   unknown_fields_.clear();
25434   bool packed_error = false;
25435 
25436   ::protozero::ProtoDecoder dec(raw, size);
25437   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25438     if (field.id() < _has_field_.size()) {
25439       _has_field_.set(field.id());
25440     }
25441     switch (field.id()) {
25442       case 1 /* name_iid */:
25443         field.get(&name_iid_);
25444         break;
25445       case 2 /* phase */:
25446         field.get(&phase_);
25447         break;
25448       case 3 /* duration_us */:
25449         field.get(&duration_us_);
25450         break;
25451       case 4 /* thread_duration_us */:
25452         field.get(&thread_duration_us_);
25453         break;
25454       case 15 /* thread_instruction_delta */:
25455         field.get(&thread_instruction_delta_);
25456         break;
25457       case 6 /* unscoped_id */:
25458         field.get(&unscoped_id_);
25459         break;
25460       case 10 /* local_id */:
25461         field.get(&local_id_);
25462         break;
25463       case 11 /* global_id */:
25464         field.get(&global_id_);
25465         break;
25466       case 7 /* id_scope */:
25467         field.get(&id_scope_);
25468         break;
25469       case 9 /* use_async_tts */:
25470         field.get(&use_async_tts_);
25471         break;
25472       case 8 /* bind_id */:
25473         field.get(&bind_id_);
25474         break;
25475       case 12 /* bind_to_enclosing */:
25476         field.get(&bind_to_enclosing_);
25477         break;
25478       case 13 /* flow_direction */:
25479         field.get(&flow_direction_);
25480         break;
25481       case 14 /* instant_event_scope */:
25482         field.get(&instant_event_scope_);
25483         break;
25484       case 18 /* pid_override */:
25485         field.get(&pid_override_);
25486         break;
25487       case 19 /* tid_override */:
25488         field.get(&tid_override_);
25489         break;
25490       default:
25491         field.SerializeAndAppendTo(&unknown_fields_);
25492         break;
25493     }
25494   }
25495   return !packed_error && !dec.bytes_left();
25496 }
25497 
SerializeAsString() const25498 std::string TrackEvent_LegacyEvent::SerializeAsString() const {
25499   ::protozero::HeapBuffered<::protozero::Message> msg;
25500   Serialize(msg.get());
25501   return msg.SerializeAsString();
25502 }
25503 
SerializeAsArray() const25504 std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
25505   ::protozero::HeapBuffered<::protozero::Message> msg;
25506   Serialize(msg.get());
25507   return msg.SerializeAsArray();
25508 }
25509 
Serialize(::protozero::Message * msg) const25510 void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
25511   // Field 1: name_iid
25512   if (_has_field_[1]) {
25513     msg->AppendVarInt(1, name_iid_);
25514   }
25515 
25516   // Field 2: phase
25517   if (_has_field_[2]) {
25518     msg->AppendVarInt(2, phase_);
25519   }
25520 
25521   // Field 3: duration_us
25522   if (_has_field_[3]) {
25523     msg->AppendVarInt(3, duration_us_);
25524   }
25525 
25526   // Field 4: thread_duration_us
25527   if (_has_field_[4]) {
25528     msg->AppendVarInt(4, thread_duration_us_);
25529   }
25530 
25531   // Field 15: thread_instruction_delta
25532   if (_has_field_[15]) {
25533     msg->AppendVarInt(15, thread_instruction_delta_);
25534   }
25535 
25536   // Field 6: unscoped_id
25537   if (_has_field_[6]) {
25538     msg->AppendVarInt(6, unscoped_id_);
25539   }
25540 
25541   // Field 10: local_id
25542   if (_has_field_[10]) {
25543     msg->AppendVarInt(10, local_id_);
25544   }
25545 
25546   // Field 11: global_id
25547   if (_has_field_[11]) {
25548     msg->AppendVarInt(11, global_id_);
25549   }
25550 
25551   // Field 7: id_scope
25552   if (_has_field_[7]) {
25553     msg->AppendString(7, id_scope_);
25554   }
25555 
25556   // Field 9: use_async_tts
25557   if (_has_field_[9]) {
25558     msg->AppendTinyVarInt(9, use_async_tts_);
25559   }
25560 
25561   // Field 8: bind_id
25562   if (_has_field_[8]) {
25563     msg->AppendVarInt(8, bind_id_);
25564   }
25565 
25566   // Field 12: bind_to_enclosing
25567   if (_has_field_[12]) {
25568     msg->AppendTinyVarInt(12, bind_to_enclosing_);
25569   }
25570 
25571   // Field 13: flow_direction
25572   if (_has_field_[13]) {
25573     msg->AppendVarInt(13, flow_direction_);
25574   }
25575 
25576   // Field 14: instant_event_scope
25577   if (_has_field_[14]) {
25578     msg->AppendVarInt(14, instant_event_scope_);
25579   }
25580 
25581   // Field 18: pid_override
25582   if (_has_field_[18]) {
25583     msg->AppendVarInt(18, pid_override_);
25584   }
25585 
25586   // Field 19: tid_override
25587   if (_has_field_[19]) {
25588     msg->AppendVarInt(19, tid_override_);
25589   }
25590 
25591   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25592 }
25593 
25594 }  // namespace perfetto
25595 }  // namespace protos
25596 }  // namespace gen
25597 #pragma GCC diagnostic pop
25598 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.pbzero.cc
25599 // Intentionally empty (crbug.com/998165)
25600 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.cc
25601 // Intentionally empty (crbug.com/998165)
25602 // gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.pbzero.cc
25603 // Intentionally empty (crbug.com/998165)
25604 // gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc
25605 // Intentionally empty (crbug.com/998165)
25606 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc
25607 // Intentionally empty (crbug.com/998165)
25608 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc
25609 // Intentionally empty (crbug.com/998165)
25610 // gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc
25611 // Intentionally empty (crbug.com/998165)
25612 // gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.pbzero.cc
25613 // Intentionally empty (crbug.com/998165)
25614 // gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc
25615 // Intentionally empty (crbug.com/998165)
25616 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc
25617 // Intentionally empty (crbug.com/998165)
25618 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc
25619 // Intentionally empty (crbug.com/998165)
25620 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.cc
25621 // Intentionally empty (crbug.com/998165)
25622 // gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc
25623 // Intentionally empty (crbug.com/998165)
25624 // gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.pbzero.cc
25625 // Intentionally empty (crbug.com/998165)
25626 // gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.pbzero.cc
25627 // Intentionally empty (crbug.com/998165)
25628 // gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.pbzero.cc
25629 // Intentionally empty (crbug.com/998165)
25630 // gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.pbzero.cc
25631 // Intentionally empty (crbug.com/998165)
25632 // gen_amalgamated begin source: gen/protos/perfetto/config/test_config.pbzero.cc
25633 // Intentionally empty (crbug.com/998165)
25634 // gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.pbzero.cc
25635 // Intentionally empty (crbug.com/998165)
25636 // gen_amalgamated begin source: gen/protos/perfetto/trace/clock_snapshot.pbzero.cc
25637 // Intentionally empty (crbug.com/998165)
25638 // gen_amalgamated begin source: gen/protos/perfetto/trace/trigger.pbzero.cc
25639 // Intentionally empty (crbug.com/998165)
25640 // gen_amalgamated begin source: gen/protos/perfetto/trace/system_info.pbzero.cc
25641 // Intentionally empty (crbug.com/998165)
25642 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_log.pbzero.cc
25643 // Intentionally empty (crbug.com/998165)
25644 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc
25645 // Intentionally empty (crbug.com/998165)
25646 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc
25647 // Intentionally empty (crbug.com/998165)
25648 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/initial_display_state.pbzero.cc
25649 // Intentionally empty (crbug.com/998165)
25650 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/packages_list.pbzero.cc
25651 // Intentionally empty (crbug.com/998165)
25652 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc
25653 // Intentionally empty (crbug.com/998165)
25654 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc
25655 // Intentionally empty (crbug.com/998165)
25656 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc
25657 // Intentionally empty (crbug.com/998165)
25658 // gen_amalgamated begin source: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc
25659 // Intentionally empty (crbug.com/998165)
25660 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc
25661 // Intentionally empty (crbug.com/998165)
25662 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc
25663 // Intentionally empty (crbug.com/998165)
25664 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc
25665 // Intentionally empty (crbug.com/998165)
25666 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc
25667 // Intentionally empty (crbug.com/998165)
25668 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/generic.pbzero.cc
25669 // Intentionally empty (crbug.com/998165)
25670 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/binder.pbzero.cc
25671 // Intentionally empty (crbug.com/998165)
25672 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/block.pbzero.cc
25673 // Intentionally empty (crbug.com/998165)
25674 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.cc
25675 // Intentionally empty (crbug.com/998165)
25676 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/clk.pbzero.cc
25677 // Intentionally empty (crbug.com/998165)
25678 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/compaction.pbzero.cc
25679 // Intentionally empty (crbug.com/998165)
25680 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc
25681 // Intentionally empty (crbug.com/998165)
25682 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ext4.pbzero.cc
25683 // Intentionally empty (crbug.com/998165)
25684 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.cc
25685 // Intentionally empty (crbug.com/998165)
25686 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fence.pbzero.cc
25687 // Intentionally empty (crbug.com/998165)
25688 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/filemap.pbzero.cc
25689 // Intentionally empty (crbug.com/998165)
25690 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.cc
25691 // Intentionally empty (crbug.com/998165)
25692 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc
25693 // Intentionally empty (crbug.com/998165)
25694 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/i2c.pbzero.cc
25695 // Intentionally empty (crbug.com/998165)
25696 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ion.pbzero.cc
25697 // Intentionally empty (crbug.com/998165)
25698 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ipi.pbzero.cc
25699 // Intentionally empty (crbug.com/998165)
25700 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/irq.pbzero.cc
25701 // Intentionally empty (crbug.com/998165)
25702 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kmem.pbzero.cc
25703 // Intentionally empty (crbug.com/998165)
25704 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc
25705 // Intentionally empty (crbug.com/998165)
25706 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mdss.pbzero.cc
25707 // Intentionally empty (crbug.com/998165)
25708 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.cc
25709 // Intentionally empty (crbug.com/998165)
25710 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/oom.pbzero.cc
25711 // Intentionally empty (crbug.com/998165)
25712 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/power.pbzero.cc
25713 // Intentionally empty (crbug.com/998165)
25714 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc
25715 // Intentionally empty (crbug.com/998165)
25716 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/regulator.pbzero.cc
25717 // Intentionally empty (crbug.com/998165)
25718 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sched.pbzero.cc
25719 // Intentionally empty (crbug.com/998165)
25720 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/scm.pbzero.cc
25721 // Intentionally empty (crbug.com/998165)
25722 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sde.pbzero.cc
25723 // Intentionally empty (crbug.com/998165)
25724 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/signal.pbzero.cc
25725 // Intentionally empty (crbug.com/998165)
25726 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sync.pbzero.cc
25727 // Intentionally empty (crbug.com/998165)
25728 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/systrace.pbzero.cc
25729 // Intentionally empty (crbug.com/998165)
25730 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/task.pbzero.cc
25731 // Intentionally empty (crbug.com/998165)
25732 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/thermal.pbzero.cc
25733 // Intentionally empty (crbug.com/998165)
25734 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.cc
25735 // Intentionally empty (crbug.com/998165)
25736 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.cc
25737 // Intentionally empty (crbug.com/998165)
25738 // gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc
25739 // Intentionally empty (crbug.com/998165)
25740 // gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc
25741 // Intentionally empty (crbug.com/998165)
25742 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/battery_counters.pbzero.cc
25743 // Intentionally empty (crbug.com/998165)
25744 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/power_rails.pbzero.cc
25745 // Intentionally empty (crbug.com/998165)
25746 // gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_stats.pbzero.cc
25747 // Intentionally empty (crbug.com/998165)
25748 // gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_tree.pbzero.cc
25749 // Intentionally empty (crbug.com/998165)
25750 // gen_amalgamated begin source: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc
25751 // Intentionally empty (crbug.com/998165)
25752 // gen_amalgamated begin source: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.cc
25753 // Intentionally empty (crbug.com/998165)
25754 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.cc
25755 // Intentionally empty (crbug.com/998165)
25756 // gen_amalgamated begin source: gen/protos/perfetto/trace/test_event.pbzero.cc
25757 // Intentionally empty (crbug.com/998165)
25758 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet.pbzero.cc
25759 // Intentionally empty (crbug.com/998165)
25760 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace.pbzero.cc
25761 // Intentionally empty (crbug.com/998165)
25762 // gen_amalgamated begin source: gen/protos/perfetto/trace/extension_descriptor.pbzero.cc
25763 // Intentionally empty (crbug.com/998165)
25764 // gen_amalgamated begin source: gen/protos/perfetto/trace/memory_graph.pbzero.cc
25765 // Intentionally empty (crbug.com/998165)
25766 // gen_amalgamated begin source: src/tracing/trace_writer_base.cc
25767 /*
25768  * Copyright (C) 2019 The Android Open Source Project
25769  *
25770  * Licensed under the Apache License, Version 2.0 (the "License");
25771  * you may not use this file except in compliance with the License.
25772  * You may obtain a copy of the License at
25773  *
25774  *      http://www.apache.org/licenses/LICENSE-2.0
25775  *
25776  * Unless required by applicable law or agreed to in writing, software
25777  * distributed under the License is distributed on an "AS IS" BASIS,
25778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25779  * See the License for the specific language governing permissions and
25780  * limitations under the License.
25781  */
25782 
25783 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
25784 
25785 namespace perfetto {
25786 
25787 // This destructor needs to be defined in a dedicated translation unit and
25788 // cannot be merged together with the other ones in virtual_destructors.cc.
25789 // This is because trace_writer_base.h/cc  is part of a separate target
25790 // (src/public:common) that is linked also by other part of the codebase.
25791 
25792 TraceWriterBase::~TraceWriterBase() = default;
25793 
25794 }  // namespace perfetto
25795 // gen_amalgamated begin source: src/tracing/core/id_allocator.cc
25796 // gen_amalgamated begin header: src/tracing/core/id_allocator.h
25797 /*
25798  * Copyright (C) 2017 The Android Open Source Project
25799  *
25800  * Licensed under the Apache License, Version 2.0 (the "License");
25801  * you may not use this file except in compliance with the License.
25802  * You may obtain a copy of the License at
25803  *
25804  *      http://www.apache.org/licenses/LICENSE-2.0
25805  *
25806  * Unless required by applicable law or agreed to in writing, software
25807  * distributed under the License is distributed on an "AS IS" BASIS,
25808  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25809  * See the License for the specific language governing permissions and
25810  * limitations under the License.
25811  */
25812 
25813 #ifndef SRC_TRACING_CORE_ID_ALLOCATOR_H_
25814 #define SRC_TRACING_CORE_ID_ALLOCATOR_H_
25815 
25816 #include <stdint.h>
25817 
25818 #include <type_traits>
25819 #include <vector>
25820 
25821 namespace perfetto {
25822 
25823 // Handles assigment of IDs (int types) from a fixed-size pool.
25824 // Zero is not considered a valid ID.
25825 // The base class takes always a uint32_t and the derived class casts and checks
25826 // bounds at compile time. This is to avoid bloating code with different
25827 // instances of the main class for each size.
25828 class IdAllocatorGeneric {
25829  public:
25830   // |max_id| is inclusive.
25831   explicit IdAllocatorGeneric(uint32_t max_id);
25832   ~IdAllocatorGeneric();
25833 
25834   // Returns an ID in the range [1, max_id] or 0 if no more ids are available.
25835   uint32_t AllocateGeneric();
25836   void FreeGeneric(uint32_t);
25837 
25838  private:
25839   IdAllocatorGeneric(const IdAllocatorGeneric&) = delete;
25840   IdAllocatorGeneric& operator=(const IdAllocatorGeneric&) = delete;
25841 
25842   const uint32_t max_id_;
25843   uint32_t last_id_ = 0;
25844   std::vector<bool> ids_;
25845 };
25846 
25847 template <typename T = uint32_t>
25848 class IdAllocator : public IdAllocatorGeneric {
25849  public:
IdAllocator(T end)25850   explicit IdAllocator(T end) : IdAllocatorGeneric(end) {
25851     static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
25852                   "T must be an unsigned integer");
25853     static_assert(sizeof(T) <= sizeof(uint32_t), "T is too big");
25854   }
25855 
Allocate()25856   T Allocate() { return static_cast<T>(AllocateGeneric()); }
Free(T id)25857   void Free(T id) { FreeGeneric(id); }
25858 };
25859 
25860 }  // namespace perfetto
25861 
25862 #endif  // SRC_TRACING_CORE_ID_ALLOCATOR_H_
25863 /*
25864  * Copyright (C) 2017 The Android Open Source Project
25865  *
25866  * Licensed under the Apache License, Version 2.0 (the "License");
25867  * you may not use this file except in compliance with the License.
25868  * You may obtain a copy of the License at
25869  *
25870  *      http://www.apache.org/licenses/LICENSE-2.0
25871  *
25872  * Unless required by applicable law or agreed to in writing, software
25873  * distributed under the License is distributed on an "AS IS" BASIS,
25874  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25875  * See the License for the specific language governing permissions and
25876  * limitations under the License.
25877  */
25878 
25879 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
25880 
25881 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
25882 
25883 namespace perfetto {
25884 
IdAllocatorGeneric(uint32_t max_id)25885 IdAllocatorGeneric::IdAllocatorGeneric(uint32_t max_id) : max_id_(max_id) {
25886   PERFETTO_DCHECK(max_id > 1);
25887 }
25888 
25889 IdAllocatorGeneric::~IdAllocatorGeneric() = default;
25890 
AllocateGeneric()25891 uint32_t IdAllocatorGeneric::AllocateGeneric() {
25892   for (uint32_t ignored = 1; ignored <= max_id_; ignored++) {
25893     last_id_ = last_id_ < max_id_ ? last_id_ + 1 : 1;
25894     const auto id = last_id_;
25895 
25896     // 0 is never a valid ID. So if we are looking for |id| == N and there are
25897     // N or less elements in the vector, they must necessarily be all < N.
25898     // e.g. if |id| == 4 and size() == 4, the vector will contain IDs 0,1,2,3.
25899     if (id >= ids_.size()) {
25900       ids_.resize(id + 1);
25901       ids_[id] = true;
25902       return id;
25903     }
25904 
25905     if (!ids_[id]) {
25906       ids_[id] = true;
25907       return id;
25908     }
25909   }
25910   return 0;
25911 }
25912 
FreeGeneric(uint32_t id)25913 void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
25914   if (id == 0 || id >= ids_.size() || !ids_[id]) {
25915     PERFETTO_DFATAL("Invalid id.");
25916     return;
25917   }
25918   ids_[id] = false;
25919 }
25920 
25921 }  // namespace perfetto
25922 // gen_amalgamated begin source: src/tracing/core/null_trace_writer.cc
25923 // gen_amalgamated begin header: src/tracing/core/null_trace_writer.h
25924 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_writer.h
25925 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/basic_types.h
25926 /*
25927  * Copyright (C) 2017 The Android Open Source Project
25928  *
25929  * Licensed under the Apache License, Version 2.0 (the "License");
25930  * you may not use this file except in compliance with the License.
25931  * You may obtain a copy of the License at
25932  *
25933  *      http://www.apache.org/licenses/LICENSE-2.0
25934  *
25935  * Unless required by applicable law or agreed to in writing, software
25936  * distributed under the License is distributed on an "AS IS" BASIS,
25937  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25938  * See the License for the specific language governing permissions and
25939  * limitations under the License.
25940  */
25941 
25942 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
25943 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
25944 
25945 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
25946 
25947 #include <stddef.h>
25948 #include <stdint.h>
25949 #include <sys/types.h>
25950 
25951 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
25952 using uid_t = unsigned int;
25953 #endif
25954 
25955 namespace perfetto {
25956 
25957 // Unique within the scope of the tracing service.
25958 using TracingSessionID = uint64_t;
25959 
25960 // Unique within the scope of the tracing service.
25961 using ProducerID = uint16_t;
25962 
25963 // Unique within the scope of the tracing service.
25964 using DataSourceInstanceID = uint64_t;
25965 
25966 // Unique within the scope of a Producer.
25967 using WriterID = uint16_t;
25968 
25969 // Unique within the scope of the tracing service.
25970 using FlushRequestID = uint64_t;
25971 
25972 // We need one FD per producer and we are not going to be able to keep > 64k FDs
25973 // open in the service.
25974 static constexpr ProducerID kMaxProducerID = static_cast<ProducerID>(-1);
25975 
25976 // 1024 Writers per producer seems a resonable bound. This reduces the ability
25977 // to memory-DoS the service by having to keep track of too many writer IDs.
25978 static constexpr WriterID kMaxWriterID = static_cast<WriterID>((1 << 10) - 1);
25979 
25980 // Unique within the scope of a {ProducerID, WriterID} tuple.
25981 using ChunkID = uint32_t;
25982 static constexpr ChunkID kMaxChunkID = static_cast<ChunkID>(-1);
25983 
25984 // Unique within the scope of the tracing service.
25985 using BufferID = uint16_t;
25986 
25987 // Target buffer ID for SharedMemoryArbiter. Values up to max uint16_t are
25988 // equivalent to a bound BufferID. Values above max uint16_t are reservation IDs
25989 // for the target buffer of a startup trace writer. Reservation IDs will be
25990 // translated to actual BufferIDs after they are bound by
25991 // SharedMemoryArbiter::BindStartupTargetBuffer().
25992 using MaybeUnboundBufferID = uint32_t;
25993 
25994 // Keep this in sync with SharedMemoryABI::PageHeader::target_buffer.
25995 static constexpr BufferID kMaxTraceBufferID = static_cast<BufferID>(-1);
25996 
25997 // Unique within the scope of a tracing session.
25998 using PacketSequenceID = uint32_t;
25999 // Used for extra packets emitted by the service, such as statistics.
26000 static constexpr PacketSequenceID kServicePacketSequenceID = 1;
26001 static constexpr PacketSequenceID kMaxPacketSequenceID =
26002     static_cast<PacketSequenceID>(-1);
26003 
26004 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
26005 
26006 constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
26007 
26008 }  // namespace perfetto
26009 
26010 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
26011 /*
26012  * Copyright (C) 2017 The Android Open Source Project
26013  *
26014  * Licensed under the Apache License, Version 2.0 (the "License");
26015  * you may not use this file except in compliance with the License.
26016  * You may obtain a copy of the License at
26017  *
26018  *      http://www.apache.org/licenses/LICENSE-2.0
26019  *
26020  * Unless required by applicable law or agreed to in writing, software
26021  * distributed under the License is distributed on an "AS IS" BASIS,
26022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26023  * See the License for the specific language governing permissions and
26024  * limitations under the License.
26025  */
26026 
26027 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
26028 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
26029 
26030 #include <functional>
26031 
26032 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26033 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
26034 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
26035 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
26036 
26037 namespace perfetto {
26038 
26039 namespace protos {
26040 namespace pbzero {
26041 class TracePacket;
26042 }  // namespace pbzero
26043 }  // namespace protos
26044 
26045 // This is a single-thread write interface that allows to write protobufs
26046 // directly into the tracing shared buffer without making any copies.
26047 // It takes care of acquiring and releasing chunks from the
26048 // SharedMemoryArbiter and splitting protos over chunks.
26049 // The idea is that each data source creates one (or more) TraceWriter for each
26050 // thread it wants to write from. Each TraceWriter will get its own dedicated
26051 // chunk and will write into the shared buffer without any locking most of the
26052 // time. Locking will happen only when a chunk is exhausted and a new one is
26053 // acquired from the arbiter.
26054 
26055 // TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
26056 // Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
26057 // the TraceWriter will keep writing into unmapped memory.
26058 
26059 class PERFETTO_EXPORT TraceWriter : public TraceWriterBase {
26060  public:
26061   using TracePacketHandle =
26062       protozero::MessageHandle<protos::pbzero::TracePacket>;
26063 
26064   TraceWriter();
26065   ~TraceWriter() override;
26066 
26067   // Returns a handle to the root proto message for the trace. The message will
26068   // be finalized either by calling directly handle.Finalize() or by letting the
26069   // handle go out of scope. The returned handle can be std::move()'d but cannot
26070   // be used after either: (i) the TraceWriter instance is destroyed, (ii) a
26071   // subsequence NewTracePacket() call is made on the same TraceWriter instance.
26072   TracePacketHandle NewTracePacket() override = 0;
26073 
26074   // Commits the data pending for the current chunk into the shared memory
26075   // buffer and sends a CommitDataRequest() to the service. This can be called
26076   // only if the handle returned by NewTracePacket() has been destroyed (i.e. we
26077   // cannot Flush() while writing a TracePacket).
26078   // Note: Flush() also happens implicitly when destroying the TraceWriter.
26079   // |callback| is an optional callback. When non-null it will request the
26080   // service to ACK the flush and will be invoked after the service has
26081   // acknowledged it. The callback might be NEVER INVOKED if the service crashes
26082   // or the IPC connection is dropped. The callback should be used only by tests
26083   // and best-effort features (logging).
26084   // TODO(primiano): right now the |callback| will be called on the IPC thread.
26085   // This is fine in the current single-thread scenario, but long-term
26086   // trace_writer_impl.cc should be smarter and post it on the right thread.
26087   void Flush(std::function<void()> callback = {}) override = 0;
26088 
26089   virtual WriterID writer_id() const = 0;
26090 
26091   // Bytes written since creation. Is not reset when new chunks are acquired.
26092   virtual uint64_t written() const override = 0;
26093 
26094  private:
26095   TraceWriter(const TraceWriter&) = delete;
26096   TraceWriter& operator=(const TraceWriter&) = delete;
26097 };
26098 
26099 }  // namespace perfetto
26100 
26101 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
26102 /*
26103  * Copyright (C) 2018 The Android Open Source Project
26104  *
26105  * Licensed under the Apache License, Version 2.0 (the "License");
26106  * you may not use this file except in compliance with the License.
26107  * You may obtain a copy of the License at
26108  *
26109  *      http://www.apache.org/licenses/LICENSE-2.0
26110  *
26111  * Unless required by applicable law or agreed to in writing, software
26112  * distributed under the License is distributed on an "AS IS" BASIS,
26113  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26114  * See the License for the specific language governing permissions and
26115  * limitations under the License.
26116  */
26117 
26118 #ifndef SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
26119 #define SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
26120 
26121 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
26122 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
26123 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
26124 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
26125 
26126 namespace perfetto {
26127 
26128 // A specialization of TraceWriter which no-ops all the writes routing them
26129 // into a fixed region of memory
26130 // See //include/perfetto/tracing/core/trace_writer.h for docs.
26131 class NullTraceWriter : public TraceWriter {
26132  public:
26133   NullTraceWriter();
26134   ~NullTraceWriter() override;
26135 
26136   // TraceWriter implementation. See documentation in trace_writer.h.
26137   // TracePacketHandle is defined in trace_writer.h
26138   TracePacketHandle NewTracePacket() override;
26139   void Flush(std::function<void()> callback = {}) override;
26140   WriterID writer_id() const override;
26141   uint64_t written() const override;
26142 
26143  private:
26144   NullTraceWriter(const NullTraceWriter&) = delete;
26145   NullTraceWriter& operator=(const NullTraceWriter&) = delete;
26146 
26147   protozero::ScatteredStreamWriterNullDelegate delegate_;
26148   protozero::ScatteredStreamWriter stream_;
26149 
26150   // The packet returned via NewTracePacket(). Its owned by this class,
26151   // TracePacketHandle has just a pointer to it.
26152   std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
26153       cur_packet_;
26154 };
26155 
26156 }  // namespace perfetto
26157 
26158 #endif  // SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
26159 /*
26160  * Copyright (C) 2018 The Android Open Source Project
26161  *
26162  * Licensed under the Apache License, Version 2.0 (the "License");
26163  * you may not use this file except in compliance with the License.
26164  * You may obtain a copy of the License at
26165  *
26166  *      http://www.apache.org/licenses/LICENSE-2.0
26167  *
26168  * Unless required by applicable law or agreed to in writing, software
26169  * distributed under the License is distributed on an "AS IS" BASIS,
26170  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26171  * See the License for the specific language governing permissions and
26172  * limitations under the License.
26173  */
26174 
26175 // gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
26176 
26177 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
26178 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
26179 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
26180 
26181 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
26182 
26183 namespace perfetto {
26184 
NullTraceWriter()26185 NullTraceWriter::NullTraceWriter() : delegate_(4096), stream_(&delegate_) {
26186   cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
26187   cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
26188 }
26189 
~NullTraceWriter()26190 NullTraceWriter::~NullTraceWriter() {}
26191 
Flush(std::function<void ()> callback)26192 void NullTraceWriter::Flush(std::function<void()> callback) {
26193   // Flush() cannot be called in the middle of a TracePacket.
26194   PERFETTO_CHECK(cur_packet_->is_finalized());
26195 
26196   if (callback)
26197     callback();
26198 }
26199 
NewTracePacket()26200 NullTraceWriter::TracePacketHandle NullTraceWriter::NewTracePacket() {
26201   // If we hit this, the caller is calling NewTracePacket() without having
26202   // finalized the previous packet.
26203   PERFETTO_DCHECK(cur_packet_->is_finalized());
26204   cur_packet_->Reset(&stream_);
26205   return TraceWriter::TracePacketHandle(cur_packet_.get());
26206 }
26207 
writer_id() const26208 WriterID NullTraceWriter::writer_id() const {
26209   return 0;
26210 }
26211 
written() const26212 uint64_t NullTraceWriter::written() const {
26213   return 0;
26214 }
26215 
26216 }  // namespace perfetto
26217 // gen_amalgamated begin source: src/tracing/core/shared_memory_abi.cc
26218 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_abi.h
26219 /*
26220  * Copyright (C) 2017 The Android Open Source Project
26221  *
26222  * Licensed under the Apache License, Version 2.0 (the "License");
26223  * you may not use this file except in compliance with the License.
26224  * You may obtain a copy of the License at
26225  *
26226  *      http://www.apache.org/licenses/LICENSE-2.0
26227  *
26228  * Unless required by applicable law or agreed to in writing, software
26229  * distributed under the License is distributed on an "AS IS" BASIS,
26230  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26231  * See the License for the specific language governing permissions and
26232  * limitations under the License.
26233  */
26234 
26235 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
26236 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
26237 
26238 #include <stddef.h>
26239 #include <stdint.h>
26240 
26241 #include <array>
26242 #include <atomic>
26243 #include <bitset>
26244 #include <thread>
26245 #include <type_traits>
26246 #include <utility>
26247 
26248 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
26249 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
26250 
26251 namespace perfetto {
26252 
26253 // This file defines the binary interface of the memory buffers shared between
26254 // Producer and Service. This is a long-term stable ABI and has to be backwards
26255 // compatible to deal with mismatching Producer and Service versions.
26256 //
26257 // Overview
26258 // --------
26259 // SMB := "Shared Memory Buffer".
26260 // In the most typical case of a multi-process architecture (i.e. Producer and
26261 // Service are hosted by different processes), a Producer means almost always
26262 // a "client process producing data" (almost: in some cases a process might host
26263 // > 1 Producer, if it links two libraries, independent of each other, that both
26264 // use Perfetto tracing).
26265 // The Service has one SMB for each Producer.
26266 // A producer has one or (typically) more data sources. They all share the same
26267 // SMB.
26268 // The SMB is a staging area to decouple data sources living in the Producer
26269 // and allow them to do non-blocking async writes.
26270 // The SMB is *not* the ultimate logging buffer seen by the Consumer. That one
26271 // is larger (~MBs) and not shared with Producers.
26272 // Each SMB is small, typically few KB. Its size is configurable by the producer
26273 // within a max limit of ~MB (see kMaxShmSize in tracing_service_impl.cc).
26274 // The SMB is partitioned into fixed-size Page(s). The size of the Pages are
26275 // determined by each Producer at connection time and cannot be changed.
26276 // Hence, different producers can have SMB(s) that have a different Page size
26277 // from each other, but the page size will be constant throughout all the
26278 // lifetime of the SMB.
26279 // Page(s) are partitioned by the Producer into variable size Chunk(s):
26280 //
26281 // +------------+      +--------------------------+
26282 // | Producer 1 |  <-> |      SMB 1 [~32K - 1MB]  |
26283 // +------------+      +--------+--------+--------+
26284 //                     |  Page  |  Page  |  Page  |
26285 //                     +--------+--------+--------+
26286 //                     | Chunk  |        | Chunk  |
26287 //                     +--------+  Chunk +--------+ <----+
26288 //                     | Chunk  |        | Chunk  |      |
26289 //                     +--------+--------+--------+      +---------------------+
26290 //                                                       |       Service       |
26291 // +------------+      +--------------------------+      +---------------------+
26292 // | Producer 2 |  <-> |      SMB 2 [~32K - 1MB]  |     /| large ring buffers  |
26293 // +------------+      +--------+--------+--------+ <--+ | (100K - several MB) |
26294 //                     |  Page  |  Page  |  Page  |      +---------------------+
26295 //                     +--------+--------+--------+
26296 //                     | Chunk  |        | Chunk  |
26297 //                     +--------+  Chunk +--------+
26298 //                     | Chunk  |        | Chunk  |
26299 //                     +--------+--------+--------+
26300 //
26301 // * Sizes of both SMB and ring buffers are purely indicative and decided at
26302 // configuration time by the Producer (for SMB sizes) and the Consumer (for the
26303 // final ring buffer size).
26304 
26305 // Page
26306 // ----
26307 // A page is a portion of the shared memory buffer and defines the granularity
26308 // of the interaction between the Producer and tracing Service. When scanning
26309 // the shared memory buffer to determine if something should be moved to the
26310 // central logging buffers, the Service most of the times looks at and moves
26311 // whole pages. Similarly, the Producer sends an IPC to invite the Service to
26312 // drain the shared memory buffer only when a whole page is filled.
26313 // Having fixed the total SMB size (hence the total memory overhead), the page
26314 // size is a triangular tradeoff between:
26315 // 1) IPC traffic: smaller pages -> more IPCs.
26316 // 2) Producer lock freedom: larger pages -> larger chunks -> data sources can
26317 //    write more data without needing to swap chunks and synchronize.
26318 // 3) Risk of write-starving the SMB: larger pages -> higher chance that the
26319 //    Service won't manage to drain them and the SMB remains full.
26320 // The page size, on the other side, has no implications on wasted memory due to
26321 // fragmentations (see Chunk below).
26322 // The size of the page is chosen by the Service at connection time and stays
26323 // fixed throughout all the lifetime of the Producer. Different producers (i.e.
26324 // ~ different client processes) can use different page sizes.
26325 // The page size must be an integer multiple of 4k (this is to allow VM page
26326 // stealing optimizations) and obviously has to be an integer divisor of the
26327 // total SMB size.
26328 
26329 // Chunk
26330 // -----
26331 // A chunk is a portion of a Page which is written and handled by a Producer.
26332 // A chunk contains a linear sequence of TracePacket(s) (the root proto).
26333 // A chunk cannot be written concurrently by two data sources. Protobufs must be
26334 // encoded as contiguous byte streams and cannot be interleaved. Therefore, on
26335 // the Producer side, a chunk is almost always owned exclusively by one thread
26336 // (% extremely peculiar slow-path cases).
26337 // Chunks are essentially single-writer single-thread lock-free arenas. Locking
26338 // happens only when a Chunk is full and a new one needs to be acquired.
26339 // Locking happens only within the scope of a Producer process. There is no
26340 // inter-process locking. The Producer cannot lock the Service and viceversa.
26341 // In the worst case, any of the two can starve the SMB, by marking all chunks
26342 // as either being read or written. But that has the only side effect of
26343 // losing the trace data.
26344 // The Producer can decide to partition each page into a number of limited
26345 // configurations (e.g., 1 page == 1 chunk, 1 page == 2 chunks and so on).
26346 
26347 // TracePacket
26348 // -----------
26349 // Is the atom of tracing. Putting aside pages and chunks a trace is merely a
26350 // sequence of TracePacket(s). TracePacket is the root protobuf message.
26351 // A TracePacket can span across several chunks (hence even across several
26352 // pages). A TracePacket can therefore be >> chunk size, >> page size and even
26353 // >> SMB size. The Chunk header carries metadata to deal with the TracePacket
26354 // splitting case.
26355 
26356 // Use only explicitly-sized types below. DO NOT use size_t or any architecture
26357 // dependent size (e.g. size_t) in the struct fields. This buffer will be read
26358 // and written by processes that have a different bitness in the same OS.
26359 // Instead it's fine to assume little-endianess. Big-endian is a dream we are
26360 // not currently pursuing.
26361 
26362 class SharedMemoryABI {
26363  public:
26364   static constexpr size_t kMinPageSize = 4 * 1024;
26365 
26366   // This is due to Chunk::size being 16 bits.
26367   static constexpr size_t kMaxPageSize = 64 * 1024;
26368 
26369   // "14" is the max number that can be encoded in a 32 bit atomic word using
26370   // 2 state bits per Chunk and leaving 4 bits for the page layout.
26371   // See PageLayout below.
26372   static constexpr size_t kMaxChunksPerPage = 14;
26373 
26374   // Each TracePacket in the Chunk is prefixed by a 4 bytes redundant VarInt
26375   // (see proto_utils.h) stating its size.
26376   static constexpr size_t kPacketHeaderSize = 4;
26377 
26378   // TraceWriter specifies this invalid packet/fragment size to signal to the
26379   // service that a packet should be discarded, because the TraceWriter couldn't
26380   // write its remaining fragments (e.g. because the SMB was exhausted).
26381   static constexpr size_t kPacketSizeDropPacket =
26382       protozero::proto_utils::kMaxMessageLength;
26383 
26384   // Chunk states and transitions:
26385   //    kChunkFree  <----------------+
26386   //         |  (Producer)           |
26387   //         V                       |
26388   //  kChunkBeingWritten             |
26389   //         |  (Producer)           |
26390   //         V                       |
26391   //  kChunkComplete                 |
26392   //         |  (Service)            |
26393   //         V                       |
26394   //  kChunkBeingRead                |
26395   //        |   (Service)            |
26396   //        +------------------------+
26397   enum ChunkState : uint32_t {
26398     // The Chunk is free. The Service shall never touch it, the Producer can
26399     // acquire it and transition it into kChunkBeingWritten.
26400     kChunkFree = 0,
26401 
26402     // The Chunk is being used by the Producer and is not complete yet.
26403     // The Service shall never touch kChunkBeingWritten pages.
26404     kChunkBeingWritten = 1,
26405 
26406     // The Service is moving the page into its non-shared ring buffer. The
26407     // Producer shall never touch kChunkBeingRead pages.
26408     kChunkBeingRead = 2,
26409 
26410     // The Producer is done writing the page and won't touch it again. The
26411     // Service can now move it to its non-shared ring buffer.
26412     // kAllChunksComplete relies on this being == 3.
26413     kChunkComplete = 3,
26414   };
26415   static constexpr const char* kChunkStateStr[] = {"Free", "BeingWritten",
26416                                                    "BeingRead", "Complete"};
26417 
26418   enum PageLayout : uint32_t {
26419     // The page is fully free and has not been partitioned yet.
26420     kPageNotPartitioned = 0,
26421 
26422     // TODO(primiano): Aligning a chunk @ 16 bytes could allow to use faster
26423     // intrinsics based on quad-word moves. Do the math and check what is the
26424     // fragmentation loss.
26425 
26426     // align4(X) := the largest integer N s.t. (N % 4) == 0 && N <= X.
26427     // 8 == sizeof(PageHeader).
26428     kPageDiv1 = 1,   // Only one chunk of size: PAGE_SIZE - 8.
26429     kPageDiv2 = 2,   // Two chunks of size: align4((PAGE_SIZE - 8) / 2).
26430     kPageDiv4 = 3,   // Four chunks of size: align4((PAGE_SIZE - 8) / 4).
26431     kPageDiv7 = 4,   // Seven chunks of size: align4((PAGE_SIZE - 8) / 7).
26432     kPageDiv14 = 5,  // Fourteen chunks of size: align4((PAGE_SIZE - 8) / 14).
26433 
26434     // The rationale for 7 and 14 above is to maximize the page usage for the
26435     // likely case of |page_size| == 4096:
26436     // (((4096 - 8) / 14) % 4) == 0, while (((4096 - 8) / 16 % 4)) == 3. So
26437     // Div16 would waste 3 * 16 = 48 bytes per page for chunk alignment gaps.
26438 
26439     kPageDivReserved1 = 6,
26440     kPageDivReserved2 = 7,
26441     kNumPageLayouts = 8,
26442   };
26443 
26444   // Keep this consistent with the PageLayout enum above.
26445   static constexpr uint32_t kNumChunksForLayout[] = {0, 1, 2, 4, 7, 14, 0, 0};
26446 
26447   // Layout of a Page.
26448   // +===================================================+
26449   // | Page header [8 bytes]                             |
26450   // | Tells how many chunks there are, how big they are |
26451   // | and their state (free, read, write, complete).    |
26452   // +===================================================+
26453   // +***************************************************+
26454   // | Chunk #0 header [8 bytes]                         |
26455   // | Tells how many packets there are and whether the  |
26456   // | whether the 1st and last ones are fragmented.     |
26457   // | Also has a chunk id to reassemble fragments.    |
26458   // +***************************************************+
26459   // +---------------------------------------------------+
26460   // | Packet #0 size [varint, up to 4 bytes]            |
26461   // + - - - - - - - - - - - - - - - - - - - - - - - - - +
26462   // | Packet #0 payload                                 |
26463   // | A TracePacket protobuf message                    |
26464   // +---------------------------------------------------+
26465   //                         ...
26466   // + . . . . . . . . . . . . . . . . . . . . . . . . . +
26467   // |      Optional padding to maintain aligment        |
26468   // + . . . . . . . . . . . . . . . . . . . . . . . . . +
26469   // +---------------------------------------------------+
26470   // | Packet #N size [varint, up to 4 bytes]            |
26471   // + - - - - - - - - - - - - - - - - - - - - - - - - - +
26472   // | Packet #N payload                                 |
26473   // | A TracePacket protobuf message                    |
26474   // +---------------------------------------------------+
26475   //                         ...
26476   // +***************************************************+
26477   // | Chunk #M header [8 bytes]                         |
26478   //                         ...
26479 
26480   // Alignment applies to start offset only. The Chunk size is *not* aligned.
26481   static constexpr uint32_t kChunkAlignment = 4;
26482   static constexpr uint32_t kChunkShift = 2;
26483   static constexpr uint32_t kChunkMask = 0x3;
26484   static constexpr uint32_t kLayoutMask = 0x70000000;
26485   static constexpr uint32_t kLayoutShift = 28;
26486   static constexpr uint32_t kAllChunksMask = 0x0FFFFFFF;
26487 
26488   // This assumes that kChunkComplete == 3.
26489   static constexpr uint32_t kAllChunksComplete = 0x0FFFFFFF;
26490   static constexpr uint32_t kAllChunksFree = 0;
26491   static constexpr size_t kInvalidPageIdx = static_cast<size_t>(-1);
26492 
26493   // There is one page header per page, at the beginning of the page.
26494   struct PageHeader {
26495     // |layout| bits:
26496     // [31] [30:28] [27:26] ... [1:0]
26497     //  |      |       |     |    |
26498     //  |      |       |     |    +---------- ChunkState[0]
26499     //  |      |       |     +--------------- ChunkState[12..1]
26500     //  |      |       +--------------------- ChunkState[13]
26501     //  |      +----------------------------- PageLayout (0 == page fully free)
26502     //  +------------------------------------ Reserved for future use
26503     std::atomic<uint32_t> layout;
26504 
26505     // If we'll ever going to use this in the future it might come handy
26506     // reviving the kPageBeingPartitioned logic (look in git log, it was there
26507     // at some point in the past).
26508     uint32_t reserved;
26509   };
26510 
26511   // There is one Chunk header per chunk (hence PageLayout per page) at the
26512   // beginning of each chunk.
26513   struct ChunkHeader {
26514     enum Flags : uint8_t {
26515       // If set, the first TracePacket in the chunk is partial and continues
26516       // from |chunk_id| - 1 (within the same |writer_id|).
26517       kFirstPacketContinuesFromPrevChunk = 1 << 0,
26518 
26519       // If set, the last TracePacket in the chunk is partial and continues on
26520       // |chunk_id| + 1 (within the same |writer_id|).
26521       kLastPacketContinuesOnNextChunk = 1 << 1,
26522 
26523       // If set, the last (fragmented) TracePacket in the chunk has holes (even
26524       // if the chunk is marked as kChunkComplete) that need to be patched
26525       // out-of-band before the chunk can be read.
26526       kChunkNeedsPatching = 1 << 2,
26527     };
26528 
26529     struct Packets {
26530       // Number of valid TracePacket protobuf messages contained in the chunk.
26531       // Each TracePacket is prefixed by its own size. This field is
26532       // monotonically updated by the Producer with release store semantic when
26533       // the packet at position |count| is started. This last packet may not be
26534       // considered complete until |count| is incremented for the subsequent
26535       // packet or the chunk is completed.
26536       uint16_t count : 10;
26537       static constexpr size_t kMaxCount = (1 << 10) - 1;
26538 
26539       // See Flags above.
26540       uint16_t flags : 6;
26541     };
26542 
26543     // A monotonic counter of the chunk within the scoped of a |writer_id|.
26544     // The tuple (ProducerID, WriterID, ChunkID) allows to figure out if two
26545     // chunks are contiguous (and hence a trace packets spanning across them can
26546     // be glued) or we had some holes due to the ring buffer wrapping.
26547     // This is set only when transitioning from kChunkFree to kChunkBeingWritten
26548     // and remains unchanged throughout the remaining lifetime of the chunk.
26549     std::atomic<uint32_t> chunk_id;
26550 
26551     // ID of the writer, unique within the producer.
26552     // Like |chunk_id|, this is set only when transitioning from kChunkFree to
26553     // kChunkBeingWritten.
26554     std::atomic<uint16_t> writer_id;
26555 
26556     // There is no ProducerID here. The service figures that out from the IPC
26557     // channel, which is unspoofable.
26558 
26559     // Updated with release-store semantics.
26560     std::atomic<Packets> packets;
26561   };
26562 
26563   class Chunk {
26564    public:
26565     Chunk();  // Constructs an invalid chunk.
26566 
26567     // Chunk is move-only, to document the scope of the Acquire/Release
26568     // TryLock operations below.
26569     Chunk(const Chunk&) = delete;
26570     Chunk operator=(const Chunk&) = delete;
26571     Chunk(Chunk&&) noexcept;
26572     Chunk& operator=(Chunk&&);
26573 
begin() const26574     uint8_t* begin() const { return begin_; }
end() const26575     uint8_t* end() const { return begin_ + size_; }
26576 
26577     // Size, including Chunk header.
size() const26578     size_t size() const { return size_; }
26579 
26580     // Begin of the first packet (or packet fragment).
payload_begin() const26581     uint8_t* payload_begin() const { return begin_ + sizeof(ChunkHeader); }
payload_size() const26582     size_t payload_size() const {
26583       PERFETTO_DCHECK(size_ >= sizeof(ChunkHeader));
26584       return size_ - sizeof(ChunkHeader);
26585     }
26586 
is_valid() const26587     bool is_valid() const { return begin_ && size_; }
26588 
26589     // Index of the chunk within the page [0..13] (13 comes from kPageDiv14).
chunk_idx() const26590     uint8_t chunk_idx() const { return chunk_idx_; }
26591 
header()26592     ChunkHeader* header() { return reinterpret_cast<ChunkHeader*>(begin_); }
26593 
writer_id()26594     uint16_t writer_id() {
26595       return header()->writer_id.load(std::memory_order_relaxed);
26596     }
26597 
26598     // Returns the count of packets and the flags with acquire-load semantics.
GetPacketCountAndFlags()26599     std::pair<uint16_t, uint8_t> GetPacketCountAndFlags() {
26600       auto packets = header()->packets.load(std::memory_order_acquire);
26601       const uint16_t packets_count = packets.count;
26602       const uint8_t packets_flags = packets.flags;
26603       return std::make_pair(packets_count, packets_flags);
26604     }
26605 
26606     // Increases |packets.count| with release semantics (note, however, that the
26607     // packet count is incremented *before* starting writing a packet). Returns
26608     // the new packet count. The increment is atomic but NOT race-free (i.e. no
26609     // CAS). Only the Producer is supposed to perform this increment, and it's
26610     // supposed to do that in a thread-safe way (holding a lock). A Chunk cannot
26611     // be shared by multiple Producer threads without locking. The packet count
26612     // is cleared by TryAcquireChunk(), when passing the new header for the
26613     // chunk.
IncrementPacketCount()26614     uint16_t IncrementPacketCount() {
26615       ChunkHeader* chunk_header = header();
26616       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
26617       packets.count++;
26618       chunk_header->packets.store(packets, std::memory_order_release);
26619       return packets.count;
26620     }
26621 
26622     // Increases |packets.count| to the given |packet_count|, but only if
26623     // |packet_count| is larger than the current value of |packets.count|.
26624     // Returns the new packet count. Same atomicity guarantees as
26625     // IncrementPacketCount().
IncreasePacketCountTo(uint16_t packet_count)26626     uint16_t IncreasePacketCountTo(uint16_t packet_count) {
26627       ChunkHeader* chunk_header = header();
26628       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
26629       if (packets.count < packet_count)
26630         packets.count = packet_count;
26631       chunk_header->packets.store(packets, std::memory_order_release);
26632       return packets.count;
26633     }
26634 
26635     // Flags are cleared by TryAcquireChunk(), by passing the new header for
26636     // the chunk.
SetFlag(ChunkHeader::Flags flag)26637     void SetFlag(ChunkHeader::Flags flag) {
26638       ChunkHeader* chunk_header = header();
26639       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
26640       packets.flags |= flag;
26641       chunk_header->packets.store(packets, std::memory_order_release);
26642     }
26643 
26644    private:
26645     friend class SharedMemoryABI;
26646     Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx);
26647 
26648     // Don't add extra fields, keep the move operator fast.
26649     uint8_t* begin_ = nullptr;
26650     uint16_t size_ = 0;
26651     uint8_t chunk_idx_ = 0;
26652   };
26653 
26654   // Construct an instance from an existing shared memory buffer.
26655   SharedMemoryABI(uint8_t* start, size_t size, size_t page_size);
26656   SharedMemoryABI();
26657 
26658   void Initialize(uint8_t* start, size_t size, size_t page_size);
26659 
start() const26660   uint8_t* start() const { return start_; }
end() const26661   uint8_t* end() const { return start_ + size_; }
size() const26662   size_t size() const { return size_; }
page_size() const26663   size_t page_size() const { return page_size_; }
num_pages() const26664   size_t num_pages() const { return num_pages_; }
is_valid()26665   bool is_valid() { return num_pages() > 0; }
26666 
page_start(size_t page_idx)26667   uint8_t* page_start(size_t page_idx) {
26668     PERFETTO_DCHECK(page_idx < num_pages_);
26669     return start_ + page_size_ * page_idx;
26670   }
26671 
page_header(size_t page_idx)26672   PageHeader* page_header(size_t page_idx) {
26673     return reinterpret_cast<PageHeader*>(page_start(page_idx));
26674   }
26675 
26676   // Returns true if the page is fully clear and has not been partitioned yet.
26677   // The state of the page can change at any point after this returns (or even
26678   // before). The Producer should use this only as a hint to decide out whether
26679   // it should TryPartitionPage() or acquire an individual chunk.
is_page_free(size_t page_idx)26680   bool is_page_free(size_t page_idx) {
26681     return page_header(page_idx)->layout.load(std::memory_order_relaxed) == 0;
26682   }
26683 
26684   // Returns true if all chunks in the page are kChunkComplete. As above, this
26685   // is advisory only. The Service is supposed to use this only to decide
26686   // whether to TryAcquireAllChunksForReading() or not.
is_page_complete(size_t page_idx)26687   bool is_page_complete(size_t page_idx) {
26688     auto layout = page_header(page_idx)->layout.load(std::memory_order_relaxed);
26689     const uint32_t num_chunks = GetNumChunksForLayout(layout);
26690     if (num_chunks == 0)
26691       return false;  // Non partitioned pages cannot be complete.
26692     return (layout & kAllChunksMask) ==
26693            (kAllChunksComplete & ((1 << (num_chunks * kChunkShift)) - 1));
26694   }
26695 
26696   // For testing / debugging only.
page_header_dbg(size_t page_idx)26697   std::string page_header_dbg(size_t page_idx) {
26698     uint32_t x = page_header(page_idx)->layout.load(std::memory_order_relaxed);
26699     return std::bitset<32>(x).to_string();
26700   }
26701 
26702   // Returns the page layout, which is a bitmap that specifies the chunking
26703   // layout of the page and each chunk's current state. Reads with an
26704   // acquire-load semantic to ensure a producer's writes corresponding to an
26705   // update of the layout (e.g. clearing a chunk's header) are observed
26706   // consistently.
GetPageLayout(size_t page_idx)26707   uint32_t GetPageLayout(size_t page_idx) {
26708     return page_header(page_idx)->layout.load(std::memory_order_acquire);
26709   }
26710 
26711   // Returns a bitmap in which each bit is set if the corresponding Chunk exists
26712   // in the page (according to the page layout) and is free. If the page is not
26713   // partitioned it returns 0 (as if the page had no free chunks).
26714   uint32_t GetFreeChunks(size_t page_idx);
26715 
26716   // Tries to atomically partition a page with the given |layout|. Returns true
26717   // if the page was free and has been partitioned with the given |layout|,
26718   // false if the page wasn't free anymore by the time we got there.
26719   // If succeeds all the chunks are atomically set in the kChunkFree state.
26720   bool TryPartitionPage(size_t page_idx, PageLayout layout);
26721 
26722   // Tries to atomically mark a single chunk within the page as
26723   // kChunkBeingWritten. Returns an invalid chunk if the page is not partitioned
26724   // or the chunk is not in the kChunkFree state. If succeeds sets the chunk
26725   // header to |header|.
TryAcquireChunkForWriting(size_t page_idx,size_t chunk_idx,const ChunkHeader * header)26726   Chunk TryAcquireChunkForWriting(size_t page_idx,
26727                                   size_t chunk_idx,
26728                                   const ChunkHeader* header) {
26729     return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingWritten, header);
26730   }
26731 
26732   // Similar to TryAcquireChunkForWriting. Fails if the chunk isn't in the
26733   // kChunkComplete state.
TryAcquireChunkForReading(size_t page_idx,size_t chunk_idx)26734   Chunk TryAcquireChunkForReading(size_t page_idx, size_t chunk_idx) {
26735     return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingRead, nullptr);
26736   }
26737 
26738   // The caller must have successfully TryAcquireAllChunksForReading().
26739   Chunk GetChunkUnchecked(size_t page_idx,
26740                           uint32_t page_layout,
26741                           size_t chunk_idx);
26742 
26743   // Puts a chunk into the kChunkComplete state. Returns the page index.
ReleaseChunkAsComplete(Chunk chunk)26744   size_t ReleaseChunkAsComplete(Chunk chunk) {
26745     return ReleaseChunk(std::move(chunk), kChunkComplete);
26746   }
26747 
26748   // Puts a chunk into the kChunkFree state. Returns the page index.
ReleaseChunkAsFree(Chunk chunk)26749   size_t ReleaseChunkAsFree(Chunk chunk) {
26750     return ReleaseChunk(std::move(chunk), kChunkFree);
26751   }
26752 
GetChunkState(size_t page_idx,size_t chunk_idx)26753   ChunkState GetChunkState(size_t page_idx, size_t chunk_idx) {
26754     PageHeader* phdr = page_header(page_idx);
26755     uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
26756     return GetChunkStateFromLayout(layout, chunk_idx);
26757   }
26758 
26759   std::pair<size_t, size_t> GetPageAndChunkIndex(const Chunk& chunk);
26760 
GetChunkSizeForLayout(uint32_t page_layout) const26761   uint16_t GetChunkSizeForLayout(uint32_t page_layout) const {
26762     return chunk_sizes_[(page_layout & kLayoutMask) >> kLayoutShift];
26763   }
26764 
GetChunkStateFromLayout(uint32_t page_layout,size_t chunk_idx)26765   static ChunkState GetChunkStateFromLayout(uint32_t page_layout,
26766                                             size_t chunk_idx) {
26767     return static_cast<ChunkState>((page_layout >> (chunk_idx * kChunkShift)) &
26768                                    kChunkMask);
26769   }
26770 
GetNumChunksForLayout(uint32_t page_layout)26771   static constexpr uint32_t GetNumChunksForLayout(uint32_t page_layout) {
26772     return kNumChunksForLayout[(page_layout & kLayoutMask) >> kLayoutShift];
26773   }
26774 
26775   // Returns a bitmap in which each bit is set if the corresponding Chunk exists
26776   // in the page (according to the page layout) and is not free. If the page is
26777   // not partitioned it returns 0 (as if the page had no used chunks). Bit N
26778   // corresponds to Chunk N.
GetUsedChunks(uint32_t page_layout)26779   static uint32_t GetUsedChunks(uint32_t page_layout) {
26780     const uint32_t num_chunks = GetNumChunksForLayout(page_layout);
26781     uint32_t res = 0;
26782     for (uint32_t i = 0; i < num_chunks; i++) {
26783       res |= ((page_layout & kChunkMask) != kChunkFree) ? (1 << i) : 0;
26784       page_layout >>= kChunkShift;
26785     }
26786     return res;
26787   }
26788 
26789  private:
26790   SharedMemoryABI(const SharedMemoryABI&) = delete;
26791   SharedMemoryABI& operator=(const SharedMemoryABI&) = delete;
26792 
26793   Chunk TryAcquireChunk(size_t page_idx,
26794                         size_t chunk_idx,
26795                         ChunkState,
26796                         const ChunkHeader*);
26797   size_t ReleaseChunk(Chunk chunk, ChunkState);
26798 
26799   uint8_t* start_ = nullptr;
26800   size_t size_ = 0;
26801   size_t page_size_ = 0;
26802   size_t num_pages_ = 0;
26803   std::array<uint16_t, kNumPageLayouts> chunk_sizes_;
26804 };
26805 
26806 }  // namespace perfetto
26807 
26808 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
26809 /*
26810  * Copyright (C) 2017 The Android Open Source Project
26811  *
26812  * Licensed under the Apache License, Version 2.0 (the "License");
26813  * you may not use this file except in compliance with the
26814  * License. You may obtain a copy of the License at
26815  *
26816  *      http://www.apache.org/licenses/LICENSE-2.0
26817  *
26818  * Unless required by applicable law or agreed to in writing,
26819  * software distributed under the License is distributed on an "AS
26820  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
26821  * express or implied. See the License for the specific language
26822  * governing permissions and limitations under the License.
26823  */
26824 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
26825 
26826 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
26827 // gen_amalgamated expanded: #include "perfetto/base/time.h"
26828 
26829 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
26830 #include <sys/mman.h>
26831 #endif
26832 
26833 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
26834 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
26835 
26836 namespace perfetto {
26837 
26838 namespace {
26839 
26840 constexpr int kRetryAttempts = 64;
26841 
WaitBeforeNextAttempt(int attempt)26842 inline void WaitBeforeNextAttempt(int attempt) {
26843   if (attempt < kRetryAttempts / 2) {
26844     std::this_thread::yield();
26845   } else {
26846     base::SleepMicroseconds((unsigned(attempt) / 10) * 1000);
26847   }
26848 }
26849 
26850 // Returns the largest 4-bytes aligned chunk size <= |page_size| / |divider|
26851 // for each divider in PageLayout.
GetChunkSize(size_t page_size,size_t divider)26852 constexpr size_t GetChunkSize(size_t page_size, size_t divider) {
26853   return ((page_size - sizeof(SharedMemoryABI::PageHeader)) / divider) & ~3UL;
26854 }
26855 
26856 // Initializer for the const |chunk_sizes_| array.
InitChunkSizes(size_t page_size)26857 std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> InitChunkSizes(
26858     size_t page_size) {
26859   static_assert(SharedMemoryABI::kNumPageLayouts ==
26860                     base::ArraySize(SharedMemoryABI::kNumChunksForLayout),
26861                 "kNumPageLayouts out of date");
26862   std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> res = {};
26863   for (size_t i = 0; i < SharedMemoryABI::kNumPageLayouts; i++) {
26864     size_t num_chunks = SharedMemoryABI::kNumChunksForLayout[i];
26865     size_t size = num_chunks == 0 ? 0 : GetChunkSize(page_size, num_chunks);
26866     PERFETTO_CHECK(size <= std::numeric_limits<uint16_t>::max());
26867     res[i] = static_cast<uint16_t>(size);
26868   }
26869   return res;
26870 }
26871 
ClearChunkHeader(SharedMemoryABI::ChunkHeader * header)26872 inline void ClearChunkHeader(SharedMemoryABI::ChunkHeader* header) {
26873   header->writer_id.store(0u, std::memory_order_relaxed);
26874   header->chunk_id.store(0u, std::memory_order_relaxed);
26875   header->packets.store({}, std::memory_order_release);
26876 }
26877 
26878 }  // namespace
26879 
26880 // static
26881 constexpr uint32_t SharedMemoryABI::kNumChunksForLayout[];
26882 constexpr const char* SharedMemoryABI::kChunkStateStr[];
26883 constexpr const size_t SharedMemoryABI::kInvalidPageIdx;
26884 constexpr const size_t SharedMemoryABI::kMinPageSize;
26885 constexpr const size_t SharedMemoryABI::kMaxPageSize;
26886 constexpr const size_t SharedMemoryABI::kPacketSizeDropPacket;
26887 
26888 SharedMemoryABI::SharedMemoryABI() = default;
26889 
SharedMemoryABI(uint8_t * start,size_t size,size_t page_size)26890 SharedMemoryABI::SharedMemoryABI(uint8_t* start,
26891                                  size_t size,
26892                                  size_t page_size) {
26893   Initialize(start, size, page_size);
26894 }
26895 
Initialize(uint8_t * start,size_t size,size_t page_size)26896 void SharedMemoryABI::Initialize(uint8_t* start,
26897                                  size_t size,
26898                                  size_t page_size) {
26899   start_ = start;
26900   size_ = size;
26901   page_size_ = page_size;
26902   num_pages_ = size / page_size;
26903   chunk_sizes_ = InitChunkSizes(page_size);
26904   static_assert(sizeof(PageHeader) == 8, "PageHeader size");
26905   static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
26906   static_assert(sizeof(ChunkHeader::chunk_id) == sizeof(ChunkID),
26907                 "ChunkID size");
26908 
26909   static_assert(sizeof(ChunkHeader::Packets) == 2, "ChunkHeader::Packets size");
26910   static_assert(alignof(ChunkHeader) == kChunkAlignment,
26911                 "ChunkHeader alignment");
26912 
26913   // In theory std::atomic does not guarantee that the underlying type
26914   // consists only of the actual atomic word. Theoretically it could have
26915   // locks or other state. In practice most implementations just implement
26916   // them without extra state. The code below overlays the atomic into the
26917   // SMB, hence relies on this implementation detail. This should be fine
26918   // pragmatically (Chrome's base makes the same assumption), but let's have a
26919   // check for this.
26920   static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t) &&
26921                     sizeof(std::atomic<uint16_t>) == sizeof(uint16_t),
26922                 "Incompatible STL <atomic> implementation");
26923 
26924   // Chec that the kAllChunks(Complete,Free) are consistent with the
26925   // ChunkState enum values.
26926 
26927   // These must be zero because rely on zero-initialized memory being
26928   // interpreted as "free".
26929   static_assert(kChunkFree == 0 && kAllChunksFree == 0,
26930                 "kChunkFree/kAllChunksFree and must be 0");
26931 
26932   static_assert((kAllChunksComplete & kChunkMask) == kChunkComplete,
26933                 "kAllChunksComplete out of sync with kChunkComplete");
26934 
26935   // Check the consistency of the kMax... constants.
26936   static_assert(sizeof(ChunkHeader::writer_id) == sizeof(WriterID),
26937                 "WriterID size");
26938   ChunkHeader chunk_header{};
26939   chunk_header.chunk_id.store(static_cast<uint32_t>(-1));
26940   PERFETTO_CHECK(chunk_header.chunk_id.load() == kMaxChunkID);
26941 
26942   chunk_header.writer_id.store(static_cast<uint16_t>(-1));
26943   PERFETTO_CHECK(kMaxWriterID <= chunk_header.writer_id.load());
26944 
26945   PERFETTO_CHECK(page_size >= kMinPageSize);
26946   PERFETTO_CHECK(page_size <= kMaxPageSize);
26947   PERFETTO_CHECK(page_size % kMinPageSize == 0);
26948   PERFETTO_CHECK(reinterpret_cast<uintptr_t>(start) % kMinPageSize == 0);
26949   PERFETTO_CHECK(size % page_size == 0);
26950 }
26951 
GetChunkUnchecked(size_t page_idx,uint32_t page_layout,size_t chunk_idx)26952 SharedMemoryABI::Chunk SharedMemoryABI::GetChunkUnchecked(size_t page_idx,
26953                                                           uint32_t page_layout,
26954                                                           size_t chunk_idx) {
26955   const size_t num_chunks = GetNumChunksForLayout(page_layout);
26956   PERFETTO_DCHECK(chunk_idx < num_chunks);
26957   // Compute the chunk virtual address and write it into |chunk|.
26958   const uint16_t chunk_size = GetChunkSizeForLayout(page_layout);
26959   size_t chunk_offset_in_page = sizeof(PageHeader) + chunk_idx * chunk_size;
26960 
26961   Chunk chunk(page_start(page_idx) + chunk_offset_in_page, chunk_size,
26962               static_cast<uint8_t>(chunk_idx));
26963   PERFETTO_DCHECK(chunk.end() <= end());
26964   return chunk;
26965 }
26966 
TryAcquireChunk(size_t page_idx,size_t chunk_idx,ChunkState desired_chunk_state,const ChunkHeader * header)26967 SharedMemoryABI::Chunk SharedMemoryABI::TryAcquireChunk(
26968     size_t page_idx,
26969     size_t chunk_idx,
26970     ChunkState desired_chunk_state,
26971     const ChunkHeader* header) {
26972   PERFETTO_DCHECK(desired_chunk_state == kChunkBeingRead ||
26973                   desired_chunk_state == kChunkBeingWritten);
26974   PageHeader* phdr = page_header(page_idx);
26975   for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
26976     uint32_t layout = phdr->layout.load(std::memory_order_acquire);
26977     const size_t num_chunks = GetNumChunksForLayout(layout);
26978 
26979     // The page layout has changed (or the page is free).
26980     if (chunk_idx >= num_chunks)
26981       return Chunk();
26982 
26983     // Verify that the chunk is still in a state that allows the transition to
26984     // |desired_chunk_state|. The only allowed transitions are:
26985     // 1. kChunkFree -> kChunkBeingWritten (Producer).
26986     // 2. kChunkComplete -> kChunkBeingRead (Service).
26987     ChunkState expected_chunk_state =
26988         desired_chunk_state == kChunkBeingWritten ? kChunkFree : kChunkComplete;
26989     auto cur_chunk_state = (layout >> (chunk_idx * kChunkShift)) & kChunkMask;
26990     if (cur_chunk_state != expected_chunk_state)
26991       return Chunk();
26992 
26993     uint32_t next_layout = layout;
26994     next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
26995     next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
26996     if (phdr->layout.compare_exchange_strong(layout, next_layout,
26997                                              std::memory_order_acq_rel)) {
26998       // Compute the chunk virtual address and write it into |chunk|.
26999       Chunk chunk = GetChunkUnchecked(page_idx, layout, chunk_idx);
27000       if (desired_chunk_state == kChunkBeingWritten) {
27001         PERFETTO_DCHECK(header);
27002         ChunkHeader* new_header = chunk.header();
27003         new_header->writer_id.store(header->writer_id,
27004                                     std::memory_order_relaxed);
27005         new_header->chunk_id.store(header->chunk_id, std::memory_order_relaxed);
27006         new_header->packets.store(header->packets, std::memory_order_release);
27007       }
27008       return chunk;
27009     }
27010     WaitBeforeNextAttempt(attempt);
27011   }
27012   return Chunk();  // All our attempts failed.
27013 }
27014 
TryPartitionPage(size_t page_idx,PageLayout layout)27015 bool SharedMemoryABI::TryPartitionPage(size_t page_idx, PageLayout layout) {
27016   PERFETTO_DCHECK(layout >= kPageDiv1 && layout <= kPageDiv14);
27017   uint32_t expected_layout = 0;  // Free page.
27018   uint32_t next_layout = (layout << kLayoutShift) & kLayoutMask;
27019   PageHeader* phdr = page_header(page_idx);
27020   if (!phdr->layout.compare_exchange_strong(expected_layout, next_layout,
27021                                             std::memory_order_acq_rel)) {
27022     return false;
27023   }
27024   return true;
27025 }
27026 
GetFreeChunks(size_t page_idx)27027 uint32_t SharedMemoryABI::GetFreeChunks(size_t page_idx) {
27028   uint32_t layout =
27029       page_header(page_idx)->layout.load(std::memory_order_relaxed);
27030   const uint32_t num_chunks = GetNumChunksForLayout(layout);
27031   uint32_t res = 0;
27032   for (uint32_t i = 0; i < num_chunks; i++) {
27033     res |= ((layout & kChunkMask) == kChunkFree) ? (1 << i) : 0;
27034     layout >>= kChunkShift;
27035   }
27036   return res;
27037 }
27038 
ReleaseChunk(Chunk chunk,ChunkState desired_chunk_state)27039 size_t SharedMemoryABI::ReleaseChunk(Chunk chunk,
27040                                      ChunkState desired_chunk_state) {
27041   PERFETTO_DCHECK(desired_chunk_state == kChunkComplete ||
27042                   desired_chunk_state == kChunkFree);
27043 
27044   size_t page_idx;
27045   size_t chunk_idx;
27046   std::tie(page_idx, chunk_idx) = GetPageAndChunkIndex(chunk);
27047 
27048   // Reset header fields, so that the service can identify when the chunk's
27049   // header has been initialized by the producer.
27050   if (desired_chunk_state == kChunkFree)
27051     ClearChunkHeader(chunk.header());
27052 
27053   for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
27054     PageHeader* phdr = page_header(page_idx);
27055     uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
27056     const size_t page_chunk_size = GetChunkSizeForLayout(layout);
27057 
27058     // TODO(primiano): this should not be a CHECK, because a malicious producer
27059     // could crash us by putting the chunk in an invalid state. This should
27060     // gracefully fail. Keep a CHECK until then.
27061     PERFETTO_CHECK(chunk.size() == page_chunk_size);
27062     const uint32_t chunk_state =
27063         ((layout >> (chunk_idx * kChunkShift)) & kChunkMask);
27064 
27065     // Verify that the chunk is still in a state that allows the transition to
27066     // |desired_chunk_state|. The only allowed transitions are:
27067     // 1. kChunkBeingWritten -> kChunkComplete (Producer).
27068     // 2. kChunkBeingRead -> kChunkFree (Service).
27069     ChunkState expected_chunk_state;
27070     if (desired_chunk_state == kChunkComplete) {
27071       expected_chunk_state = kChunkBeingWritten;
27072     } else {
27073       expected_chunk_state = kChunkBeingRead;
27074     }
27075 
27076     // TODO(primiano): should not be a CHECK (same rationale of comment above).
27077     PERFETTO_CHECK(chunk_state == expected_chunk_state);
27078     uint32_t next_layout = layout;
27079     next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
27080     next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
27081 
27082     // If we are freeing a chunk and all the other chunks in the page are free
27083     // we should de-partition the page and mark it as clear.
27084     if ((next_layout & kAllChunksMask) == kAllChunksFree)
27085       next_layout = 0;
27086 
27087     if (phdr->layout.compare_exchange_strong(layout, next_layout,
27088                                              std::memory_order_acq_rel)) {
27089       return page_idx;
27090     }
27091     WaitBeforeNextAttempt(attempt);
27092   }
27093   // Too much contention on this page. Give up. This page will be left pending
27094   // forever but there isn't much more we can do at this point.
27095   PERFETTO_DFATAL("Too much contention on page.");
27096   return kInvalidPageIdx;
27097 }
27098 
27099 SharedMemoryABI::Chunk::Chunk() = default;
27100 
Chunk(uint8_t * begin,uint16_t size,uint8_t chunk_idx)27101 SharedMemoryABI::Chunk::Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx)
27102     : begin_(begin), size_(size), chunk_idx_(chunk_idx) {
27103   PERFETTO_CHECK(reinterpret_cast<uintptr_t>(begin) % kChunkAlignment == 0);
27104   PERFETTO_CHECK(size > 0);
27105 }
27106 
Chunk(Chunk && o)27107 SharedMemoryABI::Chunk::Chunk(Chunk&& o) noexcept {
27108   *this = std::move(o);
27109 }
27110 
operator =(Chunk && o)27111 SharedMemoryABI::Chunk& SharedMemoryABI::Chunk::operator=(Chunk&& o) {
27112   begin_ = o.begin_;
27113   size_ = o.size_;
27114   chunk_idx_ = o.chunk_idx_;
27115   o.begin_ = nullptr;
27116   o.size_ = 0;
27117   o.chunk_idx_ = 0;
27118   return *this;
27119 }
27120 
GetPageAndChunkIndex(const Chunk & chunk)27121 std::pair<size_t, size_t> SharedMemoryABI::GetPageAndChunkIndex(
27122     const Chunk& chunk) {
27123   PERFETTO_DCHECK(chunk.is_valid());
27124   PERFETTO_DCHECK(chunk.begin() >= start_);
27125   PERFETTO_DCHECK(chunk.end() <= start_ + size_);
27126 
27127   // TODO(primiano): The divisions below could be avoided if we cached
27128   // |page_shift_|.
27129   const uintptr_t rel_addr = static_cast<uintptr_t>(chunk.begin() - start_);
27130   const size_t page_idx = rel_addr / page_size_;
27131   const size_t offset = rel_addr % page_size_;
27132   PERFETTO_DCHECK(offset >= sizeof(PageHeader));
27133   PERFETTO_DCHECK(offset % kChunkAlignment == 0);
27134   PERFETTO_DCHECK((offset - sizeof(PageHeader)) % chunk.size() == 0);
27135   const size_t chunk_idx = (offset - sizeof(PageHeader)) / chunk.size();
27136   PERFETTO_DCHECK(chunk_idx < kMaxChunksPerPage);
27137   PERFETTO_DCHECK(chunk_idx < GetNumChunksForLayout(GetPageLayout(page_idx)));
27138   return std::make_pair(page_idx, chunk_idx);
27139 }
27140 
27141 }  // namespace perfetto
27142 // gen_amalgamated begin source: src/tracing/core/shared_memory_arbiter_impl.cc
27143 // gen_amalgamated begin header: src/tracing/core/shared_memory_arbiter_impl.h
27144 // gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
27145 /*
27146  * Copyright (C) 2017 The Android Open Source Project
27147  *
27148  * Licensed under the Apache License, Version 2.0 (the "License");
27149  * you may not use this file except in compliance with the License.
27150  * You may obtain a copy of the License at
27151  *
27152  *      http://www.apache.org/licenses/LICENSE-2.0
27153  *
27154  * Unless required by applicable law or agreed to in writing, software
27155  * distributed under the License is distributed on an "AS IS" BASIS,
27156  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27157  * See the License for the specific language governing permissions and
27158  * limitations under the License.
27159  */
27160 
27161 #ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
27162 #define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
27163 
27164 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
27165 
27166 #include <memory>
27167 
27168 namespace perfetto {
27169 namespace base {
27170 
27171 // A simple WeakPtr for single-threaded cases.
27172 // Generally keep the WeakPtrFactory as last fields in classes: it makes the
27173 // WeakPtr(s) invalidate as first thing in the class dtor.
27174 // Usage:
27175 // class MyClass {
27176 //  MyClass() : weak_factory_(this) {}
27177 //  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
27178 //
27179 // private:
27180 //  WeakPtrFactory<MyClass> weak_factory_;
27181 // }
27182 //
27183 // int main() {
27184 //  std::unique_ptr<MyClass> foo(new MyClass);
27185 //  auto wptr = foo.GetWeakPtr();
27186 //  ASSERT_TRUE(wptr);
27187 //  ASSERT_EQ(foo.get(), wptr->get());
27188 //  foo.reset();
27189 //  ASSERT_FALSE(wptr);
27190 //  ASSERT_EQ(nullptr, wptr->get());
27191 // }
27192 
27193 template <typename T>
27194 class WeakPtrFactory;  // Forward declaration, defined below.
27195 
27196 template <typename T>
27197 class WeakPtr {
27198  public:
WeakPtr()27199   WeakPtr() {}
27200   WeakPtr(const WeakPtr&) = default;
27201   WeakPtr& operator=(const WeakPtr&) = default;
27202   WeakPtr(WeakPtr&&) = default;
27203   WeakPtr& operator=(WeakPtr&&) = default;
27204 
get() const27205   T* get() const {
27206     PERFETTO_DCHECK_THREAD(thread_checker);
27207     return handle_ ? *handle_.get() : nullptr;
27208   }
operator ->() const27209   T* operator->() const { return get(); }
operator *() const27210   T& operator*() const { return *get(); }
27211 
operator bool() const27212   explicit operator bool() const { return !!get(); }
27213 
27214  private:
27215   friend class WeakPtrFactory<T>;
WeakPtr(const std::shared_ptr<T * > & handle)27216   explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
27217 
27218   std::shared_ptr<T*> handle_;
27219   PERFETTO_THREAD_CHECKER(thread_checker)
27220 };
27221 
27222 template <typename T>
27223 class WeakPtrFactory {
27224  public:
WeakPtrFactory(T * owner)27225   explicit WeakPtrFactory(T* owner)
27226       : weak_ptr_(std::shared_ptr<T*>(new T* {owner})) {
27227     PERFETTO_DCHECK_THREAD(thread_checker);
27228   }
27229 
~WeakPtrFactory()27230   ~WeakPtrFactory() {
27231     PERFETTO_DCHECK_THREAD(thread_checker);
27232     *(weak_ptr_.handle_.get()) = nullptr;
27233   }
27234 
27235   // Can be safely called on any thread, since it simply copies |weak_ptr_|.
27236   // Note that any accesses to the returned pointer need to be made on the
27237   // thread that created/reset the factory.
GetWeakPtr() const27238   WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
27239 
27240   // Reset the factory to a new owner & thread. May only be called before any
27241   // weak pointers were passed out. Future weak pointers will be valid on the
27242   // calling thread.
Reset(T * owner)27243   void Reset(T* owner) {
27244     // Reset thread checker to current thread.
27245     PERFETTO_DETACH_FROM_THREAD(thread_checker);
27246     PERFETTO_DCHECK_THREAD(thread_checker);
27247 
27248     // We should not have passed out any weak pointers yet at this point.
27249     PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
27250 
27251     weak_ptr_ = WeakPtr<T>(std::shared_ptr<T*>(new T* {owner}));
27252   }
27253 
27254  private:
27255   WeakPtrFactory(const WeakPtrFactory&) = delete;
27256   WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
27257 
27258   WeakPtr<T> weak_ptr_;
27259   PERFETTO_THREAD_CHECKER(thread_checker)
27260 };
27261 
27262 }  // namespace base
27263 }  // namespace perfetto
27264 
27265 #endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
27266 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_arbiter.h
27267 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/tracing_service.h
27268 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory.h
27269 /*
27270  * Copyright (C) 2017 The Android Open Source Project
27271  *
27272  * Licensed under the Apache License, Version 2.0 (the "License");
27273  * you may not use this file except in compliance with the License.
27274  * You may obtain a copy of the License at
27275  *
27276  *      http://www.apache.org/licenses/LICENSE-2.0
27277  *
27278  * Unless required by applicable law or agreed to in writing, software
27279  * distributed under the License is distributed on an "AS IS" BASIS,
27280  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27281  * See the License for the specific language governing permissions and
27282  * limitations under the License.
27283  */
27284 
27285 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
27286 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
27287 
27288 #include <stddef.h>
27289 
27290 #include <memory>
27291 
27292 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27293 
27294 namespace perfetto {
27295 
27296 // An abstract interface that models the shared memory region shared between
27297 // Service and Producer. The concrete implementation of this is up to the
27298 // transport layer. This can be as simple as a malloc()-ed buffer, if both
27299 // Producer and Service are hosted in the same process, or some posix shared
27300 // memory for the out-of-process case (see src/unix_rpc).
27301 // Both this class and the Factory are subclassed by the transport layer, which
27302 // will attach platform specific fields to it (e.g., a unix file descriptor).
27303 class PERFETTO_EXPORT SharedMemory {
27304  public:
27305   class PERFETTO_EXPORT Factory {
27306    public:
27307     virtual ~Factory();
27308     virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
27309   };
27310 
27311   // The transport layer is expected to tear down the resource associated to
27312   // this object region when destroyed.
27313   virtual ~SharedMemory();
27314 
27315   virtual void* start() const = 0;
27316   virtual size_t size() const = 0;
27317   virtual int fd() const = 0;
27318 };
27319 
27320 }  // namespace perfetto
27321 
27322 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
27323 /*
27324  * Copyright (C) 2017 The Android Open Source Project
27325  *
27326  * Licensed under the Apache License, Version 2.0 (the "License");
27327  * you may not use this file except in compliance with the License.
27328  * You may obtain a copy of the License at
27329  *
27330  *      http://www.apache.org/licenses/LICENSE-2.0
27331  *
27332  * Unless required by applicable law or agreed to in writing, software
27333  * distributed under the License is distributed on an "AS IS" BASIS,
27334  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27335  * See the License for the specific language governing permissions and
27336  * limitations under the License.
27337  */
27338 
27339 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
27340 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
27341 
27342 #include <stdint.h>
27343 
27344 #include <functional>
27345 #include <memory>
27346 #include <vector>
27347 
27348 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27349 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
27350 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
27351 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
27352 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
27353 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
27354 
27355 namespace perfetto {
27356 
27357 namespace base {
27358 class TaskRunner;
27359 }  // namespace base
27360 
27361 class Consumer;
27362 class Producer;
27363 class SharedMemoryArbiter;
27364 class TraceWriter;
27365 
27366 // TODO: for the moment this assumes that all the calls happen on the same
27367 // thread/sequence. Not sure this will be the case long term in Chrome.
27368 
27369 // The API for the Producer port of the Service.
27370 // Subclassed by:
27371 // 1. The tracing_service_impl.cc business logic when returning it in response
27372 //    to the ConnectProducer() method.
27373 // 2. The transport layer (e.g., src/ipc) when the producer and
27374 //    the service don't talk locally but via some IPC mechanism.
27375 class PERFETTO_EXPORT ProducerEndpoint {
27376  public:
27377   virtual ~ProducerEndpoint();
27378 
27379   // Called by the Producer to (un)register data sources. Data sources are
27380   // identified by their name (i.e. DataSourceDescriptor.name)
27381   virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
27382   virtual void UnregisterDataSource(const std::string& name) = 0;
27383 
27384   // Associate the trace writer with the given |writer_id| with
27385   // |target_buffer|. The service may use this information to retrieve and
27386   // copy uncommitted chunks written by the trace writer into its associated
27387   // buffer, e.g. when a producer process crashes or when a flush is
27388   // necessary.
27389   virtual void RegisterTraceWriter(uint32_t writer_id,
27390                                    uint32_t target_buffer) = 0;
27391 
27392   // Remove the association of the trace writer previously created via
27393   // RegisterTraceWriter.
27394   virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
27395 
27396   // Called by the Producer to signal that some pages in the shared memory
27397   // buffer (shared between Service and Producer) have changed.
27398   // When the Producer and the Service are hosted in the same process and
27399   // hence potentially live on the same task runner, This method must call
27400   // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
27401   // if on the same thread. This is to avoid a deadlock where the Producer
27402   // exhausts its SMB and stalls waiting for the service to catch up with
27403   // reads, but the Service never gets to that because it lives on the same
27404   // thread.
27405   using CommitDataCallback = std::function<void()>;
27406   virtual void CommitData(const CommitDataRequest&,
27407                           CommitDataCallback callback = {}) = 0;
27408 
27409   virtual SharedMemory* shared_memory() const = 0;
27410 
27411   // Size of shared memory buffer pages. It's always a multiple of 4K.
27412   // See shared_memory_abi.h
27413   virtual size_t shared_buffer_page_size_kb() const = 0;
27414 
27415   // Creates a trace writer, which allows to create events, handling the
27416   // underying shared memory buffer and signalling to the Service. This method
27417   // is thread-safe but the returned object is not. A TraceWriter should be
27418   // used only from a single thread, or the caller has to handle sequencing
27419   // via a mutex or equivalent. This method can only be called if
27420   // TracingService::ConnectProducer was called with |in_process=true|.
27421   // Args:
27422   // |target_buffer| is the target buffer ID where the data produced by the
27423   // writer should be stored by the tracing service. This value is passed
27424   // upon creation of the data source (StartDataSource()) in the
27425   // DataSourceConfig.target_buffer().
27426   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
27427       BufferID target_buffer,
27428       BufferExhaustedPolicy buffer_exhausted_policy =
27429           BufferExhaustedPolicy::kDefault) = 0;
27430 
27431   // TODO(eseckler): Also expose CreateStartupTraceWriter() ?
27432 
27433   // In some cases you can access the producer's SharedMemoryArbiter (for
27434   // example if TracingService::ConnectProducer is called with
27435   // |in_process=true|). The SharedMemoryArbiter can be used to create
27436   // TraceWriters which is able to directly commit chunks. For the
27437   // |in_process=true| case this can be done without going through an IPC layer.
27438   virtual SharedMemoryArbiter* MaybeSharedMemoryArbiter() = 0;
27439 
27440   // Whether the service accepted a shared memory buffer provided by the
27441   // producer.
27442   virtual bool IsShmemProvidedByProducer() const = 0;
27443 
27444   // Called in response to a Producer::Flush(request_id) call after all data
27445   // for the flush request has been committed.
27446   virtual void NotifyFlushComplete(FlushRequestID) = 0;
27447 
27448   // Called in response to one or more Producer::StartDataSource(),
27449   // if the data source registered setting the flag
27450   // DataSourceDescriptor.will_notify_on_start.
27451   virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
27452 
27453   // Called in response to one or more Producer::StopDataSource(),
27454   // if the data source registered setting the flag
27455   // DataSourceDescriptor.will_notify_on_stop.
27456   virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
27457 
27458   // This informs the service to activate any of these triggers if any tracing
27459   // session was waiting for them.
27460   virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
27461 
27462   // Emits a synchronization barrier to linearize with the service. When
27463   // |callback| is invoked, the caller has the guarantee that the service has
27464   // seen and processed all the requests sent by this producer prior to the
27465   // Sync() call. Used mainly in tests.
27466   virtual void Sync(std::function<void()> callback) = 0;
27467 };  // class ProducerEndpoint.
27468 
27469 // The API for the Consumer port of the Service.
27470 // Subclassed by:
27471 // 1. The tracing_service_impl.cc business logic when returning it in response
27472 // to
27473 //    the ConnectConsumer() method.
27474 // 2. The transport layer (e.g., src/ipc) when the consumer and
27475 //    the service don't talk locally but via some IPC mechanism.
27476 class PERFETTO_EXPORT ConsumerEndpoint {
27477  public:
27478   virtual ~ConsumerEndpoint();
27479 
27480   // Enables tracing with the given TraceConfig. The ScopedFile argument is
27481   // used only when TraceConfig.write_into_file == true.
27482   // If TraceConfig.deferred_start == true data sources are configured via
27483   // SetupDataSource() but are not started until StartTracing() is called.
27484   // This is to support pre-initialization and fast triggering of traces.
27485   // The ScopedFile argument is used only when TraceConfig.write_into_file
27486   // == true.
27487   virtual void EnableTracing(const TraceConfig&,
27488                              base::ScopedFile = base::ScopedFile()) = 0;
27489 
27490   // Update the trace config of an existing tracing session; only a subset
27491   // of options can be changed mid-session. Currently the only
27492   // supported functionality is expanding the list of producer_name_filters()
27493   // (or removing the filter entirely) for existing data sources.
27494   virtual void ChangeTraceConfig(const TraceConfig&) = 0;
27495 
27496   // Starts all data sources configured in the trace config. This is used only
27497   // after calling EnableTracing() with TraceConfig.deferred_start=true.
27498   // It's a no-op if called after a regular EnableTracing(), without setting
27499   // deferred_start.
27500   virtual void StartTracing() = 0;
27501 
27502   virtual void DisableTracing() = 0;
27503 
27504   // Requests all data sources to flush their data immediately and invokes the
27505   // passed callback once all of them have acked the flush (in which case
27506   // the callback argument |success| will be true) or |timeout_ms| are elapsed
27507   // (in which case |success| will be false).
27508   // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
27509   // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
27510   // used.
27511   using FlushCallback = std::function<void(bool /*success*/)>;
27512   virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
27513 
27514   // Tracing data will be delivered invoking Consumer::OnTraceData().
27515   virtual void ReadBuffers() = 0;
27516 
27517   virtual void FreeBuffers() = 0;
27518 
27519   // Will call OnDetach().
27520   virtual void Detach(const std::string& key) = 0;
27521 
27522   // Will call OnAttach().
27523   virtual void Attach(const std::string& key) = 0;
27524 
27525   // Will call OnTraceStats().
27526   virtual void GetTraceStats() = 0;
27527 
27528   // Start or stop observing events of selected types. |events_mask| specifies
27529   // the types of events to observe in a bitmask of ObservableEvents::Type.
27530   // To disable observing, pass 0.
27531   // Will call OnObservableEvents() repeatedly whenever an event of an enabled
27532   // ObservableEventType occurs.
27533   // TODO(eseckler): Extend this to support producers & data sources.
27534   virtual void ObserveEvents(uint32_t events_mask) = 0;
27535 
27536   // Used to obtain the list of connected data sources and other info about
27537   // the tracing service.
27538   using QueryServiceStateCallback =
27539       std::function<void(bool success, const TracingServiceState&)>;
27540   virtual void QueryServiceState(QueryServiceStateCallback) = 0;
27541 
27542   // Used for feature detection. Makes sense only when the consumer and the
27543   // service talk over IPC and can be from different versions.
27544   using QueryCapabilitiesCallback =
27545       std::function<void(const TracingServiceCapabilities&)>;
27546   virtual void QueryCapabilities(QueryCapabilitiesCallback) = 0;
27547 };  // class ConsumerEndpoint.
27548 
27549 // The public API of the tracing Service business logic.
27550 //
27551 // Exposed to:
27552 // 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
27553 //    which forwards commands received from a remote producer or consumer to
27554 //    the actual service implementation.
27555 // 2. Tests.
27556 //
27557 // Subclassed by:
27558 //   The service business logic in src/core/tracing_service_impl.cc.
27559 class PERFETTO_EXPORT TracingService {
27560  public:
27561   using ProducerEndpoint = perfetto::ProducerEndpoint;
27562   using ConsumerEndpoint = perfetto::ConsumerEndpoint;
27563 
27564   enum class ProducerSMBScrapingMode {
27565     // Use service's default setting for SMB scraping. Currently, the default
27566     // mode is to disable SMB scraping, but this may change in the future.
27567     kDefault,
27568 
27569     // Enable scraping of uncommitted chunks in producers' shared memory
27570     // buffers.
27571     kEnabled,
27572 
27573     // Disable scraping of uncommitted chunks in producers' shared memory
27574     // buffers.
27575     kDisabled
27576   };
27577 
27578   // Implemented in src/core/tracing_service_impl.cc .
27579   static std::unique_ptr<TracingService> CreateInstance(
27580       std::unique_ptr<SharedMemory::Factory>,
27581       base::TaskRunner*);
27582 
27583   virtual ~TracingService();
27584 
27585   // Connects a Producer instance and obtains a ProducerEndpoint, which is
27586   // essentially a 1:1 channel between one Producer and the Service.
27587   //
27588   // The caller has to guarantee that the passed Producer will be alive as long
27589   // as the returned ProducerEndpoint is alive. Both the passed Producer and the
27590   // returned ProducerEndpoint must live on the same task runner of the service,
27591   // specifically:
27592   // 1) The Service will call Producer::* methods on the Service's task runner.
27593   // 2) The Producer should call ProducerEndpoint::* methods only on the
27594   //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
27595   //    which can be called on any thread. To disconnect just destroy the
27596   //    returned ProducerEndpoint object. It is safe to destroy the Producer
27597   //    once the Producer::OnDisconnect() has been invoked.
27598   //
27599   // |uid| is the trusted user id of the producer process, used by the consumers
27600   // for validating the origin of trace data. |shared_memory_size_hint_bytes|
27601   // and |shared_memory_page_size_hint_bytes| are optional hints on the size of
27602   // the shared memory buffer and its pages. The service can ignore the hints
27603   // (e.g., if the hints are unreasonably large or other sizes were configured
27604   // in a tracing session's config). |in_process| enables the ProducerEndpoint
27605   // to manage its own shared memory and enables use of
27606   // |ProducerEndpoint::CreateTraceWriter|.
27607   //
27608   // The producer can optionally provide a non-null |shm|, which the service
27609   // will adopt for the connection to the producer, provided it is correctly
27610   // sized. In this case, |shared_memory_page_size_hint_bytes| indicates the
27611   // page size used in this SMB. The producer can use this mechanism to record
27612   // tracing data to an SMB even before the tracing session is started by the
27613   // service. This is used in Chrome to implement startup tracing. If the buffer
27614   // is incorrectly sized, the service will discard the SMB and allocate a new
27615   // one, provided to the producer via ProducerEndpoint::shared_memory() after
27616   // OnTracingSetup(). To verify that the service accepted the SMB, the producer
27617   // may check via ProducerEndpoint::IsShmemProvidedByProducer(). If the service
27618   // accepted the SMB, the producer can then commit any data that is already in
27619   // the SMB after the tracing session was started by the service via
27620   // Producer::StartDataSource(). The |shm| will also be rejected when
27621   // connecting to a service that is too old (pre Android-11).
27622   //
27623   // Can return null in the unlikely event that service has too many producers
27624   // connected.
27625   virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
27626       Producer*,
27627       uid_t uid,
27628       const std::string& name,
27629       size_t shared_memory_size_hint_bytes = 0,
27630       bool in_process = false,
27631       ProducerSMBScrapingMode smb_scraping_mode =
27632           ProducerSMBScrapingMode::kDefault,
27633       size_t shared_memory_page_size_hint_bytes = 0,
27634       std::unique_ptr<SharedMemory> shm = nullptr) = 0;
27635 
27636   // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
27637   // essentially a 1:1 channel between one Consumer and the Service.
27638   // The caller has to guarantee that the passed Consumer will be alive as long
27639   // as the returned ConsumerEndpoint is alive.
27640   // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
27641   // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
27642   virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
27643                                                             uid_t) = 0;
27644 
27645   // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
27646   // the service will copy uncommitted but non-empty chunks from the SMB when
27647   // flushing (e.g. to handle unresponsive producers or producers unable to
27648   // flush their active chunks), on producer disconnect (e.g. to recover data
27649   // from crashed producers), and after disabling a tracing session (e.g. to
27650   // gather data from producers that didn't stop their data sources in time).
27651   //
27652   // This feature is currently used by Chrome.
27653   virtual void SetSMBScrapingEnabled(bool enabled) = 0;
27654 };
27655 
27656 }  // namespace perfetto
27657 
27658 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
27659 /*
27660  * Copyright (C) 2018 The Android Open Source Project
27661  *
27662  * Licensed under the Apache License, Version 2.0 (the "License");
27663  * you may not use this file except in compliance with the License.
27664  * You may obtain a copy of the License at
27665  *
27666  *      http://www.apache.org/licenses/LICENSE-2.0
27667  *
27668  * Unless required by applicable law or agreed to in writing, software
27669  * distributed under the License is distributed on an "AS IS" BASIS,
27670  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27671  * See the License for the specific language governing permissions and
27672  * limitations under the License.
27673  */
27674 
27675 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
27676 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
27677 
27678 #include <stddef.h>
27679 
27680 #include <functional>
27681 #include <memory>
27682 #include <vector>
27683 
27684 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27685 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
27686 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
27687 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
27688 
27689 namespace perfetto {
27690 
27691 namespace base {
27692 class TaskRunner;
27693 }
27694 
27695 class SharedMemory;
27696 class TraceWriter;
27697 
27698 // Used by the Producer-side of the transport layer to vend TraceWriters
27699 // from the SharedMemory it receives from the Service-side.
27700 class PERFETTO_EXPORT SharedMemoryArbiter {
27701  public:
27702   virtual ~SharedMemoryArbiter();
27703 
27704   // Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
27705   // written in each chunk header owned by a given TraceWriter and is used by
27706   // the Service to reconstruct TracePackets written by the same TraceWriter.
27707   // Returns null impl of TraceWriter if all WriterID slots are exhausted. The
27708   // writer will commit to the provided |target_buffer|. If the arbiter was
27709   // created via CreateUnbound(), only BufferExhaustedPolicy::kDrop is
27710   // supported.
27711   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
27712       BufferID target_buffer,
27713       BufferExhaustedPolicy buffer_exhausted_policy =
27714           BufferExhaustedPolicy::kDefault) = 0;
27715 
27716   // Creates a TraceWriter that will commit to the target buffer with the given
27717   // reservation ID (creating a new reservation for this ID if none exists yet).
27718   // The buffer reservation should be bound to an actual BufferID via
27719   // BindStartupTargetBuffer() once the actual BufferID is known. Only supported
27720   // if the arbiter was created using CreateUnbound(), and may be called while
27721   // the arbiter is unbound.
27722   //
27723   // While any unbound buffer reservation exists, all commits will be buffered
27724   // until all reservations were bound. Thus, until all reservations are bound,
27725   // the data written to the SMB will not be consumed by the service - the SMB
27726   // size should be chosen with this in mind. Startup writers always use
27727   // BufferExhaustedPolicy::kDrop, as we cannot feasibly stall while not
27728   // flushing to the service.
27729   //
27730   // The |target_buffer_reservation_id| should be greater than 0 but can
27731   // otherwise be freely chosen by the producer and is only used to translate
27732   // packets into the actual buffer id once
27733   // BindStartupTargetBuffer(reservation_id) is called. For example, Chrome uses
27734   // startup tracing not only for the first, but also subsequent tracing
27735   // sessions (to enable tracing in the browser process before it instructs the
27736   // tracing service to start tracing asynchronously, minimizing trace data loss
27737   // in the meantime), and increments the reservation ID between sessions.
27738   // Similarly, if more than a single target buffer per session is required
27739   // (e.g. for two different data sources), different reservation IDs should be
27740   // chosen for different targets buffers.
27741   virtual std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
27742       uint16_t target_buffer_reservation_id) = 0;
27743 
27744   // Should only be called on unbound SharedMemoryArbiters. Binds the arbiter to
27745   // the provided ProducerEndpoint and TaskRunner. Should be called only once
27746   // and on the provided |TaskRunner|. Usually called by the producer (i.e., no
27747   // specific data source) once it connects to the service. Both the endpoint
27748   // and task runner should remain valid for the remainder of the arbiter's
27749   // lifetime.
27750   virtual void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
27751                                       base::TaskRunner*) = 0;
27752 
27753   // Binds commits from TraceWriters created via CreateStartupTraceWriter() with
27754   // the given |target_buffer_reservation_id| to |target_buffer_id|. May only be
27755   // called once per |target_buffer_reservation_id|. Should be called on the
27756   // arbiter's TaskRunner, and after BindToProducerEndpoint() was called.
27757   // Usually, it is called by a specific data source, after it received its
27758   // configuration (including the target buffer ID) from the service.
27759   virtual void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
27760                                        BufferID target_buffer_id) = 0;
27761 
27762   // Treat the reservation as resolved to an invalid buffer. Commits for this
27763   // reservation will be flushed to the service ASAP. The service will free
27764   // committed chunks but otherwise ignore them. The producer can call this
27765   // method, for example, if connection to the tracing service failed or the
27766   // session was stopped concurrently before the connection was established.
27767   virtual void AbortStartupTracingForReservation(
27768       uint16_t target_buffer_reservation_id) = 0;
27769 
27770   // Notifies the service that all data for the given FlushRequestID has been
27771   // committed in the shared memory buffer. Should only be called while bound.
27772   virtual void NotifyFlushComplete(FlushRequestID) = 0;
27773 
27774   // Sets the duration during which commits are batched. Args:
27775   // |batch_commits_duration_ms|: The length of the period, during which commits
27776   // by all trace writers are accumulated, before being sent to the service.
27777   // When the period ends, all accumulated commits are flushed. On the first
27778   // commit after the last flush, another delayed flush is scheduled to run in
27779   // |batch_commits_duration_ms|. If an immediate flush occurs (via
27780   // FlushPendingCommitDataRequests()) during a batching period, any
27781   // accumulated commits up to that point will be sent to the service
27782   // immediately. And when the batching period ends, the commits that occurred
27783   // after the immediate flush will also be sent to the service.
27784   //
27785   // If the duration has already been set to a non-zero value before this method
27786   // is called, and there is already a scheduled flush with the previously-set
27787   // duration, the new duration will take effect after the scheduled flush
27788   // occurs.
27789   //
27790   // If |batch_commits_duration_ms| is non-zero, batched data that hasn't been
27791   // sent could be lost at the end of a tracing session. To avoid this,
27792   // producers should make sure that FlushPendingCommitDataRequests is called
27793   // after the last TraceWriter write and before the service has stopped
27794   // listening for commits from the tracing session's data sources (i.e.
27795   // data sources should stop asynchronously, see
27796   // DataSourceDescriptor.will_notify_on_stop=true).
27797   virtual void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) = 0;
27798 
27799   // Forces an immediate commit of the completed packets, without waiting for
27800   // the next task or for a batching period to end. Should only be called while
27801   // bound.
27802   virtual void FlushPendingCommitDataRequests(
27803       std::function<void()> callback = {}) = 0;
27804 
27805   // Create a bound arbiter instance. Args:
27806   // |SharedMemory|: the shared memory buffer to use.
27807   // |page_size|: a multiple of 4KB that defines the granularity of tracing
27808   // pages. See tradeoff considerations in shared_memory_abi.h.
27809   // |ProducerEndpoint|: The service's producer endpoint used e.g. to commit
27810   // chunks and register trace writers.
27811   // |TaskRunner|: Task runner for perfetto's main thread, which executes the
27812   // OnPagesCompleteCallback and IPC calls to the |ProducerEndpoint|.
27813   //
27814   // Implemented in src/core/shared_memory_arbiter_impl.cc.
27815   static std::unique_ptr<SharedMemoryArbiter> CreateInstance(
27816       SharedMemory*,
27817       size_t page_size,
27818       TracingService::ProducerEndpoint*,
27819       base::TaskRunner*);
27820 
27821   // Create an unbound arbiter instance, which should later be bound to a
27822   // ProducerEndpoint and TaskRunner by calling BindToProducerEndpoint(). The
27823   // returned arbiter will ONLY support trace writers with
27824   // BufferExhaustedPolicy::kDrop.
27825   //
27826   // An unbound SharedMemoryArbiter can be used to write to a producer-created
27827   // SharedMemory buffer before the producer connects to the tracing service.
27828   // The producer can then pass this SMB to the service when it connects (see
27829   // TracingService::ConnectProducer).
27830   //
27831   // To trace into the SMB before the service starts the tracing session, trace
27832   // writers can be obtained via CreateStartupTraceWriter() and later associated
27833   // with a target buffer via BindStartupTargetBuffer(), once the target buffer
27834   // is known.
27835   //
27836   // Implemented in src/core/shared_memory_arbiter_impl.cc. See CreateInstance()
27837   // for comments about the arguments.
27838   static std::unique_ptr<SharedMemoryArbiter> CreateUnboundInstance(
27839       SharedMemory*,
27840       size_t page_size);
27841 };
27842 
27843 }  // namespace perfetto
27844 
27845 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
27846 /*
27847  * Copyright (C) 2017 The Android Open Source Project
27848  *
27849  * Licensed under the Apache License, Version 2.0 (the "License");
27850  * you may not use this file except in compliance with the License.
27851  * You may obtain a copy of the License at
27852  *
27853  *      http://www.apache.org/licenses/LICENSE-2.0
27854  *
27855  * Unless required by applicable law or agreed to in writing, software
27856  * distributed under the License is distributed on an "AS IS" BASIS,
27857  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27858  * See the License for the specific language governing permissions and
27859  * limitations under the License.
27860  */
27861 
27862 #ifndef SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
27863 #define SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
27864 
27865 #include <stdint.h>
27866 
27867 #include <functional>
27868 #include <map>
27869 #include <memory>
27870 #include <mutex>
27871 #include <vector>
27872 
27873 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
27874 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
27875 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
27876 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
27877 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
27878 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
27879 
27880 namespace perfetto {
27881 
27882 class PatchList;
27883 class TraceWriter;
27884 class TraceWriterImpl;
27885 
27886 namespace base {
27887 class TaskRunner;
27888 }  // namespace base
27889 
27890 // This class handles the shared memory buffer on the producer side. It is used
27891 // to obtain thread-local chunks and to partition pages from several threads.
27892 // There is one arbiter instance per Producer.
27893 // This class is thread-safe and uses locks to do so. Data sources are supposed
27894 // to interact with this sporadically, only when they run out of space on their
27895 // current thread-local chunk.
27896 //
27897 // When the arbiter is created using CreateUnboundInstance(), the following
27898 // state transitions are possible:
27899 //
27900 //   [ !fully_bound_, !endpoint_, 0 unbound buffer reservations ]
27901 //       |     |
27902 //       |     | CreateStartupTraceWriter(buf)
27903 //       |     |  buffer reservations += buf
27904 //       |     |
27905 //       |     |             ----
27906 //       |     |            |    | CreateStartupTraceWriter(buf)
27907 //       |     |            |    |  buffer reservations += buf
27908 //       |     V            |    V
27909 //       |   [ !fully_bound_, !endpoint_, >=1 unbound buffer reservations ]
27910 //       |                                                |
27911 //       |                       BindToProducerEndpoint() |
27912 //       |                                                |
27913 //       | BindToProducerEndpoint()                       |
27914 //       |                                                V
27915 //       |   [ !fully_bound_, endpoint_, >=1 unbound buffer reservations ]
27916 //       |   A    |    A                               |     A
27917 //       |   |    |    |                               |     |
27918 //       |   |     ----                                |     |
27919 //       |   |    CreateStartupTraceWriter(buf)        |     |
27920 //       |   |     buffer reservations += buf          |     |
27921 //       |   |                                         |     |
27922 //       |   | CreateStartupTraceWriter(buf)           |     |
27923 //       |   |  where buf is not yet bound             |     |
27924 //       |   |  buffer reservations += buf             |     | (yes)
27925 //       |   |                                         |     |
27926 //       |   |        BindStartupTargetBuffer(buf, id) |-----
27927 //       |   |           buffer reservations -= buf    | reservations > 0?
27928 //       |   |                                         |
27929 //       |   |                                         | (no)
27930 //       V   |                                         V
27931 //       [ fully_bound_, endpoint_, 0 unbound buffer reservations ]
27932 //          |    A
27933 //          |    | CreateStartupTraceWriter(buf)
27934 //          |    |  where buf is already bound
27935 //           ----
27936 class SharedMemoryArbiterImpl : public SharedMemoryArbiter {
27937  public:
27938   // See SharedMemoryArbiter::CreateInstance(). |start|, |size| define the
27939   // boundaries of the shared memory buffer. ProducerEndpoint and TaskRunner may
27940   // be |nullptr| if created unbound, see
27941   // SharedMemoryArbiter::CreateUnboundInstance().
27942   SharedMemoryArbiterImpl(void* start,
27943                           size_t size,
27944                           size_t page_size,
27945                           TracingService::ProducerEndpoint*,
27946                           base::TaskRunner*);
27947 
27948   // Returns a new Chunk to write tracing data. Depending on the provided
27949   // BufferExhaustedPolicy, this may return an invalid chunk if no valid free
27950   // chunk could be found in the SMB.
27951   SharedMemoryABI::Chunk GetNewChunk(const SharedMemoryABI::ChunkHeader&,
27952                                      BufferExhaustedPolicy,
27953                                      size_t size_hint = 0);
27954 
27955   // Puts back a Chunk that has been completed and sends a request to the
27956   // service to move it to the central tracing buffer. |target_buffer| is the
27957   // absolute trace buffer ID where the service should move the chunk onto (the
27958   // producer is just to copy back the same number received in the
27959   // DataSourceConfig upon the StartDataSource() reques).
27960   // PatchList is a pointer to the list of patches for previous chunks. The
27961   // first patched entries will be removed from the patched list and sent over
27962   // to the service in the same CommitData() IPC request.
27963   void ReturnCompletedChunk(SharedMemoryABI::Chunk,
27964                             MaybeUnboundBufferID target_buffer,
27965                             PatchList*);
27966 
27967   // Send a request to the service to apply completed patches from |patch_list|.
27968   // |writer_id| is the ID of the TraceWriter that calls this method,
27969   // |target_buffer| is the global trace buffer ID of its target buffer.
27970   void SendPatches(WriterID writer_id,
27971                    MaybeUnboundBufferID target_buffer,
27972                    PatchList* patch_list);
27973 
shmem_abi_for_testing()27974   SharedMemoryABI* shmem_abi_for_testing() { return &shmem_abi_; }
27975 
set_default_layout_for_testing(SharedMemoryABI::PageLayout l)27976   static void set_default_layout_for_testing(SharedMemoryABI::PageLayout l) {
27977     default_page_layout = l;
27978   }
27979 
27980   // SharedMemoryArbiter implementation.
27981   // See include/perfetto/tracing/core/shared_memory_arbiter.h for comments.
27982   std::unique_ptr<TraceWriter> CreateTraceWriter(
27983       BufferID target_buffer,
27984       BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override;
27985   std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
27986       uint16_t target_buffer_reservation_id) override;
27987   void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
27988                               base::TaskRunner*) override;
27989   void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
27990                                BufferID target_buffer_id) override;
27991   void AbortStartupTracingForReservation(
27992       uint16_t target_buffer_reservation_id) override;
27993   void NotifyFlushComplete(FlushRequestID) override;
27994 
27995   void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) override;
27996 
27997   void FlushPendingCommitDataRequests(
27998       std::function<void()> callback = {}) override;
27999 
task_runner() const28000   base::TaskRunner* task_runner() const { return task_runner_; }
page_size() const28001   size_t page_size() const { return shmem_abi_.page_size(); }
num_pages() const28002   size_t num_pages() const { return shmem_abi_.num_pages(); }
28003 
GetWeakPtr() const28004   base::WeakPtr<SharedMemoryArbiterImpl> GetWeakPtr() const {
28005     return weak_ptr_factory_.GetWeakPtr();
28006   }
28007 
28008  private:
28009   friend class TraceWriterImpl;
28010   friend class StartupTraceWriterTest;
28011   friend class SharedMemoryArbiterImplTest;
28012 
28013   struct TargetBufferReservation {
28014     bool resolved = false;
28015     BufferID target_buffer = kInvalidBufferId;
28016   };
28017 
28018   // Placeholder for the actual target buffer ID of a startup target buffer
28019   // reservation ID in |target_buffer_reservations_|.
28020   static constexpr BufferID kInvalidBufferId = 0;
28021 
28022   static SharedMemoryABI::PageLayout default_page_layout;
28023 
28024   SharedMemoryArbiterImpl(const SharedMemoryArbiterImpl&) = delete;
28025   SharedMemoryArbiterImpl& operator=(const SharedMemoryArbiterImpl&) = delete;
28026 
28027   void UpdateCommitDataRequest(SharedMemoryABI::Chunk chunk,
28028                                WriterID writer_id,
28029                                MaybeUnboundBufferID target_buffer,
28030                                PatchList* patch_list);
28031 
28032   std::unique_ptr<TraceWriter> CreateTraceWriterInternal(
28033       MaybeUnboundBufferID target_buffer,
28034       BufferExhaustedPolicy);
28035 
28036   // Called by the TraceWriter destructor.
28037   void ReleaseWriterID(WriterID);
28038 
28039   void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
28040                                    uint16_t target_buffer_reservation_id,
28041                                    BufferID target_buffer_id);
28042 
28043   // If any flush callbacks were queued up while the arbiter or any target
28044   // buffer reservation was unbound, this wraps the pending callbacks into a new
28045   // std::function and returns it. Otherwise returns an invalid std::function.
28046   std::function<void()> TakePendingFlushCallbacksLocked();
28047 
28048   // Replace occurrences of target buffer reservation IDs in |commit_data_req_|
28049   // with their respective actual BufferIDs if they were already bound. Returns
28050   // true iff all occurrences were replaced.
28051   bool ReplaceCommitPlaceholderBufferIdsLocked();
28052 
28053   // Update and return |fully_bound_| based on the arbiter's |pending_writers_|
28054   // state.
28055   bool UpdateFullyBoundLocked();
28056 
28057   const bool initially_bound_;
28058 
28059   // Only accessed on |task_runner_| after the producer endpoint was bound.
28060   TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;
28061 
28062   // --- Begin lock-protected members ---
28063 
28064   std::mutex lock_;
28065 
28066   base::TaskRunner* task_runner_ = nullptr;
28067   SharedMemoryABI shmem_abi_;
28068   size_t page_idx_ = 0;
28069   std::unique_ptr<CommitDataRequest> commit_data_req_;
28070   size_t bytes_pending_commit_ = 0;  // SUM(chunk.size() : commit_data_req_).
28071   IdAllocator<WriterID> active_writer_ids_;
28072 
28073   // Whether the arbiter itself and all startup target buffer reservations are
28074   // bound. Note that this can become false again later if a new target buffer
28075   // reservation is created by calling CreateStartupTraceWriter() with a new
28076   // reservation id.
28077   bool fully_bound_;
28078 
28079   // IDs of writers and their assigned target buffers that should be registered
28080   // with the service after the arbiter and/or their startup target buffer is
28081   // bound.
28082   std::map<WriterID, MaybeUnboundBufferID> pending_writers_;
28083 
28084   // Callbacks for flush requests issued while the arbiter or a target buffer
28085   // reservation was unbound.
28086   std::vector<std::function<void()>> pending_flush_callbacks_;
28087 
28088   // See SharedMemoryArbiter.SetBatchCommitsDuration.
28089   uint32_t batch_commits_duration_ms_ = 0;
28090 
28091   // Indicates whether we have already scheduled a delayed flush for the
28092   // purposes of batching. Set to true at the beginning of a batching period and
28093   // cleared at the end of the period. Immediate flushes that happen during a
28094   // batching period will empty the |commit_data_req| (triggering an immediate
28095   // IPC to the service), but will not clear this flag and the
28096   // previously-scheduled delayed flush will still occur at the end of the
28097   // batching period.
28098   bool delayed_flush_scheduled_ = false;
28099 
28100   // Stores target buffer reservations for writers created via
28101   // CreateStartupTraceWriter(). A bound reservation sets
28102   // TargetBufferReservation::resolved to true and is associated with the actual
28103   // BufferID supplied in BindStartupTargetBuffer().
28104   //
28105   // TODO(eseckler): Clean up entries from this map. This would probably require
28106   // a method in SharedMemoryArbiter that allows a producer to invalidate a
28107   // reservation ID.
28108   std::map<MaybeUnboundBufferID, TargetBufferReservation>
28109       target_buffer_reservations_;
28110 
28111   // --- End lock-protected members ---
28112 
28113   // Keep at the end.
28114   base::WeakPtrFactory<SharedMemoryArbiterImpl> weak_ptr_factory_;
28115 };
28116 
28117 }  // namespace perfetto
28118 
28119 #endif  // SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
28120 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/commit_data_request.h
28121 /*
28122  * Copyright (C) 2017 The Android Open Source Project
28123  *
28124  * Licensed under the Apache License, Version 2.0 (the "License");
28125  * you may not use this file except in compliance with the License.
28126  * You may obtain a copy of the License at
28127  *
28128  *      http://www.apache.org/licenses/LICENSE-2.0
28129  *
28130  * Unless required by applicable law or agreed to in writing, software
28131  * distributed under the License is distributed on an "AS IS" BASIS,
28132  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28133  * See the License for the specific language governing permissions and
28134  * limitations under the License.
28135  */
28136 
28137 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
28138 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
28139 
28140 // Creates the aliases in the ::perfetto namespace, doing things like:
28141 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
28142 // See comments in forward_decls.h for the historical reasons of this
28143 // indirection layer.
28144 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
28145 
28146 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
28147 
28148 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
28149 // gen_amalgamated begin header: src/tracing/core/trace_writer_impl.h
28150 // gen_amalgamated begin header: src/tracing/core/patch_list.h
28151 /*
28152  * Copyright (C) 2018 The Android Open Source Project
28153  *
28154  * Licensed under the Apache License, Version 2.0 (the "License");
28155  * you may not use this file except in compliance with the License.
28156  * You may obtain a copy of the License at
28157  *
28158  *      http://www.apache.org/licenses/LICENSE-2.0
28159  *
28160  * Unless required by applicable law or agreed to in writing, software
28161  * distributed under the License is distributed on an "AS IS" BASIS,
28162  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28163  * See the License for the specific language governing permissions and
28164  * limitations under the License.
28165  */
28166 
28167 #ifndef SRC_TRACING_CORE_PATCH_LIST_H_
28168 #define SRC_TRACING_CORE_PATCH_LIST_H_
28169 
28170 #include <array>
28171 #include <forward_list>
28172 
28173 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
28174 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
28175 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
28176 
28177 namespace perfetto {
28178 
28179 // Used to handle the backfilling of the headers (the |size_field|) of nested
28180 // messages when a proto is fragmented over several chunks. These patches are
28181 // sent out-of-band to the tracing service, after having returned the initial
28182 // chunks of the fragment.
28183 // TODO(crbug.com/904477): Re-disable the move constructors when all usses of
28184 // this class have been fixed.
28185 class Patch {
28186  public:
28187   using PatchContent = std::array<uint8_t, SharedMemoryABI::kPacketHeaderSize>;
Patch(ChunkID c,uint16_t o)28188   Patch(ChunkID c, uint16_t o) : chunk_id(c), offset(o) {}
28189   Patch(const Patch&) = default;  // For tests.
28190 
28191   const ChunkID chunk_id;
28192   const uint16_t offset;
28193   PatchContent size_field{};
28194 
28195   // |size_field| contains a varint. Any varint must start with != 0. Even in
28196   // the case we want to encode a size == 0, protozero will write a redundant
28197   // varint for that, that is [0x80, 0x80, 0x80, 0x00]. So the first byte is 0
28198   // iff we never wrote any varint into that.
is_patched() const28199   bool is_patched() const { return size_field[0] != 0; }
28200 
28201   // For tests.
operator ==(const Patch & o) const28202   bool operator==(const Patch& o) const {
28203     return chunk_id == o.chunk_id && offset == o.offset &&
28204            size_field == o.size_field;
28205   }
28206 
28207  private:
28208   Patch& operator=(const Patch&) = delete;
28209 };
28210 
28211 // Note: the protozero::Message(s) will take pointers to the |size_field| of
28212 // these entries. This container must guarantee that the Patch objects are never
28213 // moved around (i.e. cannot be a vector because of reallocations can change
28214 // addresses of pre-existing entries).
28215 class PatchList {
28216  public:
28217   using ListType = std::forward_list<Patch>;
28218   using value_type = ListType::value_type;          // For gtest.
28219   using const_iterator = ListType::const_iterator;  // For gtest.
28220 
PatchList()28221   PatchList() : last_(list_.before_begin()) {}
28222 
emplace_back(ChunkID chunk_id,uint16_t offset)28223   Patch* emplace_back(ChunkID chunk_id, uint16_t offset) {
28224     PERFETTO_DCHECK(empty() || last_->chunk_id != chunk_id ||
28225                     offset >= last_->offset + sizeof(Patch::PatchContent));
28226     last_ = list_.emplace_after(last_, chunk_id, offset);
28227     return &*last_;
28228   }
28229 
pop_front()28230   void pop_front() {
28231     PERFETTO_DCHECK(!list_.empty());
28232     list_.pop_front();
28233     if (empty())
28234       last_ = list_.before_begin();
28235   }
28236 
front() const28237   const Patch& front() const {
28238     PERFETTO_DCHECK(!list_.empty());
28239     return list_.front();
28240   }
28241 
back() const28242   const Patch& back() const {
28243     PERFETTO_DCHECK(!list_.empty());
28244     return *last_;
28245   }
28246 
begin() const28247   ListType::const_iterator begin() const { return list_.begin(); }
end() const28248   ListType::const_iterator end() const { return list_.end(); }
empty() const28249   bool empty() const { return list_.empty(); }
28250 
28251  private:
28252   ListType list_;
28253   ListType::iterator last_;
28254 };
28255 
28256 }  // namespace perfetto
28257 
28258 #endif  // SRC_TRACING_CORE_PATCH_LIST_H_
28259 /*
28260  * Copyright (C) 2017 The Android Open Source Project
28261  *
28262  * Licensed under the Apache License, Version 2.0 (the "License");
28263  * you may not use this file except in compliance with the License.
28264  * You may obtain a copy of the License at
28265  *
28266  *      http://www.apache.org/licenses/LICENSE-2.0
28267  *
28268  * Unless required by applicable law or agreed to in writing, software
28269  * distributed under the License is distributed on an "AS IS" BASIS,
28270  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28271  * See the License for the specific language governing permissions and
28272  * limitations under the License.
28273  */
28274 
28275 #ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
28276 #define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
28277 
28278 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
28279 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
28280 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
28281 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
28282 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
28283 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
28284 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
28285 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
28286 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
28287 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
28288 // gen_amalgamated expanded: #include "src/tracing/core/patch_list.h"
28289 
28290 namespace perfetto {
28291 
28292 class SharedMemoryArbiterImpl;
28293 
28294 // See //include/perfetto/tracing/core/trace_writer.h for docs.
28295 class TraceWriterImpl : public TraceWriter,
28296                         public protozero::ScatteredStreamWriter::Delegate {
28297  public:
28298   // TracePacketHandle is defined in trace_writer.h
28299   TraceWriterImpl(SharedMemoryArbiterImpl*,
28300                   WriterID,
28301                   MaybeUnboundBufferID buffer_id,
28302                   BufferExhaustedPolicy);
28303   ~TraceWriterImpl() override;
28304 
28305   // TraceWriter implementation. See documentation in trace_writer.h.
28306   TracePacketHandle NewTracePacket() override;
28307   void Flush(std::function<void()> callback = {}) override;
28308   WriterID writer_id() const override;
written() const28309   uint64_t written() const override {
28310     return protobuf_stream_writer_.written();
28311   }
28312 
ResetChunkForTesting()28313   void ResetChunkForTesting() { cur_chunk_ = SharedMemoryABI::Chunk(); }
drop_packets_for_testing() const28314   bool drop_packets_for_testing() const { return drop_packets_; }
28315 
28316  private:
28317   TraceWriterImpl(const TraceWriterImpl&) = delete;
28318   TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;
28319 
28320   // ScatteredStreamWriter::Delegate implementation.
28321   protozero::ContiguousMemoryRange GetNewBuffer() override;
28322 
28323   // The per-producer arbiter that coordinates access to the shared memory
28324   // buffer from several threads.
28325   SharedMemoryArbiterImpl* const shmem_arbiter_;
28326 
28327   // ID of the current writer.
28328   const WriterID id_;
28329 
28330   // This is copied into the commit request by SharedMemoryArbiter. See comments
28331   // in data_source_config.proto for |target_buffer|. If this is a reservation
28332   // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
28333   // will also translate the reservation ID to the actual buffer ID.
28334   const MaybeUnboundBufferID target_buffer_;
28335 
28336   // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
28337   // exhausted.
28338   const BufferExhaustedPolicy buffer_exhausted_policy_;
28339 
28340   // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
28341   // this allows the Service to reconstruct the linear sequence of packets.
28342   ChunkID next_chunk_id_ = 0;
28343 
28344   // The chunk we are holding onto (if any).
28345   SharedMemoryABI::Chunk cur_chunk_;
28346 
28347   // Passed to protozero message to write directly into |cur_chunk_|. It
28348   // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
28349   // |cur_chunk_| is filled.
28350   protozero::ScatteredStreamWriter protobuf_stream_writer_;
28351 
28352   // The packet returned via NewTracePacket(). Its owned by this class,
28353   // TracePacketHandle has just a pointer to it.
28354   std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
28355       cur_packet_;
28356 
28357   // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
28358   // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
28359   uint8_t* cur_fragment_start_ = nullptr;
28360 
28361   // true if we received a call to GetNewBuffer() after NewTracePacket(),
28362   // false if GetNewBuffer() happened during NewTracePacket() prologue, while
28363   // starting the TracePacket header.
28364   bool fragmenting_packet_ = false;
28365 
28366   // Set to |true| when the current chunk contains the maximum number of packets
28367   // a chunk can contain. When this is |true|, the next packet requires starting
28368   // a new chunk.
28369   bool reached_max_packets_per_chunk_ = false;
28370 
28371   // If we fail to acquire a new chunk when the arbiter operates in
28372   // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
28373   // mode in which data is written to a local garbage chunk and dropped.
28374   bool drop_packets_ = false;
28375 
28376   // Whether the trace writer should try to acquire a new chunk from the SMB
28377   // when the next TracePacket is started because it filled the garbage chunk at
28378   // least once since the last attempt.
28379   bool retry_new_chunk_after_packet_ = false;
28380 
28381   // Points to the size field of the last packet we wrote to the current chunk.
28382   // If the chunk was already returned, this is reset to |nullptr|.
28383   uint8_t* last_packet_size_field_ = nullptr;
28384 
28385   // When a packet is fragmented across different chunks, the |size_field| of
28386   // the outstanding nested protobuf messages is redirected onto Patch entries
28387   // in this list at the time the Chunk is returned (because at that point we
28388   // have to release the ownership of the current Chunk). This list will be
28389   // later sent out-of-band to the tracing service, who will patch the required
28390   // chunks, if they are still around.
28391   PatchList patch_list_;
28392 
28393   // PID of the process that created the trace writer. Used for a DCHECK that
28394   // aims to detect unsupported process forks while tracing.
28395   const base::PlatformProcessId process_id_;
28396 };
28397 
28398 }  // namespace perfetto
28399 
28400 #endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
28401 /*
28402  * Copyright (C) 2017 The Android Open Source Project
28403  *
28404  * Licensed under the Apache License, Version 2.0 (the "License");
28405  * you may not use this file except in compliance with the License.
28406  * You may obtain a copy of the License at
28407  *
28408  *      http://www.apache.org/licenses/LICENSE-2.0
28409  *
28410  * Unless required by applicable law or agreed to in writing, software
28411  * distributed under the License is distributed on an "AS IS" BASIS,
28412  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28413  * See the License for the specific language governing permissions and
28414  * limitations under the License.
28415  */
28416 
28417 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
28418 
28419 #include <algorithm>
28420 #include <limits>
28421 #include <utility>
28422 
28423 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
28424 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
28425 // gen_amalgamated expanded: #include "perfetto/base/time.h"
28426 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
28427 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
28428 // gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
28429 // gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
28430 
28431 namespace perfetto {
28432 
28433 using Chunk = SharedMemoryABI::Chunk;
28434 
28435 namespace {
28436 static_assert(sizeof(BufferID) == sizeof(uint16_t),
28437               "The MaybeUnboundBufferID logic requires BufferID not to grow "
28438               "above uint16_t.");
28439 
MakeTargetBufferIdForReservation(uint16_t reservation_id)28440 MaybeUnboundBufferID MakeTargetBufferIdForReservation(uint16_t reservation_id) {
28441   // Reservation IDs are stored in the upper bits.
28442   PERFETTO_CHECK(reservation_id > 0);
28443   return static_cast<MaybeUnboundBufferID>(reservation_id) << 16;
28444 }
28445 
IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id)28446 bool IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id) {
28447   return (buffer_id >> 16) > 0;
28448 }
28449 }  // namespace
28450 
28451 // static
28452 SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
28453     SharedMemoryABI::PageLayout::kPageDiv1;
28454 
28455 // static
28456 constexpr BufferID SharedMemoryArbiterImpl::kInvalidBufferId;
28457 
28458 // static
CreateInstance(SharedMemory * shared_memory,size_t page_size,TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)28459 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
28460     SharedMemory* shared_memory,
28461     size_t page_size,
28462     TracingService::ProducerEndpoint* producer_endpoint,
28463     base::TaskRunner* task_runner) {
28464   return std::unique_ptr<SharedMemoryArbiterImpl>(
28465       new SharedMemoryArbiterImpl(shared_memory->start(), shared_memory->size(),
28466                                   page_size, producer_endpoint, task_runner));
28467 }
28468 
28469 // static
CreateUnboundInstance(SharedMemory * shared_memory,size_t page_size)28470 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
28471     SharedMemory* shared_memory,
28472     size_t page_size) {
28473   return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
28474       shared_memory->start(), shared_memory->size(), page_size,
28475       /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
28476 }
28477 
SharedMemoryArbiterImpl(void * start,size_t size,size_t page_size,TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)28478 SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
28479     void* start,
28480     size_t size,
28481     size_t page_size,
28482     TracingService::ProducerEndpoint* producer_endpoint,
28483     base::TaskRunner* task_runner)
28484     : initially_bound_(task_runner && producer_endpoint),
28485       producer_endpoint_(producer_endpoint),
28486       task_runner_(task_runner),
28487       shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size),
28488       active_writer_ids_(kMaxWriterID),
28489       fully_bound_(initially_bound_),
28490       weak_ptr_factory_(this) {}
28491 
GetNewChunk(const SharedMemoryABI::ChunkHeader & header,BufferExhaustedPolicy buffer_exhausted_policy,size_t size_hint)28492 Chunk SharedMemoryArbiterImpl::GetNewChunk(
28493     const SharedMemoryABI::ChunkHeader& header,
28494     BufferExhaustedPolicy buffer_exhausted_policy,
28495     size_t size_hint) {
28496   PERFETTO_DCHECK(size_hint == 0);  // Not implemented yet.
28497   // If initially unbound, we do not support stalling. In theory, we could
28498   // support stalling for TraceWriters created after the arbiter and startup
28499   // buffer reservations were bound, but to avoid raciness between the creation
28500   // of startup writers and binding, we categorically forbid kStall mode.
28501   PERFETTO_DCHECK(initially_bound_ ||
28502                   buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);
28503 
28504   int stall_count = 0;
28505   unsigned stall_interval_us = 0;
28506   bool task_runner_runs_on_current_thread = false;
28507   static const unsigned kMaxStallIntervalUs = 100000;
28508   static const int kLogAfterNStalls = 3;
28509   static const int kFlushCommitsAfterEveryNStalls = 2;
28510   static const int kAssertAtNStalls = 100;
28511 
28512   for (;;) {
28513     // TODO(primiano): Probably this lock is not really required and this code
28514     // could be rewritten leveraging only the Try* atomic operations in
28515     // SharedMemoryABI. But let's not be too adventurous for the moment.
28516     {
28517       std::unique_lock<std::mutex> scoped_lock(lock_);
28518 
28519       task_runner_runs_on_current_thread =
28520           task_runner_ && task_runner_->RunsTasksOnCurrentThread();
28521 
28522       // If more than half of the SMB.size() is filled with completed chunks for
28523       // which we haven't notified the service yet (i.e. they are still enqueued
28524       // in |commit_data_req_|), force a synchronous CommitDataRequest() even if
28525       // we acquire a chunk, to reduce the likeliness of stalling the writer.
28526       //
28527       // We can only do this if we're writing on the same thread that we access
28528       // the producer endpoint on, since we cannot notify the producer endpoint
28529       // to commit synchronously on a different thread. Attempting to flush
28530       // synchronously on another thread will lead to subtle bugs caused by
28531       // out-of-order commit requests (crbug.com/919187#c28).
28532       bool should_commit_synchronously =
28533           task_runner_runs_on_current_thread &&
28534           buffer_exhausted_policy == BufferExhaustedPolicy::kStall &&
28535           commit_data_req_ && bytes_pending_commit_ >= shmem_abi_.size() / 2;
28536 
28537       const size_t initial_page_idx = page_idx_;
28538       for (size_t i = 0; i < shmem_abi_.num_pages(); i++) {
28539         page_idx_ = (initial_page_idx + i) % shmem_abi_.num_pages();
28540         bool is_new_page = false;
28541 
28542         // TODO(primiano): make the page layout dynamic.
28543         auto layout = SharedMemoryArbiterImpl::default_page_layout;
28544 
28545         if (shmem_abi_.is_page_free(page_idx_)) {
28546           // TODO(primiano): Use the |size_hint| here to decide the layout.
28547           is_new_page = shmem_abi_.TryPartitionPage(page_idx_, layout);
28548         }
28549         uint32_t free_chunks;
28550         if (is_new_page) {
28551           free_chunks = (1 << SharedMemoryABI::kNumChunksForLayout[layout]) - 1;
28552         } else {
28553           free_chunks = shmem_abi_.GetFreeChunks(page_idx_);
28554         }
28555 
28556         for (uint32_t chunk_idx = 0; free_chunks;
28557              chunk_idx++, free_chunks >>= 1) {
28558           if (!(free_chunks & 1))
28559             continue;
28560           // We found a free chunk.
28561           Chunk chunk = shmem_abi_.TryAcquireChunkForWriting(
28562               page_idx_, chunk_idx, &header);
28563           if (!chunk.is_valid())
28564             continue;
28565           if (stall_count > kLogAfterNStalls) {
28566             PERFETTO_LOG("Recovered from stall after %d iterations",
28567                          stall_count);
28568           }
28569 
28570           if (should_commit_synchronously) {
28571             // We can't flush while holding the lock.
28572             scoped_lock.unlock();
28573             FlushPendingCommitDataRequests();
28574             return chunk;
28575           } else {
28576             return chunk;
28577           }
28578         }
28579       }
28580     }  // scoped_lock
28581 
28582     if (buffer_exhausted_policy == BufferExhaustedPolicy::kDrop) {
28583       PERFETTO_DLOG("Shared memory buffer exhaused, returning invalid Chunk!");
28584       return Chunk();
28585     }
28586 
28587     PERFETTO_DCHECK(initially_bound_);
28588 
28589     // All chunks are taken (either kBeingWritten by us or kBeingRead by the
28590     // Service).
28591     if (stall_count++ == kLogAfterNStalls) {
28592       PERFETTO_LOG("Shared memory buffer overrun! Stalling");
28593     }
28594 
28595     if (stall_count == kAssertAtNStalls) {
28596       PERFETTO_FATAL(
28597           "Shared memory buffer max stall count exceeded; possible deadlock");
28598     }
28599 
28600     // If the IPC thread itself is stalled because the current process has
28601     // filled up the SMB, we need to make sure that the service can process and
28602     // purge the chunks written by our process, by flushing any pending commit
28603     // requests. Because other threads in our process can continue to
28604     // concurrently grab, fill and commit any chunks purged by the service, it
28605     // is possible that the SMB remains full and the IPC thread remains stalled,
28606     // needing to flush the concurrently queued up commits again. This is
28607     // particularly likely with in-process perfetto service where the IPC thread
28608     // is the service thread. To avoid remaining stalled forever in such a
28609     // situation, we attempt to flush periodically after every N stalls.
28610     if (stall_count % kFlushCommitsAfterEveryNStalls == 0 &&
28611         task_runner_runs_on_current_thread) {
28612       // TODO(primiano): sending the IPC synchronously is a temporary workaround
28613       // until the backpressure logic in probes_producer is sorted out. Until
28614       // then the risk is that we stall the message loop waiting for the tracing
28615       // service to consume the shared memory buffer (SMB) and, for this reason,
28616       // never run the task that tells the service to purge the SMB. This must
28617       // happen iff we are on the IPC thread, not doing this will cause
28618       // deadlocks, doing this on the wrong thread causes out-of-order data
28619       // commits (crbug.com/919187#c28).
28620       FlushPendingCommitDataRequests();
28621     } else {
28622       base::SleepMicroseconds(stall_interval_us);
28623       stall_interval_us =
28624           std::min(kMaxStallIntervalUs, (stall_interval_us + 1) * 8);
28625     }
28626   }
28627 }
28628 
ReturnCompletedChunk(Chunk chunk,MaybeUnboundBufferID target_buffer,PatchList * patch_list)28629 void SharedMemoryArbiterImpl::ReturnCompletedChunk(
28630     Chunk chunk,
28631     MaybeUnboundBufferID target_buffer,
28632     PatchList* patch_list) {
28633   PERFETTO_DCHECK(chunk.is_valid());
28634   const WriterID writer_id = chunk.writer_id();
28635   UpdateCommitDataRequest(std::move(chunk), writer_id, target_buffer,
28636                           patch_list);
28637 }
28638 
SendPatches(WriterID writer_id,MaybeUnboundBufferID target_buffer,PatchList * patch_list)28639 void SharedMemoryArbiterImpl::SendPatches(WriterID writer_id,
28640                                           MaybeUnboundBufferID target_buffer,
28641                                           PatchList* patch_list) {
28642   PERFETTO_DCHECK(!patch_list->empty() && patch_list->front().is_patched());
28643   UpdateCommitDataRequest(Chunk(), writer_id, target_buffer, patch_list);
28644 }
28645 
UpdateCommitDataRequest(Chunk chunk,WriterID writer_id,MaybeUnboundBufferID target_buffer,PatchList * patch_list)28646 void SharedMemoryArbiterImpl::UpdateCommitDataRequest(
28647     Chunk chunk,
28648     WriterID writer_id,
28649     MaybeUnboundBufferID target_buffer,
28650     PatchList* patch_list) {
28651   // Note: chunk will be invalid if the call came from SendPatches().
28652   base::TaskRunner* task_runner_to_post_delayed_callback_on = nullptr;
28653   // The delay with which the flush will be posted.
28654   uint32_t flush_delay_ms = 0;
28655   base::WeakPtr<SharedMemoryArbiterImpl> weak_this;
28656   {
28657     std::lock_guard<std::mutex> scoped_lock(lock_);
28658 
28659     if (!commit_data_req_) {
28660       commit_data_req_.reset(new CommitDataRequest());
28661 
28662       // Flushing the commit is only supported while we're |fully_bound_|. If we
28663       // aren't, we'll flush when |fully_bound_| is updated.
28664       if (fully_bound_ && !delayed_flush_scheduled_) {
28665         weak_this = weak_ptr_factory_.GetWeakPtr();
28666         task_runner_to_post_delayed_callback_on = task_runner_;
28667         flush_delay_ms = batch_commits_duration_ms_;
28668         delayed_flush_scheduled_ = true;
28669       }
28670     }
28671 
28672     // If a valid chunk is specified, return it and attach it to the request.
28673     if (chunk.is_valid()) {
28674       PERFETTO_DCHECK(chunk.writer_id() == writer_id);
28675       uint8_t chunk_idx = chunk.chunk_idx();
28676       bytes_pending_commit_ += chunk.size();
28677       size_t page_idx = shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
28678 
28679       // DO NOT access |chunk| after this point, has been std::move()-d above.
28680 
28681       CommitDataRequest::ChunksToMove* ctm =
28682           commit_data_req_->add_chunks_to_move();
28683       ctm->set_page(static_cast<uint32_t>(page_idx));
28684       ctm->set_chunk(chunk_idx);
28685       ctm->set_target_buffer(target_buffer);
28686     }
28687 
28688     // Get the completed patches for previous chunks from the |patch_list|
28689     // and attach them.
28690     ChunkID last_chunk_id = 0;  // 0 is irrelevant but keeps the compiler happy.
28691     CommitDataRequest::ChunkToPatch* last_chunk_req = nullptr;
28692     while (!patch_list->empty() && patch_list->front().is_patched()) {
28693       if (!last_chunk_req || last_chunk_id != patch_list->front().chunk_id) {
28694         last_chunk_req = commit_data_req_->add_chunks_to_patch();
28695         last_chunk_req->set_writer_id(writer_id);
28696         last_chunk_id = patch_list->front().chunk_id;
28697         last_chunk_req->set_chunk_id(last_chunk_id);
28698         last_chunk_req->set_target_buffer(target_buffer);
28699       }
28700       auto* patch_req = last_chunk_req->add_patches();
28701       patch_req->set_offset(patch_list->front().offset);
28702       patch_req->set_data(&patch_list->front().size_field[0],
28703                           patch_list->front().size_field.size());
28704       patch_list->pop_front();
28705     }
28706     // Patches are enqueued in the |patch_list| in order and are notified to
28707     // the service when the chunk is returned. The only case when the current
28708     // patch list is incomplete is if there is an unpatched entry at the head of
28709     // the |patch_list| that belongs to the same ChunkID as the last one we are
28710     // about to send to the service.
28711     if (last_chunk_req && !patch_list->empty() &&
28712         patch_list->front().chunk_id == last_chunk_id) {
28713       last_chunk_req->set_has_more_patches(true);
28714     }
28715 
28716     // If the buffer is filling up, we don't want to wait for the next delayed
28717     // flush to happen. So post a flush for immediate execution.
28718     if (fully_bound_ && bytes_pending_commit_ >= shmem_abi_.size() / 2) {
28719       weak_this = weak_ptr_factory_.GetWeakPtr();
28720       task_runner_to_post_delayed_callback_on = task_runner_;
28721       flush_delay_ms = 0;
28722     }
28723   }  // scoped_lock(lock_)
28724 
28725   // We shouldn't post tasks while locked.
28726   // |task_runner_to_post_delayed_callback_on| remains valid after unlocking,
28727   // because |task_runner_| is never reset.
28728   if (task_runner_to_post_delayed_callback_on) {
28729     task_runner_to_post_delayed_callback_on->PostDelayedTask(
28730         [weak_this] {
28731           if (!weak_this)
28732             return;
28733           {
28734             std::lock_guard<std::mutex> scoped_lock(weak_this.get()->lock_);
28735             // Clear |delayed_flush_scheduled_|, allowing the next call to
28736             // UpdateCommitDataRequest to start another batching period.
28737             weak_this.get()->delayed_flush_scheduled_ = false;
28738           }
28739           weak_this->FlushPendingCommitDataRequests();
28740         },
28741         flush_delay_ms);
28742   }
28743 }
28744 
SetBatchCommitsDuration(uint32_t batch_commits_duration_ms)28745 void SharedMemoryArbiterImpl::SetBatchCommitsDuration(
28746     uint32_t batch_commits_duration_ms) {
28747   std::lock_guard<std::mutex> scoped_lock(lock_);
28748   batch_commits_duration_ms_ = batch_commits_duration_ms;
28749 }
28750 
28751 // This function is quite subtle. When making changes keep in mind these two
28752 // challenges:
28753 // 1) If the producer stalls and we happen to be on the |task_runner_| IPC
28754 //    thread (or, for in-process cases, on the same thread where
28755 //    TracingServiceImpl lives), the CommitData() call must be synchronous and
28756 //    not posted, to avoid deadlocks.
28757 // 2) When different threads hit this function, we must guarantee that we don't
28758 //    accidentally make commits out of order. See commit 4e4fe8f56ef and
28759 //    crbug.com/919187 for more context.
FlushPendingCommitDataRequests(std::function<void ()> callback)28760 void SharedMemoryArbiterImpl::FlushPendingCommitDataRequests(
28761     std::function<void()> callback) {
28762   std::unique_ptr<CommitDataRequest> req;
28763   {
28764     std::unique_lock<std::mutex> scoped_lock(lock_);
28765 
28766     // Flushing is only supported while |fully_bound_|, and there may still be
28767     // unbound startup trace writers. If so, skip the commit for now - it'll be
28768     // done when |fully_bound_| is updated.
28769     if (!fully_bound_) {
28770       if (callback)
28771         pending_flush_callbacks_.push_back(callback);
28772       return;
28773     }
28774 
28775     // May be called by TraceWriterImpl on any thread.
28776     base::TaskRunner* task_runner = task_runner_;
28777     if (!task_runner->RunsTasksOnCurrentThread()) {
28778       // We shouldn't post a task while holding a lock. |task_runner| remains
28779       // valid after unlocking, because |task_runner_| is never reset.
28780       scoped_lock.unlock();
28781 
28782       auto weak_this = weak_ptr_factory_.GetWeakPtr();
28783       task_runner->PostTask([weak_this, callback] {
28784         if (weak_this)
28785           weak_this->FlushPendingCommitDataRequests(std::move(callback));
28786       });
28787       return;
28788     }
28789 
28790     // |commit_data_req_| could have become a nullptr, for example when a forced
28791     // sync flush happens in GetNewChunk().
28792     if (commit_data_req_) {
28793       // Make sure any placeholder buffer IDs from StartupWriters are replaced
28794       // before sending the request.
28795       bool all_placeholders_replaced =
28796           ReplaceCommitPlaceholderBufferIdsLocked();
28797       // We're |fully_bound_|, thus all writers are bound and all placeholders
28798       // should have been replaced.
28799       PERFETTO_DCHECK(all_placeholders_replaced);
28800 
28801       req = std::move(commit_data_req_);
28802       bytes_pending_commit_ = 0;
28803     }
28804   }  // scoped_lock
28805 
28806   if (req) {
28807     producer_endpoint_->CommitData(*req, callback);
28808   } else if (callback) {
28809     // If |req| was nullptr, it means that an enqueued deferred commit was
28810     // executed just before this. At this point send an empty commit request
28811     // to the service, just to linearize with it and give the guarantee to the
28812     // caller that the data has been flushed into the service.
28813     producer_endpoint_->CommitData(CommitDataRequest(), std::move(callback));
28814   }
28815 }
28816 
CreateTraceWriter(BufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)28817 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriter(
28818     BufferID target_buffer,
28819     BufferExhaustedPolicy buffer_exhausted_policy) {
28820   PERFETTO_CHECK(target_buffer > 0);
28821   return CreateTraceWriterInternal(target_buffer, buffer_exhausted_policy);
28822 }
28823 
CreateStartupTraceWriter(uint16_t target_buffer_reservation_id)28824 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateStartupTraceWriter(
28825     uint16_t target_buffer_reservation_id) {
28826   PERFETTO_CHECK(!initially_bound_);
28827   return CreateTraceWriterInternal(
28828       MakeTargetBufferIdForReservation(target_buffer_reservation_id),
28829       BufferExhaustedPolicy::kDrop);
28830 }
28831 
BindToProducerEndpoint(TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)28832 void SharedMemoryArbiterImpl::BindToProducerEndpoint(
28833     TracingService::ProducerEndpoint* producer_endpoint,
28834     base::TaskRunner* task_runner) {
28835   PERFETTO_DCHECK(producer_endpoint && task_runner);
28836   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
28837   PERFETTO_CHECK(!initially_bound_);
28838 
28839   bool should_flush = false;
28840   std::function<void()> flush_callback;
28841   {
28842     std::lock_guard<std::mutex> scoped_lock(lock_);
28843     PERFETTO_CHECK(!fully_bound_);
28844     PERFETTO_CHECK(!producer_endpoint_ && !task_runner_);
28845 
28846     producer_endpoint_ = producer_endpoint;
28847     task_runner_ = task_runner;
28848 
28849     // Now that we're bound to a task runner, also reset the WeakPtrFactory to
28850     // it. Because this code runs on the task runner, the factory's weak
28851     // pointers will be valid on it.
28852     weak_ptr_factory_.Reset(this);
28853 
28854     // All writers registered so far should be startup trace writers, since
28855     // the producer cannot feasibly know the target buffer for any future
28856     // session yet.
28857     for (const auto& entry : pending_writers_) {
28858       PERFETTO_CHECK(IsReservationTargetBufferId(entry.second));
28859     }
28860 
28861     // If all buffer reservations are bound, we can flush pending commits.
28862     if (UpdateFullyBoundLocked()) {
28863       should_flush = true;
28864       flush_callback = TakePendingFlushCallbacksLocked();
28865     }
28866   }  // scoped_lock
28867 
28868   // Attempt to flush any pending commits (and run pending flush callbacks). If
28869   // there are none, this will have no effect. If we ended up in a race that
28870   // changed |fully_bound_| back to false, the commit will happen once we become
28871   // |fully_bound_| again.
28872   if (should_flush)
28873     FlushPendingCommitDataRequests(flush_callback);
28874 }
28875 
BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,BufferID target_buffer_id)28876 void SharedMemoryArbiterImpl::BindStartupTargetBuffer(
28877     uint16_t target_buffer_reservation_id,
28878     BufferID target_buffer_id) {
28879   PERFETTO_DCHECK(target_buffer_id > 0);
28880   PERFETTO_CHECK(!initially_bound_);
28881 
28882   std::unique_lock<std::mutex> scoped_lock(lock_);
28883 
28884   // We should already be bound to an endpoint, but not fully bound.
28885   PERFETTO_CHECK(!fully_bound_);
28886   PERFETTO_CHECK(producer_endpoint_);
28887   PERFETTO_CHECK(task_runner_);
28888   PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
28889 
28890   BindStartupTargetBufferImpl(std::move(scoped_lock),
28891                               target_buffer_reservation_id, target_buffer_id);
28892 }
28893 
AbortStartupTracingForReservation(uint16_t target_buffer_reservation_id)28894 void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
28895     uint16_t target_buffer_reservation_id) {
28896   PERFETTO_CHECK(!initially_bound_);
28897 
28898   std::unique_lock<std::mutex> scoped_lock(lock_);
28899 
28900   // If we are already bound to an arbiter, we may need to flush after aborting
28901   // the session, and thus should be running on the arbiter's task runner.
28902   if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
28903     // We shouldn't post tasks while locked.
28904     auto* task_runner = task_runner_;
28905     scoped_lock.unlock();
28906 
28907     auto weak_this = weak_ptr_factory_.GetWeakPtr();
28908     task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
28909       if (!weak_this)
28910         return;
28911       weak_this->AbortStartupTracingForReservation(
28912           target_buffer_reservation_id);
28913     });
28914     return;
28915   }
28916 
28917   PERFETTO_CHECK(!fully_bound_);
28918 
28919   // Bind the target buffer reservation to an invalid buffer (ID 0), so that
28920   // existing commits, as well as future commits (of currently acquired chunks),
28921   // will be released as free free by the service but otherwise ignored (i.e.
28922   // not copied into any valid target buffer).
28923   BindStartupTargetBufferImpl(std::move(scoped_lock),
28924                               target_buffer_reservation_id,
28925                               /*target_buffer_id=*/kInvalidBufferId);
28926 }
28927 
BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,uint16_t target_buffer_reservation_id,BufferID target_buffer_id)28928 void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
28929     std::unique_lock<std::mutex> scoped_lock,
28930     uint16_t target_buffer_reservation_id,
28931     BufferID target_buffer_id) {
28932   // We should already be bound to an endpoint if the target buffer is valid.
28933   PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
28934                   target_buffer_id == kInvalidBufferId);
28935 
28936   MaybeUnboundBufferID reserved_id =
28937       MakeTargetBufferIdForReservation(target_buffer_reservation_id);
28938 
28939   bool should_flush = false;
28940   std::function<void()> flush_callback;
28941   std::vector<std::pair<WriterID, BufferID>> writers_to_register;
28942 
28943   TargetBufferReservation& reservation =
28944       target_buffer_reservations_[reserved_id];
28945   PERFETTO_CHECK(!reservation.resolved);
28946   reservation.resolved = true;
28947   reservation.target_buffer = target_buffer_id;
28948 
28949   // Collect trace writers associated with the reservation.
28950   for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
28951     if (it->second == reserved_id) {
28952       // No need to register writers that have an invalid target buffer.
28953       if (target_buffer_id != kInvalidBufferId) {
28954         writers_to_register.push_back(
28955             std::make_pair(it->first, target_buffer_id));
28956       }
28957       it = pending_writers_.erase(it);
28958     } else {
28959       it++;
28960     }
28961   }
28962 
28963   // If all buffer reservations are bound, we can flush pending commits.
28964   if (UpdateFullyBoundLocked()) {
28965     should_flush = true;
28966     flush_callback = TakePendingFlushCallbacksLocked();
28967   }
28968 
28969   scoped_lock.unlock();
28970 
28971   // Register any newly bound trace writers with the service.
28972   for (const auto& writer_and_target_buffer : writers_to_register) {
28973     producer_endpoint_->RegisterTraceWriter(writer_and_target_buffer.first,
28974                                             writer_and_target_buffer.second);
28975   }
28976 
28977   // Attempt to flush any pending commits (and run pending flush callbacks). If
28978   // there are none, this will have no effect. If we ended up in a race that
28979   // changed |fully_bound_| back to false, the commit will happen once we become
28980   // |fully_bound_| again.
28981   if (should_flush)
28982     FlushPendingCommitDataRequests(flush_callback);
28983 }
28984 
28985 std::function<void()>
TakePendingFlushCallbacksLocked()28986 SharedMemoryArbiterImpl::TakePendingFlushCallbacksLocked() {
28987   if (pending_flush_callbacks_.empty())
28988     return std::function<void()>();
28989 
28990   std::vector<std::function<void()>> pending_flush_callbacks;
28991   pending_flush_callbacks.swap(pending_flush_callbacks_);
28992   // Capture the callback list into the lambda by copy.
28993   return [pending_flush_callbacks]() {
28994     for (auto& callback : pending_flush_callbacks)
28995       callback();
28996   };
28997 }
28998 
NotifyFlushComplete(FlushRequestID req_id)28999 void SharedMemoryArbiterImpl::NotifyFlushComplete(FlushRequestID req_id) {
29000   base::TaskRunner* task_runner_to_commit_on = nullptr;
29001 
29002   {
29003     std::lock_guard<std::mutex> scoped_lock(lock_);
29004     // If a commit_data_req_ exists it means that somebody else already posted a
29005     // FlushPendingCommitDataRequests() task.
29006     if (!commit_data_req_) {
29007       commit_data_req_.reset(new CommitDataRequest());
29008 
29009       // Flushing the commit is only supported while we're |fully_bound_|. If we
29010       // aren't, we'll flush when |fully_bound_| is updated.
29011       if (fully_bound_)
29012         task_runner_to_commit_on = task_runner_;
29013     } else {
29014       // If there is another request queued and that also contains is a reply
29015       // to a flush request, reply with the highest id.
29016       req_id = std::max(req_id, commit_data_req_->flush_request_id());
29017     }
29018     commit_data_req_->set_flush_request_id(req_id);
29019   }  // scoped_lock
29020 
29021   // We shouldn't post tasks while locked. |task_runner_to_commit_on|
29022   // remains valid after unlocking, because |task_runner_| is never reset.
29023   if (task_runner_to_commit_on) {
29024     auto weak_this = weak_ptr_factory_.GetWeakPtr();
29025     task_runner_to_commit_on->PostTask([weak_this] {
29026       if (weak_this)
29027         weak_this->FlushPendingCommitDataRequests();
29028     });
29029   }
29030 }
29031 
CreateTraceWriterInternal(MaybeUnboundBufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)29032 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriterInternal(
29033     MaybeUnboundBufferID target_buffer,
29034     BufferExhaustedPolicy buffer_exhausted_policy) {
29035   WriterID id;
29036   base::TaskRunner* task_runner_to_register_on = nullptr;
29037 
29038   {
29039     std::lock_guard<std::mutex> scoped_lock(lock_);
29040     id = active_writer_ids_.Allocate();
29041 
29042     if (!id)
29043       return std::unique_ptr<TraceWriter>(new NullTraceWriter());
29044 
29045     PERFETTO_DCHECK(!pending_writers_.count(id));
29046 
29047     if (IsReservationTargetBufferId(target_buffer)) {
29048       // If the reservation is new, mark it as unbound in
29049       // |target_buffer_reservations_|. Otherwise, if the reservation was
29050       // already bound, choose the bound buffer ID now.
29051       auto it_and_inserted = target_buffer_reservations_.insert(
29052           {target_buffer, TargetBufferReservation()});
29053       if (it_and_inserted.first->second.resolved)
29054         target_buffer = it_and_inserted.first->second.target_buffer;
29055     }
29056 
29057     if (IsReservationTargetBufferId(target_buffer)) {
29058       // The arbiter and/or startup buffer reservations are not bound yet, so
29059       // buffer the registration of the writer until after we're bound.
29060       pending_writers_[id] = target_buffer;
29061 
29062       // Mark the arbiter as not fully bound, since we now have at least one
29063       // unbound trace writer / target buffer reservation.
29064       fully_bound_ = false;
29065     } else if (target_buffer != kInvalidBufferId) {
29066       // Trace writer is bound, so arbiter should be bound to an endpoint, too.
29067       PERFETTO_CHECK(producer_endpoint_ && task_runner_);
29068       task_runner_to_register_on = task_runner_;
29069     }
29070   }  // scoped_lock
29071 
29072   // We shouldn't post tasks while locked. |task_runner_to_register_on|
29073   // remains valid after unlocking, because |task_runner_| is never reset.
29074   if (task_runner_to_register_on) {
29075     auto weak_this = weak_ptr_factory_.GetWeakPtr();
29076     task_runner_to_register_on->PostTask([weak_this, id, target_buffer] {
29077       if (weak_this)
29078         weak_this->producer_endpoint_->RegisterTraceWriter(id, target_buffer);
29079     });
29080   }
29081 
29082   return std::unique_ptr<TraceWriter>(
29083       new TraceWriterImpl(this, id, target_buffer, buffer_exhausted_policy));
29084 }
29085 
ReleaseWriterID(WriterID id)29086 void SharedMemoryArbiterImpl::ReleaseWriterID(WriterID id) {
29087   base::TaskRunner* task_runner = nullptr;
29088   {
29089     std::lock_guard<std::mutex> scoped_lock(lock_);
29090     active_writer_ids_.Free(id);
29091 
29092     auto it = pending_writers_.find(id);
29093     if (it != pending_writers_.end()) {
29094       // Writer hasn't been bound yet and thus also not yet registered with the
29095       // service.
29096       pending_writers_.erase(it);
29097       return;
29098     }
29099 
29100     // A trace writer from an aborted session may be destroyed before the
29101     // arbiter is bound to a task runner. In that case, it was never registered
29102     // with the service.
29103     if (!task_runner_)
29104       return;
29105 
29106     task_runner = task_runner_;
29107   }  // scoped_lock
29108 
29109   // We shouldn't post tasks while locked. |task_runner| remains valid after
29110   // unlocking, because |task_runner_| is never reset.
29111   auto weak_this = weak_ptr_factory_.GetWeakPtr();
29112   task_runner->PostTask([weak_this, id] {
29113     if (weak_this)
29114       weak_this->producer_endpoint_->UnregisterTraceWriter(id);
29115   });
29116 }
29117 
ReplaceCommitPlaceholderBufferIdsLocked()29118 bool SharedMemoryArbiterImpl::ReplaceCommitPlaceholderBufferIdsLocked() {
29119   if (!commit_data_req_)
29120     return true;
29121 
29122   bool all_placeholders_replaced = true;
29123   for (auto& chunk : *commit_data_req_->mutable_chunks_to_move()) {
29124     if (!IsReservationTargetBufferId(chunk.target_buffer()))
29125       continue;
29126     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
29127     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
29128     if (!it->second.resolved) {
29129       all_placeholders_replaced = false;
29130       continue;
29131     }
29132     chunk.set_target_buffer(it->second.target_buffer);
29133   }
29134   for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
29135     if (!IsReservationTargetBufferId(chunk.target_buffer()))
29136       continue;
29137     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
29138     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
29139     if (!it->second.resolved) {
29140       all_placeholders_replaced = false;
29141       continue;
29142     }
29143     chunk.set_target_buffer(it->second.target_buffer);
29144   }
29145   return all_placeholders_replaced;
29146 }
29147 
UpdateFullyBoundLocked()29148 bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
29149   if (!producer_endpoint_) {
29150     PERFETTO_DCHECK(!fully_bound_);
29151     return false;
29152   }
29153   // We're fully bound if all target buffer reservations have a valid associated
29154   // BufferID.
29155   fully_bound_ = std::none_of(
29156       target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
29157       [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
29158         return !entry.second.resolved;
29159       });
29160   return fully_bound_;
29161 }
29162 
29163 }  // namespace perfetto
29164 // gen_amalgamated begin source: src/tracing/core/trace_packet.cc
29165 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_packet.h
29166 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/slice.h
29167 /*
29168  * Copyright (C) 2017 The Android Open Source Project
29169  *
29170  * Licensed under the Apache License, Version 2.0 (the "License");
29171  * you may not use this file except in compliance with the License.
29172  * You may obtain a copy of the License at
29173  *
29174  *      http://www.apache.org/licenses/LICENSE-2.0
29175  *
29176  * Unless required by applicable law or agreed to in writing, software
29177  * distributed under the License is distributed on an "AS IS" BASIS,
29178  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29179  * See the License for the specific language governing permissions and
29180  * limitations under the License.
29181  */
29182 
29183 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
29184 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
29185 
29186 #include <stddef.h>
29187 #include <string.h>
29188 
29189 #include <memory>
29190 #include <string>
29191 #include <vector>
29192 
29193 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
29194 
29195 namespace perfetto {
29196 
29197 // A simple wrapper around a virtually contiguous memory range that contains a
29198 // TracePacket, or just a portion of it.
29199 struct Slice {
Sliceperfetto::Slice29200   Slice() : start(nullptr), size(0) {}
Sliceperfetto::Slice29201   Slice(const void* st, size_t sz) : start(st), size(sz) {}
29202   Slice(Slice&& other) noexcept = default;
29203 
29204   // Create a Slice which owns |size| bytes of memory.
Allocateperfetto::Slice29205   static Slice Allocate(size_t size) {
29206     Slice slice;
29207     slice.own_data_.reset(new uint8_t[size]);
29208     slice.start = &slice.own_data_[0];
29209     slice.size = size;
29210     return slice;
29211   }
29212 
own_dataperfetto::Slice29213   uint8_t* own_data() {
29214     PERFETTO_DCHECK(own_data_);
29215     return own_data_.get();
29216   }
29217 
29218   const void* start;
29219   size_t size;
29220 
29221  private:
29222   Slice(const Slice&) = delete;
29223   void operator=(const Slice&) = delete;
29224 
29225   std::unique_ptr<uint8_t[]> own_data_;
29226 };
29227 
29228 // TODO(primiano): most TracePacket(s) fit in a slice or two. We need something
29229 // a bit more clever here that has inline capacity for 2 slices and then uses a
29230 // std::forward_list or a std::vector for the less likely cases.
29231 using Slices = std::vector<Slice>;
29232 
29233 }  // namespace perfetto
29234 
29235 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
29236 /*
29237  * Copyright (C) 2017 The Android Open Source Project
29238  *
29239  * Licensed under the Apache License, Version 2.0 (the "License");
29240  * you may not use this file except in compliance with the License.
29241  * You may obtain a copy of the License at
29242  *
29243  *      http://www.apache.org/licenses/LICENSE-2.0
29244  *
29245  * Unless required by applicable law or agreed to in writing, software
29246  * distributed under the License is distributed on an "AS IS" BASIS,
29247  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29248  * See the License for the specific language governing permissions and
29249  * limitations under the License.
29250  */
29251 
29252 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
29253 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
29254 
29255 #include <stddef.h>
29256 #include <memory>
29257 #include <tuple>
29258 
29259 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29260 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
29261 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
29262 
29263 namespace perfetto {
29264 
29265 // A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
29266 // (see trace_packet.proto). The TracePacket is decoded only if the Consumer
29267 // requests that. This is to allow Consumer(s) to just stream the packet over
29268 // the network or save it to a file without wasting time decoding it and without
29269 // needing to depend on libprotobuf or the trace_packet.pb.h header.
29270 // If the packets are saved / streamed and not just consumed locally, consumers
29271 // should ensure to preserve the unknown fields in the proto. A consumer, in
29272 // fact, might have an older version .proto which is newer on the producer.
29273 class PERFETTO_EXPORT TracePacket {
29274  public:
29275   using const_iterator = Slices::const_iterator;
29276 
29277   // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
29278   static constexpr uint32_t kPacketFieldNumber = 1;
29279 
29280   // Maximum size of the preamble returned by GetProtoPreamble().
29281   static constexpr size_t kMaxPreambleBytes = 8;
29282 
29283   TracePacket();
29284   ~TracePacket();
29285   TracePacket(TracePacket&&) noexcept;
29286   TracePacket& operator=(TracePacket&&);
29287 
29288   // Accesses all the raw slices in the packet, for saving them to file/network.
slices() const29289   const Slices& slices() const { return slices_; }
29290 
29291   // Mutator, used only by the service and tests.
29292   void AddSlice(Slice);
29293 
29294   // Does not copy / take ownership of the memory of the slice. The TracePacket
29295   // will be valid only as long as the original buffer is valid.
29296   void AddSlice(const void* start, size_t size);
29297 
29298   // Total size of all slices.
size() const29299   size_t size() const { return size_; }
29300 
29301   // Generates a protobuf preamble suitable to represent this packet as a
29302   // repeated field within a root trace.proto message.
29303   // Returns a pointer to a buffer, owned by this class, containing the preamble
29304   // and its size.
29305   std::tuple<char*, size_t> GetProtoPreamble();
29306 
29307   // Returns the raw protobuf bytes of the slices, all stitched together into
29308   // a string. Only for testing.
29309   std::string GetRawBytesForTesting();
29310 
29311  private:
29312   TracePacket(const TracePacket&) = delete;
29313   TracePacket& operator=(const TracePacket&) = delete;
29314 
29315   Slices slices_;     // Not owned.
29316   size_t size_ = 0;   // SUM(slice.size for slice in slices_).
29317   char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.
29318 
29319   // Remember to update the move operators and their unittest if adding new
29320   // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
29321   // std::move(TracePacket) to clear up the moved-from instance.
29322 };
29323 
29324 }  // namespace perfetto
29325 
29326 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
29327 /*
29328  * Copyright (C) 2017 The Android Open Source Project
29329  *
29330  * Licensed under the Apache License, Version 2.0 (the "License");
29331  * you may not use this file except in compliance with the License.
29332  * You may obtain a copy of the License at
29333  *
29334  *      http://www.apache.org/licenses/LICENSE-2.0
29335  *
29336  * Unless required by applicable law or agreed to in writing, software
29337  * distributed under the License is distributed on an "AS IS" BASIS,
29338  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29339  * See the License for the specific language governing permissions and
29340  * limitations under the License.
29341  */
29342 
29343 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
29344 
29345 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
29346 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
29347 
29348 namespace perfetto {
29349 
29350 TracePacket::TracePacket() = default;
29351 TracePacket::~TracePacket() = default;
29352 
TracePacket(TracePacket && other)29353 TracePacket::TracePacket(TracePacket&& other) noexcept {
29354   *this = std::move(other);
29355 }
29356 
operator =(TracePacket && other)29357 TracePacket& TracePacket::operator=(TracePacket&& other) {
29358   slices_ = std::move(other.slices_);
29359   other.slices_.clear();
29360   size_ = other.size_;
29361   other.size_ = 0;
29362   return *this;
29363 }
29364 
AddSlice(Slice slice)29365 void TracePacket::AddSlice(Slice slice) {
29366   size_ += slice.size;
29367   slices_.push_back(std::move(slice));
29368 }
29369 
AddSlice(const void * start,size_t size)29370 void TracePacket::AddSlice(const void* start, size_t size) {
29371   size_ += size;
29372   slices_.emplace_back(start, size);
29373 }
29374 
GetProtoPreamble()29375 std::tuple<char*, size_t> TracePacket::GetProtoPreamble() {
29376   using protozero::proto_utils::MakeTagLengthDelimited;
29377   using protozero::proto_utils::WriteVarInt;
29378   uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble_[0]);
29379 
29380   constexpr uint8_t tag = MakeTagLengthDelimited(kPacketFieldNumber);
29381   static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
29382   *(ptr++) = tag;
29383 
29384   ptr = WriteVarInt(size(), ptr);
29385   size_t preamble_size = reinterpret_cast<uintptr_t>(ptr) -
29386                          reinterpret_cast<uintptr_t>(&preamble_[0]);
29387   PERFETTO_DCHECK(preamble_size <= sizeof(preamble_));
29388   return std::make_tuple(&preamble_[0], preamble_size);
29389 }
29390 
GetRawBytesForTesting()29391 std::string TracePacket::GetRawBytesForTesting() {
29392   std::string data;
29393   data.resize(size());
29394   size_t pos = 0;
29395   for (const Slice& slice : slices()) {
29396     PERFETTO_CHECK(pos + slice.size <= data.size());
29397     memcpy(&data[pos], slice.start, slice.size);
29398     pos += slice.size;
29399   }
29400   return data;
29401 }
29402 
29403 }  // namespace perfetto
29404 // gen_amalgamated begin source: src/tracing/core/trace_writer_impl.cc
29405 /*
29406  * Copyright (C) 2017 The Android Open Source Project
29407  *
29408  * Licensed under the Apache License, Version 2.0 (the "License");
29409  * you may not use this file except in compliance with the License.
29410  * You may obtain a copy of the License at
29411  *
29412  *      http://www.apache.org/licenses/LICENSE-2.0
29413  *
29414  * Unless required by applicable law or agreed to in writing, software
29415  * distributed under the License is distributed on an "AS IS" BASIS,
29416  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29417  * See the License for the specific language governing permissions and
29418  * limitations under the License.
29419  */
29420 
29421 // gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
29422 
29423 #include <string.h>
29424 
29425 #include <algorithm>
29426 #include <type_traits>
29427 #include <utility>
29428 
29429 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
29430 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
29431 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29432 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
29433 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
29434 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
29435 
29436 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
29437 
29438 using protozero::proto_utils::kMessageLengthFieldSize;
29439 using protozero::proto_utils::WriteRedundantVarInt;
29440 using ChunkHeader = perfetto::SharedMemoryABI::ChunkHeader;
29441 
29442 namespace perfetto {
29443 
29444 namespace {
29445 constexpr size_t kPacketHeaderSize = SharedMemoryABI::kPacketHeaderSize;
29446 uint8_t g_garbage_chunk[1024];
29447 }  // namespace
29448 
TraceWriterImpl(SharedMemoryArbiterImpl * shmem_arbiter,WriterID id,MaybeUnboundBufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)29449 TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
29450                                  WriterID id,
29451                                  MaybeUnboundBufferID target_buffer,
29452                                  BufferExhaustedPolicy buffer_exhausted_policy)
29453     : shmem_arbiter_(shmem_arbiter),
29454       id_(id),
29455       target_buffer_(target_buffer),
29456       buffer_exhausted_policy_(buffer_exhausted_policy),
29457       protobuf_stream_writer_(this),
29458       process_id_(base::GetProcessId()) {
29459   // TODO(primiano): we could handle the case of running out of TraceWriterID(s)
29460   // more gracefully and always return a no-op TracePacket in NewTracePacket().
29461   PERFETTO_CHECK(id_ != 0);
29462 
29463   cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
29464   cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
29465 }
29466 
~TraceWriterImpl()29467 TraceWriterImpl::~TraceWriterImpl() {
29468   if (cur_chunk_.is_valid()) {
29469     cur_packet_->Finalize();
29470     Flush();
29471   }
29472   shmem_arbiter_->ReleaseWriterID(id_);
29473 }
29474 
Flush(std::function<void ()> callback)29475 void TraceWriterImpl::Flush(std::function<void()> callback) {
29476   // Flush() cannot be called in the middle of a TracePacket.
29477   PERFETTO_CHECK(cur_packet_->is_finalized());
29478 
29479   if (cur_chunk_.is_valid()) {
29480     shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
29481                                          &patch_list_);
29482   } else {
29483     PERFETTO_DCHECK(patch_list_.empty());
29484   }
29485   // Always issue the Flush request, even if there is nothing to flush, just
29486   // for the sake of getting the callback posted back.
29487   shmem_arbiter_->FlushPendingCommitDataRequests(callback);
29488   protobuf_stream_writer_.Reset({nullptr, nullptr});
29489 
29490   // |last_packet_size_field_| might have pointed into the chunk we returned.
29491   last_packet_size_field_ = nullptr;
29492 }
29493 
NewTracePacket()29494 TraceWriterImpl::TracePacketHandle TraceWriterImpl::NewTracePacket() {
29495   // If we hit this, the caller is calling NewTracePacket() without having
29496   // finalized the previous packet.
29497   PERFETTO_CHECK(cur_packet_->is_finalized());
29498   // If we hit this, this trace writer was created in a different process. This
29499   // likely means that the process forked while tracing was active, and the
29500   // forked child process tried to emit a trace event. This is not supported, as
29501   // it would lead to two processes writing to the same tracing SMB.
29502   PERFETTO_DCHECK(process_id_ == base::GetProcessId());
29503 
29504   fragmenting_packet_ = false;
29505 
29506   // Reserve space for the size of the message. Note: this call might re-enter
29507   // into this class invoking GetNewBuffer() if there isn't enough space or if
29508   // this is the very first call to NewTracePacket().
29509   static_assert(kPacketHeaderSize == kMessageLengthFieldSize,
29510                 "The packet header must match the Message header size");
29511 
29512   bool was_dropping_packets = drop_packets_;
29513 
29514   // It doesn't make sense to begin a packet that is going to fragment
29515   // immediately after (8 is just an arbitrary estimation on the minimum size of
29516   // a realistic packet).
29517   bool chunk_too_full =
29518       protobuf_stream_writer_.bytes_available() < kPacketHeaderSize + 8;
29519   if (chunk_too_full || reached_max_packets_per_chunk_ ||
29520       retry_new_chunk_after_packet_) {
29521     protobuf_stream_writer_.Reset(GetNewBuffer());
29522   }
29523 
29524   // Send any completed patches to the service to facilitate trace data
29525   // recovery by the service. This should only happen when we're completing
29526   // the first packet in a chunk which was a continuation from the previous
29527   // chunk, i.e. at most once per chunk.
29528   if (!patch_list_.empty() && patch_list_.front().is_patched()) {
29529     shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
29530   }
29531 
29532   cur_packet_->Reset(&protobuf_stream_writer_);
29533   uint8_t* header = protobuf_stream_writer_.ReserveBytes(kPacketHeaderSize);
29534   memset(header, 0, kPacketHeaderSize);
29535   cur_packet_->set_size_field(header);
29536   last_packet_size_field_ = header;
29537 
29538   TracePacketHandle handle(cur_packet_.get());
29539   cur_fragment_start_ = protobuf_stream_writer_.write_ptr();
29540   fragmenting_packet_ = true;
29541 
29542   if (PERFETTO_LIKELY(!drop_packets_)) {
29543     uint16_t new_packet_count = cur_chunk_.IncrementPacketCount();
29544     reached_max_packets_per_chunk_ =
29545         new_packet_count == ChunkHeader::Packets::kMaxCount;
29546 
29547     if (PERFETTO_UNLIKELY(was_dropping_packets)) {
29548       // We've succeeded to get a new chunk from the SMB after we entered
29549       // drop_packets_ mode. Record a marker into the new packet to indicate the
29550       // data loss.
29551       cur_packet_->set_previous_packet_dropped(true);
29552     }
29553   }
29554 
29555   return handle;
29556 }
29557 
29558 // Called by the Message. We can get here in two cases:
29559 // 1. In the middle of writing a Message,
29560 // when |fragmenting_packet_| == true. In this case we want to update the
29561 // chunk header with a partial packet and start a new partial packet in the
29562 // new chunk.
29563 // 2. While calling ReserveBytes() for the packet header in NewTracePacket().
29564 // In this case |fragmenting_packet_| == false and we just want a new chunk
29565 // without creating any fragments.
GetNewBuffer()29566 protozero::ContiguousMemoryRange TraceWriterImpl::GetNewBuffer() {
29567   if (fragmenting_packet_ && drop_packets_) {
29568     // We can't write the remaining data of the fragmenting packet to a new
29569     // chunk, because we have already lost some of its data in the garbage
29570     // chunk. Thus, we will wrap around in the garbage chunk, wait until the
29571     // current packet was completed, and then attempt to get a new chunk from
29572     // the SMB again. Instead, if |drop_packets_| is true and
29573     // |fragmenting_packet_| is false, we try to acquire a valid chunk because
29574     // the SMB exhaustion might be resolved.
29575     retry_new_chunk_after_packet_ = true;
29576     return protozero::ContiguousMemoryRange{
29577         &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
29578   }
29579 
29580   // Attempt to grab the next chunk before finalizing the current one, so that
29581   // we know whether we need to start dropping packets before writing the
29582   // current packet fragment's header.
29583   ChunkHeader::Packets packets = {};
29584   if (fragmenting_packet_) {
29585     packets.count = 1;
29586     packets.flags = ChunkHeader::kFirstPacketContinuesFromPrevChunk;
29587   }
29588 
29589   // The memory order of the stores below doesn't really matter. This |header|
29590   // is just a local temporary object. The GetNewChunk() call below will copy it
29591   // into the shared buffer with the proper barriers.
29592   ChunkHeader header = {};
29593   header.writer_id.store(id_, std::memory_order_relaxed);
29594   header.chunk_id.store(next_chunk_id_, std::memory_order_relaxed);
29595   header.packets.store(packets, std::memory_order_relaxed);
29596 
29597   SharedMemoryABI::Chunk new_chunk =
29598       shmem_arbiter_->GetNewChunk(header, buffer_exhausted_policy_);
29599   if (!new_chunk.is_valid()) {
29600     // Shared memory buffer exhausted, switch into |drop_packets_| mode. We'll
29601     // drop data until the garbage chunk has been filled once and then retry.
29602 
29603     // If we started a packet in one of the previous (valid) chunks, we need to
29604     // tell the service to discard it.
29605     if (fragmenting_packet_) {
29606       // We can only end up here if the previous chunk was a valid chunk,
29607       // because we never try to acquire a new chunk in |drop_packets_| mode
29608       // while fragmenting.
29609       PERFETTO_DCHECK(!drop_packets_);
29610 
29611       // Backfill the last fragment's header with an invalid size (too large),
29612       // so that the service's TraceBuffer throws out the incomplete packet.
29613       // It'll restart reading from the next chunk we submit.
29614       WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
29615                            cur_packet_->size_field());
29616 
29617       // Reset the size field, since we should not write the current packet's
29618       // size anymore after this.
29619       cur_packet_->set_size_field(nullptr);
29620 
29621       // We don't set kLastPacketContinuesOnNextChunk or kChunkNeedsPatching on
29622       // the last chunk, because its last fragment will be discarded anyway.
29623       // However, the current packet fragment points to a valid |cur_chunk_| and
29624       // may have non-finalized nested messages which will continue in the
29625       // garbage chunk and currently still point into |cur_chunk_|. As we are
29626       // about to return |cur_chunk_|, we need to invalidate the size fields of
29627       // those nested messages. Normally we move them in the |patch_list_| (see
29628       // below) but in this case, it doesn't make sense to send patches for a
29629       // fragment that will be discarded for sure. Thus, we clean up any size
29630       // field references into |cur_chunk_|.
29631       for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
29632            nested_msg = nested_msg->nested_message()) {
29633         uint8_t* const cur_hdr = nested_msg->size_field();
29634 
29635         // If this is false the protozero Message has already been instructed to
29636         // write, upon Finalize(), its size into the patch list.
29637         bool size_field_points_within_chunk =
29638             cur_hdr >= cur_chunk_.payload_begin() &&
29639             cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
29640 
29641         if (size_field_points_within_chunk)
29642           nested_msg->set_size_field(nullptr);
29643       }
29644     } else if (!drop_packets_ && last_packet_size_field_) {
29645       // If we weren't dropping packets before, we should indicate to the
29646       // service that we're about to lose data. We do this by invalidating the
29647       // size of the last packet in |cur_chunk_|. The service will record
29648       // statistics about packets with kPacketSizeDropPacket size.
29649       PERFETTO_DCHECK(cur_packet_->is_finalized());
29650       PERFETTO_DCHECK(cur_chunk_.is_valid());
29651 
29652       // |last_packet_size_field_| should point within |cur_chunk_|'s payload.
29653       PERFETTO_DCHECK(last_packet_size_field_ >= cur_chunk_.payload_begin() &&
29654                       last_packet_size_field_ + kMessageLengthFieldSize <=
29655                           cur_chunk_.end());
29656 
29657       WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
29658                            last_packet_size_field_);
29659     }
29660 
29661     if (cur_chunk_.is_valid()) {
29662       shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_),
29663                                            target_buffer_, &patch_list_);
29664     }
29665 
29666     drop_packets_ = true;
29667     cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
29668     reached_max_packets_per_chunk_ = false;
29669     retry_new_chunk_after_packet_ = false;
29670     last_packet_size_field_ = nullptr;
29671 
29672     PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_garbage_chunk,
29673                                         sizeof(g_garbage_chunk),
29674                                         "nobody reads the garbage chunk")
29675     return protozero::ContiguousMemoryRange{
29676         &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
29677   }  // if (!new_chunk.is_valid())
29678 
29679   PERFETTO_DCHECK(new_chunk.is_valid());
29680 
29681   if (fragmenting_packet_) {
29682     // We should not be fragmenting a packet after we exited drop_packets_ mode,
29683     // because we only retry to get a new chunk when a fresh packet is started.
29684     PERFETTO_DCHECK(!drop_packets_);
29685 
29686     uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
29687     PERFETTO_DCHECK(wptr >= cur_fragment_start_);
29688     uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
29689     PERFETTO_DCHECK(partial_size < cur_chunk_.size());
29690 
29691     // Backfill the packet header with the fragment size.
29692     PERFETTO_DCHECK(partial_size > 0);
29693     cur_packet_->inc_size_already_written(partial_size);
29694     cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
29695     WriteRedundantVarInt(partial_size, cur_packet_->size_field());
29696 
29697     // Descend in the stack of non-finalized nested submessages (if any) and
29698     // detour their |size_field| into the |patch_list_|. At this point we have
29699     // to release the chunk and they cannot write anymore into that.
29700     // TODO(primiano): add tests to cover this logic.
29701     bool chunk_needs_patching = false;
29702     for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
29703          nested_msg = nested_msg->nested_message()) {
29704       uint8_t* const cur_hdr = nested_msg->size_field();
29705 
29706       // If this is false the protozero Message has already been instructed to
29707       // write, upon Finalize(), its size into the patch list.
29708       bool size_field_points_within_chunk =
29709           cur_hdr >= cur_chunk_.payload_begin() &&
29710           cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
29711 
29712       if (size_field_points_within_chunk) {
29713         auto offset =
29714             static_cast<uint16_t>(cur_hdr - cur_chunk_.payload_begin());
29715         const ChunkID cur_chunk_id =
29716             cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
29717         Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
29718         nested_msg->set_size_field(&patch->size_field[0]);
29719         chunk_needs_patching = true;
29720       } else {
29721 #if PERFETTO_DCHECK_IS_ON()
29722         // Ensure that the size field of the message points to an element of the
29723         // patch list.
29724         auto patch_it = std::find_if(
29725             patch_list_.begin(), patch_list_.end(),
29726             [cur_hdr](const Patch& p) { return &p.size_field[0] == cur_hdr; });
29727         PERFETTO_DCHECK(patch_it != patch_list_.end());
29728 #endif
29729       }
29730     }  // for(nested_msg
29731 
29732     if (chunk_needs_patching)
29733       cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
29734   }  // if(fragmenting_packet)
29735 
29736   if (cur_chunk_.is_valid()) {
29737     // ReturnCompletedChunk will consume the first patched entries from
29738     // |patch_list_| and shrink it.
29739     shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
29740                                          &patch_list_);
29741   }
29742 
29743   // Switch to the new chunk.
29744   drop_packets_ = false;
29745   reached_max_packets_per_chunk_ = false;
29746   retry_new_chunk_after_packet_ = false;
29747   next_chunk_id_++;
29748   cur_chunk_ = std::move(new_chunk);
29749   last_packet_size_field_ = nullptr;
29750 
29751   uint8_t* payload_begin = cur_chunk_.payload_begin();
29752   if (fragmenting_packet_) {
29753     cur_packet_->set_size_field(payload_begin);
29754     last_packet_size_field_ = payload_begin;
29755     memset(payload_begin, 0, kPacketHeaderSize);
29756     payload_begin += kPacketHeaderSize;
29757     cur_fragment_start_ = payload_begin;
29758   }
29759 
29760   return protozero::ContiguousMemoryRange{payload_begin, cur_chunk_.end()};
29761 }
29762 
writer_id() const29763 WriterID TraceWriterImpl::writer_id() const {
29764   return id_;
29765 }
29766 
29767 // Base class definitions.
29768 TraceWriter::TraceWriter() = default;
29769 TraceWriter::~TraceWriter() = default;
29770 
29771 }  // namespace perfetto
29772 // gen_amalgamated begin source: src/tracing/core/virtual_destructors.cc
29773 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/consumer.h
29774 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/observable_events.h
29775 /*
29776  * Copyright (C) 2017 The Android Open Source Project
29777  *
29778  * Licensed under the Apache License, Version 2.0 (the "License");
29779  * you may not use this file except in compliance with the License.
29780  * You may obtain a copy of the License at
29781  *
29782  *      http://www.apache.org/licenses/LICENSE-2.0
29783  *
29784  * Unless required by applicable law or agreed to in writing, software
29785  * distributed under the License is distributed on an "AS IS" BASIS,
29786  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29787  * See the License for the specific language governing permissions and
29788  * limitations under the License.
29789  */
29790 
29791 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
29792 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
29793 
29794 // Creates the aliases in the ::perfetto namespace, doing things like:
29795 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
29796 // See comments in forward_decls.h for the historical reasons of this
29797 // indirection layer.
29798 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
29799 
29800 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
29801 
29802 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
29803 /*
29804  * Copyright (C) 2017 The Android Open Source Project
29805  *
29806  * Licensed under the Apache License, Version 2.0 (the "License");
29807  * you may not use this file except in compliance with the License.
29808  * You may obtain a copy of the License at
29809  *
29810  *      http://www.apache.org/licenses/LICENSE-2.0
29811  *
29812  * Unless required by applicable law or agreed to in writing, software
29813  * distributed under the License is distributed on an "AS IS" BASIS,
29814  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29815  * See the License for the specific language governing permissions and
29816  * limitations under the License.
29817  */
29818 
29819 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
29820 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
29821 
29822 #include <vector>
29823 
29824 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29825 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
29826 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
29827 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
29828 namespace perfetto {
29829 
29830 class TracePacket;
29831 
29832 class PERFETTO_EXPORT Consumer {
29833  public:
29834   virtual ~Consumer();
29835 
29836   // Called by Service (or more typically by the transport layer, on behalf of
29837   // the remote Service), once the Consumer <> Service connection has been
29838   // established.
29839   virtual void OnConnect() = 0;
29840 
29841   // Called by the Service or by the transport layer if the connection with the
29842   // service drops, either voluntarily (e.g., by destroying the ConsumerEndpoint
29843   // obtained through Service::ConnectConsumer()) or involuntarily (e.g., if the
29844   // Service process crashes).
29845   virtual void OnDisconnect() = 0;
29846 
29847   // Called by the Service after the tracing session has ended. This can happen
29848   // for a variety of reasons:
29849   // - The consumer explicitly called DisableTracing()
29850   // - The TraceConfig's |duration_ms| has been reached.
29851   // - The TraceConfig's |max_file_size_bytes| has been reached.
29852   // - An error occurred while trying to enable tracing.
29853   virtual void OnTracingDisabled() = 0;
29854 
29855   // Called back by the Service (or transport layer) after invoking
29856   // TracingService::ConsumerEndpoint::ReadBuffers(). This function can be
29857   // called more than once. Each invocation can carry one or more
29858   // TracePacket(s). Upon the last call, |has_more| is set to true (i.e.
29859   // |has_more| is a !EOF).
29860   virtual void OnTraceData(std::vector<TracePacket>, bool has_more) = 0;
29861 
29862   // Called back by the Service (or transport layer) after invoking
29863   // TracingService::ConsumerEndpoint::Detach().
29864   // The consumer can disconnect at this point and the trace session will keep
29865   // on going. A new consumer can later re-attach passing back the same |key|
29866   // passed to Detach(), but only if the two requests come from the same uid.
29867   virtual void OnDetach(bool success) = 0;
29868 
29869   // Called back by the Service (or transport layer) after invoking
29870   // TracingService::ConsumerEndpoint::Attach().
29871   virtual void OnAttach(bool success, const TraceConfig&) = 0;
29872 
29873   // Called back by the Service (or transport layer) after invoking
29874   // TracingService::ConsumerEndpoint::GetTraceStats().
29875   virtual void OnTraceStats(bool success, const TraceStats&) = 0;
29876 
29877   // Called back by the Service (or transport layer) after invoking
29878   // TracingService::ConsumerEndpoint::ObserveEvents() whenever one or more
29879   // ObservableEvents of enabled event types occur.
29880   virtual void OnObservableEvents(const ObservableEvents&) = 0;
29881 };
29882 
29883 }  // namespace perfetto
29884 
29885 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
29886 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/producer.h
29887 /*
29888  * Copyright (C) 2017 The Android Open Source Project
29889  *
29890  * Licensed under the Apache License, Version 2.0 (the "License");
29891  * you may not use this file except in compliance with the License.
29892  * You may obtain a copy of the License at
29893  *
29894  *      http://www.apache.org/licenses/LICENSE-2.0
29895  *
29896  * Unless required by applicable law or agreed to in writing, software
29897  * distributed under the License is distributed on an "AS IS" BASIS,
29898  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29899  * See the License for the specific language governing permissions and
29900  * limitations under the License.
29901  */
29902 
29903 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
29904 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
29905 
29906 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29907 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
29908 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
29909 namespace perfetto {
29910 
29911 class SharedMemory;
29912 
29913 // A Producer is an entity that connects to the write-only port of the Service
29914 // and exposes the ability to produce performance data on-demand. The lifecycle
29915 // of a Producer is as follows:
29916 // 1. The producer connects to the service and advertises its data sources
29917 //    (e.g., the ability to get kernel ftraces, to list process stats).
29918 // 2. The service acknowledges the connection and sends over the SharedMemory
29919 //    region that will be used to exchange data (together with the signalling
29920 //    API TracingService::ProducerEndpoint::OnPageAcquired()/OnPageReleased()).
29921 // 3. At some point later on, the Service asks the Producer to turn on some of
29922 //    the previously registered data sources, together with some configuration
29923 //    parameters. This happens via the StartDataSource() callback.
29924 // 4. In response to that the Producer will spawn an instance of the given data
29925 //    source and inject its data into the shared memory buffer (obtained during
29926 //    OnConnect).
29927 // This interface is subclassed by:
29928 //  1. The actual producer code in the clients e.g., the ftrace reader process.
29929 //  2. The transport layer when interposing RPC between service and producers.
29930 class PERFETTO_EXPORT Producer {
29931  public:
29932   virtual ~Producer();
29933 
29934   // Called by Service (or more typically by the transport layer, on behalf of
29935   // the remote Service), once the Producer <> Service connection has been
29936   // established.
29937   virtual void OnConnect() = 0;
29938 
29939   // Called by the Service or by the transport layer if the connection with the
29940   // service drops, either voluntarily (e.g., by destroying the ProducerEndpoint
29941   // obtained through Service::ConnectProducer()) or involuntarily (e.g., if the
29942   // Service process crashes).
29943   // The Producer is expected to tear down all its data sources if this happens.
29944   // Once this call returns it is possible to safely destroy the Producer
29945   // instance.
29946   virtual void OnDisconnect() = 0;
29947 
29948   // Called by the Service after OnConnect but before the first DataSource is
29949   // created. Can be used for any setup required before tracing begins.
29950   virtual void OnTracingSetup() = 0;
29951 
29952   // The lifecycle methods below are always called in the following sequence:
29953   // SetupDataSource  -> StartDataSource -> StopDataSource.
29954   // Or, in the edge case where a trace is aborted immediately:
29955   // SetupDataSource  -> StopDataSource.
29956   // The Setup+Start call sequence is always guaranateed, regardless of the
29957   // TraceConfig.deferred_start flags.
29958   // Called by the Service to configure one of the data sources previously
29959   // registered through TracingService::ProducerEndpoint::RegisterDataSource().
29960   // This method is always called before StartDataSource. There is always a
29961   // SetupDataSource() call before each StartDataSource() call.
29962   // Args:
29963   // - DataSourceInstanceID is an identifier chosen by the Service that should
29964   //   be assigned to the newly created data source instance. It is used to
29965   //   match the StopDataSource() request below.
29966   // - DataSourceConfig is the configuration for the new data source (e.g.,
29967   //   tells which trace categories to enable).
29968   virtual void SetupDataSource(DataSourceInstanceID,
29969                                const DataSourceConfig&) = 0;
29970 
29971   // Called by the Service to turn on one of the data sources previously
29972   // registered through TracingService::ProducerEndpoint::RegisterDataSource()
29973   // and initialized through SetupDataSource().
29974   // Both arguments are guaranteed to be identical to the ones passed to the
29975   // prior SetupDataSource() call.
29976   virtual void StartDataSource(DataSourceInstanceID,
29977                                const DataSourceConfig&) = 0;
29978 
29979   // Called by the Service to shut down an existing data source instance.
29980   virtual void StopDataSource(DataSourceInstanceID) = 0;
29981 
29982   // Called by the service to request the Producer to commit the data of the
29983   // given data sources and return their chunks into the shared memory buffer.
29984   // The Producer is expected to invoke NotifyFlushComplete(FlushRequestID) on
29985   // the Service after the data has been committed. The producer has to either
29986   // reply to the flush requests in order, or can just reply to the latest one
29987   // Upon seeing a NotifyFlushComplete(N), the service will assume that all
29988   // flushes < N have also been committed.
29989   virtual void Flush(FlushRequestID,
29990                      const DataSourceInstanceID* data_source_ids,
29991                      size_t num_data_sources) = 0;
29992 
29993   // Called by the service to instruct the given data sources to stop referring
29994   // to any trace contents emitted so far. The intent is that after processing
29995   // this call, the rest of the trace should be parsable even if all of the
29996   // packets emitted so far have been lost (for example due to ring buffer
29997   // overwrites).
29998   //
29999   // Called only for Producers with active data sources that have opted in by
30000   // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
30001   //
30002   // The way this call is handled is up to the individual Producer
30003   // implementation. Some might wish to emit invalidation markers in the trace
30004   // (see TracePacket.incremental_state_cleared for an existing field), and
30005   // handle them when parsing the trace.
30006   virtual void ClearIncrementalState(
30007       const DataSourceInstanceID* data_source_ids,
30008       size_t num_data_sources) = 0;
30009 };
30010 
30011 }  // namespace perfetto
30012 
30013 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
30014 /*
30015  * Copyright (C) 2018 The Android Open Source Project
30016  *
30017  * Licensed under the Apache License, Version 2.0 (the "License");
30018  * you may not use this file except in compliance with the License.
30019  * You may obtain a copy of the License at
30020  *
30021  *      http://www.apache.org/licenses/LICENSE-2.0
30022  *
30023  * Unless required by applicable law or agreed to in writing, software
30024  * distributed under the License is distributed on an "AS IS" BASIS,
30025  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30026  * See the License for the specific language governing permissions and
30027  * limitations under the License.
30028  */
30029 
30030 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
30031 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
30032 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
30033 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
30034 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
30035 
30036 // This translation unit contains the definitions for the destructor of pure
30037 // virtual interfaces for the current build target. The alternative would be
30038 // introducing a one-liner .cc file for each pure virtual interface, which is
30039 // overkill. This is for compliance with -Wweak-vtables.
30040 
30041 namespace perfetto {
30042 
30043 Consumer::~Consumer() = default;
30044 Producer::~Producer() = default;
30045 TracingService::~TracingService() = default;
30046 ConsumerEndpoint::~ConsumerEndpoint() = default;
30047 ProducerEndpoint::~ProducerEndpoint() = default;
30048 SharedMemory::~SharedMemory() = default;
30049 SharedMemory::Factory::~Factory() = default;
30050 SharedMemoryArbiter::~SharedMemoryArbiter() = default;
30051 
30052 }  // namespace perfetto
30053 // gen_amalgamated begin source: src/tracing/data_source.cc
30054 /*
30055  * Copyright (C) 2019 The Android Open Source Project
30056  *
30057  * Licensed under the Apache License, Version 2.0 (the "License");
30058  * you may not use this file except in compliance with the License.
30059  * You may obtain a copy of the License at
30060  *
30061  *      http://www.apache.org/licenses/LICENSE-2.0
30062  *
30063  * Unless required by applicable law or agreed to in writing, software
30064  * distributed under the License is distributed on an "AS IS" BASIS,
30065  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30066  * See the License for the specific language governing permissions and
30067  * limitations under the License.
30068  */
30069 
30070 // gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
30071 
30072 namespace perfetto {
30073 
30074 DataSourceBase::StopArgs::~StopArgs() = default;
30075 DataSourceBase::~DataSourceBase() = default;
OnSetup(const SetupArgs &)30076 void DataSourceBase::OnSetup(const SetupArgs&) {}
OnStart(const StartArgs &)30077 void DataSourceBase::OnStart(const StartArgs&) {}
OnStop(const StopArgs &)30078 void DataSourceBase::OnStop(const StopArgs&) {}
30079 
30080 }  // namespace perfetto
30081 // gen_amalgamated begin source: src/tracing/debug_annotation.cc
30082 /*
30083  * Copyright (C) 2019 The Android Open Source Project
30084  *
30085  * Licensed under the Apache License, Version 2.0 (the "License");
30086  * you may not use this file except in compliance with the License.
30087  * You may obtain a copy of the License at
30088  *
30089  *      http://www.apache.org/licenses/LICENSE-2.0
30090  *
30091  * Unless required by applicable law or agreed to in writing, software
30092  * distributed under the License is distributed on an "AS IS" BASIS,
30093  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30094  * See the License for the specific language governing permissions and
30095  * limitations under the License.
30096  */
30097 
30098 // gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
30099 
30100 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
30101 
30102 namespace perfetto {
30103 
30104 DebugAnnotation::~DebugAnnotation() = default;
30105 
30106 namespace internal {
30107 
WriteDebugAnnotation(protos::pbzero::DebugAnnotation * annotation,const char * value)30108 void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
30109                           const char* value) {
30110   annotation->set_string_value(value);
30111 }
30112 
WriteDebugAnnotation(protos::pbzero::DebugAnnotation * annotation,const std::string & value)30113 void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
30114                           const std::string& value) {
30115   annotation->set_string_value(value);
30116 }
30117 
WriteDebugAnnotation(protos::pbzero::DebugAnnotation * annotation,const void * value)30118 void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
30119                           const void* value) {
30120   annotation->set_pointer_value(reinterpret_cast<uint64_t>(value));
30121 }
30122 
WriteDebugAnnotation(protos::pbzero::DebugAnnotation * annotation,const DebugAnnotation & custom_annotation)30123 void WriteDebugAnnotation(protos::pbzero::DebugAnnotation* annotation,
30124                           const DebugAnnotation& custom_annotation) {
30125   custom_annotation.Add(annotation);
30126 }
30127 
30128 }  // namespace internal
30129 }  // namespace perfetto
30130 // gen_amalgamated begin source: src/tracing/event_context.cc
30131 /*
30132  * Copyright (C) 2019 The Android Open Source Project
30133  *
30134  * Licensed under the Apache License, Version 2.0 (the "License");
30135  * you may not use this file except in compliance with the License.
30136  * You may obtain a copy of the License at
30137  *
30138  *      http://www.apache.org/licenses/LICENSE-2.0
30139  *
30140  * Unless required by applicable law or agreed to in writing, software
30141  * distributed under the License is distributed on an "AS IS" BASIS,
30142  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30143  * See the License for the specific language governing permissions and
30144  * limitations under the License.
30145  */
30146 
30147 // gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
30148 
30149 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
30150 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
30151 
30152 namespace perfetto {
30153 
EventContext(EventContext::TracePacketHandle trace_packet,internal::TrackEventIncrementalState * incremental_state)30154 EventContext::EventContext(
30155     EventContext::TracePacketHandle trace_packet,
30156     internal::TrackEventIncrementalState* incremental_state)
30157     : trace_packet_(std::move(trace_packet)),
30158       event_(trace_packet_->set_track_event()),
30159       incremental_state_(incremental_state) {}
30160 
~EventContext()30161 EventContext::~EventContext() {
30162   if (!trace_packet_)
30163     return;
30164 
30165   // When the track event is finalized (i.e., the context is destroyed), we
30166   // should flush any newly seen interned data to the trace. The data has
30167   // earlier been written to a heap allocated protobuf message
30168   // (|serialized_interned_data|). Here we just need to flush it to the main
30169   // trace.
30170   auto& serialized_interned_data = incremental_state_->serialized_interned_data;
30171   if (PERFETTO_LIKELY(serialized_interned_data.empty()))
30172     return;
30173 
30174   auto ranges = serialized_interned_data.GetRanges();
30175   trace_packet_->AppendScatteredBytes(
30176       perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
30177       &ranges[0], ranges.size());
30178 
30179   // Reset the message but keep one buffer allocated for future use.
30180   serialized_interned_data.Reset();
30181 }
30182 
30183 }  // namespace perfetto
30184 // gen_amalgamated begin source: src/tracing/internal/tracing_muxer_impl.cc
30185 // gen_amalgamated begin header: src/tracing/internal/tracing_muxer_impl.h
30186 /*
30187  * Copyright (C) 2019 The Android Open Source Project
30188  *
30189  * Licensed under the Apache License, Version 2.0 (the "License");
30190  * you may not use this file except in compliance with the License.
30191  * You may obtain a copy of the License at
30192  *
30193  *      http://www.apache.org/licenses/LICENSE-2.0
30194  *
30195  * Unless required by applicable law or agreed to in writing, software
30196  * distributed under the License is distributed on an "AS IS" BASIS,
30197  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30198  * See the License for the specific language governing permissions and
30199  * limitations under the License.
30200  */
30201 
30202 #ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
30203 #define SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
30204 
30205 #include <stddef.h>
30206 #include <stdint.h>
30207 
30208 #include <array>
30209 #include <atomic>
30210 #include <bitset>
30211 #include <map>
30212 #include <memory>
30213 #include <vector>
30214 
30215 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
30216 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
30217 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
30218 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
30219 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
30220 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
30221 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
30222 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
30223 // gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
30224 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
30225 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
30226 namespace perfetto {
30227 
30228 class ConsumerEndpoint;
30229 class DataSourceBase;
30230 class ProducerEndpoint;
30231 class TraceWriterBase;
30232 class TracingBackend;
30233 class TracingSession;
30234 struct TracingInitArgs;
30235 
30236 namespace base {
30237 class TaskRunner;
30238 }
30239 
30240 namespace internal {
30241 
30242 struct DataSourceStaticState;
30243 
30244 // This class acts as a bridge between the public API and the TracingBackend(s).
30245 // It exposes a simplified view of the world to the API methods handling all the
30246 // bookkeeping to map data source instances and trace writers to the various
30247 // backends. It deals with N data sources, M backends (1 backend == 1 tracing
30248 // service == 1 producer connection) and T concurrent tracing sessions.
30249 //
30250 // Handing data source registration and start/stop flows [producer side]:
30251 // ----------------------------------------------------------------------
30252 // 1. The API client subclasses perfetto::DataSource and calls
30253 //    DataSource::Register<MyDataSource>(). In turn this calls into the
30254 //    TracingMuxer.
30255 // 2. The tracing muxer iterates through all the backends (1 backend == 1
30256 //    service == 1 producer connection) and registers the data source on each
30257 //    backend.
30258 // 3. When any (services behind a) backend starts tracing and requests to start
30259 //    that specific data source, the TracingMuxerImpl constructs a new instance
30260 //    of MyDataSource and calls the OnStart() method.
30261 //
30262 // Controlling trace and retrieving trace data [consumer side]:
30263 // ------------------------------------------------------------
30264 // 1. The API client calls Tracing::NewTrace(), returns a RAII TracingSession
30265 //    object.
30266 // 2. NewTrace() calls into internal::TracingMuxer(Impl). TracingMuxer
30267 //    subclasses the TracingSession object (TracingSessionImpl) and returns it.
30268 // 3. The tracing muxer identifies the backend (according to the args passed to
30269 //    NewTrace), creates a new Consumer and connects to it.
30270 // 4. When the API client calls Start()/Stop()/ReadTrace() methods, the
30271 //    TracingMuxer forwards them to the consumer associated to the
30272 //    TracingSession. Likewise for callbacks coming from the consumer-side of
30273 //    the service.
30274 class TracingMuxerImpl : public TracingMuxer {
30275  public:
30276   // This is different than TracingSessionID because it's global across all
30277   // backends. TracingSessionID is global only within the scope of one service.
30278   using TracingSessionGlobalID = uint64_t;
30279 
30280   static void InitializeInstance(const TracingInitArgs&);
30281 
30282   // TracingMuxer implementation.
30283   bool RegisterDataSource(const DataSourceDescriptor&,
30284                           DataSourceFactory,
30285                           DataSourceStaticState*) override;
30286   std::unique_ptr<TraceWriterBase> CreateTraceWriter(
30287       DataSourceState*,
30288       BufferExhaustedPolicy buffer_exhausted_policy) override;
30289   void DestroyStoppedTraceWritersForCurrentThread() override;
30290 
30291   std::unique_ptr<TracingSession> CreateTracingSession(BackendType);
30292 
30293   // Producer-side bookkeeping methods.
30294   void UpdateDataSourcesOnAllBackends();
30295   void SetupDataSource(TracingBackendId,
30296                        DataSourceInstanceID,
30297                        const DataSourceConfig&);
30298   void StartDataSource(TracingBackendId, DataSourceInstanceID);
30299   void StopDataSource_AsyncBegin(TracingBackendId, DataSourceInstanceID);
30300   void StopDataSource_AsyncEnd(TracingBackendId, DataSourceInstanceID);
30301 
30302   // Consumer-side bookkeeping methods.
30303   void SetupTracingSession(TracingSessionGlobalID,
30304                            const std::shared_ptr<TraceConfig>&,
30305                            base::ScopedFile trace_fd = base::ScopedFile());
30306   void StartTracingSession(TracingSessionGlobalID);
30307   void StopTracingSession(TracingSessionGlobalID);
30308   void DestroyTracingSession(TracingSessionGlobalID);
30309   void ReadTracingSessionData(
30310       TracingSessionGlobalID,
30311       std::function<void(TracingSession::ReadTraceCallbackArgs)>);
30312   void GetTraceStats(TracingSessionGlobalID,
30313                      TracingSession::GetTraceStatsCallback);
30314 
30315  private:
30316   // For each TracingBackend we create and register one ProducerImpl instance.
30317   // This talks to the producer-side of the service, gets start/stop requests
30318   // from it and routes them to the registered data sources.
30319   // One ProducerImpl == one backend == one tracing service.
30320   // This class is needed to disambiguate callbacks coming from different
30321   // services. TracingMuxerImpl can't directly implement the Producer interface
30322   // because the Producer virtual methods don't allow to identify the service.
30323   class ProducerImpl : public Producer {
30324    public:
30325     ProducerImpl(TracingMuxerImpl*,
30326                  TracingBackendId,
30327                  uint32_t shmem_batch_commits_duration_ms);
30328     ~ProducerImpl() override;
30329 
30330     void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
30331     void RegisterDataSource(const DataSourceDescriptor&,
30332                             DataSourceFactory,
30333                             DataSourceStaticState*);
30334 
30335     // perfetto::Producer implementation.
30336     void OnConnect() override;
30337     void OnDisconnect() override;
30338     void OnTracingSetup() override;
30339     void SetupDataSource(DataSourceInstanceID,
30340                          const DataSourceConfig&) override;
30341     void StartDataSource(DataSourceInstanceID,
30342                          const DataSourceConfig&) override;
30343     void StopDataSource(DataSourceInstanceID) override;
30344     void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
30345     void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
30346 
30347     PERFETTO_THREAD_CHECKER(thread_checker_)
30348     TracingMuxerImpl* const muxer_;
30349     TracingBackendId const backend_id_;
30350     bool connected_ = false;
30351 
30352     const uint32_t shmem_batch_commits_duration_ms_ = 0;
30353 
30354     // Set of data sources that have been actually registered on this producer.
30355     // This can be a subset of the global |data_sources_|, because data sources
30356     // can register before the producer is fully connected.
30357     std::bitset<kMaxDataSources> registered_data_sources_{};
30358 
30359     std::unique_ptr<ProducerEndpoint> service_;  // Keep last.
30360   };
30361 
30362   // For each TracingSession created by the API client (Tracing::NewTrace() we
30363   // create and register one ConsumerImpl instance.
30364   // This talks to the consumer-side of the service, gets end-of-trace and
30365   // on-trace-data callbacks and routes them to the API client callbacks.
30366   // This class is needed to disambiguate callbacks coming from different
30367   // tracing sessions.
30368   class ConsumerImpl : public Consumer {
30369    public:
30370     ConsumerImpl(TracingMuxerImpl*, TracingBackendId, TracingSessionGlobalID);
30371     ~ConsumerImpl() override;
30372 
30373     void Initialize(std::unique_ptr<ConsumerEndpoint> endpoint);
30374 
30375     // perfetto::Consumer implementation.
30376     void OnConnect() override;
30377     void OnDisconnect() override;
30378     void OnTracingDisabled() override;
30379     void OnTraceData(std::vector<TracePacket>, bool has_more) override;
30380     void OnDetach(bool success) override;
30381     void OnAttach(bool success, const TraceConfig&) override;
30382     void OnTraceStats(bool success, const TraceStats&) override;
30383     void OnObservableEvents(const ObservableEvents&) override;
30384 
30385     void NotifyStartComplete();
30386     void NotifyStopComplete();
30387 
30388     // Will eventually inform the |muxer_| when it is safe to remove |this|.
30389     void Disconnect();
30390 
30391     TracingMuxerImpl* const muxer_;
30392     TracingBackendId const backend_id_;
30393     TracingSessionGlobalID const session_id_;
30394     bool connected_ = false;
30395 
30396     // This is to handle the case where the Setup call from the API client
30397     // arrives before the consumer has connected. In this case we keep around
30398     // the config and check if we have it after connection.
30399     bool start_pending_ = false;
30400 
30401     // Similarly if the session is stopped before the consumer was connected, we
30402     // need to wait until the session has started before stopping it.
30403     bool stop_pending_ = false;
30404 
30405     // Similarly we need to buffer a call to get trace statistics if the
30406     // consumer wasn't connected yet.
30407     bool get_trace_stats_pending_ = false;
30408 
30409     // Whether this session was already stopped. This will happen in response to
30410     // Stop{,Blocking}, but also if the service stops the session for us
30411     // automatically (e.g., when there are no data sources).
30412     bool stopped_ = false;
30413 
30414     // shared_ptr because it's posted across threads. This is to avoid copying
30415     // it more than once.
30416     std::shared_ptr<TraceConfig> trace_config_;
30417     base::ScopedFile trace_fd_;
30418 
30419     // If the API client passes a callback to start, we should invoke this when
30420     // NotifyStartComplete() is invoked.
30421     std::function<void()> start_complete_callback_;
30422 
30423     // An internal callback used to implement StartBlocking().
30424     std::function<void()> blocking_start_complete_callback_;
30425 
30426     // If the API client passes a callback to stop, we should invoke this when
30427     // OnTracingDisabled() is invoked.
30428     std::function<void()> stop_complete_callback_;
30429 
30430     // An internal callback used to implement StopBlocking().
30431     std::function<void()> blocking_stop_complete_callback_;
30432 
30433     // Callback passed to ReadTrace().
30434     std::function<void(TracingSession::ReadTraceCallbackArgs)>
30435         read_trace_callback_;
30436 
30437     // Callback passed to GetTraceStats().
30438     TracingSession::GetTraceStatsCallback get_trace_stats_callback_;
30439 
30440     // The states of all data sources in this tracing session. |true| means the
30441     // data source has started tracing.
30442     using DataSourceHandle = std::pair<std::string, std::string>;
30443     std::map<DataSourceHandle, bool> data_source_states_;
30444 
30445     std::unique_ptr<ConsumerEndpoint> service_;  // Keep before last.
30446     PERFETTO_THREAD_CHECKER(thread_checker_)     // Keep last.
30447   };
30448 
30449   // This object is returned to API clients when they call
30450   // Tracing::CreateTracingSession().
30451   class TracingSessionImpl : public TracingSession {
30452    public:
30453     TracingSessionImpl(TracingMuxerImpl*, TracingSessionGlobalID);
30454     ~TracingSessionImpl() override;
30455     void Setup(const TraceConfig&, int fd) override;
30456     void Start() override;
30457     void StartBlocking() override;
30458     void SetOnStartCallback(std::function<void()>) override;
30459     void Stop() override;
30460     void StopBlocking() override;
30461     void ReadTrace(ReadTraceCallback) override;
30462     void SetOnStopCallback(std::function<void()>) override;
30463     void GetTraceStats(GetTraceStatsCallback) override;
30464 
30465    private:
30466     TracingMuxerImpl* const muxer_;
30467     TracingSessionGlobalID const session_id_;
30468   };
30469 
30470   struct RegisteredDataSource {
30471     DataSourceDescriptor descriptor;
30472     DataSourceFactory factory{};
30473     DataSourceStaticState* static_state = nullptr;
30474   };
30475 
30476   struct RegisteredBackend {
30477     // Backends are supposed to have static lifetime.
30478     TracingBackend* backend = nullptr;
30479     TracingBackendId id = 0;
30480     BackendType type{};
30481 
30482     std::unique_ptr<ProducerImpl> producer;
30483 
30484     // The calling code can request more than one concurrently active tracing
30485     // session for the same backend. We need to create one consumer per session.
30486     std::vector<std::unique_ptr<ConsumerImpl>> consumers;
30487   };
30488 
30489   explicit TracingMuxerImpl(const TracingInitArgs&);
30490   void Initialize(const TracingInitArgs& args);
30491   ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
30492   void OnConsumerDisconnected(ConsumerImpl* consumer);
30493 
30494   struct FindDataSourceRes {
30495     FindDataSourceRes() = default;
FindDataSourceResperfetto::internal::TracingMuxerImpl::FindDataSourceRes30496     FindDataSourceRes(DataSourceStaticState* a, DataSourceState* b, uint32_t c)
30497         : static_state(a), internal_state(b), instance_idx(c) {}
operator boolperfetto::internal::TracingMuxerImpl::FindDataSourceRes30498     explicit operator bool() const { return !!internal_state; }
30499 
30500     DataSourceStaticState* static_state = nullptr;
30501     DataSourceState* internal_state = nullptr;
30502     uint32_t instance_idx = 0;
30503   };
30504   FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
30505 
30506   std::unique_ptr<base::TaskRunner> task_runner_;
30507   std::vector<RegisteredDataSource> data_sources_;
30508   std::vector<RegisteredBackend> backends_;
30509 
30510   std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
30511 
30512   PERFETTO_THREAD_CHECKER(thread_checker_)
30513 };
30514 
30515 }  // namespace internal
30516 }  // namespace perfetto
30517 
30518 #endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
30519 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_stats.h
30520 /*
30521  * Copyright (C) 2017 The Android Open Source Project
30522  *
30523  * Licensed under the Apache License, Version 2.0 (the "License");
30524  * you may not use this file except in compliance with the License.
30525  * You may obtain a copy of the License at
30526  *
30527  *      http://www.apache.org/licenses/LICENSE-2.0
30528  *
30529  * Unless required by applicable law or agreed to in writing, software
30530  * distributed under the License is distributed on an "AS IS" BASIS,
30531  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30532  * See the License for the specific language governing permissions and
30533  * limitations under the License.
30534  */
30535 
30536 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
30537 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
30538 
30539 // Creates the aliases in the ::perfetto namespace, doing things like:
30540 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
30541 // See comments in forward_decls.h for the historical reasons of this
30542 // indirection layer.
30543 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
30544 
30545 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
30546 
30547 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
30548 /*
30549  * Copyright (C) 2019 The Android Open Source Project
30550  *
30551  * Licensed under the Apache License, Version 2.0 (the "License");
30552  * you may not use this file except in compliance with the License.
30553  * You may obtain a copy of the License at
30554  *
30555  *      http://www.apache.org/licenses/LICENSE-2.0
30556  *
30557  * Unless required by applicable law or agreed to in writing, software
30558  * distributed under the License is distributed on an "AS IS" BASIS,
30559  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
30560  * See the License for the specific language governing permissions and
30561  * limitations under the License.
30562  */
30563 
30564 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
30565 
30566 #include <algorithm>
30567 #include <atomic>
30568 #include <mutex>
30569 #include <vector>
30570 
30571 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
30572 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
30573 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
30574 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
30575 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
30576 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
30577 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
30578 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
30579 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
30580 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
30581 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
30582 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
30583 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
30584 // gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
30585 // gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
30586 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
30587 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
30588 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
30589 
30590 namespace perfetto {
30591 namespace internal {
30592 
30593 namespace {
30594 
30595 class StopArgsImpl : public DataSourceBase::StopArgs {
30596  public:
HandleStopAsynchronously() const30597   std::function<void()> HandleStopAsynchronously() const override {
30598     auto closure = std::move(async_stop_closure);
30599     async_stop_closure = std::function<void()>();
30600     return closure;
30601   }
30602 
30603   mutable std::function<void()> async_stop_closure;
30604 };
30605 
ComputeConfigHash(const DataSourceConfig & config)30606 uint64_t ComputeConfigHash(const DataSourceConfig& config) {
30607   base::Hash hasher;
30608   std::string config_bytes = config.SerializeAsString();
30609   hasher.Update(config_bytes.data(), config_bytes.size());
30610   return hasher.digest();
30611 }
30612 
30613 }  // namespace
30614 
30615 // ----- Begin of TracingMuxerImpl::ProducerImpl
ProducerImpl(TracingMuxerImpl * muxer,TracingBackendId backend_id,uint32_t shmem_batch_commits_duration_ms)30616 TracingMuxerImpl::ProducerImpl::ProducerImpl(
30617     TracingMuxerImpl* muxer,
30618     TracingBackendId backend_id,
30619     uint32_t shmem_batch_commits_duration_ms)
30620     : muxer_(muxer),
30621       backend_id_(backend_id),
30622       shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms) {}
30623 TracingMuxerImpl::ProducerImpl::~ProducerImpl() = default;
30624 
Initialize(std::unique_ptr<ProducerEndpoint> endpoint)30625 void TracingMuxerImpl::ProducerImpl::Initialize(
30626     std::unique_ptr<ProducerEndpoint> endpoint) {
30627   service_ = std::move(endpoint);
30628 }
30629 
OnConnect()30630 void TracingMuxerImpl::ProducerImpl::OnConnect() {
30631   PERFETTO_DLOG("Producer connected");
30632   PERFETTO_DCHECK_THREAD(thread_checker_);
30633   PERFETTO_DCHECK(!connected_);
30634   connected_ = true;
30635   muxer_->UpdateDataSourcesOnAllBackends();
30636 }
30637 
OnDisconnect()30638 void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
30639   PERFETTO_DCHECK_THREAD(thread_checker_);
30640   connected_ = false;
30641   // TODO: handle more gracefully. Right now we only handle the case of retrying
30642   // when not being able to reach the service in the first place (this is
30643   // handled transparently by ProducerIPCClientImpl).
30644   // If the connection is dropped afterwards (e.g., traced crashes), instead, we
30645   // don't recover from that. In order to handle that we would have to reconnect
30646   // and re-register all the data sources.
30647   PERFETTO_ELOG(
30648       "The connection to the tracing service dropped. Tracing will no longer "
30649       "work until this process is restarted");
30650 }
30651 
OnTracingSetup()30652 void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
30653   PERFETTO_DCHECK_THREAD(thread_checker_);
30654   service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
30655       shmem_batch_commits_duration_ms_);
30656 }
30657 
SetupDataSource(DataSourceInstanceID id,const DataSourceConfig & cfg)30658 void TracingMuxerImpl::ProducerImpl::SetupDataSource(
30659     DataSourceInstanceID id,
30660     const DataSourceConfig& cfg) {
30661   PERFETTO_DCHECK_THREAD(thread_checker_);
30662   muxer_->SetupDataSource(backend_id_, id, cfg);
30663 }
30664 
StartDataSource(DataSourceInstanceID id,const DataSourceConfig &)30665 void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
30666                                                      const DataSourceConfig&) {
30667   PERFETTO_DCHECK_THREAD(thread_checker_);
30668   muxer_->StartDataSource(backend_id_, id);
30669   service_->NotifyDataSourceStarted(id);
30670 }
30671 
StopDataSource(DataSourceInstanceID id)30672 void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
30673   PERFETTO_DCHECK_THREAD(thread_checker_);
30674   muxer_->StopDataSource_AsyncBegin(backend_id_, id);
30675 }
30676 
Flush(FlushRequestID flush_id,const DataSourceInstanceID *,size_t)30677 void TracingMuxerImpl::ProducerImpl::Flush(FlushRequestID flush_id,
30678                                            const DataSourceInstanceID*,
30679                                            size_t) {
30680   // Flush is not plumbed for now, we just ack straight away.
30681   PERFETTO_DCHECK_THREAD(thread_checker_);
30682   service_->NotifyFlushComplete(flush_id);
30683 }
30684 
ClearIncrementalState(const DataSourceInstanceID *,size_t)30685 void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
30686     const DataSourceInstanceID*,
30687     size_t) {
30688   PERFETTO_DCHECK_THREAD(thread_checker_);
30689   // TODO(skyostil): Mark each affected data source's incremental state as
30690   // needing to be cleared.
30691 }
30692 // ----- End of TracingMuxerImpl::ProducerImpl methods.
30693 
30694 // ----- Begin of TracingMuxerImpl::ConsumerImpl
ConsumerImpl(TracingMuxerImpl * muxer,TracingBackendId backend_id,TracingSessionGlobalID session_id)30695 TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
30696                                              TracingBackendId backend_id,
30697                                              TracingSessionGlobalID session_id)
30698     : muxer_(muxer), backend_id_(backend_id), session_id_(session_id) {}
30699 
30700 TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() = default;
30701 
Initialize(std::unique_ptr<ConsumerEndpoint> endpoint)30702 void TracingMuxerImpl::ConsumerImpl::Initialize(
30703     std::unique_ptr<ConsumerEndpoint> endpoint) {
30704   PERFETTO_DCHECK_THREAD(thread_checker_);
30705   service_ = std::move(endpoint);
30706   // Observe data source instance events so we get notified when tracing starts.
30707   service_->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
30708 }
30709 
OnConnect()30710 void TracingMuxerImpl::ConsumerImpl::OnConnect() {
30711   PERFETTO_DCHECK_THREAD(thread_checker_);
30712   PERFETTO_DCHECK(!connected_);
30713   connected_ = true;
30714 
30715   // If the API client configured and started tracing before we connected,
30716   // tell the backend about it now.
30717   if (trace_config_) {
30718     muxer_->SetupTracingSession(session_id_, trace_config_);
30719     if (start_pending_)
30720       muxer_->StartTracingSession(session_id_);
30721     if (get_trace_stats_pending_)
30722       muxer_->GetTraceStats(session_id_, std::move(get_trace_stats_callback_));
30723     if (stop_pending_)
30724       muxer_->StopTracingSession(session_id_);
30725   }
30726 }
30727 
OnDisconnect()30728 void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
30729   PERFETTO_DCHECK_THREAD(thread_checker_);
30730   // It shouldn't be necessary to call StopTracingSession. If we get this call
30731   // it means that the service did shutdown before us, so there is no point
30732   // trying it to ask it to stop the session. We should just remember to cleanup
30733   // the consumer vector.
30734   connected_ = false;
30735 
30736   // TODO notify the client somehow.
30737 
30738   // Notify the muxer that it is safe to destroy |this|. This is needed because
30739   // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
30740   // access until OnDisconnect() is called.
30741   muxer_->OnConsumerDisconnected(this);
30742 }
30743 
Disconnect()30744 void TracingMuxerImpl::ConsumerImpl::Disconnect() {
30745   // This is weird and deserves a comment.
30746   //
30747   // When we called the ConnectConsumer method on the service it returns
30748   // us a ConsumerEndpoint which we stored in |service_|, however this
30749   // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
30750   // |this|. Part of the API contract to TracingService::ConnectConsumer is that
30751   // the ConsumerImpl pointer has to be valid until the
30752   // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
30753   // ConsumerEndpoint |service_|. Eventually this will call
30754   // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
30755   // call the destructor of |this|.
30756   service_.reset();
30757 }
30758 
OnTracingDisabled()30759 void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled() {
30760   PERFETTO_DCHECK_THREAD(thread_checker_);
30761   PERFETTO_DCHECK(!stopped_);
30762   stopped_ = true;
30763   // If we're still waiting for the start event, fire it now. This may happen if
30764   // there are no active data sources in the session.
30765   NotifyStartComplete();
30766   NotifyStopComplete();
30767 }
30768 
NotifyStartComplete()30769 void TracingMuxerImpl::ConsumerImpl::NotifyStartComplete() {
30770   PERFETTO_DCHECK_THREAD(thread_checker_);
30771   if (start_complete_callback_) {
30772     muxer_->task_runner_->PostTask(std::move(start_complete_callback_));
30773     start_complete_callback_ = nullptr;
30774   }
30775   if (blocking_start_complete_callback_) {
30776     muxer_->task_runner_->PostTask(
30777         std::move(blocking_start_complete_callback_));
30778     blocking_start_complete_callback_ = nullptr;
30779   }
30780 }
30781 
NotifyStopComplete()30782 void TracingMuxerImpl::ConsumerImpl::NotifyStopComplete() {
30783   PERFETTO_DCHECK_THREAD(thread_checker_);
30784   if (stop_complete_callback_) {
30785     muxer_->task_runner_->PostTask(std::move(stop_complete_callback_));
30786     stop_complete_callback_ = nullptr;
30787   }
30788   if (blocking_stop_complete_callback_) {
30789     muxer_->task_runner_->PostTask(std::move(blocking_stop_complete_callback_));
30790     blocking_stop_complete_callback_ = nullptr;
30791   }
30792 }
30793 
OnTraceData(std::vector<TracePacket> packets,bool has_more)30794 void TracingMuxerImpl::ConsumerImpl::OnTraceData(
30795     std::vector<TracePacket> packets,
30796     bool has_more) {
30797   PERFETTO_DCHECK_THREAD(thread_checker_);
30798   if (!read_trace_callback_)
30799     return;
30800 
30801   size_t capacity = 0;
30802   for (const auto& packet : packets) {
30803     // 16 is an over-estimation of the proto preamble size
30804     capacity += packet.size() + 16;
30805   }
30806 
30807   // The shared_ptr is to avoid making a copy of the buffer when PostTask-ing.
30808   std::shared_ptr<std::vector<char>> buf(new std::vector<char>());
30809   buf->reserve(capacity);
30810   for (auto& packet : packets) {
30811     char* start;
30812     size_t size;
30813     std::tie(start, size) = packet.GetProtoPreamble();
30814     buf->insert(buf->end(), start, start + size);
30815     for (auto& slice : packet.slices()) {
30816       const auto* slice_data = reinterpret_cast<const char*>(slice.start);
30817       buf->insert(buf->end(), slice_data, slice_data + slice.size);
30818     }
30819   }
30820 
30821   auto callback = read_trace_callback_;
30822   muxer_->task_runner_->PostTask([callback, buf, has_more] {
30823     TracingSession::ReadTraceCallbackArgs callback_arg{};
30824     callback_arg.data = buf->size() ? &(*buf)[0] : nullptr;
30825     callback_arg.size = buf->size();
30826     callback_arg.has_more = has_more;
30827     callback(callback_arg);
30828   });
30829 
30830   if (!has_more)
30831     read_trace_callback_ = nullptr;
30832 }
30833 
OnObservableEvents(const ObservableEvents & events)30834 void TracingMuxerImpl::ConsumerImpl::OnObservableEvents(
30835     const ObservableEvents& events) {
30836   if (events.instance_state_changes_size()) {
30837     for (const auto& state_change : events.instance_state_changes()) {
30838       DataSourceHandle handle{state_change.producer_name(),
30839                               state_change.data_source_name()};
30840       data_source_states_[handle] =
30841           state_change.state() ==
30842           ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED;
30843     }
30844     // Data sources are first reported as being stopped before starting, so once
30845     // all the data sources we know about have started we can declare tracing
30846     // begun.
30847     if (start_complete_callback_ || blocking_start_complete_callback_) {
30848       bool all_data_sources_started = std::all_of(
30849           data_source_states_.cbegin(), data_source_states_.cend(),
30850           [](std::pair<DataSourceHandle, bool> state) { return state.second; });
30851       if (all_data_sources_started)
30852         NotifyStartComplete();
30853     }
30854   }
30855 }
30856 
OnTraceStats(bool success,const TraceStats & trace_stats)30857 void TracingMuxerImpl::ConsumerImpl::OnTraceStats(
30858     bool success,
30859     const TraceStats& trace_stats) {
30860   if (!get_trace_stats_callback_)
30861     return;
30862   TracingSession::GetTraceStatsCallbackArgs callback_arg{};
30863   callback_arg.success = success;
30864   callback_arg.trace_stats_data = trace_stats.SerializeAsArray();
30865   muxer_->task_runner_->PostTask(
30866       std::bind(std::move(get_trace_stats_callback_), std::move(callback_arg)));
30867   get_trace_stats_callback_ = nullptr;
30868 }
30869 
30870 // The callbacks below are not used.
OnDetach(bool)30871 void TracingMuxerImpl::ConsumerImpl::OnDetach(bool) {}
OnAttach(bool,const TraceConfig &)30872 void TracingMuxerImpl::ConsumerImpl::OnAttach(bool, const TraceConfig&) {}
30873 // ----- End of TracingMuxerImpl::ConsumerImpl
30874 
30875 // ----- Begin of TracingMuxerImpl::TracingSessionImpl
30876 
30877 // TracingSessionImpl is the RAII object returned to API clients when they
30878 // invoke Tracing::CreateTracingSession. They use it for starting/stopping
30879 // tracing.
30880 
TracingSessionImpl(TracingMuxerImpl * muxer,TracingSessionGlobalID session_id)30881 TracingMuxerImpl::TracingSessionImpl::TracingSessionImpl(
30882     TracingMuxerImpl* muxer,
30883     TracingSessionGlobalID session_id)
30884     : muxer_(muxer), session_id_(session_id) {}
30885 
30886 // Can be destroyed from any thread.
~TracingSessionImpl()30887 TracingMuxerImpl::TracingSessionImpl::~TracingSessionImpl() {
30888   auto* muxer = muxer_;
30889   auto session_id = session_id_;
30890   muxer->task_runner_->PostTask(
30891       [muxer, session_id] { muxer->DestroyTracingSession(session_id); });
30892 }
30893 
30894 // Can be called from any thread.
Setup(const TraceConfig & cfg,int fd)30895 void TracingMuxerImpl::TracingSessionImpl::Setup(const TraceConfig& cfg,
30896                                                  int fd) {
30897   auto* muxer = muxer_;
30898   auto session_id = session_id_;
30899   std::shared_ptr<TraceConfig> trace_config(new TraceConfig(cfg));
30900   if (fd >= 0) {
30901     trace_config->set_write_into_file(true);
30902     fd = dup(fd);
30903   }
30904   muxer->task_runner_->PostTask([muxer, session_id, trace_config, fd] {
30905     muxer->SetupTracingSession(session_id, trace_config, base::ScopedFile(fd));
30906   });
30907 }
30908 
30909 // Can be called from any thread.
Start()30910 void TracingMuxerImpl::TracingSessionImpl::Start() {
30911   auto* muxer = muxer_;
30912   auto session_id = session_id_;
30913   muxer->task_runner_->PostTask(
30914       [muxer, session_id] { muxer->StartTracingSession(session_id); });
30915 }
30916 
30917 // Can be called from any thread except the service thread.
StartBlocking()30918 void TracingMuxerImpl::TracingSessionImpl::StartBlocking() {
30919   PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
30920   auto* muxer = muxer_;
30921   auto session_id = session_id_;
30922   base::WaitableEvent tracing_started;
30923   muxer->task_runner_->PostTask([muxer, session_id, &tracing_started] {
30924     auto* consumer = muxer->FindConsumer(session_id);
30925     PERFETTO_DCHECK(!consumer->blocking_start_complete_callback_);
30926     consumer->blocking_start_complete_callback_ = [&] {
30927       tracing_started.Notify();
30928     };
30929     muxer->StartTracingSession(session_id);
30930   });
30931   tracing_started.Wait();
30932 }
30933 
30934 // Can be called from any thread.
Stop()30935 void TracingMuxerImpl::TracingSessionImpl::Stop() {
30936   auto* muxer = muxer_;
30937   auto session_id = session_id_;
30938   muxer->task_runner_->PostTask(
30939       [muxer, session_id] { muxer->StopTracingSession(session_id); });
30940 }
30941 
30942 // Can be called from any thread except the service thread.
StopBlocking()30943 void TracingMuxerImpl::TracingSessionImpl::StopBlocking() {
30944   PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
30945   auto* muxer = muxer_;
30946   auto session_id = session_id_;
30947   base::WaitableEvent tracing_stopped;
30948   muxer->task_runner_->PostTask([muxer, session_id, &tracing_stopped] {
30949     auto* consumer = muxer->FindConsumer(session_id);
30950     PERFETTO_DCHECK(!consumer->blocking_stop_complete_callback_);
30951     consumer->blocking_stop_complete_callback_ = [&] {
30952       tracing_stopped.Notify();
30953     };
30954     muxer->StopTracingSession(session_id);
30955   });
30956   tracing_stopped.Wait();
30957 }
30958 
30959 // Can be called from any thread.
ReadTrace(ReadTraceCallback cb)30960 void TracingMuxerImpl::TracingSessionImpl::ReadTrace(ReadTraceCallback cb) {
30961   auto* muxer = muxer_;
30962   auto session_id = session_id_;
30963   muxer->task_runner_->PostTask([muxer, session_id, cb] {
30964     muxer->ReadTracingSessionData(session_id, std::move(cb));
30965   });
30966 }
30967 
30968 // Can be called from any thread.
SetOnStartCallback(std::function<void ()> cb)30969 void TracingMuxerImpl::TracingSessionImpl::SetOnStartCallback(
30970     std::function<void()> cb) {
30971   auto* muxer = muxer_;
30972   auto session_id = session_id_;
30973   muxer->task_runner_->PostTask([muxer, session_id, cb] {
30974     auto* consumer = muxer->FindConsumer(session_id);
30975     consumer->start_complete_callback_ = cb;
30976   });
30977 }
30978 
30979 // Can be called from any thread.
SetOnStopCallback(std::function<void ()> cb)30980 void TracingMuxerImpl::TracingSessionImpl::SetOnStopCallback(
30981     std::function<void()> cb) {
30982   auto* muxer = muxer_;
30983   auto session_id = session_id_;
30984   muxer->task_runner_->PostTask([muxer, session_id, cb] {
30985     auto* consumer = muxer->FindConsumer(session_id);
30986     consumer->stop_complete_callback_ = cb;
30987   });
30988 }
30989 
30990 // Can be called from any thread.
GetTraceStats(GetTraceStatsCallback cb)30991 void TracingMuxerImpl::TracingSessionImpl::GetTraceStats(
30992     GetTraceStatsCallback cb) {
30993   auto* muxer = muxer_;
30994   auto session_id = session_id_;
30995   muxer->task_runner_->PostTask([muxer, session_id, cb] {
30996     muxer->GetTraceStats(session_id, std::move(cb));
30997   });
30998 }
30999 
31000 // ----- End of TracingMuxerImpl::TracingSessionImpl
31001 
31002 // static
31003 TracingMuxer* TracingMuxer::instance_ = nullptr;
31004 
31005 // This is called by perfetto::Tracing::Initialize().
31006 // Can be called on any thread. Typically, but not necessarily, that will be
31007 // the embedder's main thread.
TracingMuxerImpl(const TracingInitArgs & args)31008 TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
31009     : TracingMuxer(args.platform ? args.platform
31010                                  : Platform::GetDefaultPlatform()) {
31011   PERFETTO_DETACH_FROM_THREAD(thread_checker_);
31012 
31013   // Create the thread where muxer, producers and service will live.
31014   task_runner_ = platform_->CreateTaskRunner({});
31015 
31016   // Run the initializer on that thread.
31017   task_runner_->PostTask([this, args] { Initialize(args); });
31018 }
31019 
Initialize(const TracingInitArgs & args)31020 void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
31021   PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.
31022 
31023   auto add_backend = [this, &args](TracingBackend* backend, BackendType type) {
31024     if (!backend) {
31025       // We skip the log in release builds because the *_backend_fake.cc code
31026       // has already an ELOG before returning a nullptr.
31027       PERFETTO_DLOG("Backend creation failed, type %d", static_cast<int>(type));
31028       return;
31029     }
31030     TracingBackendId backend_id = backends_.size();
31031     backends_.emplace_back();
31032     RegisteredBackend& rb = backends_.back();
31033     rb.backend = backend;
31034     rb.id = backend_id;
31035     rb.type = type;
31036     rb.producer.reset(new ProducerImpl(this, backend_id,
31037                                        args.shmem_batch_commits_duration_ms));
31038     TracingBackend::ConnectProducerArgs conn_args;
31039     conn_args.producer = rb.producer.get();
31040     conn_args.producer_name = platform_->GetCurrentProcessName();
31041     conn_args.task_runner = task_runner_.get();
31042     conn_args.shmem_size_hint_bytes = args.shmem_size_hint_kb * 1024;
31043     conn_args.shmem_page_size_hint_bytes = args.shmem_page_size_hint_kb * 1024;
31044     rb.producer->Initialize(rb.backend->ConnectProducer(conn_args));
31045   };
31046 
31047   if (args.backends & kSystemBackend) {
31048     PERFETTO_CHECK(args.system_backend_factory_);
31049     add_backend(args.system_backend_factory_(), kSystemBackend);
31050   }
31051 
31052   if (args.backends & kInProcessBackend) {
31053     PERFETTO_CHECK(args.in_process_backend_factory_);
31054     add_backend(args.in_process_backend_factory_(), kInProcessBackend);
31055   }
31056 
31057   if (args.backends & kCustomBackend) {
31058     PERFETTO_CHECK(args.custom_backend);
31059     add_backend(args.custom_backend, kCustomBackend);
31060   }
31061 
31062   if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
31063     PERFETTO_FATAL("Unsupported tracing backend type");
31064   }
31065 }
31066 
31067 // Can be called from any thread (but not concurrently).
RegisterDataSource(const DataSourceDescriptor & descriptor,DataSourceFactory factory,DataSourceStaticState * static_state)31068 bool TracingMuxerImpl::RegisterDataSource(
31069     const DataSourceDescriptor& descriptor,
31070     DataSourceFactory factory,
31071     DataSourceStaticState* static_state) {
31072   // Ignore repeated registrations.
31073   if (static_state->index != kMaxDataSources)
31074     return true;
31075 
31076   static std::atomic<uint32_t> last_id{};
31077   uint32_t new_index = last_id++;
31078   if (new_index >= kMaxDataSources) {
31079     PERFETTO_DLOG(
31080         "RegisterDataSource failed: too many data sources already registered");
31081     return false;
31082   }
31083 
31084   // Initialize the static state.
31085   static_assert(sizeof(static_state->instances[0]) >= sizeof(DataSourceState),
31086                 "instances[] size mismatch");
31087   for (size_t i = 0; i < static_state->instances.size(); i++)
31088     new (&static_state->instances[i]) DataSourceState{};
31089 
31090   static_state->index = new_index;
31091 
31092   task_runner_->PostTask([this, descriptor, factory, static_state] {
31093     data_sources_.emplace_back();
31094     RegisteredDataSource& rds = data_sources_.back();
31095     rds.descriptor = descriptor;
31096     rds.factory = factory;
31097     rds.static_state = static_state;
31098     UpdateDataSourcesOnAllBackends();
31099   });
31100   return true;
31101 }
31102 
31103 // Called by the service of one of the backends.
SetupDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id,const DataSourceConfig & cfg)31104 void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
31105                                        DataSourceInstanceID instance_id,
31106                                        const DataSourceConfig& cfg) {
31107   PERFETTO_DCHECK_THREAD(thread_checker_);
31108   PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
31109                 cfg.name().c_str());
31110   uint64_t config_hash = ComputeConfigHash(cfg);
31111 
31112   for (const auto& rds : data_sources_) {
31113     if (rds.descriptor.name() != cfg.name())
31114       continue;
31115     DataSourceStaticState& static_state = *rds.static_state;
31116 
31117     // If this data source is already active for this exact config, don't start
31118     // another instance. This happens when we have several data sources with the
31119     // same name, in which case the service sends one SetupDataSource event for
31120     // each one. Since we can't map which event maps to which data source, we
31121     // ensure each event only starts one data source instance.
31122     // TODO(skyostil): Register a unique id with each data source to the service
31123     // to disambiguate.
31124     bool active_for_config = false;
31125     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
31126       if (!static_state.TryGet(i))
31127         continue;
31128       auto* internal_state =
31129           reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
31130       if (internal_state->backend_id == backend_id &&
31131           internal_state->config_hash == config_hash) {
31132         active_for_config = true;
31133         break;
31134       }
31135     }
31136     if (active_for_config) {
31137       PERFETTO_DLOG(
31138           "Data source %s is already active with this config, skipping",
31139           cfg.name().c_str());
31140       continue;
31141     }
31142 
31143     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
31144       // Find a free slot.
31145       if (static_state.TryGet(i))
31146         continue;
31147 
31148       auto* internal_state =
31149           reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
31150       std::lock_guard<std::recursive_mutex> guard(internal_state->lock);
31151       static_assert(
31152           std::is_same<decltype(internal_state->data_source_instance_id),
31153                        DataSourceInstanceID>::value,
31154           "data_source_instance_id type mismatch");
31155       internal_state->backend_id = backend_id;
31156       internal_state->data_source_instance_id = instance_id;
31157       internal_state->buffer_id =
31158           static_cast<internal::BufferId>(cfg.target_buffer());
31159       internal_state->config_hash = config_hash;
31160       internal_state->data_source = rds.factory();
31161 
31162       // This must be made at the end. See matching acquire-load in
31163       // DataSource::Trace().
31164       static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);
31165 
31166       DataSourceBase::SetupArgs setup_args;
31167       setup_args.config = &cfg;
31168       setup_args.internal_instance_index = i;
31169       internal_state->data_source->OnSetup(setup_args);
31170       return;
31171     }
31172     PERFETTO_ELOG(
31173         "Maximum number of data source instances exhausted. "
31174         "Dropping data source %" PRIu64,
31175         instance_id);
31176     break;
31177   }
31178 }
31179 
31180 // Called by the service of one of the backends.
StartDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id)31181 void TracingMuxerImpl::StartDataSource(TracingBackendId backend_id,
31182                                        DataSourceInstanceID instance_id) {
31183   PERFETTO_DLOG("Starting data source %" PRIu64, instance_id);
31184   PERFETTO_DCHECK_THREAD(thread_checker_);
31185 
31186   auto ds = FindDataSource(backend_id, instance_id);
31187   if (!ds) {
31188     PERFETTO_ELOG("Could not find data source to start");
31189     return;
31190   }
31191 
31192   DataSourceBase::StartArgs start_args{};
31193   start_args.internal_instance_index = ds.instance_idx;
31194 
31195   std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
31196   ds.internal_state->trace_lambda_enabled = true;
31197   ds.internal_state->data_source->OnStart(start_args);
31198 }
31199 
31200 // Called by the service of one of the backends.
StopDataSource_AsyncBegin(TracingBackendId backend_id,DataSourceInstanceID instance_id)31201 void TracingMuxerImpl::StopDataSource_AsyncBegin(
31202     TracingBackendId backend_id,
31203     DataSourceInstanceID instance_id) {
31204   PERFETTO_DLOG("Stopping data source %" PRIu64, instance_id);
31205   PERFETTO_DCHECK_THREAD(thread_checker_);
31206 
31207   auto ds = FindDataSource(backend_id, instance_id);
31208   if (!ds) {
31209     PERFETTO_ELOG("Could not find data source to stop");
31210     return;
31211   }
31212 
31213   StopArgsImpl stop_args{};
31214   stop_args.internal_instance_index = ds.instance_idx;
31215   stop_args.async_stop_closure = [this, backend_id, instance_id] {
31216     // TracingMuxerImpl is long lived, capturing |this| is okay.
31217     // The notification closure can be moved out of the StopArgs by the
31218     // embedder to handle stop asynchronously. The embedder might then
31219     // call the closure on a different thread than the current one, hence
31220     // this nested PostTask().
31221     task_runner_->PostTask([this, backend_id, instance_id] {
31222       StopDataSource_AsyncEnd(backend_id, instance_id);
31223     });
31224   };
31225 
31226   {
31227     std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
31228     ds.internal_state->data_source->OnStop(stop_args);
31229   }
31230 
31231   // If the embedder hasn't called StopArgs.HandleStopAsynchronously() run the
31232   // async closure here. In theory we could avoid the PostTask and call
31233   // straight into CompleteDataSourceAsyncStop(). We keep that to reduce
31234   // divergencies between the deferred-stop vs non-deferred-stop code paths.
31235   if (stop_args.async_stop_closure)
31236     std::move(stop_args.async_stop_closure)();
31237 }
31238 
StopDataSource_AsyncEnd(TracingBackendId backend_id,DataSourceInstanceID instance_id)31239 void TracingMuxerImpl::StopDataSource_AsyncEnd(
31240     TracingBackendId backend_id,
31241     DataSourceInstanceID instance_id) {
31242   PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
31243   PERFETTO_DCHECK_THREAD(thread_checker_);
31244 
31245   auto ds = FindDataSource(backend_id, instance_id);
31246   if (!ds) {
31247     PERFETTO_ELOG(
31248         "Async stop of data source %" PRIu64
31249         " failed. This might be due to calling the async_stop_closure twice.",
31250         instance_id);
31251     return;
31252   }
31253 
31254   const uint32_t mask = ~(1 << ds.instance_idx);
31255   ds.static_state->valid_instances.fetch_and(mask, std::memory_order_acq_rel);
31256 
31257   // Take the mutex to prevent that the data source is in the middle of
31258   // a Trace() execution where it called GetDataSourceLocked() while we
31259   // destroy it.
31260   {
31261     std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
31262     ds.internal_state->trace_lambda_enabled = false;
31263     ds.internal_state->data_source.reset();
31264   }
31265 
31266   // The other fields of internal_state are deliberately *not* cleared.
31267   // See races-related comments of DataSource::Trace().
31268 
31269   TracingMuxer::generation_++;
31270 
31271   // |backends_| is append-only, Backend instances are always valid.
31272   PERFETTO_CHECK(backend_id < backends_.size());
31273   ProducerImpl* producer = backends_[backend_id].producer.get();
31274   if (producer && producer->connected_) {
31275     // Flush any commits that might have been batched by SharedMemoryArbiter.
31276     producer->service_->MaybeSharedMemoryArbiter()
31277         ->FlushPendingCommitDataRequests();
31278     producer->service_->NotifyDataSourceStopped(instance_id);
31279   }
31280 }
31281 
DestroyStoppedTraceWritersForCurrentThread()31282 void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
31283   // Iterate across all possible data source types.
31284   auto cur_generation = generation_.load(std::memory_order_acquire);
31285   auto* root_tls = GetOrCreateTracingTLS();
31286 
31287   auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
31288     // |tls| has a vector of per-data-source-instance thread-local state.
31289     DataSourceStaticState* static_state = tls.static_state;
31290     if (!static_state)
31291       return;  // Slot not used.
31292 
31293     // Iterate across all possible instances for this data source.
31294     for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
31295       DataSourceInstanceThreadLocalState& ds_tls = tls.per_instance[inst];
31296       if (!ds_tls.trace_writer)
31297         continue;
31298 
31299       DataSourceState* ds_state = static_state->TryGet(inst);
31300       if (ds_state && ds_state->backend_id == ds_tls.backend_id &&
31301           ds_state->buffer_id == ds_tls.buffer_id) {
31302         continue;
31303       }
31304 
31305       // The DataSource instance has been destroyed or recycled.
31306       ds_tls.Reset();  // Will also destroy the |ds_tls.trace_writer|.
31307     }
31308   };
31309 
31310   for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
31311     // |tls| has a vector of per-data-source-instance thread-local state.
31312     DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
31313     destroy_stopped_instances(tls);
31314   }
31315   destroy_stopped_instances(root_tls->track_event_tls);
31316   root_tls->generation = cur_generation;
31317 }
31318 
31319 // Called both when a new data source is registered or when a new backend
31320 // connects. In both cases we want to be sure we reflected the data source
31321 // registrations on the backends.
UpdateDataSourcesOnAllBackends()31322 void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
31323   PERFETTO_DCHECK_THREAD(thread_checker_);
31324   for (RegisteredDataSource& rds : data_sources_) {
31325     for (RegisteredBackend& backend : backends_) {
31326       // We cannot call RegisterDataSource on the backend before it connects.
31327       if (!backend.producer->connected_)
31328         continue;
31329 
31330       PERFETTO_DCHECK(rds.static_state->index < kMaxDataSourceInstances);
31331       if (backend.producer->registered_data_sources_.test(
31332               rds.static_state->index))
31333         continue;
31334 
31335       rds.descriptor.set_will_notify_on_start(true);
31336       rds.descriptor.set_will_notify_on_stop(true);
31337       backend.producer->service_->RegisterDataSource(rds.descriptor);
31338       backend.producer->registered_data_sources_.set(rds.static_state->index);
31339     }
31340   }
31341 }
31342 
SetupTracingSession(TracingSessionGlobalID session_id,const std::shared_ptr<TraceConfig> & trace_config,base::ScopedFile trace_fd)31343 void TracingMuxerImpl::SetupTracingSession(
31344     TracingSessionGlobalID session_id,
31345     const std::shared_ptr<TraceConfig>& trace_config,
31346     base::ScopedFile trace_fd) {
31347   PERFETTO_DCHECK_THREAD(thread_checker_);
31348   PERFETTO_CHECK(!trace_fd || trace_config->write_into_file());
31349 
31350   auto* consumer = FindConsumer(session_id);
31351   if (!consumer)
31352     return;
31353 
31354   consumer->trace_config_ = trace_config;
31355   if (trace_fd)
31356     consumer->trace_fd_ = std::move(trace_fd);
31357 
31358   if (!consumer->connected_)
31359     return;
31360 
31361   // Only used in the deferred start mode.
31362   if (trace_config->deferred_start()) {
31363     consumer->service_->EnableTracing(*trace_config,
31364                                       std::move(consumer->trace_fd_));
31365   }
31366 }
31367 
StartTracingSession(TracingSessionGlobalID session_id)31368 void TracingMuxerImpl::StartTracingSession(TracingSessionGlobalID session_id) {
31369   PERFETTO_DCHECK_THREAD(thread_checker_);
31370 
31371   auto* consumer = FindConsumer(session_id);
31372 
31373   if (!consumer)
31374     return;
31375 
31376   if (!consumer->trace_config_) {
31377     PERFETTO_ELOG("Must call Setup(config) first");
31378     return;
31379   }
31380 
31381   if (!consumer->connected_) {
31382     consumer->start_pending_ = true;
31383     return;
31384   }
31385 
31386   consumer->start_pending_ = false;
31387   if (consumer->trace_config_->deferred_start()) {
31388     consumer->service_->StartTracing();
31389   } else {
31390     consumer->service_->EnableTracing(*consumer->trace_config_,
31391                                       std::move(consumer->trace_fd_));
31392   }
31393 
31394   // TODO implement support for the deferred-start + fast-triggering case.
31395 }
31396 
StopTracingSession(TracingSessionGlobalID session_id)31397 void TracingMuxerImpl::StopTracingSession(TracingSessionGlobalID session_id) {
31398   PERFETTO_DCHECK_THREAD(thread_checker_);
31399   auto* consumer = FindConsumer(session_id);
31400   if (!consumer)
31401     return;
31402 
31403   if (consumer->start_pending_) {
31404     // If the session hasn't started yet, wait until it does before stopping.
31405     consumer->stop_pending_ = true;
31406     return;
31407   }
31408 
31409   consumer->stop_pending_ = false;
31410   if (consumer->stopped_) {
31411     // If the session was already stopped (e.g., it failed to start), don't try
31412     // stopping again.
31413     consumer->NotifyStopComplete();
31414   } else if (!consumer->trace_config_) {
31415     PERFETTO_ELOG("Must call Setup(config) and Start() first");
31416     return;
31417   } else {
31418     consumer->service_->DisableTracing();
31419   }
31420 
31421   consumer->trace_config_.reset();
31422 }
31423 
DestroyTracingSession(TracingSessionGlobalID session_id)31424 void TracingMuxerImpl::DestroyTracingSession(
31425     TracingSessionGlobalID session_id) {
31426   PERFETTO_DCHECK_THREAD(thread_checker_);
31427   for (RegisteredBackend& backend : backends_) {
31428     // We need to find the consumer (if any) and call Disconnect as we destroy
31429     // the tracing session. We can't call Disconnect() inside this for loop
31430     // because in the in-process case this will end up to a synchronous call to
31431     // OnConsumerDisconnect which will invalidate all the iterators to
31432     // |backend.consumers|.
31433     ConsumerImpl* consumer = nullptr;
31434     for (auto& con : backend.consumers) {
31435       if (con->session_id_ == session_id) {
31436         consumer = con.get();
31437         break;
31438       }
31439     }
31440     if (consumer) {
31441       // We broke out of the loop above on the assumption that each backend will
31442       // only have a single consumer per session. This DCHECK ensures that
31443       // this is the case.
31444       PERFETTO_DCHECK(
31445           std::count_if(backend.consumers.begin(), backend.consumers.end(),
31446                         [session_id](const std::unique_ptr<ConsumerImpl>& con) {
31447                           return con->session_id_ == session_id;
31448                         }) == 1u);
31449       consumer->Disconnect();
31450     }
31451   }
31452 }
31453 
ReadTracingSessionData(TracingSessionGlobalID session_id,std::function<void (TracingSession::ReadTraceCallbackArgs)> callback)31454 void TracingMuxerImpl::ReadTracingSessionData(
31455     TracingSessionGlobalID session_id,
31456     std::function<void(TracingSession::ReadTraceCallbackArgs)> callback) {
31457   PERFETTO_DCHECK_THREAD(thread_checker_);
31458   auto* consumer = FindConsumer(session_id);
31459   if (!consumer)
31460     return;
31461   PERFETTO_DCHECK(!consumer->read_trace_callback_);
31462   consumer->read_trace_callback_ = std::move(callback);
31463   consumer->service_->ReadBuffers();
31464 }
31465 
GetTraceStats(TracingSessionGlobalID session_id,TracingSession::GetTraceStatsCallback callback)31466 void TracingMuxerImpl::GetTraceStats(
31467     TracingSessionGlobalID session_id,
31468     TracingSession::GetTraceStatsCallback callback) {
31469   PERFETTO_DCHECK_THREAD(thread_checker_);
31470   auto* consumer = FindConsumer(session_id);
31471   if (!consumer) {
31472     TracingSession::GetTraceStatsCallbackArgs callback_arg{};
31473     callback_arg.success = false;
31474     callback(std::move(callback_arg));
31475     return;
31476   }
31477   PERFETTO_DCHECK(!consumer->get_trace_stats_callback_);
31478   consumer->get_trace_stats_callback_ = std::move(callback);
31479   if (!consumer->connected_) {
31480     consumer->get_trace_stats_pending_ = true;
31481     return;
31482   }
31483   consumer->get_trace_stats_pending_ = false;
31484   consumer->service_->GetTraceStats();
31485 }
31486 
FindConsumer(TracingSessionGlobalID session_id)31487 TracingMuxerImpl::ConsumerImpl* TracingMuxerImpl::FindConsumer(
31488     TracingSessionGlobalID session_id) {
31489   PERFETTO_DCHECK_THREAD(thread_checker_);
31490   for (RegisteredBackend& backend : backends_) {
31491     for (auto& consumer : backend.consumers) {
31492       if (consumer->session_id_ == session_id) {
31493         PERFETTO_DCHECK(consumer->service_);
31494         return consumer.get();
31495       }
31496     }
31497   }
31498   return nullptr;
31499 }
31500 
OnConsumerDisconnected(ConsumerImpl * consumer)31501 void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
31502   PERFETTO_DCHECK_THREAD(thread_checker_);
31503   for (RegisteredBackend& backend : backends_) {
31504     auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
31505       return con.get() == consumer;
31506     };
31507     backend.consumers.erase(std::remove_if(backend.consumers.begin(),
31508                                            backend.consumers.end(), pred),
31509                             backend.consumers.end());
31510   }
31511 }
31512 
FindDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id)31513 TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
31514     TracingBackendId backend_id,
31515     DataSourceInstanceID instance_id) {
31516   PERFETTO_DCHECK_THREAD(thread_checker_);
31517   for (const auto& rds : data_sources_) {
31518     DataSourceStaticState* static_state = rds.static_state;
31519     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
31520       auto* internal_state = static_state->TryGet(i);
31521       if (internal_state && internal_state->backend_id == backend_id &&
31522           internal_state->data_source_instance_id == instance_id) {
31523         return FindDataSourceRes(static_state, internal_state, i);
31524       }
31525     }
31526   }
31527   return FindDataSourceRes();
31528 }
31529 
31530 // Can be called from any thread.
CreateTraceWriter(DataSourceState * data_source,BufferExhaustedPolicy buffer_exhausted_policy)31531 std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
31532     DataSourceState* data_source,
31533     BufferExhaustedPolicy buffer_exhausted_policy) {
31534   ProducerImpl* producer = backends_[data_source->backend_id].producer.get();
31535   return producer->service_->CreateTraceWriter(data_source->buffer_id,
31536                                                buffer_exhausted_policy);
31537 }
31538 
31539 // This is called via the public API Tracing::NewTrace().
31540 // Can be called from any thread.
CreateTracingSession(BackendType backend_type)31541 std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
31542     BackendType backend_type) {
31543   TracingSessionGlobalID session_id = ++next_tracing_session_id_;
31544 
31545   // |backend_type| can only specify one backend, not an OR-ed mask.
31546   PERFETTO_CHECK((backend_type & (backend_type - 1)) == 0);
31547 
31548   // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
31549   task_runner_->PostTask([this, backend_type, session_id] {
31550     for (RegisteredBackend& backend : backends_) {
31551       if (backend_type && backend.type != backend_type)
31552         continue;
31553 
31554       backend.consumers.emplace_back(
31555           new ConsumerImpl(this, backend.id, session_id));
31556       auto& consumer = backend.consumers.back();
31557       TracingBackend::ConnectConsumerArgs conn_args;
31558       conn_args.consumer = consumer.get();
31559       conn_args.task_runner = task_runner_.get();
31560       consumer->Initialize(backend.backend->ConnectConsumer(conn_args));
31561       return;
31562     }
31563     PERFETTO_ELOG(
31564         "Cannot create tracing session, no tracing backend ready for type=%d",
31565         backend_type);
31566   });
31567 
31568   return std::unique_ptr<TracingSession>(
31569       new TracingSessionImpl(this, session_id));
31570 }
31571 
InitializeInstance(const TracingInitArgs & args)31572 void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
31573   if (instance_)
31574     PERFETTO_FATAL("Tracing already initialized");
31575   instance_ = new TracingMuxerImpl(args);
31576 }
31577 
31578 TracingMuxer::~TracingMuxer() = default;
31579 
31580 static_assert(std::is_same<internal::BufferId, BufferID>::value,
31581               "public's BufferId and tracing/core's BufferID diverged");
31582 
31583 }  // namespace internal
31584 }  // namespace perfetto
31585 // gen_amalgamated begin source: src/tracing/internal/track_event_internal.cc
31586 // gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.pbzero.h
31587 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
31588 
31589 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
31590 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
31591 
31592 #include <stddef.h>
31593 #include <stdint.h>
31594 
31595 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31596 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31597 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31598 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
31599 
31600 namespace perfetto {
31601 namespace protos {
31602 namespace pbzero {
31603 
31604 class TrackEventCategory;
31605 
31606 class TrackEventDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
31607  public:
TrackEventDescriptor_Decoder(const uint8_t * data,size_t len)31608   TrackEventDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TrackEventDescriptor_Decoder(const std::string & raw)31609   explicit TrackEventDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TrackEventDescriptor_Decoder(const::protozero::ConstBytes & raw)31610   explicit TrackEventDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_available_categories() const31611   bool has_available_categories() const { return at<1>().valid(); }
available_categories() const31612   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> available_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
31613 };
31614 
31615 class TrackEventDescriptor : public ::protozero::Message {
31616  public:
31617   using Decoder = TrackEventDescriptor_Decoder;
31618   enum : int32_t {
31619     kAvailableCategoriesFieldNumber = 1,
31620   };
add_available_categories()31621   template <typename T = TrackEventCategory> T* add_available_categories() {
31622     return BeginNestedMessage<T>(1);
31623   }
31624 
31625 };
31626 
31627 class TrackEventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
31628  public:
TrackEventCategory_Decoder(const uint8_t * data,size_t len)31629   TrackEventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TrackEventCategory_Decoder(const std::string & raw)31630   explicit TrackEventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TrackEventCategory_Decoder(const::protozero::ConstBytes & raw)31631   explicit TrackEventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_name() const31632   bool has_name() const { return at<1>().valid(); }
name() const31633   ::protozero::ConstChars name() const { return at<1>().as_string(); }
has_description() const31634   bool has_description() const { return at<2>().valid(); }
description() const31635   ::protozero::ConstChars description() const { return at<2>().as_string(); }
has_tags() const31636   bool has_tags() const { return at<3>().valid(); }
tags() const31637   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> tags() const { return GetRepeated<::protozero::ConstChars>(3); }
31638 };
31639 
31640 class TrackEventCategory : public ::protozero::Message {
31641  public:
31642   using Decoder = TrackEventCategory_Decoder;
31643   enum : int32_t {
31644     kNameFieldNumber = 1,
31645     kDescriptionFieldNumber = 2,
31646     kTagsFieldNumber = 3,
31647   };
set_name(const std::string & value)31648   void set_name(const std::string& value) {
31649     AppendBytes(1, value.data(), value.size());
31650   }
set_name(const char * data,size_t size)31651   void set_name(const char* data, size_t size) {
31652     AppendBytes(1, data, size);
31653   }
set_description(const std::string & value)31654   void set_description(const std::string& value) {
31655     AppendBytes(2, value.data(), value.size());
31656   }
set_description(const char * data,size_t size)31657   void set_description(const char* data, size_t size) {
31658     AppendBytes(2, data, size);
31659   }
add_tags(const std::string & value)31660   void add_tags(const std::string& value) {
31661     AppendBytes(3, value.data(), value.size());
31662   }
add_tags(const char * data,size_t size)31663   void add_tags(const char* data, size_t size) {
31664     AppendBytes(3, data, size);
31665   }
31666 };
31667 
31668 } // Namespace.
31669 } // Namespace.
31670 } // Namespace.
31671 #endif  // Include guard.
31672 // gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.h
31673 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
31674 
31675 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
31676 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
31677 
31678 #include <stddef.h>
31679 #include <stdint.h>
31680 
31681 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31682 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31683 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31684 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
31685 
31686 namespace perfetto {
31687 namespace protos {
31688 namespace pbzero {
31689 
31690 class TrackEventDefaults;
31691 
31692 class TracePacketDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
31693  public:
TracePacketDefaults_Decoder(const uint8_t * data,size_t len)31694   TracePacketDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TracePacketDefaults_Decoder(const std::string & raw)31695   explicit TracePacketDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TracePacketDefaults_Decoder(const::protozero::ConstBytes & raw)31696   explicit TracePacketDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_timestamp_clock_id() const31697   bool has_timestamp_clock_id() const { return at<58>().valid(); }
timestamp_clock_id() const31698   uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
has_track_event_defaults() const31699   bool has_track_event_defaults() const { return at<11>().valid(); }
track_event_defaults() const31700   ::protozero::ConstBytes track_event_defaults() const { return at<11>().as_bytes(); }
31701 };
31702 
31703 class TracePacketDefaults : public ::protozero::Message {
31704  public:
31705   using Decoder = TracePacketDefaults_Decoder;
31706   enum : int32_t {
31707     kTimestampClockIdFieldNumber = 58,
31708     kTrackEventDefaultsFieldNumber = 11,
31709   };
set_timestamp_clock_id(uint32_t value)31710   void set_timestamp_clock_id(uint32_t value) {
31711     AppendVarInt(58, value);
31712   }
set_track_event_defaults()31713   template <typename T = TrackEventDefaults> T* set_track_event_defaults() {
31714     return BeginNestedMessage<T>(11);
31715   }
31716 
31717 };
31718 
31719 } // Namespace.
31720 } // Namespace.
31721 } // Namespace.
31722 #endif  // Include guard.
31723 /*
31724  * Copyright (C) 2019 The Android Open Source Project
31725  *
31726  * Licensed under the Apache License, Version 2.0 (the "License");
31727  * you may not use this file except in compliance with the License.
31728  * You may obtain a copy of the License at
31729  *
31730  *      http://www.apache.org/licenses/LICENSE-2.0
31731  *
31732  * Unless required by applicable law or agreed to in writing, software
31733  * distributed under the License is distributed on an "AS IS" BASIS,
31734  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31735  * See the License for the specific language governing permissions and
31736  * limitations under the License.
31737  */
31738 
31739 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
31740 
31741 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
31742 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
31743 // gen_amalgamated expanded: #include "perfetto/base/time.h"
31744 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
31745 // gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
31746 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
31747 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
31748 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
31749 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
31750 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
31751 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
31752 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
31753 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
31754 
31755 namespace perfetto {
31756 namespace internal {
31757 
31758 BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;
31759 
31760 namespace {
31761 
31762 std::atomic<perfetto::base::PlatformThreadId> g_main_thread;
31763 static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
31764 static constexpr const char kSlowTag[] = "slow";
31765 static constexpr const char kDebugTag[] = "debug";
31766 
31767 struct InternedEventCategory
31768     : public TrackEventInternedDataIndex<
31769           InternedEventCategory,
31770           perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
31771           const char*,
31772           SmallInternedDataTraits> {
Addperfetto::internal::__anon7bab3a4f4211::InternedEventCategory31773   static void Add(protos::pbzero::InternedData* interned_data,
31774                   size_t iid,
31775                   const char* value,
31776                   size_t length) {
31777     auto category = interned_data->add_event_categories();
31778     category->set_iid(iid);
31779     category->set_name(value, length);
31780   }
31781 };
31782 
31783 struct InternedEventName
31784     : public TrackEventInternedDataIndex<
31785           InternedEventName,
31786           perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber,
31787           const char*,
31788           SmallInternedDataTraits> {
Addperfetto::internal::__anon7bab3a4f4211::InternedEventName31789   static void Add(protos::pbzero::InternedData* interned_data,
31790                   size_t iid,
31791                   const char* value) {
31792     auto name = interned_data->add_event_names();
31793     name->set_iid(iid);
31794     name->set_name(value);
31795   }
31796 };
31797 
31798 struct InternedDebugAnnotationName
31799     : public TrackEventInternedDataIndex<
31800           InternedDebugAnnotationName,
31801           perfetto::protos::pbzero::InternedData::
31802               kDebugAnnotationNamesFieldNumber,
31803           const char*,
31804           SmallInternedDataTraits> {
Addperfetto::internal::__anon7bab3a4f4211::InternedDebugAnnotationName31805   static void Add(protos::pbzero::InternedData* interned_data,
31806                   size_t iid,
31807                   const char* value) {
31808     auto name = interned_data->add_debug_annotation_names();
31809     name->set_iid(iid);
31810     name->set_name(value);
31811   }
31812 };
31813 
31814 enum class MatchType { kExact, kPattern };
31815 
NameMatchesPattern(const std::string & pattern,const std::string & name,MatchType match_type)31816 bool NameMatchesPattern(const std::string& pattern,
31817                         const std::string& name,
31818                         MatchType match_type) {
31819   // To avoid pulling in all of std::regex, for now we only support a single "*"
31820   // wildcard at the end of the pattern.
31821   size_t i = pattern.find('*');
31822   if (i != std::string::npos) {
31823     PERFETTO_DCHECK(i == pattern.size() - 1);
31824     if (match_type != MatchType::kPattern)
31825       return false;
31826     return name.substr(0, i) == pattern.substr(0, i);
31827   }
31828   return name == pattern;
31829 }
31830 
NameMatchesPatternList(const std::vector<std::string> & patterns,const std::string & name,MatchType match_type)31831 bool NameMatchesPatternList(const std::vector<std::string>& patterns,
31832                             const std::string& name,
31833                             MatchType match_type) {
31834   for (const auto& pattern : patterns) {
31835     if (NameMatchesPattern(pattern, name, match_type))
31836       return true;
31837   }
31838   return false;
31839 }
31840 
31841 }  // namespace
31842 
31843 // static
Initialize(const TrackEventCategoryRegistry & registry,bool (* register_data_source)(const DataSourceDescriptor &))31844 bool TrackEventInternal::Initialize(
31845     const TrackEventCategoryRegistry& registry,
31846     bool (*register_data_source)(const DataSourceDescriptor&)) {
31847   if (!g_main_thread)
31848     g_main_thread = perfetto::base::GetThreadId();
31849 
31850   DataSourceDescriptor dsd;
31851   dsd.set_name("track_event");
31852 
31853   protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
31854   for (size_t i = 0; i < registry.category_count(); i++) {
31855     auto category = registry.GetCategory(i);
31856     // Don't register group categories.
31857     if (category->IsGroup())
31858       continue;
31859     auto cat = ted->add_available_categories();
31860     cat->set_name(category->name);
31861     if (category->description)
31862       cat->set_description(category->description);
31863     for (const auto& tag : category->tags) {
31864       if (tag)
31865         cat->add_tags(tag);
31866     }
31867     // Disabled-by-default categories get a "slow" tag.
31868     if (!strncmp(category->name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)))
31869       cat->add_tags(kSlowTag);
31870   }
31871   dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
31872 
31873   return register_data_source(dsd);
31874 }
31875 
31876 // static
EnableTracing(const TrackEventCategoryRegistry & registry,const protos::gen::TrackEventConfig & config,uint32_t instance_index)31877 void TrackEventInternal::EnableTracing(
31878     const TrackEventCategoryRegistry& registry,
31879     const protos::gen::TrackEventConfig& config,
31880     uint32_t instance_index) {
31881   for (size_t i = 0; i < registry.category_count(); i++) {
31882     if (IsCategoryEnabled(registry, config, *registry.GetCategory(i)))
31883       registry.EnableCategoryForInstance(i, instance_index);
31884   }
31885 }
31886 
31887 // static
DisableTracing(const TrackEventCategoryRegistry & registry,uint32_t instance_index)31888 void TrackEventInternal::DisableTracing(
31889     const TrackEventCategoryRegistry& registry,
31890     uint32_t instance_index) {
31891   for (size_t i = 0; i < registry.category_count(); i++)
31892     registry.DisableCategoryForInstance(i, instance_index);
31893 }
31894 
31895 // static
IsCategoryEnabled(const TrackEventCategoryRegistry & registry,const protos::gen::TrackEventConfig & config,const Category & category)31896 bool TrackEventInternal::IsCategoryEnabled(
31897     const TrackEventCategoryRegistry& registry,
31898     const protos::gen::TrackEventConfig& config,
31899     const Category& category) {
31900   // If this is a group category, check if any of its constituent categories are
31901   // enabled. If so, then this one is enabled too.
31902   if (category.IsGroup()) {
31903     bool result = false;
31904     category.ForEachGroupMember([&](const char* member_name, size_t name_size) {
31905       for (size_t i = 0; i < registry.category_count(); i++) {
31906         const auto ref_category = registry.GetCategory(i);
31907         // Groups can't refer to other groups.
31908         if (ref_category->IsGroup())
31909           continue;
31910         // Require an exact match.
31911         if (ref_category->name_size() != name_size ||
31912             strncmp(ref_category->name, member_name, name_size)) {
31913           continue;
31914         }
31915         if (IsCategoryEnabled(registry, config, *ref_category)) {
31916           result = true;
31917           // Break ForEachGroupMember() loop.
31918           return false;
31919         }
31920         break;
31921       }
31922       // No match found => keep iterating.
31923       return true;
31924     });
31925     return result;
31926   }
31927 
31928   auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
31929     for (const auto& tag : category.tags) {
31930       if (!tag)
31931         break;
31932       if (matcher(tag))
31933         return true;
31934     }
31935     // Legacy "disabled-by-default" categories automatically get the "slow" tag.
31936     if (!strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)) &&
31937         matcher(kSlowTag)) {
31938       return true;
31939     }
31940     return false;
31941   };
31942 
31943   // First try exact matches, then pattern matches.
31944   const std::array<MatchType, 2> match_types = {
31945       {MatchType::kExact, MatchType::kPattern}};
31946   for (auto match_type : match_types) {
31947     // 1. Enabled categories.
31948     if (NameMatchesPatternList(config.enabled_categories(), category.name,
31949                                match_type)) {
31950       return true;
31951     }
31952 
31953     // 2. Enabled tags.
31954     if (has_matching_tag([&](const char* tag) {
31955           return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
31956         })) {
31957       return true;
31958     }
31959 
31960     // 3. Disabled categories.
31961     if (NameMatchesPatternList(config.disabled_categories(), category.name,
31962                                match_type)) {
31963       return false;
31964     }
31965 
31966     // 4. Disabled tags.
31967     if (has_matching_tag([&](const char* tag) {
31968           if (config.disabled_tags_size()) {
31969             return NameMatchesPatternList(config.disabled_tags(), tag,
31970                                           match_type);
31971           } else {
31972             // The "slow" and "debug" tags are disabled by default.
31973             return NameMatchesPattern(kSlowTag, tag, match_type) ||
31974                    NameMatchesPattern(kDebugTag, tag, match_type);
31975           }
31976         })) {
31977       return false;
31978     }
31979   }
31980 
31981   // If nothing matched, enable the category by default.
31982   return true;
31983 }
31984 
31985 // static
GetTimeNs()31986 uint64_t TrackEventInternal::GetTimeNs() {
31987   if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
31988     return static_cast<uint64_t>(perfetto::base::GetBootTimeNs().count());
31989   PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
31990   return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
31991 }
31992 
31993 // static
ResetIncrementalState(TraceWriterBase * trace_writer,uint64_t timestamp)31994 void TrackEventInternal::ResetIncrementalState(TraceWriterBase* trace_writer,
31995                                                uint64_t timestamp) {
31996   auto default_track = ThreadTrack::Current();
31997   {
31998     // Mark any incremental state before this point invalid. Also set up
31999     // defaults so that we don't need to repeat constant data for each packet.
32000     auto packet = NewTracePacket(
32001         trace_writer, timestamp,
32002         protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
32003     auto defaults = packet->set_trace_packet_defaults();
32004     defaults->set_timestamp_clock_id(GetClockId());
32005 
32006     // Establish the default track for this event sequence.
32007     auto track_defaults = defaults->set_track_event_defaults();
32008     track_defaults->set_track_uuid(default_track.uuid);
32009   }
32010 
32011   // Every thread should write a descriptor for its default track, because most
32012   // trace points won't explicitly reference it.
32013   WriteTrackDescriptor(default_track, trace_writer);
32014 
32015   // Additionally the main thread should dump the process descriptor.
32016   if (perfetto::base::GetThreadId() == g_main_thread)
32017     WriteTrackDescriptor(ProcessTrack::Current(), trace_writer);
32018 }
32019 
32020 // static
32021 protozero::MessageHandle<protos::pbzero::TracePacket>
NewTracePacket(TraceWriterBase * trace_writer,uint64_t timestamp,uint32_t seq_flags)32022 TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
32023                                    uint64_t timestamp,
32024                                    uint32_t seq_flags) {
32025   auto packet = trace_writer->NewTracePacket();
32026   packet->set_timestamp(timestamp);
32027   // TODO(skyostil): Stop emitting this for every event once the trace
32028   // processor understands trace packet defaults.
32029   if (GetClockId() != protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
32030     packet->set_timestamp_clock_id(GetClockId());
32031   packet->set_sequence_flags(seq_flags);
32032   return packet;
32033 }
32034 
32035 // static
WriteEvent(TraceWriterBase * trace_writer,TrackEventIncrementalState * incr_state,const Category * category,const char * name,perfetto::protos::pbzero::TrackEvent::Type type,uint64_t timestamp)32036 EventContext TrackEventInternal::WriteEvent(
32037     TraceWriterBase* trace_writer,
32038     TrackEventIncrementalState* incr_state,
32039     const Category* category,
32040     const char* name,
32041     perfetto::protos::pbzero::TrackEvent::Type type,
32042     uint64_t timestamp) {
32043   PERFETTO_DCHECK(g_main_thread);
32044 
32045   if (incr_state->was_cleared) {
32046     incr_state->was_cleared = false;
32047     ResetIncrementalState(trace_writer, timestamp);
32048   }
32049   auto packet = NewTracePacket(trace_writer, timestamp);
32050   EventContext ctx(std::move(packet), incr_state);
32051 
32052   auto track_event = ctx.event();
32053   if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
32054     track_event->set_type(type);
32055 
32056   // We assume that |category| and |name| point to strings with static lifetime.
32057   // This means we can use their addresses as interning keys.
32058   if (category && type != protos::pbzero::TrackEvent::TYPE_SLICE_END) {
32059     category->ForEachGroupMember(
32060         [&](const char* member_name, size_t name_size) {
32061           size_t category_iid =
32062               InternedEventCategory::Get(&ctx, member_name, name_size);
32063           track_event->add_category_iids(category_iid);
32064           return true;
32065         });
32066   }
32067   if (name) {
32068     size_t name_iid = InternedEventName::Get(&ctx, name);
32069     track_event->set_name_iid(name_iid);
32070   }
32071   return ctx;
32072 }
32073 
32074 // static
AddDebugAnnotation(perfetto::EventContext * event_ctx,const char * name)32075 protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
32076     perfetto::EventContext* event_ctx,
32077     const char* name) {
32078   auto annotation = event_ctx->event()->add_debug_annotations();
32079   annotation->set_name_iid(InternedDebugAnnotationName::Get(event_ctx, name));
32080   return annotation;
32081 }
32082 
32083 }  // namespace internal
32084 }  // namespace perfetto
32085 // gen_amalgamated begin source: src/tracing/platform.cc
32086 /*
32087  * Copyright (C) 2019 The Android Open Source Project
32088  *
32089  * Licensed under the Apache License, Version 2.0 (the "License");
32090  * you may not use this file except in compliance with the License.
32091  * You may obtain a copy of the License at
32092  *
32093  *      http://www.apache.org/licenses/LICENSE-2.0
32094  *
32095  * Unless required by applicable law or agreed to in writing, software
32096  * distributed under the License is distributed on an "AS IS" BASIS,
32097  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32098  * See the License for the specific language governing permissions and
32099  * limitations under the License.
32100  */
32101 
32102 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
32103 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
32104 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
32105 
32106 namespace perfetto {
32107 
32108 PlatformThreadLocalObject::~PlatformThreadLocalObject() = default;
32109 Platform::~Platform() = default;
32110 
32111 // static
32112 std::unique_ptr<PlatformThreadLocalObject>
CreateInstance()32113 PlatformThreadLocalObject::CreateInstance() {
32114   return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
32115 }
32116 
32117 }  // namespace perfetto
32118 // gen_amalgamated begin source: src/tracing/tracing.cc
32119 /*
32120  * Copyright (C) 2019 The Android Open Source Project
32121  *
32122  * Licensed under the Apache License, Version 2.0 (the "License");
32123  * you may not use this file except in compliance with the License.
32124  * You may obtain a copy of the License at
32125  *
32126  *      http://www.apache.org/licenses/LICENSE-2.0
32127  *
32128  * Unless required by applicable law or agreed to in writing, software
32129  * distributed under the License is distributed on an "AS IS" BASIS,
32130  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32131  * See the License for the specific language governing permissions and
32132  * limitations under the License.
32133  */
32134 
32135 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
32136 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
32137 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
32138 
32139 #include <condition_variable>
32140 #include <mutex>
32141 
32142 namespace perfetto {
32143 
32144 // static
InitializeInternal(const TracingInitArgs & args)32145 void Tracing::InitializeInternal(const TracingInitArgs& args) {
32146   static bool was_initialized = false;
32147   static TracingInitArgs init_args;
32148   if (was_initialized) {
32149     // Should not be reinitialized with different args.
32150     PERFETTO_DCHECK(init_args == args);
32151     return;
32152   }
32153 
32154   // Make sure the headers and implementation files agree on the build config.
32155   PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
32156   internal::TracingMuxerImpl::InitializeInstance(args);
32157   internal::TrackRegistry::InitializeInstance();
32158   was_initialized = true;
32159   init_args = args;
32160 }
32161 
32162 //  static
NewTrace(BackendType backend)32163 std::unique_ptr<TracingSession> Tracing::NewTrace(BackendType backend) {
32164   return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
32165       ->CreateTracingSession(backend);
32166 }
32167 
ReadTraceBlocking()32168 std::vector<char> TracingSession::ReadTraceBlocking() {
32169   std::vector<char> raw_trace;
32170   std::mutex mutex;
32171   std::condition_variable cv;
32172   bool all_read = false;
32173 
32174   ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
32175     raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
32176     std::unique_lock<std::mutex> lock(mutex);
32177     all_read = !cb.has_more;
32178     if (all_read)
32179       cv.notify_one();
32180   });
32181 
32182   {
32183     std::unique_lock<std::mutex> lock(mutex);
32184     cv.wait(lock, [&all_read] { return all_read; });
32185   }
32186   return raw_trace;
32187 }
32188 
32189 TracingSession::GetTraceStatsCallbackArgs
GetTraceStatsBlocking()32190 TracingSession::GetTraceStatsBlocking() {
32191   std::mutex mutex;
32192   std::condition_variable cv;
32193   GetTraceStatsCallbackArgs result;
32194   bool stats_read = false;
32195 
32196   GetTraceStats(
32197       [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
32198         result = std::move(args);
32199         std::unique_lock<std::mutex> lock(mutex);
32200         stats_read = true;
32201         cv.notify_one();
32202       });
32203 
32204   {
32205     std::unique_lock<std::mutex> lock(mutex);
32206     cv.wait(lock, [&stats_read] { return stats_read; });
32207   }
32208   return result;
32209 }
32210 
32211 }  // namespace perfetto
32212 // gen_amalgamated begin source: src/tracing/track.cc
32213 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.h
32214 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
32215 
32216 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
32217 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
32218 
32219 #include <stddef.h>
32220 #include <stdint.h>
32221 
32222 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
32223 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
32224 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
32225 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
32226 
32227 namespace perfetto {
32228 namespace protos {
32229 namespace pbzero {
32230 
32231 enum ProcessDescriptor_ChromeProcessType : int32_t;
32232 
32233 enum ProcessDescriptor_ChromeProcessType : int32_t {
32234   ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
32235   ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
32236   ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
32237   ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
32238   ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
32239   ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
32240   ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
32241   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
32242   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
32243 };
32244 
32245 const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
32246 const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
32247 
32248 class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
32249  public:
ProcessDescriptor_Decoder(const uint8_t * data,size_t len)32250   ProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ProcessDescriptor_Decoder(const std::string & raw)32251   explicit ProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ProcessDescriptor_Decoder(const::protozero::ConstBytes & raw)32252   explicit ProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_pid() const32253   bool has_pid() const { return at<1>().valid(); }
pid() const32254   int32_t pid() const { return at<1>().as_int32(); }
has_cmdline() const32255   bool has_cmdline() const { return at<2>().valid(); }
cmdline() const32256   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
has_process_name() const32257   bool has_process_name() const { return at<6>().valid(); }
process_name() const32258   ::protozero::ConstChars process_name() const { return at<6>().as_string(); }
has_process_priority() const32259   bool has_process_priority() const { return at<5>().valid(); }
process_priority() const32260   int32_t process_priority() const { return at<5>().as_int32(); }
has_chrome_process_type() const32261   bool has_chrome_process_type() const { return at<4>().valid(); }
chrome_process_type() const32262   int32_t chrome_process_type() const { return at<4>().as_int32(); }
has_legacy_sort_index() const32263   bool has_legacy_sort_index() const { return at<3>().valid(); }
legacy_sort_index() const32264   int32_t legacy_sort_index() const { return at<3>().as_int32(); }
32265 };
32266 
32267 class ProcessDescriptor : public ::protozero::Message {
32268  public:
32269   using Decoder = ProcessDescriptor_Decoder;
32270   enum : int32_t {
32271     kPidFieldNumber = 1,
32272     kCmdlineFieldNumber = 2,
32273     kProcessNameFieldNumber = 6,
32274     kProcessPriorityFieldNumber = 5,
32275     kChromeProcessTypeFieldNumber = 4,
32276     kLegacySortIndexFieldNumber = 3,
32277   };
32278   using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
32279   static const ChromeProcessType PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
32280   static const ChromeProcessType PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
32281   static const ChromeProcessType PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
32282   static const ChromeProcessType PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
32283   static const ChromeProcessType PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
32284   static const ChromeProcessType PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
32285   static const ChromeProcessType PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
32286   static const ChromeProcessType PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
32287   static const ChromeProcessType PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
set_pid(int32_t value)32288   void set_pid(int32_t value) {
32289     AppendVarInt(1, value);
32290   }
add_cmdline(const std::string & value)32291   void add_cmdline(const std::string& value) {
32292     AppendBytes(2, value.data(), value.size());
32293   }
add_cmdline(const char * data,size_t size)32294   void add_cmdline(const char* data, size_t size) {
32295     AppendBytes(2, data, size);
32296   }
set_process_name(const std::string & value)32297   void set_process_name(const std::string& value) {
32298     AppendBytes(6, value.data(), value.size());
32299   }
set_process_name(const char * data,size_t size)32300   void set_process_name(const char* data, size_t size) {
32301     AppendBytes(6, data, size);
32302   }
set_process_priority(int32_t value)32303   void set_process_priority(int32_t value) {
32304     AppendVarInt(5, value);
32305   }
set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value)32306   void set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value) {
32307     AppendTinyVarInt(4, value);
32308   }
set_legacy_sort_index(int32_t value)32309   void set_legacy_sort_index(int32_t value) {
32310     AppendVarInt(3, value);
32311   }
32312 };
32313 
32314 } // Namespace.
32315 } // Namespace.
32316 } // Namespace.
32317 #endif  // Include guard.
32318 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h
32319 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
32320 
32321 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
32322 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
32323 
32324 #include <stddef.h>
32325 #include <stdint.h>
32326 
32327 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
32328 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
32329 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
32330 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
32331 
32332 namespace perfetto {
32333 namespace protos {
32334 namespace pbzero {
32335 
32336 enum ThreadDescriptor_ChromeThreadType : int32_t;
32337 
32338 enum ThreadDescriptor_ChromeThreadType : int32_t {
32339   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
32340   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
32341   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
32342   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
32343   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
32344   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
32345   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
32346   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
32347   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
32348   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
32349   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
32350   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
32351   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
32352   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
32353 };
32354 
32355 const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
32356 const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
32357 
32358 class ThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
32359  public:
ThreadDescriptor_Decoder(const uint8_t * data,size_t len)32360   ThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ThreadDescriptor_Decoder(const std::string & raw)32361   explicit ThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ThreadDescriptor_Decoder(const::protozero::ConstBytes & raw)32362   explicit ThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_pid() const32363   bool has_pid() const { return at<1>().valid(); }
pid() const32364   int32_t pid() const { return at<1>().as_int32(); }
has_tid() const32365   bool has_tid() const { return at<2>().valid(); }
tid() const32366   int32_t tid() const { return at<2>().as_int32(); }
has_thread_name() const32367   bool has_thread_name() const { return at<5>().valid(); }
thread_name() const32368   ::protozero::ConstChars thread_name() const { return at<5>().as_string(); }
has_chrome_thread_type() const32369   bool has_chrome_thread_type() const { return at<4>().valid(); }
chrome_thread_type() const32370   int32_t chrome_thread_type() const { return at<4>().as_int32(); }
has_reference_timestamp_us() const32371   bool has_reference_timestamp_us() const { return at<6>().valid(); }
reference_timestamp_us() const32372   int64_t reference_timestamp_us() const { return at<6>().as_int64(); }
has_reference_thread_time_us() const32373   bool has_reference_thread_time_us() const { return at<7>().valid(); }
reference_thread_time_us() const32374   int64_t reference_thread_time_us() const { return at<7>().as_int64(); }
has_reference_thread_instruction_count() const32375   bool has_reference_thread_instruction_count() const { return at<8>().valid(); }
reference_thread_instruction_count() const32376   int64_t reference_thread_instruction_count() const { return at<8>().as_int64(); }
has_legacy_sort_index() const32377   bool has_legacy_sort_index() const { return at<3>().valid(); }
legacy_sort_index() const32378   int32_t legacy_sort_index() const { return at<3>().as_int32(); }
32379 };
32380 
32381 class ThreadDescriptor : public ::protozero::Message {
32382  public:
32383   using Decoder = ThreadDescriptor_Decoder;
32384   enum : int32_t {
32385     kPidFieldNumber = 1,
32386     kTidFieldNumber = 2,
32387     kThreadNameFieldNumber = 5,
32388     kChromeThreadTypeFieldNumber = 4,
32389     kReferenceTimestampUsFieldNumber = 6,
32390     kReferenceThreadTimeUsFieldNumber = 7,
32391     kReferenceThreadInstructionCountFieldNumber = 8,
32392     kLegacySortIndexFieldNumber = 3,
32393   };
32394   using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
32395   static const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
32396   static const ChromeThreadType CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
32397   static const ChromeThreadType CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
32398   static const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
32399   static const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
32400   static const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
32401   static const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
32402   static const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
32403   static const ChromeThreadType CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
32404   static const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
32405   static const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
32406   static const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
32407   static const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
32408   static const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
set_pid(int32_t value)32409   void set_pid(int32_t value) {
32410     AppendVarInt(1, value);
32411   }
set_tid(int32_t value)32412   void set_tid(int32_t value) {
32413     AppendVarInt(2, value);
32414   }
set_thread_name(const std::string & value)32415   void set_thread_name(const std::string& value) {
32416     AppendBytes(5, value.data(), value.size());
32417   }
set_thread_name(const char * data,size_t size)32418   void set_thread_name(const char* data, size_t size) {
32419     AppendBytes(5, data, size);
32420   }
set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value)32421   void set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value) {
32422     AppendTinyVarInt(4, value);
32423   }
set_reference_timestamp_us(int64_t value)32424   void set_reference_timestamp_us(int64_t value) {
32425     AppendVarInt(6, value);
32426   }
set_reference_thread_time_us(int64_t value)32427   void set_reference_thread_time_us(int64_t value) {
32428     AppendVarInt(7, value);
32429   }
set_reference_thread_instruction_count(int64_t value)32430   void set_reference_thread_instruction_count(int64_t value) {
32431     AppendVarInt(8, value);
32432   }
set_legacy_sort_index(int32_t value)32433   void set_legacy_sort_index(int32_t value) {
32434     AppendVarInt(3, value);
32435   }
32436 };
32437 
32438 } // Namespace.
32439 } // Namespace.
32440 } // Namespace.
32441 #endif  // Include guard.
32442 /*
32443  * Copyright (C) 2019 The Android Open Source Project
32444  *
32445  * Licensed under the Apache License, Version 2.0 (the "License");
32446  * you may not use this file except in compliance with the License.
32447  * You may obtain a copy of the License at
32448  *
32449  *      http://www.apache.org/licenses/LICENSE-2.0
32450  *
32451  * Unless required by applicable law or agreed to in writing, software
32452  * distributed under the License is distributed on an "AS IS" BASIS,
32453  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32454  * See the License for the specific language governing permissions and
32455  * limitations under the License.
32456  */
32457 
32458 // gen_amalgamated expanded: #include "perfetto/tracing/track.h"
32459 
32460 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
32461 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
32462 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
32463 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
32464 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
32465 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
32466 
32467 namespace perfetto {
32468 
32469 // static
32470 uint64_t Track::process_uuid;
32471 
Serialize() const32472 protos::gen::TrackDescriptor Track::Serialize() const {
32473   protos::gen::TrackDescriptor desc;
32474   desc.set_uuid(uuid);
32475   if (parent_uuid)
32476     desc.set_parent_uuid(parent_uuid);
32477   return desc;
32478 }
32479 
Serialize(protos::pbzero::TrackDescriptor * desc) const32480 void Track::Serialize(protos::pbzero::TrackDescriptor* desc) const {
32481   auto bytes = Serialize().SerializeAsString();
32482   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
32483 }
32484 
Serialize() const32485 protos::gen::TrackDescriptor ProcessTrack::Serialize() const {
32486   auto desc = Track::Serialize();
32487   auto pd = desc.mutable_process();
32488   pd->set_pid(static_cast<int32_t>(pid));
32489   // TODO(skyostil): Record command line.
32490   return desc;
32491 }
32492 
Serialize(protos::pbzero::TrackDescriptor * desc) const32493 void ProcessTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
32494   auto bytes = Serialize().SerializeAsString();
32495   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
32496 }
32497 
Serialize() const32498 protos::gen::TrackDescriptor ThreadTrack::Serialize() const {
32499   auto desc = Track::Serialize();
32500   auto td = desc.mutable_thread();
32501   td->set_pid(static_cast<int32_t>(pid));
32502   td->set_tid(static_cast<int32_t>(tid));
32503   // TODO(skyostil): Record thread name.
32504   return desc;
32505 }
32506 
Serialize(protos::pbzero::TrackDescriptor * desc) const32507 void ThreadTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
32508   auto bytes = Serialize().SerializeAsString();
32509   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
32510 }
32511 
32512 namespace internal {
32513 
32514 // static
32515 TrackRegistry* TrackRegistry::instance_;
32516 
32517 TrackRegistry::TrackRegistry() = default;
32518 TrackRegistry::~TrackRegistry() = default;
32519 
32520 // static
InitializeInstance()32521 void TrackRegistry::InitializeInstance() {
32522   // TODO(eseckler): Chrome may call this more than once. Once Chrome doesn't
32523   // call this directly anymore, bring back DCHECK(!instance_) instead.
32524   if (instance_)
32525     return;
32526   instance_ = new TrackRegistry();
32527   Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
32528 }
32529 
UpdateTrack(Track track,const std::string & serialized_desc)32530 void TrackRegistry::UpdateTrack(Track track,
32531                                 const std::string& serialized_desc) {
32532   std::lock_guard<std::mutex> lock(mutex_);
32533   tracks_[track.uuid] = std::move(serialized_desc);
32534 }
32535 
UpdateTrackImpl(Track track,std::function<void (protos::pbzero::TrackDescriptor *)> fill_function)32536 void TrackRegistry::UpdateTrackImpl(
32537     Track track,
32538     std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
32539   constexpr size_t kInitialSliceSize = 32;
32540   constexpr size_t kMaximumSliceSize = 4096;
32541   protozero::HeapBuffered<protos::pbzero::TrackDescriptor> new_descriptor(
32542       kInitialSliceSize, kMaximumSliceSize);
32543   fill_function(new_descriptor.get());
32544   auto serialized_desc = new_descriptor.SerializeAsString();
32545   UpdateTrack(track, serialized_desc);
32546 }
32547 
EraseTrack(Track track)32548 void TrackRegistry::EraseTrack(Track track) {
32549   std::lock_guard<std::mutex> lock(mutex_);
32550   tracks_.erase(track.uuid);
32551 }
32552 
32553 // static
WriteTrackDescriptor(const SerializedTrackDescriptor & desc,protozero::MessageHandle<protos::pbzero::TracePacket> packet)32554 void TrackRegistry::WriteTrackDescriptor(
32555     const SerializedTrackDescriptor& desc,
32556     protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
32557   packet->AppendString(
32558       perfetto::protos::pbzero::TracePacket::kTrackDescriptorFieldNumber, desc);
32559 }
32560 
32561 }  // namespace internal
32562 }  // namespace perfetto
32563 // gen_amalgamated begin source: src/tracing/track_event_category_registry.cc
32564 /*
32565  * Copyright (C) 2019 The Android Open Source Project
32566  *
32567  * Licensed under the Apache License, Version 2.0 (the "License");
32568  * you may not use this file except in compliance with the License.
32569  * You may obtain a copy of the License at
32570  *
32571  *      http://www.apache.org/licenses/LICENSE-2.0
32572  *
32573  * Unless required by applicable law or agreed to in writing, software
32574  * distributed under the License is distributed on an "AS IS" BASIS,
32575  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32576  * See the License for the specific language governing permissions and
32577  * limitations under the License.
32578  */
32579 
32580 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
32581 
32582 namespace perfetto {
32583 
32584 // static
FromDynamicCategory(const char * name)32585 Category Category::FromDynamicCategory(const char* name) {
32586   if (GetNthNameSize(1, name, name)) {
32587     Category group(Group(name));
32588     PERFETTO_DCHECK(group.name);
32589     return group;
32590   }
32591   Category category(name);
32592   PERFETTO_DCHECK(category.name);
32593   return category;
32594 }
32595 
FromDynamicCategory(const DynamicCategory & dynamic_category)32596 Category Category::FromDynamicCategory(
32597     const DynamicCategory& dynamic_category) {
32598   return FromDynamicCategory(dynamic_category.name.c_str());
32599 }
32600 
32601 namespace internal {
32602 
NullCategory(const perfetto::DynamicCategory &)32603 perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&) {
32604   return perfetto::DynamicCategory{};
32605 }
32606 
GetCategory(size_t index) const32607 const Category* TrackEventCategoryRegistry::GetCategory(size_t index) const {
32608   PERFETTO_DCHECK(index < category_count_);
32609   return &categories_[index];
32610 }
32611 
EnableCategoryForInstance(size_t category_index,uint32_t instance_index) const32612 void TrackEventCategoryRegistry::EnableCategoryForInstance(
32613     size_t category_index,
32614     uint32_t instance_index) const {
32615   PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
32616   PERFETTO_DCHECK(category_index < category_count_);
32617   // Matches the acquire_load in DataSource::Trace().
32618   state_storage_[category_index].fetch_or(
32619       static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
32620 }
32621 
DisableCategoryForInstance(size_t category_index,uint32_t instance_index) const32622 void TrackEventCategoryRegistry::DisableCategoryForInstance(
32623     size_t category_index,
32624     uint32_t instance_index) const {
32625   PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
32626   PERFETTO_DCHECK(category_index < category_count_);
32627   // Matches the acquire_load in DataSource::Trace().
32628   state_storage_[category_index].fetch_and(
32629       static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
32630 }
32631 
32632 }  // namespace internal
32633 }  // namespace perfetto
32634 // gen_amalgamated begin source: src/tracing/track_event_legacy.cc
32635 /*
32636  * Copyright (C) 2020 The Android Open Source Project
32637  *
32638  * Licensed under the Apache License, Version 2.0 (the "License");
32639  * you may not use this file except in compliance with the License.
32640  * You may obtain a copy of the License at
32641  *
32642  *      http://www.apache.org/licenses/LICENSE-2.0
32643  *
32644  * Unless required by applicable law or agreed to in writing, software
32645  * distributed under the License is distributed on an "AS IS" BASIS,
32646  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32647  * See the License for the specific language governing permissions and
32648  * limitations under the License.
32649  */
32650 
32651 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
32652 
32653 // gen_amalgamated expanded: #include "perfetto/tracing/track.h"
32654 
32655 namespace perfetto {
32656 namespace legacy {
32657 
32658 template <>
ConvertThreadId(const PerfettoLegacyCurrentThreadId &,uint64_t *,int32_t *,int32_t *)32659 bool ConvertThreadId(const PerfettoLegacyCurrentThreadId&,
32660                      uint64_t*,
32661                      int32_t*,
32662                      int32_t*) {
32663   // No need to override anything for events on to the current thread.
32664   return false;
32665 }
32666 
32667 }  // namespace legacy
32668 
32669 namespace internal {
32670 
Write(protos::pbzero::TrackEvent::LegacyEvent * event,uint32_t event_flags) const32671 void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
32672                           uint32_t event_flags) const {
32673   // Legacy flow events always use bind_id.
32674   if (event_flags &
32675       (legacy::kTraceEventFlagFlowOut | legacy::kTraceEventFlagFlowIn)) {
32676     // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
32677     // avoid collisions.
32678     if (id_flags_ & legacy::kTraceEventFlagHasLocalId) {
32679       event->set_bind_id(raw_id_ ^ ProcessTrack::Current().uuid);
32680     } else {
32681       event->set_bind_id(raw_id_);
32682     }
32683     return;
32684   }
32685 
32686   uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
32687                                       legacy::kTraceEventFlagHasLocalId |
32688                                       legacy::kTraceEventFlagHasGlobalId);
32689   switch (scope_flags) {
32690     case legacy::kTraceEventFlagHasId:
32691       event->set_unscoped_id(raw_id_);
32692       break;
32693     case legacy::kTraceEventFlagHasLocalId:
32694       event->set_local_id(raw_id_);
32695       break;
32696     case legacy::kTraceEventFlagHasGlobalId:
32697       event->set_global_id(raw_id_);
32698       break;
32699   }
32700   if (scope_)
32701     event->set_id_scope(scope_);
32702 }
32703 
32704 }  // namespace internal
32705 }  // namespace perfetto
32706 // gen_amalgamated begin source: src/tracing/virtual_destructors.cc
32707 /*
32708  * Copyright (C) 2019 The Android Open Source Project
32709  *
32710  * Licensed under the Apache License, Version 2.0 (the "License");
32711  * you may not use this file except in compliance with the License.
32712  * You may obtain a copy of the License at
32713  *
32714  *      http://www.apache.org/licenses/LICENSE-2.0
32715  *
32716  * Unless required by applicable law or agreed to in writing, software
32717  * distributed under the License is distributed on an "AS IS" BASIS,
32718  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32719  * See the License for the specific language governing permissions and
32720  * limitations under the License.
32721  */
32722 
32723 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
32724 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
32725 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
32726 
32727 // This translation unit contains the definitions for the destructor of pure
32728 // virtual interfaces for the src/public:public target. The alternative would be
32729 // introducing a one-liner .cc file for each pure virtual interface, which is
32730 // overkill. This is for compliance with -Wweak-vtables.
32731 
32732 namespace perfetto {
32733 namespace internal {
32734 
32735 TracingTLS::~TracingTLS() = default;
32736 
32737 }  // namespace internal
32738 
32739 TracingBackend::~TracingBackend() = default;
32740 TracingSession::~TracingSession() = default;
32741 
32742 }  // namespace perfetto
32743 // gen_amalgamated begin source: src/tracing/core/metatrace_writer.cc
32744 // gen_amalgamated begin header: src/tracing/core/metatrace_writer.h
32745 /*
32746  * Copyright (C) 2019 The Android Open Source Project
32747  *
32748  * Licensed under the Apache License, Version 2.0 (the "License");
32749  * you may not use this file except in compliance with the License.
32750  * You may obtain a copy of the License at
32751  *
32752  *      http://www.apache.org/licenses/LICENSE-2.0
32753  *
32754  * Unless required by applicable law or agreed to in writing, software
32755  * distributed under the License is distributed on an "AS IS" BASIS,
32756  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32757  * See the License for the specific language governing permissions and
32758  * limitations under the License.
32759  */
32760 
32761 #ifndef SRC_TRACING_CORE_METATRACE_WRITER_H_
32762 #define SRC_TRACING_CORE_METATRACE_WRITER_H_
32763 
32764 #include <functional>
32765 #include <memory>
32766 
32767 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
32768 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
32769 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
32770 
32771 namespace perfetto {
32772 
32773 namespace base {
32774 class TaskRunner;
32775 }
32776 
32777 class TraceWriter;
32778 
32779 // Complements the base::metatrace infrastructure.
32780 // It hooks a callback to metatrace::Enable() and writes metatrace events into
32781 // a TraceWriter whenever the metatrace ring buffer is half full.
32782 // It is safe to create and attempt to start multiple instances of this class,
32783 // however only the first one will succeed because the metatrace framework
32784 // doesn't support multiple instances.
32785 // This class is defined here (instead of directly in src/probes/) so it can
32786 // be reused by other components (e.g. heapprofd).
32787 class MetatraceWriter {
32788  public:
32789   static constexpr char kDataSourceName[] = "perfetto.metatrace";
32790 
32791   MetatraceWriter();
32792   ~MetatraceWriter();
32793 
32794   MetatraceWriter(const MetatraceWriter&) = delete;
32795   MetatraceWriter& operator=(const MetatraceWriter&) = delete;
32796   MetatraceWriter(MetatraceWriter&&) = delete;
32797   MetatraceWriter& operator=(MetatraceWriter&&) = delete;
32798 
32799   void Enable(base::TaskRunner*, std::unique_ptr<TraceWriter>, uint32_t tags);
32800   void Disable();
32801   void WriteAllAndFlushTraceWriter(std::function<void()> callback);
32802 
32803  private:
32804   void WriteAllAvailableEvents();
32805 
32806   bool started_ = false;
32807   base::TaskRunner* task_runner_ = nullptr;
32808   std::unique_ptr<TraceWriter> trace_writer_;
32809   PERFETTO_THREAD_CHECKER(thread_checker_)
32810   base::WeakPtrFactory<MetatraceWriter> weak_ptr_factory_;  // Keep last.
32811 };
32812 
32813 }  // namespace perfetto
32814 
32815 #endif  // SRC_TRACING_CORE_METATRACE_WRITER_H_
32816 // gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h
32817 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
32818 
32819 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
32820 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
32821 
32822 #include <stddef.h>
32823 #include <stdint.h>
32824 
32825 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
32826 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
32827 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
32828 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
32829 
32830 namespace perfetto {
32831 namespace protos {
32832 namespace pbzero {
32833 
32834 class PerfettoMetatrace_Arg;
32835 
32836 class PerfettoMetatrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
32837  public:
PerfettoMetatrace_Decoder(const uint8_t * data,size_t len)32838   PerfettoMetatrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
PerfettoMetatrace_Decoder(const std::string & raw)32839   explicit PerfettoMetatrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
PerfettoMetatrace_Decoder(const::protozero::ConstBytes & raw)32840   explicit PerfettoMetatrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_event_id() const32841   bool has_event_id() const { return at<1>().valid(); }
event_id() const32842   uint32_t event_id() const { return at<1>().as_uint32(); }
has_counter_id() const32843   bool has_counter_id() const { return at<2>().valid(); }
counter_id() const32844   uint32_t counter_id() const { return at<2>().as_uint32(); }
has_event_name() const32845   bool has_event_name() const { return at<8>().valid(); }
event_name() const32846   ::protozero::ConstChars event_name() const { return at<8>().as_string(); }
has_counter_name() const32847   bool has_counter_name() const { return at<9>().valid(); }
counter_name() const32848   ::protozero::ConstChars counter_name() const { return at<9>().as_string(); }
has_event_duration_ns() const32849   bool has_event_duration_ns() const { return at<3>().valid(); }
event_duration_ns() const32850   uint32_t event_duration_ns() const { return at<3>().as_uint32(); }
has_counter_value() const32851   bool has_counter_value() const { return at<4>().valid(); }
counter_value() const32852   int32_t counter_value() const { return at<4>().as_int32(); }
has_thread_id() const32853   bool has_thread_id() const { return at<5>().valid(); }
thread_id() const32854   uint32_t thread_id() const { return at<5>().as_uint32(); }
has_has_overruns() const32855   bool has_has_overruns() const { return at<6>().valid(); }
has_overruns() const32856   bool has_overruns() const { return at<6>().as_bool(); }
has_args() const32857   bool has_args() const { return at<7>().valid(); }
args() const32858   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(7); }
32859 };
32860 
32861 class PerfettoMetatrace : public ::protozero::Message {
32862  public:
32863   using Decoder = PerfettoMetatrace_Decoder;
32864   enum : int32_t {
32865     kEventIdFieldNumber = 1,
32866     kCounterIdFieldNumber = 2,
32867     kEventNameFieldNumber = 8,
32868     kCounterNameFieldNumber = 9,
32869     kEventDurationNsFieldNumber = 3,
32870     kCounterValueFieldNumber = 4,
32871     kThreadIdFieldNumber = 5,
32872     kHasOverrunsFieldNumber = 6,
32873     kArgsFieldNumber = 7,
32874   };
32875   using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
set_event_id(uint32_t value)32876   void set_event_id(uint32_t value) {
32877     AppendVarInt(1, value);
32878   }
set_counter_id(uint32_t value)32879   void set_counter_id(uint32_t value) {
32880     AppendVarInt(2, value);
32881   }
set_event_name(const std::string & value)32882   void set_event_name(const std::string& value) {
32883     AppendBytes(8, value.data(), value.size());
32884   }
set_event_name(const char * data,size_t size)32885   void set_event_name(const char* data, size_t size) {
32886     AppendBytes(8, data, size);
32887   }
set_counter_name(const std::string & value)32888   void set_counter_name(const std::string& value) {
32889     AppendBytes(9, value.data(), value.size());
32890   }
set_counter_name(const char * data,size_t size)32891   void set_counter_name(const char* data, size_t size) {
32892     AppendBytes(9, data, size);
32893   }
set_event_duration_ns(uint32_t value)32894   void set_event_duration_ns(uint32_t value) {
32895     AppendVarInt(3, value);
32896   }
set_counter_value(int32_t value)32897   void set_counter_value(int32_t value) {
32898     AppendVarInt(4, value);
32899   }
set_thread_id(uint32_t value)32900   void set_thread_id(uint32_t value) {
32901     AppendVarInt(5, value);
32902   }
set_has_overruns(bool value)32903   void set_has_overruns(bool value) {
32904     AppendTinyVarInt(6, value);
32905   }
add_args()32906   template <typename T = PerfettoMetatrace_Arg> T* add_args() {
32907     return BeginNestedMessage<T>(7);
32908   }
32909 
32910 };
32911 
32912 class PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
32913  public:
PerfettoMetatrace_Arg_Decoder(const uint8_t * data,size_t len)32914   PerfettoMetatrace_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
PerfettoMetatrace_Arg_Decoder(const std::string & raw)32915   explicit PerfettoMetatrace_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
PerfettoMetatrace_Arg_Decoder(const::protozero::ConstBytes & raw)32916   explicit PerfettoMetatrace_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_key() const32917   bool has_key() const { return at<1>().valid(); }
key() const32918   ::protozero::ConstChars key() const { return at<1>().as_string(); }
has_value() const32919   bool has_value() const { return at<2>().valid(); }
value() const32920   ::protozero::ConstChars value() const { return at<2>().as_string(); }
32921 };
32922 
32923 class PerfettoMetatrace_Arg : public ::protozero::Message {
32924  public:
32925   using Decoder = PerfettoMetatrace_Arg_Decoder;
32926   enum : int32_t {
32927     kKeyFieldNumber = 1,
32928     kValueFieldNumber = 2,
32929   };
set_key(const std::string & value)32930   void set_key(const std::string& value) {
32931     AppendBytes(1, value.data(), value.size());
32932   }
set_key(const char * data,size_t size)32933   void set_key(const char* data, size_t size) {
32934     AppendBytes(1, data, size);
32935   }
set_value(const std::string & value)32936   void set_value(const std::string& value) {
32937     AppendBytes(2, value.data(), value.size());
32938   }
set_value(const char * data,size_t size)32939   void set_value(const char* data, size_t size) {
32940     AppendBytes(2, data, size);
32941   }
32942 };
32943 
32944 } // Namespace.
32945 } // Namespace.
32946 } // Namespace.
32947 #endif  // Include guard.
32948 /*
32949  * Copyright (C) 2019 The Android Open Source Project
32950  *
32951  * Licensed under the Apache License, Version 2.0 (the "License");
32952  * you may not use this file except in compliance with the License.
32953  * You may obtain a copy of the License at
32954  *
32955  *      http://www.apache.org/licenses/LICENSE-2.0
32956  *
32957  * Unless required by applicable law or agreed to in writing, software
32958  * distributed under the License is distributed on an "AS IS" BASIS,
32959  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32960  * See the License for the specific language governing permissions and
32961  * limitations under the License.
32962  */
32963 
32964 // gen_amalgamated expanded: #include "src/tracing/core/metatrace_writer.h"
32965 
32966 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
32967 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
32968 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
32969 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
32970 
32971 // gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
32972 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
32973 
32974 namespace perfetto {
32975 
32976 // static
32977 constexpr char MetatraceWriter::kDataSourceName[];
32978 
MetatraceWriter()32979 MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}
32980 
~MetatraceWriter()32981 MetatraceWriter::~MetatraceWriter() {
32982   Disable();
32983 }
32984 
Enable(base::TaskRunner * task_runner,std::unique_ptr<TraceWriter> trace_writer,uint32_t tags)32985 void MetatraceWriter::Enable(base::TaskRunner* task_runner,
32986                              std::unique_ptr<TraceWriter> trace_writer,
32987                              uint32_t tags) {
32988   PERFETTO_DCHECK_THREAD(thread_checker_);
32989   if (started_) {
32990     PERFETTO_DFATAL_OR_ELOG("Metatrace already started from this instance");
32991     return;
32992   }
32993   task_runner_ = task_runner;
32994   trace_writer_ = std::move(trace_writer);
32995   auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
32996   bool enabled = metatrace::Enable(
32997       [weak_ptr] {
32998         if (weak_ptr)
32999           weak_ptr->WriteAllAvailableEvents();
33000       },
33001       task_runner, tags);
33002   if (!enabled)
33003     return;
33004   started_ = true;
33005 }
33006 
Disable()33007 void MetatraceWriter::Disable() {
33008   PERFETTO_DCHECK_THREAD(thread_checker_);
33009   if (!started_)
33010     return;
33011   metatrace::Disable();
33012   started_ = false;
33013   trace_writer_.reset();
33014 }
33015 
WriteAllAvailableEvents()33016 void MetatraceWriter::WriteAllAvailableEvents() {
33017   PERFETTO_DCHECK_THREAD(thread_checker_);
33018   if (!started_)
33019     return;
33020   for (auto it = metatrace::RingBuffer::GetReadIterator(); it; ++it) {
33021     auto type_and_id = it->type_and_id.load(std::memory_order_acquire);
33022     if (type_and_id == 0)
33023       break;  // Stop at the first incomplete event.
33024 
33025     auto packet = trace_writer_->NewTracePacket();
33026     packet->set_timestamp(it->timestamp_ns());
33027     auto* evt = packet->set_perfetto_metatrace();
33028     uint16_t type = type_and_id & metatrace::Record::kTypeMask;
33029     uint16_t id = type_and_id & ~metatrace::Record::kTypeMask;
33030     if (type == metatrace::Record::kTypeCounter) {
33031       evt->set_counter_id(id);
33032       evt->set_counter_value(it->counter_value);
33033     } else {
33034       evt->set_event_id(id);
33035       evt->set_event_duration_ns(it->duration_ns);
33036     }
33037 
33038     evt->set_thread_id(static_cast<uint32_t>(it->thread_id));
33039 
33040     if (metatrace::RingBuffer::has_overruns())
33041       evt->set_has_overruns(true);
33042   }
33043   // The |it| destructor will automatically update the read index position in
33044   // the meta-trace ring buffer.
33045 }
33046 
WriteAllAndFlushTraceWriter(std::function<void ()> callback)33047 void MetatraceWriter::WriteAllAndFlushTraceWriter(
33048     std::function<void()> callback) {
33049   PERFETTO_DCHECK_THREAD(thread_checker_);
33050   if (!started_)
33051     return;
33052   WriteAllAvailableEvents();
33053   trace_writer_->Flush(std::move(callback));
33054 }
33055 
33056 }  // namespace perfetto
33057 // gen_amalgamated begin source: src/tracing/core/packet_stream_validator.cc
33058 // gen_amalgamated begin header: src/tracing/core/packet_stream_validator.h
33059 /*
33060  * Copyright (C) 2018 The Android Open Source Project
33061  *
33062  * Licensed under the Apache License, Version 2.0 (the "License");
33063  * you may not use this file except in compliance with the License.
33064  * You may obtain a copy of the License at
33065  *
33066  *      http://www.apache.org/licenses/LICENSE-2.0
33067  *
33068  * Unless required by applicable law or agreed to in writing, software
33069  * distributed under the License is distributed on an "AS IS" BASIS,
33070  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33071  * See the License for the specific language governing permissions and
33072  * limitations under the License.
33073  */
33074 
33075 #ifndef SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
33076 #define SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
33077 
33078 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
33079 
33080 namespace perfetto {
33081 
33082 // Checks that the stream of trace packets sent by the producer is well formed.
33083 // This includes:
33084 //
33085 // - Checking that the packets are not truncated.
33086 // - There are no dangling bytes left over in the packets.
33087 // - Any trusted fields (e.g., uid) are not set.
33088 //
33089 // Note that we only validate top-level fields in the trace proto; sub-messages
33090 // are simply skipped.
33091 class PacketStreamValidator {
33092  public:
33093   PacketStreamValidator() = delete;
33094 
33095   static bool Validate(const Slices&);
33096 };
33097 
33098 }  // namespace perfetto
33099 
33100 #endif  // SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
33101 /*
33102  * Copyright (C) 2018 The Android Open Source Project
33103  *
33104  * Licensed under the Apache License, Version 2.0 (the "License");
33105  * you may not use this file except in compliance with the License.
33106  * You may obtain a copy of the License at
33107  *
33108  *      http://www.apache.org/licenses/LICENSE-2.0
33109  *
33110  * Unless required by applicable law or agreed to in writing, software
33111  * distributed under the License is distributed on an "AS IS" BASIS,
33112  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33113  * See the License for the specific language governing permissions and
33114  * limitations under the License.
33115  */
33116 
33117 // gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
33118 
33119 #include <inttypes.h>
33120 #include <stddef.h>
33121 
33122 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
33123 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
33124 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
33125 
33126 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
33127 
33128 namespace perfetto {
33129 
33130 namespace {
33131 
33132 using protozero::proto_utils::ProtoWireType;
33133 
33134 const uint32_t kReservedFieldIds[] = {
33135     protos::pbzero::TracePacket::kTrustedUidFieldNumber,
33136     protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
33137     protos::pbzero::TracePacket::kTraceConfigFieldNumber,
33138     protos::pbzero::TracePacket::kTraceStatsFieldNumber,
33139     protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
33140     protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
33141 };
33142 
33143 // This translation unit is quite subtle and perf-sensitive. Remember to check
33144 // BM_PacketStreamValidator in perfetto_benchmarks when making changes.
33145 
33146 // Checks that a packet, spread over several slices, is well-formed and doesn't
33147 // contain reserved top-level fields.
33148 // The checking logic is based on a state-machine that skips the fields' payload
33149 // and operates as follows:
33150 //              +-------------------------------+ <-------------------------+
33151 // +----------> | Read field preamble (varint)  | <----------------------+  |
33152 // |            +-------------------------------+                        |  |
33153 // |              |              |            |                          |  |
33154 // |       <Varint>        <Fixed 32/64>     <Length-delimited field>    |  |
33155 // |          V                  |                      V                |  |
33156 // |  +------------------+       |               +--------------+        |  |
33157 // |  | Read field value |       |               | Read length  |        |  |
33158 // |  | (another varint) |       |               |   (varint)   |        |  |
33159 // |  +------------------+       |               +--------------+        |  |
33160 // |           |                 V                      V                |  |
33161 // +-----------+        +----------------+     +-----------------+       |  |
33162 //                      | Skip 4/8 Bytes |     | Skip $len Bytes |-------+  |
33163 //                      +----------------+     +-----------------+          |
33164 //                               |                                          |
33165 //                               +------------------------------------------+
33166 class ProtoFieldParserFSM {
33167  public:
33168   // This method effectively continuously parses varints (either for the field
33169   // preamble or the payload or the submessage length) and tells the caller
33170   // (the Validate() method) how many bytes to skip until the next field.
Push(uint8_t octet)33171   size_t Push(uint8_t octet) {
33172     varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
33173     if (octet & 0x80) {
33174       varint_shift_ += 7;
33175       if (varint_shift_ >= 64)
33176         state_ = kInvalidVarInt;
33177       return 0;
33178     }
33179     uint64_t varint = varint_;
33180     varint_ = 0;
33181     varint_shift_ = 0;
33182 
33183     switch (state_) {
33184       case kFieldPreamble: {
33185         uint64_t field_type = varint & 7;  // 7 = 0..0111
33186         auto field_id = static_cast<uint32_t>(varint >> 3);
33187         // Check if the field id is reserved, go into an error state if it is.
33188         for (size_t i = 0; i < base::ArraySize(kReservedFieldIds); ++i) {
33189           if (field_id == kReservedFieldIds[i]) {
33190             state_ = kWroteReservedField;
33191             return 0;
33192           }
33193         }
33194         // The field type is legit, now check it's well formed and within
33195         // boundaries.
33196         if (field_type == static_cast<uint64_t>(ProtoWireType::kVarInt)) {
33197           state_ = kVarIntValue;
33198         } else if (field_type ==
33199                    static_cast<uint64_t>(ProtoWireType::kFixed32)) {
33200           return 4;
33201         } else if (field_type ==
33202                    static_cast<uint64_t>(ProtoWireType::kFixed64)) {
33203           return 8;
33204         } else if (field_type ==
33205                    static_cast<uint64_t>(ProtoWireType::kLengthDelimited)) {
33206           state_ = kLenDelimitedLen;
33207         } else {
33208           state_ = kUnknownFieldType;
33209         }
33210         return 0;
33211       }
33212 
33213       case kVarIntValue: {
33214         // Consume the int field payload and go back to the next field.
33215         state_ = kFieldPreamble;
33216         return 0;
33217       }
33218 
33219       case kLenDelimitedLen: {
33220         if (varint > protozero::proto_utils::kMaxMessageLength) {
33221           state_ = kMessageTooBig;
33222           return 0;
33223         }
33224         state_ = kFieldPreamble;
33225         return static_cast<size_t>(varint);
33226       }
33227 
33228       case kWroteReservedField:
33229       case kUnknownFieldType:
33230       case kMessageTooBig:
33231       case kInvalidVarInt:
33232         // Persistent error states.
33233         return 0;
33234 
33235     }          // switch(state_)
33236     return 0;  // To keep GCC happy.
33237   }
33238 
33239   // Queried at the end of the all payload. A message is well-formed only
33240   // if the FSM is back to the state where it should parse the next field and
33241   // hasn't started parsing any preamble.
valid() const33242   bool valid() const { return state_ == kFieldPreamble && varint_shift_ == 0; }
state() const33243   int state() const { return static_cast<int>(state_); }
33244 
33245  private:
33246   enum State {
33247     kFieldPreamble = 0,  // Parsing the varint for the field preamble.
33248     kVarIntValue,        // Parsing the varint value for the field payload.
33249     kLenDelimitedLen,    // Parsing the length of the length-delimited field.
33250 
33251     // Error states:
33252     kWroteReservedField,  // Tried to set a reserved field id.
33253     kUnknownFieldType,    // Encountered an invalid field type.
33254     kMessageTooBig,       // Size of the length delimited message was too big.
33255     kInvalidVarInt,       // VarInt larger than 64 bits.
33256   };
33257 
33258   State state_ = kFieldPreamble;
33259   uint64_t varint_ = 0;
33260   uint32_t varint_shift_ = 0;
33261 };
33262 
33263 }  // namespace
33264 
33265 // static
Validate(const Slices & slices)33266 bool PacketStreamValidator::Validate(const Slices& slices) {
33267   ProtoFieldParserFSM parser;
33268   size_t skip_bytes = 0;
33269   for (const Slice& slice : slices) {
33270     for (size_t i = 0; i < slice.size;) {
33271       const size_t skip_bytes_cur_slice = std::min(skip_bytes, slice.size - i);
33272       if (skip_bytes_cur_slice > 0) {
33273         i += skip_bytes_cur_slice;
33274         skip_bytes -= skip_bytes_cur_slice;
33275       } else {
33276         uint8_t octet = *(reinterpret_cast<const uint8_t*>(slice.start) + i);
33277         skip_bytes = parser.Push(octet);
33278         i++;
33279       }
33280     }
33281   }
33282   if (skip_bytes == 0 && parser.valid())
33283     return true;
33284 
33285   PERFETTO_DLOG("Packet validation error (state %d, skip = %zu)",
33286                 parser.state(), skip_bytes);
33287   return false;
33288 }
33289 
33290 }  // namespace perfetto
33291 // gen_amalgamated begin source: src/tracing/core/trace_buffer.cc
33292 // gen_amalgamated begin header: src/tracing/core/trace_buffer.h
33293 /*
33294  * Copyright (C) 2018 The Android Open Source Project
33295  *
33296  * Licensed under the Apache License, Version 2.0 (the "License");
33297  * you may not use this file except in compliance with the License.
33298  * You may obtain a copy of the License at
33299  *
33300  *      http://www.apache.org/licenses/LICENSE-2.0
33301  *
33302  * Unless required by applicable law or agreed to in writing, software
33303  * distributed under the License is distributed on an "AS IS" BASIS,
33304  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33305  * See the License for the specific language governing permissions and
33306  * limitations under the License.
33307  */
33308 
33309 #ifndef SRC_TRACING_CORE_TRACE_BUFFER_H_
33310 #define SRC_TRACING_CORE_TRACE_BUFFER_H_
33311 
33312 #include <stdint.h>
33313 #include <string.h>
33314 
33315 #include <array>
33316 #include <limits>
33317 #include <map>
33318 #include <tuple>
33319 
33320 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
33321 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
33322 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
33323 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
33324 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
33325 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
33326 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
33327 
33328 namespace perfetto {
33329 
33330 class TracePacket;
33331 
33332 // The main buffer, owned by the tracing service, where all the trace data is
33333 // ultimately stored into. The service will own several instances of this class,
33334 // at least one per active consumer (as defined in the |buffers| section of
33335 // trace_config.proto) and will copy chunks from the producer's shared memory
33336 // buffers into here when a CommitData IPC is received.
33337 //
33338 // Writing into the buffer
33339 // -----------------------
33340 // Data is copied from the SMB(s) using CopyChunkUntrusted(). The buffer will
33341 // hence contain data coming from different producers and different writer
33342 // sequences, more specifically:
33343 // - The service receives data by several producer(s), identified by their ID.
33344 // - Each producer writes several sequences identified by the same WriterID.
33345 //   (they correspond to TraceWriter instances in the producer).
33346 // - Each Writer writes, in order, several chunks.
33347 // - Each chunk contains zero, one, or more TracePacket(s), or even just
33348 //   fragments of packets (when they span across several chunks).
33349 //
33350 // So at any point in time, the buffer will contain a variable number of logical
33351 // sequences identified by the {ProducerID, WriterID} tuple. Any given chunk
33352 // will only contain packets (or fragments) belonging to the same sequence.
33353 //
33354 // The buffer operates by default as a ring buffer.
33355 // It has two overwrite policies:
33356 //  1. kOverwrite (default): if the write pointer reaches the read pointer, old
33357 //     unread chunks will be overwritten by new chunks.
33358 //  2. kDiscard: if the write pointer reaches the read pointer, unread chunks
33359 //     are preserved and the new chunks are discarded. Any future write becomes
33360 //     a no-op, even if the reader manages to fully catch up. This is because
33361 //     once a chunk is discarded, the sequence of packets is broken and trying
33362 //     to recover would be too hard (also due to the fact that, at the same
33363 //     time, we allow out-of-order commits and chunk re-writes).
33364 //
33365 // Chunks are (over)written in the same order of the CopyChunkUntrusted() calls.
33366 // When overwriting old content, entire chunks are overwritten or clobbered.
33367 // The buffer never leaves a partial chunk around. Chunks' payload is copied
33368 // as-is, but their header is not and is repacked in order to keep the
33369 // ProducerID around.
33370 //
33371 // Chunks are stored in the buffer next to each other. Each chunk is prefixed by
33372 // an inline header (ChunkRecord), which contains most of the fields of the
33373 // SharedMemoryABI ChunkHeader + the ProducerID + the size of the payload.
33374 // It's a conventional binary object stream essentially, where each ChunkRecord
33375 // tells where it ends and hence where to find the next one, like this:
33376 //
33377 //          .-------------------------. 16 byte boundary
33378 //          | ChunkRecord:   16 bytes |
33379 //          | - chunk id:     4 bytes |
33380 //          | - producer id:  2 bytes |
33381 //          | - writer id:    2 bytes |
33382 //          | - #fragments:   2 bytes |
33383 //    +-----+ - record size:  2 bytes |
33384 //    |     | - flags+pad:    4 bytes |
33385 //    |     +-------------------------+
33386 //    |     |                         |
33387 //    |     :     Chunk payload       :
33388 //    |     |                         |
33389 //    |     +-------------------------+
33390 //    |     |    Optional padding     |
33391 //    +---> +-------------------------+ 16 byte boundary
33392 //          |      ChunkRecord        |
33393 //          :                         :
33394 // Chunks stored in the buffer are always rounded up to 16 bytes (that is
33395 // sizeof(ChunkRecord)), in order to avoid further inner fragmentation.
33396 // Special "padding" chunks can be put in the buffer, e.g. in the case when we
33397 // try to write a chunk of size N while the write pointer is at the end of the
33398 // buffer, but the write pointer is < N bytes from the end (and hence needs to
33399 // wrap over).
33400 // Because of this, the buffer is self-describing: the contents of the buffer
33401 // can be reconstructed by just looking at the buffer content (this will be
33402 // quite useful in future to recover the buffer from crash reports).
33403 //
33404 // However, in order to keep some operations (patching and reading) fast, a
33405 // lookaside index is maintained (in |index_|), keeping each chunk in the buffer
33406 // indexed by their {ProducerID, WriterID, ChunkID} tuple.
33407 //
33408 // Patching data out-of-band
33409 // -------------------------
33410 // This buffer also supports patching chunks' payload out-of-band, after they
33411 // have been stored. This is to allow producers to backfill the "size" fields
33412 // of the protos that spawn across several chunks, when the previous chunks are
33413 // returned to the service. The MaybePatchChunkContents() deals with the fact
33414 // that a chunk might have been lost (because of wrapping) by the time the OOB
33415 // IPC comes.
33416 //
33417 // Reading from the buffer
33418 // -----------------------
33419 // This class supports one reader only (the consumer). Reads are NOT idempotent
33420 // as they move the read cursors around. Reading back the buffer is the most
33421 // conceptually complex part. The ReadNextTracePacket() method operates with
33422 // whole packet granularity. Packets are returned only when all their fragments
33423 // are available.
33424 // This class takes care of:
33425 // - Gluing packets within the same sequence, even if they are not stored
33426 //   adjacently in the buffer.
33427 // - Re-ordering chunks within a sequence (using the ChunkID, which wraps).
33428 // - Detecting holes in packet fragments (because of loss of chunks).
33429 // Reads guarantee that packets for the same sequence are read in FIFO order
33430 // (according to their ChunkID), but don't give any guarantee about the read
33431 // order of packets from different sequences, see comments in
33432 // ReadNextTracePacket() below.
33433 class TraceBuffer {
33434  public:
33435   static const size_t InlineChunkHeaderSize;  // For test/fake_packet.{cc,h}.
33436 
33437   // See comment in the header above.
33438   enum OverwritePolicy { kOverwrite, kDiscard };
33439 
33440   // Argument for out-of-band patches applied through TryPatchChunkContents().
33441   struct Patch {
33442     // From SharedMemoryABI::kPacketHeaderSize.
33443     static constexpr size_t kSize = 4;
33444 
33445     size_t offset_untrusted;
33446     std::array<uint8_t, kSize> data;
33447   };
33448 
33449   // Identifiers that are constant for a packet sequence.
33450   struct PacketSequenceProperties {
33451     ProducerID producer_id_trusted;
33452     uid_t producer_uid_trusted;
33453     WriterID writer_id;
33454   };
33455 
33456   // Can return nullptr if the memory allocation fails.
33457   static std::unique_ptr<TraceBuffer> Create(size_t size_in_bytes,
33458                                              OverwritePolicy = kOverwrite);
33459 
33460   ~TraceBuffer();
33461 
33462   // Copies a Chunk from a producer Shared Memory Buffer into the trace buffer.
33463   // |src| points to the first packet in the SharedMemoryABI's chunk shared with
33464   // an untrusted producer. "untrusted" here means: the producer might be
33465   // malicious and might change |src| concurrently while we read it (internally
33466   // this method memcpy()-s first the chunk before processing it). None of the
33467   // arguments should be trusted, unless otherwise stated. We can trust that
33468   // |src| points to a valid memory area, but not its contents.
33469   //
33470   // This method may be called multiple times for the same chunk. In this case,
33471   // the original chunk's payload will be overridden and its number of fragments
33472   // and flags adjusted to match |num_fragments| and |chunk_flags|. The service
33473   // may use this to insert partial chunks (|chunk_complete = false|) before the
33474   // producer has committed them.
33475   //
33476   // If |chunk_complete| is |false|, the TraceBuffer will only consider the
33477   // first |num_fragments - 1| packets to be complete, since the producer may
33478   // not have finished writing the latest packet. Reading from a sequence will
33479   // also not progress past any incomplete chunks until they were rewritten with
33480   // |chunk_complete = true|, e.g. after a producer's commit.
33481   //
33482   // TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
33483   void CopyChunkUntrusted(ProducerID producer_id_trusted,
33484                           uid_t producer_uid_trusted,
33485                           WriterID writer_id,
33486                           ChunkID chunk_id,
33487                           uint16_t num_fragments,
33488                           uint8_t chunk_flags,
33489                           bool chunk_complete,
33490                           const uint8_t* src,
33491                           size_t size);
33492   // Applies a batch of |patches| to the given chunk, if the given chunk is
33493   // still in the buffer. Does nothing if the given ChunkID is gone.
33494   // Returns true if the chunk has been found and patched, false otherwise.
33495   // |other_patches_pending| is used to determine whether this is the only
33496   // batch of patches for the chunk or there is more.
33497   // If |other_patches_pending| == false, the chunk is marked as ready to be
33498   // consumed. If true, the state of the chunk is not altered.
33499   bool TryPatchChunkContents(ProducerID,
33500                              WriterID,
33501                              ChunkID,
33502                              const Patch* patches,
33503                              size_t patches_size,
33504                              bool other_patches_pending);
33505 
33506   // To read the contents of the buffer the caller needs to:
33507   //   BeginRead()
33508   //   while (ReadNextTracePacket(packet_fragments)) { ... }
33509   // No other calls to any other method should be interleaved between
33510   // BeginRead() and ReadNextTracePacket().
33511   // Reads in the TraceBuffer are NOT idempotent.
33512   void BeginRead();
33513 
33514   // Returns the next packet in the buffer, if any, and the producer_id,
33515   // producer_uid, and writer_id of the producer/writer that wrote it (as passed
33516   // in the CopyChunkUntrusted() call). Returns false if no packets can be read
33517   // at this point. If a packet was read successfully,
33518   // |previous_packet_on_sequence_dropped| is set to |true| if the previous
33519   // packet on the sequence was dropped from the buffer before it could be read
33520   // (e.g. because its chunk was overridden due to the ring buffer wrapping or
33521   // due to an ABI violation), and to |false| otherwise.
33522   //
33523   // This function returns only complete packets. Specifically:
33524   // When there is at least one complete packet in the buffer, this function
33525   // returns true and populates the TracePacket argument with the boundaries of
33526   // each fragment for one packet.
33527   // TracePacket will have at least one slice when this function returns true.
33528   // When there are no whole packets eligible to read (e.g. we are still missing
33529   // fragments) this function returns false.
33530   // This function guarantees also that packets for a given
33531   // {ProducerID, WriterID} are read in FIFO order.
33532   // This function does not guarantee any ordering w.r.t. packets belonging to
33533   // different WriterID(s). For instance, given the following packets copied
33534   // into the buffer:
33535   //   {ProducerID: 1, WriterID: 1}: P1 P2 P3
33536   //   {ProducerID: 1, WriterID: 2}: P4 P5 P6
33537   //   {ProducerID: 2, WriterID: 1}: P7 P8 P9
33538   // The following read sequence is possible:
33539   //   P1, P4, P7, P2, P3, P5, P8, P9, P6
33540   // But the following is guaranteed to NOT happen:
33541   //   P1, P5, P7, P4 (P4 cannot come after P5)
33542   bool ReadNextTracePacket(TracePacket*,
33543                            PacketSequenceProperties* sequence_properties,
33544                            bool* previous_packet_on_sequence_dropped);
33545 
stats() const33546   const TraceStats::BufferStats& stats() const { return stats_; }
size() const33547   size_t size() const { return size_; }
33548 
33549  private:
33550   friend class TraceBufferTest;
33551 
33552   // ChunkRecord is a Chunk header stored inline in the |data_| buffer, before
33553   // the chunk payload (the packets' data). The |data_| buffer looks like this:
33554   // +---------------+------------------++---------------+-----------------+
33555   // | ChunkRecord 1 | Chunk payload 1  || ChunkRecord 2 | Chunk payload 2 | ...
33556   // +---------------+------------------++---------------+-----------------+
33557   // Most of the ChunkRecord fields are copied from SharedMemoryABI::ChunkHeader
33558   // (the chunk header used in the shared memory buffers).
33559   // A ChunkRecord can be a special "padding" record. In this case its payload
33560   // should be ignored and the record should be just skipped.
33561   //
33562   // Full page move optimization:
33563   // This struct has to be exactly (sizeof(PageHeader) + sizeof(ChunkHeader))
33564   // (from shared_memory_abi.h) to allow full page move optimizations
33565   // (TODO(primiano): not implemented yet). In the special case of moving a full
33566   // 4k page that contains only one chunk, in fact, we can just ask the kernel
33567   // to move the full SHM page (see SPLICE_F_{GIFT,MOVE}) and overlay the
33568   // ChunkRecord on top of the moved SMB's header (page + chunk header).
33569   // This special requirement is covered by static_assert(s) in the .cc file.
33570   struct ChunkRecord {
ChunkRecordperfetto::TraceBuffer::ChunkRecord33571     explicit ChunkRecord(size_t sz) : flags{0}, is_padding{0} {
33572       PERFETTO_DCHECK(sz >= sizeof(ChunkRecord) &&
33573                       sz % sizeof(ChunkRecord) == 0 && sz <= kMaxSize);
33574       size = static_cast<decltype(size)>(sz);
33575     }
33576 
is_validperfetto::TraceBuffer::ChunkRecord33577     bool is_valid() const { return size != 0; }
33578 
33579     // Keep this structure packed and exactly 16 bytes (128 bits) big.
33580 
33581     // [32 bits] Monotonic counter within the same writer_id.
33582     ChunkID chunk_id = 0;
33583 
33584     // [16 bits] ID of the Producer from which the Chunk was copied from.
33585     ProducerID producer_id = 0;
33586 
33587     // [16 bits] Unique per Producer (but not within the service).
33588     // If writer_id == kWriterIdPadding the record should just be skipped.
33589     WriterID writer_id = 0;
33590 
33591     // Number of fragments contained in the chunk.
33592     uint16_t num_fragments = 0;
33593 
33594     // Size in bytes, including sizeof(ChunkRecord) itself.
33595     uint16_t size;
33596 
33597     uint8_t flags : 6;  // See SharedMemoryABI::ChunkHeader::flags.
33598     uint8_t is_padding : 1;
33599     uint8_t unused_flag : 1;
33600 
33601     // Not strictly needed, can be reused for more fields in the future. But
33602     // right now helps to spot chunks in hex dumps.
33603     char unused[3] = {'C', 'H', 'U'};
33604 
33605     static constexpr size_t kMaxSize =
33606         std::numeric_limits<decltype(size)>::max();
33607   };
33608 
33609   // Lookaside index entry. This serves two purposes:
33610   // 1) Allow a fast lookup of ChunkRecord by their ID (the tuple
33611   //   {ProducerID, WriterID, ChunkID}). This is used when applying out-of-band
33612   //   patches to the contents of the chunks after they have been copied into
33613   //   the TraceBuffer.
33614   // 2) keep the chunks ordered by their ID. This is used when reading back.
33615   // 3) Keep metadata about the status of the chunk, e.g. whether the contents
33616   //    have been read already and should be skipped in a future read pass.
33617   // This struct should not have any field that is essential for reconstructing
33618   // the contents of the buffer from a crash dump.
33619   struct ChunkMeta {
33620     // Key used for sorting in the map.
33621     struct Key {
Keyperfetto::TraceBuffer::ChunkMeta::Key33622       Key(ProducerID p, WriterID w, ChunkID c)
33623           : producer_id{p}, writer_id{w}, chunk_id{c} {}
33624 
Keyperfetto::TraceBuffer::ChunkMeta::Key33625       explicit Key(const ChunkRecord& cr)
33626           : Key(cr.producer_id, cr.writer_id, cr.chunk_id) {}
33627 
33628       // Note that this sorting doesn't keep into account the fact that ChunkID
33629       // will wrap over at some point. The extra logic in SequenceIterator deals
33630       // with that.
operator <perfetto::TraceBuffer::ChunkMeta::Key33631       bool operator<(const Key& other) const {
33632         return std::tie(producer_id, writer_id, chunk_id) <
33633                std::tie(other.producer_id, other.writer_id, other.chunk_id);
33634       }
33635 
operator ==perfetto::TraceBuffer::ChunkMeta::Key33636       bool operator==(const Key& other) const {
33637         return std::tie(producer_id, writer_id, chunk_id) ==
33638                std::tie(other.producer_id, other.writer_id, other.chunk_id);
33639       }
33640 
operator !=perfetto::TraceBuffer::ChunkMeta::Key33641       bool operator!=(const Key& other) const { return !(*this == other); }
33642 
33643       // These fields should match at all times the corresponding fields in
33644       // the |chunk_record|. They are copied here purely for efficiency to avoid
33645       // dereferencing the buffer all the time.
33646       ProducerID producer_id;
33647       WriterID writer_id;
33648       ChunkID chunk_id;
33649     };
33650 
33651     enum IndexFlags : uint8_t {
33652       // If set, the chunk state was kChunkComplete at the time it was copied.
33653       // If unset, the chunk was still kChunkBeingWritten while copied. When
33654       // reading from the chunk's sequence, the sequence will not advance past
33655       // this chunk until this flag is set.
33656       kComplete = 1 << 0,
33657 
33658       // If set, we skipped the last packet that we read from this chunk e.g.
33659       // because we it was a continuation from a previous chunk that was dropped
33660       // or due to an ABI violation.
33661       kLastReadPacketSkipped = 1 << 1
33662     };
33663 
ChunkMetaperfetto::TraceBuffer::ChunkMeta33664     ChunkMeta(ChunkRecord* r, uint16_t p, bool complete, uint8_t f, uid_t u)
33665         : chunk_record{r}, trusted_uid{u}, flags{f}, num_fragments{p} {
33666       if (complete)
33667         index_flags = kComplete;
33668     }
33669 
is_completeperfetto::TraceBuffer::ChunkMeta33670     bool is_complete() const { return index_flags & kComplete; }
33671 
set_completeperfetto::TraceBuffer::ChunkMeta33672     void set_complete(bool complete) {
33673       if (complete) {
33674         index_flags |= kComplete;
33675       } else {
33676         index_flags &= ~kComplete;
33677       }
33678     }
33679 
last_read_packet_skippedperfetto::TraceBuffer::ChunkMeta33680     bool last_read_packet_skipped() const {
33681       return index_flags & kLastReadPacketSkipped;
33682     }
33683 
set_last_read_packet_skippedperfetto::TraceBuffer::ChunkMeta33684     void set_last_read_packet_skipped(bool skipped) {
33685       if (skipped) {
33686         index_flags |= kLastReadPacketSkipped;
33687       } else {
33688         index_flags &= ~kLastReadPacketSkipped;
33689       }
33690     }
33691 
33692     ChunkRecord* const chunk_record;  // Addr of ChunkRecord within |data_|.
33693     const uid_t trusted_uid;          // uid of the producer.
33694 
33695     // Flags set by TraceBuffer to track the state of the chunk in the index.
33696     uint8_t index_flags = 0;
33697 
33698     // Correspond to |chunk_record->flags| and |chunk_record->num_fragments|.
33699     // Copied here for performance reasons (avoids having to dereference
33700     // |chunk_record| while iterating over ChunkMeta) and to aid debugging in
33701     // case the buffer gets corrupted.
33702     uint8_t flags = 0;           // See SharedMemoryABI::ChunkHeader::flags.
33703     uint16_t num_fragments = 0;  // Total number of packet fragments.
33704 
33705     uint16_t num_fragments_read = 0;  // Number of fragments already read.
33706 
33707     // The start offset of the next fragment (the |num_fragments_read|-th) to be
33708     // read. This is the offset in bytes from the beginning of the ChunkRecord's
33709     // payload (the 1st fragment starts at |chunk_record| +
33710     // sizeof(ChunkRecord)).
33711     uint16_t cur_fragment_offset = 0;
33712   };
33713 
33714   using ChunkMap = std::map<ChunkMeta::Key, ChunkMeta>;
33715 
33716   // Allows to iterate over a sub-sequence of |index_| for all keys belonging to
33717   // the same {ProducerID,WriterID}. Furthermore takes into account the wrapping
33718   // of ChunkID. Instances are valid only as long as the |index_| is not altered
33719   // (can be used safely only between adjacent ReadNextTracePacket() calls).
33720   // The order of the iteration will proceed in the following order:
33721   // |wrapping_id| + 1 -> |seq_end|, |seq_begin| -> |wrapping_id|.
33722   // Practical example:
33723   // - Assume that kMaxChunkID == 7
33724   // - Assume that we have all 8 chunks in the range (0..7).
33725   // - Hence, |seq_begin| == c0, |seq_end| == c7
33726   // - Assume |wrapping_id| = 4 (c4 is the last chunk copied over
33727   //   through a CopyChunkUntrusted()).
33728   // The resulting iteration order will be: c5, c6, c7, c0, c1, c2, c3, c4.
33729   struct SequenceIterator {
33730     // Points to the 1st key (the one with the numerically min ChunkID).
33731     ChunkMap::iterator seq_begin;
33732 
33733     // Points one past the last key (the one with the numerically max ChunkID).
33734     ChunkMap::iterator seq_end;
33735 
33736     // Current iterator, always >= seq_begin && <= seq_end.
33737     ChunkMap::iterator cur;
33738 
33739     // The latest ChunkID written. Determines the start/end of the sequence.
33740     ChunkID wrapping_id;
33741 
is_validperfetto::TraceBuffer::SequenceIterator33742     bool is_valid() const { return cur != seq_end; }
33743 
producer_idperfetto::TraceBuffer::SequenceIterator33744     ProducerID producer_id() const {
33745       PERFETTO_DCHECK(is_valid());
33746       return cur->first.producer_id;
33747     }
33748 
writer_idperfetto::TraceBuffer::SequenceIterator33749     WriterID writer_id() const {
33750       PERFETTO_DCHECK(is_valid());
33751       return cur->first.writer_id;
33752     }
33753 
chunk_idperfetto::TraceBuffer::SequenceIterator33754     ChunkID chunk_id() const {
33755       PERFETTO_DCHECK(is_valid());
33756       return cur->first.chunk_id;
33757     }
33758 
operator *perfetto::TraceBuffer::SequenceIterator33759     ChunkMeta& operator*() {
33760       PERFETTO_DCHECK(is_valid());
33761       return cur->second;
33762     }
33763 
33764     // Moves |cur| to the next chunk in the index.
33765     // is_valid() will become false after calling this, if this was the last
33766     // entry of the sequence.
33767     void MoveNext();
33768 
MoveToEndperfetto::TraceBuffer::SequenceIterator33769     void MoveToEnd() { cur = seq_end; }
33770   };
33771 
33772   enum class ReadAheadResult {
33773     kSucceededReturnSlices,
33774     kFailedMoveToNextSequence,
33775     kFailedStayOnSameSequence,
33776   };
33777 
33778   enum class ReadPacketResult {
33779     kSucceeded,
33780     kFailedInvalidPacket,
33781     kFailedEmptyPacket,
33782   };
33783 
33784   explicit TraceBuffer(OverwritePolicy);
33785   TraceBuffer(const TraceBuffer&) = delete;
33786   TraceBuffer& operator=(const TraceBuffer&) = delete;
33787 
33788   bool Initialize(size_t size);
33789 
33790   // Returns an object that allows to iterate over chunks in the |index_| that
33791   // have the same {ProducerID, WriterID} of
33792   // |seq_begin.first.{producer,writer}_id|. |seq_begin| must be an iterator to
33793   // the first entry in the |index_| that has a different {ProducerID, WriterID}
33794   // from the previous one. It is valid for |seq_begin| to be == index_.end()
33795   // (i.e. if the index is empty). The iteration takes care of ChunkID wrapping,
33796   // by using |last_chunk_id_|.
33797   SequenceIterator GetReadIterForSequence(ChunkMap::iterator seq_begin);
33798 
33799   // Used as a last resort when a buffer corruption is detected.
33800   void ClearContentsAndResetRWCursors();
33801 
33802   // Adds a padding record of the given size (must be a multiple of
33803   // sizeof(ChunkRecord)).
33804   void AddPaddingRecord(size_t);
33805 
33806   // Look for contiguous fragment of the same packet starting from |read_iter_|.
33807   // If a contiguous packet is found, all the fragments are pushed into
33808   // TracePacket and the function returns kSucceededReturnSlices. If not, the
33809   // function returns either kFailedMoveToNextSequence or
33810   // kFailedStayOnSameSequence, telling the caller to continue looking for
33811   // packets.
33812   ReadAheadResult ReadAhead(TracePacket*);
33813 
33814   // Deletes (by marking the record invalid and removing form the index) all
33815   // chunks from |wptr_| to |wptr_| + |bytes_to_clear|.
33816   // Returns:
33817   //   * The size of the gap left between the next valid Chunk and the end of
33818   //     the deletion range.
33819   //   * 0 if no next valid chunk exists (if the buffer is still zeroed).
33820   //   * -1 if the buffer |overwrite_policy_| == kDiscard and the deletion would
33821   //     cause unread chunks to be overwritten. In this case the buffer is left
33822   //     untouched.
33823   // Graphically, assume the initial situation is the following (|wptr_| = 10).
33824   // |0        |10 (wptr_)       |30       |40                 |60
33825   // +---------+-----------------+---------+-------------------+---------+
33826   // | Chunk 1 | Chunk 2         | Chunk 3 | Chunk 4           | Chunk 5 |
33827   // +---------+-----------------+---------+-------------------+---------+
33828   //           |_________Deletion range_______|~~return value~~|
33829   //
33830   // A call to DeleteNextChunksFor(32) will remove chunks 2,3,4 and return 18
33831   // (60 - 42), the distance between chunk 5 and the end of the deletion range.
33832   ssize_t DeleteNextChunksFor(size_t bytes_to_clear);
33833 
33834   // Decodes the boundaries of the next packet (or a fragment) pointed by
33835   // ChunkMeta and pushes that into |TracePacket|. It also increments the
33836   // |num_fragments_read| counter.
33837   // TracePacket can be nullptr, in which case the read state is still advanced.
33838   // When TracePacket is not nullptr, ProducerID must also be not null and will
33839   // be updated with the ProducerID that originally wrote the chunk.
33840   ReadPacketResult ReadNextPacketInChunk(ChunkMeta*, TracePacket*);
33841 
DcheckIsAlignedAndWithinBounds(const uint8_t * ptr) const33842   void DcheckIsAlignedAndWithinBounds(const uint8_t* ptr) const {
33843     PERFETTO_DCHECK(ptr >= begin() && ptr <= end() - sizeof(ChunkRecord));
33844     PERFETTO_DCHECK(
33845         (reinterpret_cast<uintptr_t>(ptr) & (alignof(ChunkRecord) - 1)) == 0);
33846   }
33847 
GetChunkRecordAt(uint8_t * ptr)33848   ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
33849     DcheckIsAlignedAndWithinBounds(ptr);
33850     // We may be accessing a new (empty) record.
33851     data_.EnsureCommitted(
33852         static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
33853     return reinterpret_cast<ChunkRecord*>(ptr);
33854   }
33855 
33856   void DiscardWrite();
33857 
33858   // |src| can be nullptr (in which case |size| must be ==
33859   // record.size - sizeof(ChunkRecord)), for the case of writing a padding
33860   // record. |wptr_| is NOT advanced by this function, the caller must do that.
WriteChunkRecord(uint8_t * wptr,const ChunkRecord & record,const uint8_t * src,size_t size)33861   void WriteChunkRecord(uint8_t* wptr,
33862                         const ChunkRecord& record,
33863                         const uint8_t* src,
33864                         size_t size) {
33865     // Note: |record.size| will be slightly bigger than |size| because of the
33866     // ChunkRecord header and rounding, to ensure that all ChunkRecord(s) are
33867     // multiple of sizeof(ChunkRecord). The invariant is:
33868     // record.size >= |size| + sizeof(ChunkRecord) (== if no rounding).
33869     PERFETTO_DCHECK(size <= ChunkRecord::kMaxSize);
33870     PERFETTO_DCHECK(record.size >= sizeof(record));
33871     PERFETTO_DCHECK(record.size % sizeof(record) == 0);
33872     PERFETTO_DCHECK(record.size >= size + sizeof(record));
33873     PERFETTO_CHECK(record.size <= size_to_end());
33874     DcheckIsAlignedAndWithinBounds(wptr);
33875 
33876     // We may be writing to this area for the first time.
33877     data_.EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
33878 
33879     // Deliberately not a *D*CHECK.
33880     PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
33881     memcpy(wptr, &record, sizeof(record));
33882     if (PERFETTO_LIKELY(src)) {
33883       // If the producer modifies the data in the shared memory buffer while we
33884       // are copying it to the central buffer, TSAN will (rightfully) flag that
33885       // as a race. However the entire purpose of copying the data into the
33886       // central buffer is that we can validate it without worrying that the
33887       // producer changes it from under our feet, so this race is benign. The
33888       // alternative would be to try computing which part of the buffer is safe
33889       // to read (assuming a well-behaving client), but the risk of introducing
33890       // a bug that way outweighs the benefit.
33891       PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
33892           src, size, "Benign race when copying chunk from shared memory.")
33893       memcpy(wptr + sizeof(record), src, size);
33894     } else {
33895       PERFETTO_DCHECK(size == record.size - sizeof(record));
33896     }
33897     const size_t rounding_size = record.size - sizeof(record) - size;
33898     memset(wptr + sizeof(record) + size, 0, rounding_size);
33899   }
33900 
begin() const33901   uint8_t* begin() const { return reinterpret_cast<uint8_t*>(data_.Get()); }
end() const33902   uint8_t* end() const { return begin() + size_; }
size_to_end() const33903   size_t size_to_end() const { return static_cast<size_t>(end() - wptr_); }
33904 
33905   base::PagedMemory data_;
33906   size_t size_ = 0;            // Size in bytes of |data_|.
33907   size_t max_chunk_size_ = 0;  // Max size in bytes allowed for a chunk.
33908   uint8_t* wptr_ = nullptr;    // Write pointer.
33909 
33910   // An index that keeps track of the positions and metadata of each
33911   // ChunkRecord.
33912   ChunkMap index_;
33913 
33914   // Read iterator used for ReadNext(). It is reset by calling BeginRead().
33915   // It becomes invalid after any call to methods that alters the |index_|.
33916   SequenceIterator read_iter_;
33917 
33918   // See comments at the top of the file.
33919   OverwritePolicy overwrite_policy_ = kOverwrite;
33920 
33921   // Only used when |overwrite_policy_ == kDiscard|. This is set the first time
33922   // a write fails because it would overwrite unread chunks.
33923   bool discard_writes_ = false;
33924 
33925   // Keeps track of the highest ChunkID written for a given sequence, taking
33926   // into account a potential overflow of ChunkIDs. In the case of overflow,
33927   // stores the highest ChunkID written since the overflow.
33928   //
33929   // TODO(primiano): should clean up keys from this map. Right now it grows
33930   // without bounds (although realistically is not a problem unless we have too
33931   // many producers/writers within the same trace session).
33932   std::map<std::pair<ProducerID, WriterID>, ChunkID> last_chunk_id_written_;
33933 
33934   // Statistics about buffer usage.
33935   TraceStats::BufferStats stats_;
33936 
33937 #if PERFETTO_DCHECK_IS_ON()
33938   bool changed_since_last_read_ = false;
33939 #endif
33940 
33941   // When true disable some DCHECKs that have been put in place to detect
33942   // bugs in the producers. This is for tests that feed malicious inputs and
33943   // hence mimic a buggy producer.
33944   bool suppress_client_dchecks_for_testing_ = false;
33945 };
33946 
33947 }  // namespace perfetto
33948 
33949 #endif  // SRC_TRACING_CORE_TRACE_BUFFER_H_
33950 /*
33951  * Copyright (C) 2018 The Android Open Source Project
33952  *
33953  * Licensed under the Apache License, Version 2.0 (the "License");
33954  * you may not use this file except in compliance with the License.
33955  * You may obtain a copy of the License at
33956  *
33957  *      http://www.apache.org/licenses/LICENSE-2.0
33958  *
33959  * Unless required by applicable law or agreed to in writing, software
33960  * distributed under the License is distributed on an "AS IS" BASIS,
33961  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33962  * See the License for the specific language governing permissions and
33963  * limitations under the License.
33964  */
33965 
33966 // gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
33967 
33968 #include <limits>
33969 
33970 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
33971 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
33972 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
33973 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
33974 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
33975 
33976 #define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
33977 #if TRACE_BUFFER_VERBOSE_LOGGING()
33978 #define TRACE_BUFFER_DLOG PERFETTO_DLOG
33979 namespace {
33980 constexpr char kHexDigits[] = "0123456789abcdef";
HexDump(const uint8_t * src,size_t size)33981 std::string HexDump(const uint8_t* src, size_t size) {
33982   std::string buf;
33983   buf.reserve(4096 * 4);
33984   char line[64];
33985   char* c = line;
33986   for (size_t i = 0; i < size; i++) {
33987     *c++ = kHexDigits[(src[i] >> 4) & 0x0f];
33988     *c++ = kHexDigits[(src[i] >> 0) & 0x0f];
33989     if (i % 16 == 15) {
33990       buf.append("\n");
33991       buf.append(line);
33992       c = line;
33993     }
33994   }
33995   return buf;
33996 }
33997 }  // namespace
33998 #else
33999 #define TRACE_BUFFER_DLOG(...) void()
34000 #endif
34001 
34002 namespace perfetto {
34003 
34004 namespace {
34005 constexpr uint8_t kFirstPacketContinuesFromPrevChunk =
34006     SharedMemoryABI::ChunkHeader::kFirstPacketContinuesFromPrevChunk;
34007 constexpr uint8_t kLastPacketContinuesOnNextChunk =
34008     SharedMemoryABI::ChunkHeader::kLastPacketContinuesOnNextChunk;
34009 constexpr uint8_t kChunkNeedsPatching =
34010     SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
34011 }  // namespace.
34012 
34013 constexpr size_t TraceBuffer::ChunkRecord::kMaxSize;
34014 constexpr size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
34015 
34016 // static
Create(size_t size_in_bytes,OverwritePolicy pol)34017 std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
34018                                                  OverwritePolicy pol) {
34019   std::unique_ptr<TraceBuffer> trace_buffer(new TraceBuffer(pol));
34020   if (!trace_buffer->Initialize(size_in_bytes))
34021     return nullptr;
34022   return trace_buffer;
34023 }
34024 
TraceBuffer(OverwritePolicy pol)34025 TraceBuffer::TraceBuffer(OverwritePolicy pol) : overwrite_policy_(pol) {
34026   // See comments in ChunkRecord for the rationale of this.
34027   static_assert(sizeof(ChunkRecord) == sizeof(SharedMemoryABI::PageHeader) +
34028                                            sizeof(SharedMemoryABI::ChunkHeader),
34029                 "ChunkRecord out of sync with the layout of SharedMemoryABI");
34030 }
34031 
34032 TraceBuffer::~TraceBuffer() = default;
34033 
Initialize(size_t size)34034 bool TraceBuffer::Initialize(size_t size) {
34035   static_assert(
34036       SharedMemoryABI::kMinPageSize % sizeof(ChunkRecord) == 0,
34037       "sizeof(ChunkRecord) must be an integer divider of a page size");
34038   data_ = base::PagedMemory::Allocate(
34039       size, base::PagedMemory::kMayFail | base::PagedMemory::kDontCommit);
34040   if (!data_.IsValid()) {
34041     PERFETTO_ELOG("Trace buffer allocation failed (size: %zu)", size);
34042     return false;
34043   }
34044   size_ = size;
34045   stats_.set_buffer_size(size);
34046   max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
34047   wptr_ = begin();
34048   index_.clear();
34049   last_chunk_id_written_.clear();
34050   read_iter_ = GetReadIterForSequence(index_.end());
34051   return true;
34052 }
34053 
34054 // Note: |src| points to a shmem region that is shared with the producer. Assume
34055 // that the producer is malicious and will change the content of |src|
34056 // while we execute here. Don't do any processing on it other than memcpy().
CopyChunkUntrusted(ProducerID producer_id_trusted,uid_t producer_uid_trusted,WriterID writer_id,ChunkID chunk_id,uint16_t num_fragments,uint8_t chunk_flags,bool chunk_complete,const uint8_t * src,size_t size)34057 void TraceBuffer::CopyChunkUntrusted(ProducerID producer_id_trusted,
34058                                      uid_t producer_uid_trusted,
34059                                      WriterID writer_id,
34060                                      ChunkID chunk_id,
34061                                      uint16_t num_fragments,
34062                                      uint8_t chunk_flags,
34063                                      bool chunk_complete,
34064                                      const uint8_t* src,
34065                                      size_t size) {
34066   // |record_size| = |size| + sizeof(ChunkRecord), rounded up to avoid to end
34067   // up in a fragmented state where size_to_end() < sizeof(ChunkRecord).
34068   const size_t record_size =
34069       base::AlignUp<sizeof(ChunkRecord)>(size + sizeof(ChunkRecord));
34070   if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
34071     stats_.set_abi_violations(stats_.abi_violations() + 1);
34072     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34073     return;
34074   }
34075 
34076   TRACE_BUFFER_DLOG("CopyChunk @ %lu, size=%zu", wptr_ - begin(), record_size);
34077 
34078 #if PERFETTO_DCHECK_IS_ON()
34079   changed_since_last_read_ = true;
34080 #endif
34081 
34082   // If the chunk hasn't been completed, we should only consider the first
34083   // |num_fragments - 1| packets complete. For simplicity, we simply disregard
34084   // the last one when we copy the chunk.
34085   if (PERFETTO_UNLIKELY(!chunk_complete)) {
34086     if (num_fragments > 0) {
34087       num_fragments--;
34088       // These flags should only affect the last packet in the chunk. We clear
34089       // them, so that TraceBuffer is able to look at the remaining packets in
34090       // this chunk.
34091       chunk_flags &= ~kLastPacketContinuesOnNextChunk;
34092       chunk_flags &= ~kChunkNeedsPatching;
34093     }
34094   }
34095 
34096   ChunkRecord record(record_size);
34097   record.producer_id = producer_id_trusted;
34098   record.chunk_id = chunk_id;
34099   record.writer_id = writer_id;
34100   record.num_fragments = num_fragments;
34101   record.flags = chunk_flags;
34102   ChunkMeta::Key key(record);
34103 
34104   // Check whether we have already copied the same chunk previously. This may
34105   // happen if the service scrapes chunks in a potentially incomplete state
34106   // before receiving commit requests for them from the producer. Note that the
34107   // service may scrape and thus override chunks in arbitrary order since the
34108   // chunks aren't ordered in the SMB.
34109   const auto it = index_.find(key);
34110   if (PERFETTO_UNLIKELY(it != index_.end())) {
34111     ChunkMeta* record_meta = &it->second;
34112     ChunkRecord* prev = record_meta->chunk_record;
34113 
34114     // Verify that the old chunk's metadata corresponds to the new one.
34115     // Overridden chunks should never change size, since the page layout is
34116     // fixed per writer. The number of fragments should also never decrease and
34117     // flags should not be removed.
34118     if (PERFETTO_UNLIKELY(ChunkMeta::Key(*prev) != key ||
34119                           prev->size != record_size ||
34120                           prev->num_fragments > num_fragments ||
34121                           (prev->flags & chunk_flags) != prev->flags)) {
34122       stats_.set_abi_violations(stats_.abi_violations() + 1);
34123       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34124       return;
34125     }
34126 
34127     // If we've already started reading from chunk N+1 following this chunk N,
34128     // don't override chunk N. Otherwise we may end up reading a packet from
34129     // chunk N after having read from chunk N+1, thereby violating sequential
34130     // read of packets. This shouldn't happen if the producer is well-behaved,
34131     // because it shouldn't start chunk N+1 before completing chunk N.
34132     ChunkMeta::Key subsequent_key = key;
34133     static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
34134                   "ChunkID wraps");
34135     subsequent_key.chunk_id++;
34136     const auto subsequent_it = index_.find(subsequent_key);
34137     if (subsequent_it != index_.end() &&
34138         subsequent_it->second.num_fragments_read > 0) {
34139       stats_.set_abi_violations(stats_.abi_violations() + 1);
34140       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34141       return;
34142     }
34143 
34144     // If this chunk was previously copied with the same number of fragments and
34145     // the number didn't change, there's no need to copy it again. If the
34146     // previous chunk was complete already, this should always be the case.
34147     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_ ||
34148                     !record_meta->is_complete() ||
34149                     (chunk_complete && prev->num_fragments == num_fragments));
34150     if (prev->num_fragments == num_fragments) {
34151       TRACE_BUFFER_DLOG("  skipping recommit of identical chunk");
34152       return;
34153     }
34154 
34155     // We should not have read past the last packet.
34156     if (record_meta->num_fragments_read > prev->num_fragments) {
34157       PERFETTO_ELOG(
34158           "TraceBuffer read too many fragments from an incomplete chunk");
34159       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34160       return;
34161     }
34162 
34163     uint8_t* wptr = reinterpret_cast<uint8_t*>(prev);
34164     TRACE_BUFFER_DLOG("  overriding chunk @ %lu, size=%zu", wptr - begin(),
34165                       record_size);
34166 
34167     // Update chunk meta data stored in the index, as it may have changed.
34168     record_meta->num_fragments = num_fragments;
34169     record_meta->flags = chunk_flags;
34170     record_meta->set_complete(chunk_complete);
34171 
34172     // Override the ChunkRecord contents at the original |wptr|.
34173     TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr - begin(),
34174                       uintptr_t(wptr - begin()) + record_size, record_size);
34175     WriteChunkRecord(wptr, record, src, size);
34176     TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr, record_size).c_str());
34177     stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
34178     return;
34179   }
34180 
34181   if (PERFETTO_UNLIKELY(discard_writes_))
34182     return DiscardWrite();
34183 
34184   // If there isn't enough room from the given write position. Write a padding
34185   // record to clear the end of the buffer and wrap back.
34186   const size_t cached_size_to_end = size_to_end();
34187   if (PERFETTO_UNLIKELY(record_size > cached_size_to_end)) {
34188     ssize_t res = DeleteNextChunksFor(cached_size_to_end);
34189     if (res == -1)
34190       return DiscardWrite();
34191     PERFETTO_DCHECK(static_cast<size_t>(res) <= cached_size_to_end);
34192     AddPaddingRecord(cached_size_to_end);
34193     wptr_ = begin();
34194     stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
34195     PERFETTO_DCHECK(size_to_end() >= record_size);
34196   }
34197 
34198   // At this point either |wptr_| points to an untouched part of the buffer
34199   // (i.e. *wptr_ == 0) or we are about to overwrite one or more ChunkRecord(s).
34200   // In the latter case we need to first figure out where the next valid
34201   // ChunkRecord is (if it exists) and add padding between the new record.
34202   // Example ((w) == write cursor):
34203   //
34204   // Initial state (wtpr_ == 0):
34205   // |0 (w)    |10               |30                  |50
34206   // +---------+-----------------+--------------------+--------------------+
34207   // | Chunk 1 | Chunk 2         | Chunk 3            | Chunk 4            |
34208   // +---------+-----------------+--------------------+--------------------+
34209   //
34210   // Let's assume we now want now write a 5th Chunk of size == 35. The final
34211   // state should look like this:
34212   // |0                                |35 (w)         |50
34213   // +---------------------------------+---------------+--------------------+
34214   // | Chunk 5                         | Padding Chunk | Chunk 4            |
34215   // +---------------------------------+---------------+--------------------+
34216 
34217   // Deletes all chunks from |wptr_| to |wptr_| + |record_size|.
34218   ssize_t del_res = DeleteNextChunksFor(record_size);
34219   if (del_res == -1)
34220     return DiscardWrite();
34221   size_t padding_size = static_cast<size_t>(del_res);
34222 
34223   // Now first insert the new chunk. At the end, if necessary, add the padding.
34224   stats_.set_chunks_written(stats_.chunks_written() + 1);
34225   stats_.set_bytes_written(stats_.bytes_written() + record_size);
34226   auto it_and_inserted = index_.emplace(
34227       key, ChunkMeta(GetChunkRecordAt(wptr_), num_fragments, chunk_complete,
34228                      chunk_flags, producer_uid_trusted));
34229   PERFETTO_DCHECK(it_and_inserted.second);
34230   TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr_ - begin(),
34231                     uintptr_t(wptr_ - begin()) + record_size, record_size);
34232   WriteChunkRecord(wptr_, record, src, size);
34233   TRACE_BUFFER_DLOG("Chunk raw: %s", HexDump(wptr_, record_size).c_str());
34234   wptr_ += record_size;
34235   if (wptr_ >= end()) {
34236     PERFETTO_DCHECK(padding_size == 0);
34237     wptr_ = begin();
34238     stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
34239   }
34240   DcheckIsAlignedAndWithinBounds(wptr_);
34241 
34242   // Chunks may be received out of order, so only update last_chunk_id if the
34243   // new chunk_id is larger. But take into account overflows by only selecting
34244   // the new ID if its distance to the latest ID is smaller than half the number
34245   // space.
34246   //
34247   // This accounts for both the case where the new ID has just overflown and
34248   // last_chunk_id be updated even though it's smaller (e.g. |chunk_id| = 1 and
34249   // |last_chunk_id| = kMaxChunkId; chunk_id - last_chunk_id = 0) and the case
34250   // where the new ID is an out-of-order ID right after an overflow and
34251   // last_chunk_id shouldn't be updated even though it's larger (e.g. |chunk_id|
34252   // = kMaxChunkId and |last_chunk_id| = 1; chunk_id - last_chunk_id =
34253   // kMaxChunkId - 1).
34254   auto producer_and_writer_id = std::make_pair(producer_id_trusted, writer_id);
34255   ChunkID& last_chunk_id = last_chunk_id_written_[producer_and_writer_id];
34256   static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
34257                 "This code assumes that ChunkID wraps at kMaxChunkID");
34258   if (chunk_id - last_chunk_id < kMaxChunkID / 2) {
34259     last_chunk_id = chunk_id;
34260   } else {
34261     stats_.set_chunks_committed_out_of_order(
34262         stats_.chunks_committed_out_of_order() + 1);
34263   }
34264 
34265   if (padding_size)
34266     AddPaddingRecord(padding_size);
34267 }
34268 
DeleteNextChunksFor(size_t bytes_to_clear)34269 ssize_t TraceBuffer::DeleteNextChunksFor(size_t bytes_to_clear) {
34270   PERFETTO_CHECK(!discard_writes_);
34271 
34272   // Find the position of the first chunk which begins at or after
34273   // (|wptr_| + |bytes|). Note that such a chunk might not exist and we might
34274   // either reach the end of the buffer or a zeroed region of the buffer.
34275   uint8_t* next_chunk_ptr = wptr_;
34276   uint8_t* search_end = wptr_ + bytes_to_clear;
34277   TRACE_BUFFER_DLOG("Delete [%zu %zu]", wptr_ - begin(), search_end - begin());
34278   DcheckIsAlignedAndWithinBounds(wptr_);
34279   PERFETTO_DCHECK(search_end <= end());
34280   std::vector<ChunkMap::iterator> index_delete;
34281   uint64_t chunks_overwritten = stats_.chunks_overwritten();
34282   uint64_t bytes_overwritten = stats_.bytes_overwritten();
34283   uint64_t padding_bytes_cleared = stats_.padding_bytes_cleared();
34284   while (next_chunk_ptr < search_end) {
34285     const ChunkRecord& next_chunk = *GetChunkRecordAt(next_chunk_ptr);
34286     TRACE_BUFFER_DLOG(
34287         "  scanning chunk [%zu %zu] (valid=%d)", next_chunk_ptr - begin(),
34288         next_chunk_ptr - begin() + next_chunk.size, next_chunk.is_valid());
34289 
34290     // We just reached the untouched part of the buffer, it's going to be all
34291     // zeroes from here to end().
34292     // Optimization: if during Initialize() we fill the buffer with padding
34293     // records we could get rid of this branch.
34294     if (PERFETTO_UNLIKELY(!next_chunk.is_valid())) {
34295       // This should happen only at the first iteration. The zeroed area can
34296       // only begin precisely at the |wptr_|, not after. Otherwise it means that
34297       // we wrapped but screwed up the ChunkRecord chain.
34298       PERFETTO_DCHECK(next_chunk_ptr == wptr_);
34299       return 0;
34300     }
34301 
34302     // Remove |next_chunk| from the index, unless it's a padding record (padding
34303     // records are not part of the index).
34304     if (PERFETTO_LIKELY(!next_chunk.is_padding)) {
34305       ChunkMeta::Key key(next_chunk);
34306       auto it = index_.find(key);
34307       bool will_remove = false;
34308       if (PERFETTO_LIKELY(it != index_.end())) {
34309         const ChunkMeta& meta = it->second;
34310         if (PERFETTO_UNLIKELY(meta.num_fragments_read < meta.num_fragments)) {
34311           if (overwrite_policy_ == kDiscard)
34312             return -1;
34313           chunks_overwritten++;
34314           bytes_overwritten += next_chunk.size;
34315         }
34316         index_delete.push_back(it);
34317         will_remove = true;
34318       }
34319       TRACE_BUFFER_DLOG(
34320           "  del index {%" PRIu32 ",%" PRIu32 ",%u} @ [%lu - %lu] %d",
34321           key.producer_id, key.writer_id, key.chunk_id,
34322           next_chunk_ptr - begin(), next_chunk_ptr - begin() + next_chunk.size,
34323           will_remove);
34324       PERFETTO_DCHECK(will_remove);
34325     } else {
34326       padding_bytes_cleared += next_chunk.size;
34327     }
34328 
34329     next_chunk_ptr += next_chunk.size;
34330 
34331     // We should never hit this, unless we managed to screw up while writing
34332     // to the buffer and breaking the ChunkRecord(s) chain.
34333     // TODO(primiano): Write more meaningful logging with the status of the
34334     // buffer, to get more actionable bugs in case we hit this.
34335     PERFETTO_CHECK(next_chunk_ptr <= end());
34336   }
34337 
34338   // Remove from the index.
34339   for (auto it : index_delete) {
34340     index_.erase(it);
34341   }
34342   stats_.set_chunks_overwritten(chunks_overwritten);
34343   stats_.set_bytes_overwritten(bytes_overwritten);
34344   stats_.set_padding_bytes_cleared(padding_bytes_cleared);
34345 
34346   PERFETTO_DCHECK(next_chunk_ptr >= search_end && next_chunk_ptr <= end());
34347   return static_cast<ssize_t>(next_chunk_ptr - search_end);
34348 }
34349 
AddPaddingRecord(size_t size)34350 void TraceBuffer::AddPaddingRecord(size_t size) {
34351   PERFETTO_DCHECK(size >= sizeof(ChunkRecord) && size <= ChunkRecord::kMaxSize);
34352   ChunkRecord record(size);
34353   record.is_padding = 1;
34354   TRACE_BUFFER_DLOG("AddPaddingRecord @ [%lu - %lu] %zu", wptr_ - begin(),
34355                     uintptr_t(wptr_ - begin()) + size, size);
34356   WriteChunkRecord(wptr_, record, nullptr, size - sizeof(ChunkRecord));
34357   stats_.set_padding_bytes_written(stats_.padding_bytes_written() + size);
34358   // |wptr_| is deliberately not advanced when writing a padding record.
34359 }
34360 
TryPatchChunkContents(ProducerID producer_id,WriterID writer_id,ChunkID chunk_id,const Patch * patches,size_t patches_size,bool other_patches_pending)34361 bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
34362                                         WriterID writer_id,
34363                                         ChunkID chunk_id,
34364                                         const Patch* patches,
34365                                         size_t patches_size,
34366                                         bool other_patches_pending) {
34367   ChunkMeta::Key key(producer_id, writer_id, chunk_id);
34368   auto it = index_.find(key);
34369   if (it == index_.end()) {
34370     stats_.set_patches_failed(stats_.patches_failed() + 1);
34371     return false;
34372   }
34373   ChunkMeta& chunk_meta = it->second;
34374 
34375   // Check that the index is consistent with the actual ProducerID/WriterID
34376   // stored in the ChunkRecord.
34377   PERFETTO_DCHECK(ChunkMeta::Key(*chunk_meta.chunk_record) == key);
34378   uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_meta.chunk_record);
34379   PERFETTO_DCHECK(chunk_begin >= begin());
34380   uint8_t* chunk_end = chunk_begin + chunk_meta.chunk_record->size;
34381   PERFETTO_DCHECK(chunk_end <= end());
34382 
34383   static_assert(Patch::kSize == SharedMemoryABI::kPacketHeaderSize,
34384                 "Patch::kSize out of sync with SharedMemoryABI");
34385 
34386   for (size_t i = 0; i < patches_size; i++) {
34387     uint8_t* ptr =
34388         chunk_begin + sizeof(ChunkRecord) + patches[i].offset_untrusted;
34389     TRACE_BUFFER_DLOG("PatchChunk {%" PRIu32 ",%" PRIu32
34390                       ",%u} size=%zu @ %zu with {%02x %02x %02x %02x} cur "
34391                       "{%02x %02x %02x %02x}",
34392                       producer_id, writer_id, chunk_id, chunk_end - chunk_begin,
34393                       patches[i].offset_untrusted, patches[i].data[0],
34394                       patches[i].data[1], patches[i].data[2],
34395                       patches[i].data[3], ptr[0], ptr[1], ptr[2], ptr[3]);
34396     if (ptr < chunk_begin + sizeof(ChunkRecord) ||
34397         ptr > chunk_end - Patch::kSize) {
34398       // Either the IPC was so slow and in the meantime the writer managed to
34399       // wrap over |chunk_id| or the producer sent a malicious IPC.
34400       stats_.set_patches_failed(stats_.patches_failed() + 1);
34401       return false;
34402     }
34403 
34404     // DCHECK that we are writing into a zero-filled size field and not into
34405     // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
34406     // zero-fill reservations in debug builds.
34407     char zero[Patch::kSize]{};
34408     PERFETTO_DCHECK(memcmp(ptr, &zero, Patch::kSize) == 0);
34409 
34410     memcpy(ptr, &patches[i].data[0], Patch::kSize);
34411   }
34412   TRACE_BUFFER_DLOG(
34413       "Chunk raw (after patch): %s",
34414       HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
34415 
34416   stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
34417   if (!other_patches_pending) {
34418     chunk_meta.flags &= ~kChunkNeedsPatching;
34419     chunk_meta.chunk_record->flags = chunk_meta.flags;
34420   }
34421   return true;
34422 }
34423 
BeginRead()34424 void TraceBuffer::BeginRead() {
34425   read_iter_ = GetReadIterForSequence(index_.begin());
34426 #if PERFETTO_DCHECK_IS_ON()
34427   changed_since_last_read_ = false;
34428 #endif
34429 }
34430 
GetReadIterForSequence(ChunkMap::iterator seq_begin)34431 TraceBuffer::SequenceIterator TraceBuffer::GetReadIterForSequence(
34432     ChunkMap::iterator seq_begin) {
34433   SequenceIterator iter;
34434   iter.seq_begin = seq_begin;
34435   if (seq_begin == index_.end()) {
34436     iter.cur = iter.seq_end = index_.end();
34437     return iter;
34438   }
34439 
34440 #if PERFETTO_DCHECK_IS_ON()
34441   // Either |seq_begin| is == index_.begin() or the item immediately before must
34442   // belong to a different {ProducerID, WriterID} sequence.
34443   if (seq_begin != index_.begin() && seq_begin != index_.end()) {
34444     auto prev_it = seq_begin;
34445     prev_it--;
34446     PERFETTO_DCHECK(
34447         seq_begin == index_.begin() ||
34448         std::tie(prev_it->first.producer_id, prev_it->first.writer_id) <
34449             std::tie(seq_begin->first.producer_id, seq_begin->first.writer_id));
34450   }
34451 #endif
34452 
34453   // Find the first entry that has a greater {ProducerID, WriterID} (or just
34454   // index_.end() if we reached the end).
34455   ChunkMeta::Key key = seq_begin->first;  // Deliberate copy.
34456   key.chunk_id = kMaxChunkID;
34457   iter.seq_end = index_.upper_bound(key);
34458   PERFETTO_DCHECK(iter.seq_begin != iter.seq_end);
34459 
34460   // Now find the first entry between [seq_begin, seq_end) that is
34461   // > last_chunk_id_written_. This is where we the sequence will start (see
34462   // notes about wrapping of IDs in the header).
34463   auto producer_and_writer_id = std::make_pair(key.producer_id, key.writer_id);
34464   PERFETTO_DCHECK(last_chunk_id_written_.count(producer_and_writer_id));
34465   iter.wrapping_id = last_chunk_id_written_[producer_and_writer_id];
34466   key.chunk_id = iter.wrapping_id;
34467   iter.cur = index_.upper_bound(key);
34468   if (iter.cur == iter.seq_end)
34469     iter.cur = iter.seq_begin;
34470   return iter;
34471 }
34472 
MoveNext()34473 void TraceBuffer::SequenceIterator::MoveNext() {
34474   // Stop iterating when we reach the end of the sequence.
34475   // Note: |seq_begin| might be == |seq_end|.
34476   if (cur == seq_end || cur->first.chunk_id == wrapping_id) {
34477     cur = seq_end;
34478     return;
34479   }
34480 
34481   // If the current chunk wasn't completed yet, we shouldn't advance past it as
34482   // it may be rewritten with additional packets.
34483   if (!cur->second.is_complete()) {
34484     cur = seq_end;
34485     return;
34486   }
34487 
34488   ChunkID last_chunk_id = cur->first.chunk_id;
34489   if (++cur == seq_end)
34490     cur = seq_begin;
34491 
34492   // There may be a missing chunk in the sequence of chunks, in which case the
34493   // next chunk's ID won't follow the last one's. If so, skip the rest of the
34494   // sequence. We'll return to it later once the hole is filled.
34495   if (last_chunk_id + 1 != cur->first.chunk_id)
34496     cur = seq_end;
34497 }
34498 
ReadNextTracePacket(TracePacket * packet,PacketSequenceProperties * sequence_properties,bool * previous_packet_on_sequence_dropped)34499 bool TraceBuffer::ReadNextTracePacket(
34500     TracePacket* packet,
34501     PacketSequenceProperties* sequence_properties,
34502     bool* previous_packet_on_sequence_dropped) {
34503   // Note: MoveNext() moves only within the next chunk within the same
34504   // {ProducerID, WriterID} sequence. Here we want to:
34505   // - return the next patched+complete packet in the current sequence, if any.
34506   // - return the first patched+complete packet in the next sequence, if any.
34507   // - return false if none of the above is found.
34508   TRACE_BUFFER_DLOG("ReadNextTracePacket()");
34509 
34510   // Just in case we forget to initialize these below.
34511   *sequence_properties = {0, kInvalidUid, 0};
34512   *previous_packet_on_sequence_dropped = false;
34513 
34514   // At the start of each sequence iteration, we consider the last read packet
34515   // dropped. While iterating over the chunks in the sequence, we update this
34516   // flag based on our knowledge about the last packet that was read from each
34517   // chunk (|last_read_packet_skipped| in ChunkMeta).
34518   bool previous_packet_dropped = true;
34519 
34520 #if PERFETTO_DCHECK_IS_ON()
34521   PERFETTO_DCHECK(!changed_since_last_read_);
34522 #endif
34523   for (;; read_iter_.MoveNext()) {
34524     if (PERFETTO_UNLIKELY(!read_iter_.is_valid())) {
34525       // We ran out of chunks in the current {ProducerID, WriterID} sequence or
34526       // we just reached the index_.end().
34527 
34528       if (PERFETTO_UNLIKELY(read_iter_.seq_end == index_.end()))
34529         return false;
34530 
34531       // We reached the end of sequence, move to the next one.
34532       // Note: ++read_iter_.seq_end might become index_.end(), but
34533       // GetReadIterForSequence() knows how to deal with that.
34534       read_iter_ = GetReadIterForSequence(read_iter_.seq_end);
34535       PERFETTO_DCHECK(read_iter_.is_valid() && read_iter_.cur != index_.end());
34536       previous_packet_dropped = true;
34537     }
34538 
34539     ChunkMeta* chunk_meta = &*read_iter_;
34540 
34541     // If the chunk has holes that are awaiting to be patched out-of-band,
34542     // skip the current sequence and move to the next one.
34543     if (chunk_meta->flags & kChunkNeedsPatching) {
34544       read_iter_.MoveToEnd();
34545       continue;
34546     }
34547 
34548     const ProducerID trusted_producer_id = read_iter_.producer_id();
34549     const WriterID writer_id = read_iter_.writer_id();
34550     const uid_t trusted_uid = chunk_meta->trusted_uid;
34551 
34552     // At this point we have a chunk in |chunk_meta| that has not been fully
34553     // read. We don't know yet whether we have enough data to read the full
34554     // packet (in the case it's fragmented over several chunks) and we are about
34555     // to find that out. Specifically:
34556     // A) If the first fragment is unread and is a fragment continuing from a
34557     //    previous chunk, it means we have missed the previous ChunkID. In
34558     //    fact, if this wasn't the case, a previous call to ReadNext() shouldn't
34559     //    have moved the cursor to this chunk.
34560     // B) Any fragment > 0 && < last is always readable. By definition an inner
34561     //    packet is never fragmented and hence doesn't require neither stitching
34562     //    nor any out-of-band patching. The same applies to the last packet
34563     //    iff it doesn't continue on the next chunk.
34564     // C) If the last packet (which might be also the only packet in the chunk)
34565     //    is a fragment and continues on the next chunk, we peek at the next
34566     //    chunks and, if we have all of them, mark as read and move the cursor.
34567     //
34568     // +---------------+   +-------------------+  +---------------+
34569     // | ChunkID: 1    |   | ChunkID: 2        |  | ChunkID: 3    |
34570     // |---------------+   +-------------------+  +---------------+
34571     // | Packet 1      |   |                   |  | ... Packet 3  |
34572     // | Packet 2      |   | ... Packet 3  ... |  | Packet 4      |
34573     // | Packet 3  ... |   |                   |  | Packet 5 ...  |
34574     // +---------------+   +-------------------+  +---------------+
34575 
34576     PERFETTO_DCHECK(chunk_meta->num_fragments_read <=
34577                     chunk_meta->num_fragments);
34578 
34579     // If we didn't read any packets from this chunk, the last packet was from
34580     // the previous chunk we iterated over; so don't update
34581     // |previous_packet_dropped| in this case.
34582     if (chunk_meta->num_fragments_read > 0)
34583       previous_packet_dropped = chunk_meta->last_read_packet_skipped();
34584 
34585     while (chunk_meta->num_fragments_read < chunk_meta->num_fragments) {
34586       enum { kSkip = 0, kReadOnePacket, kTryReadAhead } action;
34587       if (chunk_meta->num_fragments_read == 0) {
34588         if (chunk_meta->flags & kFirstPacketContinuesFromPrevChunk) {
34589           action = kSkip;  // Case A.
34590         } else if (chunk_meta->num_fragments == 1 &&
34591                    (chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
34592           action = kTryReadAhead;  // Case C.
34593         } else {
34594           action = kReadOnePacket;  // Case B.
34595         }
34596       } else if (chunk_meta->num_fragments_read <
34597                      chunk_meta->num_fragments - 1 ||
34598                  !(chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
34599         action = kReadOnePacket;  // Case B.
34600       } else {
34601         action = kTryReadAhead;  // Case C.
34602       }
34603 
34604       TRACE_BUFFER_DLOG("  chunk %u, packet %hu of %hu, action=%d",
34605                         read_iter_.chunk_id(), chunk_meta->num_fragments_read,
34606                         chunk_meta->num_fragments, action);
34607 
34608       if (action == kSkip) {
34609         // This fragment will be skipped forever, not just in this ReadPacket()
34610         // iteration. This happens by virtue of ReadNextPacketInChunk()
34611         // incrementing the |num_fragments_read| and marking the fragment as
34612         // read even if we didn't really.
34613         ReadNextPacketInChunk(chunk_meta, nullptr);
34614         chunk_meta->set_last_read_packet_skipped(true);
34615         previous_packet_dropped = true;
34616         continue;
34617       }
34618 
34619       if (action == kReadOnePacket) {
34620         // The easy peasy case B.
34621         ReadPacketResult result = ReadNextPacketInChunk(chunk_meta, packet);
34622 
34623         if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
34624           *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
34625           *previous_packet_on_sequence_dropped = previous_packet_dropped;
34626           return true;
34627         } else if (result == ReadPacketResult::kFailedEmptyPacket) {
34628           // We can ignore and skip empty packets.
34629           PERFETTO_DCHECK(packet->slices().empty());
34630           continue;
34631         }
34632 
34633         // In extremely rare cases (producer bugged / malicious) the chunk might
34634         // contain an invalid fragment. In such case we don't want to stall the
34635         // sequence but just skip the chunk and move on. ReadNextPacketInChunk()
34636         // marks the chunk as fully read, so we don't attempt to read from it
34637         // again in a future call to ReadBuffers(). It also already records an
34638         // abi violation for this.
34639         PERFETTO_DCHECK(result == ReadPacketResult::kFailedInvalidPacket);
34640         chunk_meta->set_last_read_packet_skipped(true);
34641         previous_packet_dropped = true;
34642         break;
34643       }
34644 
34645       PERFETTO_DCHECK(action == kTryReadAhead);
34646       ReadAheadResult ra_res = ReadAhead(packet);
34647       if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
34648         stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
34649         *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
34650         *previous_packet_on_sequence_dropped = previous_packet_dropped;
34651         return true;
34652       }
34653 
34654       if (ra_res == ReadAheadResult::kFailedMoveToNextSequence) {
34655         // readahead didn't find a contiguous packet sequence. We'll try again
34656         // on the next ReadPacket() call.
34657         stats_.set_readaheads_failed(stats_.readaheads_failed() + 1);
34658 
34659         // TODO(primiano): optimization: this MoveToEnd() is the reason why
34660         // MoveNext() (that is called in the outer for(;;MoveNext)) needs to
34661         // deal gracefully with the case of |cur|==|seq_end|. Maybe we can do
34662         // something to avoid that check by reshuffling the code here?
34663         read_iter_.MoveToEnd();
34664 
34665         // This break will go back to beginning of the for(;;MoveNext()). That
34666         // will move to the next sequence because we set the read iterator to
34667         // its end.
34668         break;
34669       }
34670 
34671       PERFETTO_DCHECK(ra_res == ReadAheadResult::kFailedStayOnSameSequence);
34672 
34673       // In this case ReadAhead() might advance |read_iter_|, so we need to
34674       // re-cache the |chunk_meta| pointer to point to the current chunk.
34675       chunk_meta = &*read_iter_;
34676       chunk_meta->set_last_read_packet_skipped(true);
34677       previous_packet_dropped = true;
34678     }  // while(...)  [iterate over packet fragments for the current chunk].
34679   }    // for(;;MoveNext()) [iterate over chunks].
34680 }
34681 
ReadAhead(TracePacket * packet)34682 TraceBuffer::ReadAheadResult TraceBuffer::ReadAhead(TracePacket* packet) {
34683   static_assert(static_cast<ChunkID>(kMaxChunkID + 1) == 0,
34684                 "relying on kMaxChunkID to wrap naturally");
34685   TRACE_BUFFER_DLOG(" readahead start @ chunk %u", read_iter_.chunk_id());
34686   ChunkID next_chunk_id = read_iter_.chunk_id() + 1;
34687   SequenceIterator it = read_iter_;
34688   for (it.MoveNext(); it.is_valid(); it.MoveNext(), next_chunk_id++) {
34689     // We should stay within the same sequence while iterating here.
34690     PERFETTO_DCHECK(it.producer_id() == read_iter_.producer_id() &&
34691                     it.writer_id() == read_iter_.writer_id());
34692 
34693     TRACE_BUFFER_DLOG("   expected chunk ID: %u, actual ID: %u", next_chunk_id,
34694                       it.chunk_id());
34695 
34696     if (PERFETTO_UNLIKELY((*it).num_fragments == 0))
34697       continue;
34698 
34699     // If we miss the next chunk, stop looking in the current sequence and
34700     // try another sequence. This chunk might come in the near future.
34701     // The second condition is the edge case of a buggy/malicious
34702     // producer. The ChunkID is contiguous but its flags don't make sense.
34703     if (it.chunk_id() != next_chunk_id ||
34704         PERFETTO_UNLIKELY(
34705             !((*it).flags & kFirstPacketContinuesFromPrevChunk))) {
34706       return ReadAheadResult::kFailedMoveToNextSequence;
34707     }
34708 
34709     // If the chunk is contiguous but has not been patched yet move to the next
34710     // sequence and try coming back here on the next ReadNextTracePacket() call.
34711     // TODO(primiano): add a test to cover this, it's a subtle case.
34712     if ((*it).flags & kChunkNeedsPatching)
34713       return ReadAheadResult::kFailedMoveToNextSequence;
34714 
34715     // This is the case of an intermediate chunk which contains only one
34716     // fragment which continues on the next chunk. This is the case for large
34717     // packets, e.g.: [Packet0, Packet1(0)] [Packet1(1)] [Packet1(2), ...]
34718     // (Packet1(X) := fragment X of Packet1).
34719     if ((*it).num_fragments == 1 &&
34720         ((*it).flags & kLastPacketContinuesOnNextChunk)) {
34721       continue;
34722     }
34723 
34724     // We made it! We got all fragments for the packet without holes.
34725     TRACE_BUFFER_DLOG("  readahead success @ chunk %u", it.chunk_id());
34726     PERFETTO_DCHECK(((*it).num_fragments == 1 &&
34727                      !((*it).flags & kLastPacketContinuesOnNextChunk)) ||
34728                     (*it).num_fragments > 1);
34729 
34730     // Now let's re-iterate over the [read_iter_, it] sequence and mark
34731     // all the fragments as read.
34732     bool packet_corruption = false;
34733     for (;;) {
34734       PERFETTO_DCHECK(read_iter_.is_valid());
34735       TRACE_BUFFER_DLOG("    commit chunk %u", read_iter_.chunk_id());
34736       if (PERFETTO_LIKELY((*read_iter_).num_fragments > 0)) {
34737         // In the unlikely case of a corrupted packet (corrupted or empty
34738         // fragment), invalidate the all stitching and move on to the next chunk
34739         // in the same sequence, if any.
34740         packet_corruption |= ReadNextPacketInChunk(&*read_iter_, packet) ==
34741                              ReadPacketResult::kFailedInvalidPacket;
34742       }
34743       if (read_iter_.cur == it.cur)
34744         break;
34745       read_iter_.MoveNext();
34746     }  // for(;;)
34747     PERFETTO_DCHECK(read_iter_.cur == it.cur);
34748 
34749     if (PERFETTO_UNLIKELY(packet_corruption)) {
34750       // ReadNextPacketInChunk() already records an abi violation for this case.
34751       *packet = TracePacket();  // clear.
34752       return ReadAheadResult::kFailedStayOnSameSequence;
34753     }
34754 
34755     return ReadAheadResult::kSucceededReturnSlices;
34756   }  // for(it...)  [readahead loop]
34757   return ReadAheadResult::kFailedMoveToNextSequence;
34758 }
34759 
ReadNextPacketInChunk(ChunkMeta * chunk_meta,TracePacket * packet)34760 TraceBuffer::ReadPacketResult TraceBuffer::ReadNextPacketInChunk(
34761     ChunkMeta* chunk_meta,
34762     TracePacket* packet) {
34763   PERFETTO_DCHECK(chunk_meta->num_fragments_read < chunk_meta->num_fragments);
34764   PERFETTO_DCHECK(!(chunk_meta->flags & kChunkNeedsPatching));
34765 
34766   const uint8_t* record_begin =
34767       reinterpret_cast<const uint8_t*>(chunk_meta->chunk_record);
34768   const uint8_t* record_end = record_begin + chunk_meta->chunk_record->size;
34769   const uint8_t* packets_begin = record_begin + sizeof(ChunkRecord);
34770   const uint8_t* packet_begin = packets_begin + chunk_meta->cur_fragment_offset;
34771 
34772   if (PERFETTO_UNLIKELY(packet_begin < packets_begin ||
34773                         packet_begin >= record_end)) {
34774     // The producer has a bug or is malicious and did declare that the chunk
34775     // contains more packets beyond its boundaries.
34776     stats_.set_abi_violations(stats_.abi_violations() + 1);
34777     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34778     chunk_meta->cur_fragment_offset = 0;
34779     chunk_meta->num_fragments_read = chunk_meta->num_fragments;
34780     if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
34781       stats_.set_chunks_read(stats_.chunks_read() + 1);
34782       stats_.set_bytes_read(stats_.bytes_read() +
34783                             chunk_meta->chunk_record->size);
34784     }
34785     return ReadPacketResult::kFailedInvalidPacket;
34786   }
34787 
34788   // A packet (or a fragment) starts with a varint stating its size, followed
34789   // by its content. The varint shouldn't be larger than 4 bytes (just in case
34790   // the producer is using a redundant encoding)
34791   uint64_t packet_size = 0;
34792   const uint8_t* header_end =
34793       std::min(packet_begin + protozero::proto_utils::kMessageLengthFieldSize,
34794                record_end);
34795   const uint8_t* packet_data = protozero::proto_utils::ParseVarInt(
34796       packet_begin, header_end, &packet_size);
34797 
34798   const uint8_t* next_packet = packet_data + packet_size;
34799   if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
34800                         next_packet > record_end)) {
34801     // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
34802     // packet by writing an invalid size in the last fragment's header. We
34803     // should handle this case without recording an ABI violation (since Android
34804     // R).
34805     if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
34806       stats_.set_abi_violations(stats_.abi_violations() + 1);
34807       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34808     } else {
34809       stats_.set_trace_writer_packet_loss(stats_.trace_writer_packet_loss() +
34810                                           1);
34811     }
34812     chunk_meta->cur_fragment_offset = 0;
34813     chunk_meta->num_fragments_read = chunk_meta->num_fragments;
34814     if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
34815       stats_.set_chunks_read(stats_.chunks_read() + 1);
34816       stats_.set_bytes_read(stats_.bytes_read() +
34817                             chunk_meta->chunk_record->size);
34818     }
34819     return ReadPacketResult::kFailedInvalidPacket;
34820   }
34821 
34822   chunk_meta->cur_fragment_offset =
34823       static_cast<uint16_t>(next_packet - packets_begin);
34824   chunk_meta->num_fragments_read++;
34825 
34826   if (PERFETTO_UNLIKELY(chunk_meta->num_fragments_read ==
34827                             chunk_meta->num_fragments &&
34828                         chunk_meta->is_complete())) {
34829     stats_.set_chunks_read(stats_.chunks_read() + 1);
34830     stats_.set_bytes_read(stats_.bytes_read() + chunk_meta->chunk_record->size);
34831   } else {
34832     // We have at least one more packet to parse. It should be within the chunk.
34833     if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
34834         chunk_meta->chunk_record->size) {
34835       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
34836     }
34837   }
34838 
34839   chunk_meta->set_last_read_packet_skipped(false);
34840 
34841   if (PERFETTO_UNLIKELY(packet_size == 0))
34842     return ReadPacketResult::kFailedEmptyPacket;
34843 
34844   if (PERFETTO_LIKELY(packet))
34845     packet->AddSlice(packet_data, static_cast<size_t>(packet_size));
34846 
34847   return ReadPacketResult::kSucceeded;
34848 }
34849 
DiscardWrite()34850 void TraceBuffer::DiscardWrite() {
34851   PERFETTO_DCHECK(overwrite_policy_ == kDiscard);
34852   discard_writes_ = true;
34853   stats_.set_chunks_discarded(stats_.chunks_discarded() + 1);
34854   TRACE_BUFFER_DLOG("  discarding write");
34855 }
34856 
34857 }  // namespace perfetto
34858 // gen_amalgamated begin source: src/tracing/core/tracing_service_impl.cc
34859 // gen_amalgamated begin header: src/tracing/core/tracing_service_impl.h
34860 // gen_amalgamated begin header: include/perfetto/ext/base/circular_queue.h
34861 /*
34862  * Copyright (C) 2019 The Android Open Source Project
34863  *
34864  * Licensed under the Apache License, Version 2.0 (the "License");
34865  * you may not use this file except in compliance with the License.
34866  * You may obtain a copy of the License at
34867  *
34868  *      http://www.apache.org/licenses/LICENSE-2.0
34869  *
34870  * Unless required by applicable law or agreed to in writing, software
34871  * distributed under the License is distributed on an "AS IS" BASIS,
34872  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34873  * See the License for the specific language governing permissions and
34874  * limitations under the License.
34875  */
34876 
34877 #ifndef INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
34878 #define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
34879 
34880 #include <stdint.h>
34881 #include <iterator>
34882 
34883 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
34884 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
34885 
34886 namespace perfetto {
34887 namespace base {
34888 
34889 // CircularQueue is a push-back-only / pop-front-only queue with the following
34890 // characteristics:
34891 // - The storage is based on a flat circular buffer. Beginning and end wrap
34892 //   as necessary, to keep pushes and pops O(1) as long as capacity expansion is
34893 //   not required.
34894 // - Capacity is automatically expanded like in a std::vector. Expansion has a
34895 //   O(N) cost.
34896 // - It allows random access, allowing in-place std::sort.
34897 // - Iterators are not stable. Mutating the container invalidates all iterators.
34898 // - It doesn't bother with const-correctness.
34899 //
34900 // Implementation details:
34901 // Internally, |begin|, |end| and iterators use 64-bit monotonic indexes, which
34902 // are incremented as if the queue was backed by unlimited storage.
34903 // Even assuming that elements are inserted and removed every nanosecond, 64 bit
34904 // is enough for 584 years.
34905 // Wrapping happens only when addressing elements in the underlying circular
34906 // storage. This limits the complexity and avoiding dealing with modular
34907 // arithmetic all over the places.
34908 template <class T>
34909 class CircularQueue {
34910  public:
34911   class Iterator {
34912    public:
34913     using difference_type = ptrdiff_t;
34914     using value_type = T;
34915     using pointer = T*;
34916     using reference = T&;
34917     using iterator_category = std::random_access_iterator_tag;
34918 
Iterator(CircularQueue * queue,uint64_t pos,uint32_t generation)34919     Iterator(CircularQueue* queue, uint64_t pos, uint32_t generation)
34920         : queue_(queue),
34921           pos_(pos)
34922 #if PERFETTO_DCHECK_IS_ON()
34923           ,
34924           generation_(generation)
34925 #endif
34926     {
34927       ignore_result(generation);
34928     }
34929 
operator ->()34930     T* operator->() {
34931 #if PERFETTO_DCHECK_IS_ON()
34932       PERFETTO_DCHECK(generation_ == queue_->generation());
34933 #endif
34934       return queue_->Get(pos_);
34935     }
34936 
operator ->() const34937     const T* operator->() const {
34938       return const_cast<CircularQueue<T>::Iterator*>(this)->operator->();
34939     }
34940 
operator *()34941     T& operator*() { return *(operator->()); }
operator *() const34942     const T& operator*() const { return *(operator->()); }
34943 
operator [](difference_type i)34944     value_type& operator[](difference_type i) { return *(*this + i); }
34945 
operator [](difference_type i) const34946     const value_type& operator[](difference_type i) const {
34947       return const_cast<CircularQueue<T>::Iterator&>(*this)[i];
34948     }
34949 
operator ++()34950     Iterator& operator++() {
34951       Add(1);
34952       return *this;
34953     }
34954 
operator ++(int)34955     Iterator operator++(int) {
34956       Iterator ret = *this;
34957       Add(1);
34958       return ret;
34959     }
34960 
operator --()34961     Iterator& operator--() {
34962       Add(-1);
34963       return *this;
34964     }
34965 
operator --(int)34966     Iterator operator--(int) {
34967       Iterator ret = *this;
34968       Add(-1);
34969       return ret;
34970     }
34971 
operator +(const Iterator & iter,difference_type offset)34972     friend Iterator operator+(const Iterator& iter, difference_type offset) {
34973       Iterator ret = iter;
34974       ret.Add(offset);
34975       return ret;
34976     }
34977 
operator +=(difference_type offset)34978     Iterator& operator+=(difference_type offset) {
34979       Add(offset);
34980       return *this;
34981     }
34982 
operator -(const Iterator & iter,difference_type offset)34983     friend Iterator operator-(const Iterator& iter, difference_type offset) {
34984       Iterator ret = iter;
34985       ret.Add(-offset);
34986       return ret;
34987     }
34988 
operator -=(difference_type offset)34989     Iterator& operator-=(difference_type offset) {
34990       Add(-offset);
34991       return *this;
34992     }
34993 
operator -(const Iterator & lhs,const Iterator & rhs)34994     friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) {
34995       return static_cast<ptrdiff_t>(lhs.pos_) -
34996              static_cast<ptrdiff_t>(rhs.pos_);
34997     }
34998 
operator ==(const Iterator & lhs,const Iterator & rhs)34999     friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
35000       return lhs.pos_ == rhs.pos_;
35001     }
35002 
operator !=(const Iterator & lhs,const Iterator & rhs)35003     friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
35004       return lhs.pos_ != rhs.pos_;
35005     }
35006 
operator <(const Iterator & lhs,const Iterator & rhs)35007     friend bool operator<(const Iterator& lhs, const Iterator& rhs) {
35008       return lhs.pos_ < rhs.pos_;
35009     }
35010 
operator <=(const Iterator & lhs,const Iterator & rhs)35011     friend bool operator<=(const Iterator& lhs, const Iterator& rhs) {
35012       return lhs.pos_ <= rhs.pos_;
35013     }
35014 
operator >(const Iterator & lhs,const Iterator & rhs)35015     friend bool operator>(const Iterator& lhs, const Iterator& rhs) {
35016       return lhs.pos_ > rhs.pos_;
35017     }
35018 
operator >=(const Iterator & lhs,const Iterator & rhs)35019     friend bool operator>=(const Iterator& lhs, const Iterator& rhs) {
35020       return lhs.pos_ >= rhs.pos_;
35021     }
35022 
35023    private:
Add(difference_type offset)35024     inline void Add(difference_type offset) {
35025       pos_ = static_cast<uint64_t>(static_cast<difference_type>(pos_) + offset);
35026       PERFETTO_DCHECK(pos_ <= queue_->end_);
35027     }
35028 
35029     CircularQueue* queue_;
35030     uint64_t pos_;
35031 
35032 #if PERFETTO_DCHECK_IS_ON()
35033     uint32_t generation_;
35034 #endif
35035   };
35036 
CircularQueue(size_t initial_capacity=1024)35037   CircularQueue(size_t initial_capacity = 1024) { Grow(initial_capacity); }
35038 
CircularQueue(CircularQueue && other)35039   CircularQueue(CircularQueue&& other) noexcept {
35040     // Copy all fields using the (private) default copy assignment operator.
35041     *this = other;
35042     increment_generation();
35043     new (&other) CircularQueue();  // Reset the old queue so it's still usable.
35044   }
35045 
operator =(CircularQueue && other)35046   CircularQueue& operator=(CircularQueue&& other) {
35047     this->~CircularQueue();                      // Destroy the current state.
35048     new (this) CircularQueue(std::move(other));  // Use the move ctor above.
35049     return *this;
35050   }
35051 
~CircularQueue()35052   ~CircularQueue() {
35053     if (!entries_) {
35054       PERFETTO_DCHECK(empty());
35055       return;
35056     }
35057     clear();  // Invoke destructors on all alive entries.
35058     PERFETTO_DCHECK(empty());
35059     free(entries_);
35060   }
35061 
35062   template <typename... Args>
emplace_back(Args &&...args)35063   void emplace_back(Args&&... args) {
35064     increment_generation();
35065     if (PERFETTO_UNLIKELY(size() >= capacity_))
35066       Grow();
35067     T* slot = Get(end_++);
35068     new (slot) T(std::forward<Args>(args)...);
35069   }
35070 
erase_front(size_t n)35071   void erase_front(size_t n) {
35072     increment_generation();
35073     for (; n && (begin_ < end_); --n) {
35074       Get(begin_)->~T();
35075       begin_++;  // This needs to be its own statement, Get() checks begin_.
35076     }
35077   }
35078 
pop_front()35079   void pop_front() { erase_front(1); }
35080 
clear()35081   void clear() { erase_front(size()); }
35082 
at(size_t idx)35083   T& at(size_t idx) {
35084     PERFETTO_DCHECK(idx < size());
35085     return *Get(begin_ + idx);
35086   }
35087 
begin()35088   Iterator begin() { return Iterator(this, begin_, generation()); }
end()35089   Iterator end() { return Iterator(this, end_, generation()); }
front()35090   T& front() { return *begin(); }
back()35091   T& back() { return *(end() - 1); }
35092 
empty() const35093   bool empty() const { return size() == 0; }
35094 
size() const35095   size_t size() const {
35096     PERFETTO_DCHECK(end_ - begin_ <= capacity_);
35097     return static_cast<size_t>(end_ - begin_);
35098   }
35099 
capacity() const35100   size_t capacity() const { return capacity_; }
35101 
35102 #if PERFETTO_DCHECK_IS_ON()
generation() const35103   uint32_t generation() const { return generation_; }
increment_generation()35104   void increment_generation() { ++generation_; }
35105 #else
generation() const35106   uint32_t generation() const { return 0; }
increment_generation()35107   void increment_generation() {}
35108 #endif
35109 
35110  private:
35111   CircularQueue(const CircularQueue&) = delete;
35112   CircularQueue& operator=(const CircularQueue&) = default;
35113 
Grow(size_t new_capacity=0)35114   void Grow(size_t new_capacity = 0) {
35115     // Capacity must be always a power of two. This allows Get() to use a simple
35116     // bitwise-AND for handling the wrapping instead of a full division.
35117     new_capacity = new_capacity ? new_capacity : capacity_ * 2;
35118     PERFETTO_CHECK((new_capacity & (new_capacity - 1)) == 0);  // Must be pow2.
35119 
35120     // On 32-bit systems this might hit the 4GB wall and overflow. We can't do
35121     // anything other than crash in this case.
35122     PERFETTO_CHECK(new_capacity > capacity_);
35123     size_t malloc_size = new_capacity * sizeof(T);
35124     PERFETTO_CHECK(malloc_size > new_capacity);
35125     auto* new_vec = static_cast<T*>(malloc(malloc_size));
35126 
35127     // Move all elements in the expanded array.
35128     size_t new_size = 0;
35129     for (uint64_t i = begin_; i < end_; i++)
35130       new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.
35131 
35132     // Even if all the elements are std::move()-d and likely empty, we are still
35133     // required to call the dtor for them.
35134     for (uint64_t i = begin_; i < end_; i++)
35135       Get(i)->~T();
35136     free(entries_);  // It's fine to free(nullptr) (for the ctor call case).
35137 
35138     begin_ = 0;
35139     end_ = new_size;
35140     capacity_ = new_capacity;
35141     entries_ = new_vec;
35142   }
35143 
Get(uint64_t pos)35144   inline T* Get(uint64_t pos) {
35145     PERFETTO_DCHECK(pos >= begin_ && pos < end_);
35146     PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
35147     auto index = static_cast<size_t>(pos & (capacity_ - 1));
35148     return &entries_[index];
35149   }
35150 
35151   // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
35152   // to allow having uninitialized entries inside it.
35153   T* entries_ = nullptr;
35154   size_t capacity_ = 0;  // Number of allocated slots (NOT bytes) in |entries_|.
35155 
35156   // The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
35157   // is used only when dereferencing entries in the vector.
35158   uint64_t begin_ = 0;
35159   uint64_t end_ = 0;
35160 
35161 // Generation is used in debug builds only for checking iterator validity.
35162 #if PERFETTO_DCHECK_IS_ON()
35163   uint32_t generation_ = 0;
35164 #endif
35165 };
35166 
35167 }  // namespace base
35168 }  // namespace perfetto
35169 
35170 #endif  // INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
35171 /*
35172  * Copyright (C) 2017 The Android Open Source Project
35173  *
35174  * Licensed under the Apache License, Version 2.0 (the "License");
35175  * you may not use this file except in compliance with the License.
35176  * You may obtain a copy of the License at
35177  *
35178  *      http://www.apache.org/licenses/LICENSE-2.0
35179  *
35180  * Unless required by applicable law or agreed to in writing, software
35181  * distributed under the License is distributed on an "AS IS" BASIS,
35182  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35183  * See the License for the specific language governing permissions and
35184  * limitations under the License.
35185  */
35186 
35187 #ifndef SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
35188 #define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
35189 
35190 #include <algorithm>
35191 #include <functional>
35192 #include <map>
35193 #include <memory>
35194 #include <mutex>
35195 #include <set>
35196 #include <utility>
35197 #include <vector>
35198 
35199 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
35200 // gen_amalgamated expanded: #include "perfetto/base/time.h"
35201 // gen_amalgamated expanded: #include "perfetto/ext/base/circular_queue.h"
35202 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
35203 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
35204 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
35205 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
35206 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
35207 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
35208 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
35209 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
35210 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
35211 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
35212 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
35213 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
35214 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
35215 
35216 namespace perfetto {
35217 
35218 namespace base {
35219 class TaskRunner;
35220 }  // namespace base
35221 
35222 class Consumer;
35223 class Producer;
35224 class SharedMemory;
35225 class SharedMemoryArbiterImpl;
35226 class TraceBuffer;
35227 class TracePacket;
35228 
35229 // The tracing service business logic.
35230 class TracingServiceImpl : public TracingService {
35231  private:
35232   struct DataSourceInstance;
35233 
35234  public:
35235   static constexpr size_t kDefaultShmPageSize = 4096ul;
35236   static constexpr size_t kDefaultShmSize = 256 * 1024ul;
35237   static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
35238   static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
35239   static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
35240                                             0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
35241                                             0x6d, 0x57, 0xa0, 0x79};
35242 
35243   // The implementation behind the service endpoint exposed to each producer.
35244   class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
35245    public:
35246     ProducerEndpointImpl(ProducerID,
35247                          uid_t uid,
35248                          TracingServiceImpl*,
35249                          base::TaskRunner*,
35250                          Producer*,
35251                          const std::string& producer_name,
35252                          bool in_process,
35253                          bool smb_scraping_enabled);
35254     ~ProducerEndpointImpl() override;
35255 
35256     // TracingService::ProducerEndpoint implementation.
35257     void RegisterDataSource(const DataSourceDescriptor&) override;
35258     void UnregisterDataSource(const std::string& name) override;
35259     void RegisterTraceWriter(uint32_t writer_id,
35260                              uint32_t target_buffer) override;
35261     void UnregisterTraceWriter(uint32_t writer_id) override;
35262     void CommitData(const CommitDataRequest&, CommitDataCallback) override;
35263     void SetupSharedMemory(std::unique_ptr<SharedMemory>,
35264                            size_t page_size_bytes,
35265                            bool provided_by_producer);
35266     std::unique_ptr<TraceWriter> CreateTraceWriter(
35267         BufferID,
35268         BufferExhaustedPolicy) override;
35269     SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
35270     bool IsShmemProvidedByProducer() const override;
35271     void NotifyFlushComplete(FlushRequestID) override;
35272     void NotifyDataSourceStarted(DataSourceInstanceID) override;
35273     void NotifyDataSourceStopped(DataSourceInstanceID) override;
35274     SharedMemory* shared_memory() const override;
35275     size_t shared_buffer_page_size_kb() const override;
35276     void ActivateTriggers(const std::vector<std::string>&) override;
35277     void Sync(std::function<void()> callback) override;
35278 
35279     void OnTracingSetup();
35280     void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
35281     void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
35282     void StopDataSource(DataSourceInstanceID);
35283     void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
35284     void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
35285     void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
35286 
is_allowed_target_buffer(BufferID buffer_id) const35287     bool is_allowed_target_buffer(BufferID buffer_id) const {
35288       return allowed_target_buffers_.count(buffer_id);
35289     }
35290 
buffer_id_for_writer(WriterID writer_id) const35291     base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
35292       const auto it = writers_.find(writer_id);
35293       if (it != writers_.end())
35294         return it->second;
35295       return base::nullopt;
35296     }
35297 
uid() const35298     uid_t uid() const { return uid_; }
35299 
35300    private:
35301     friend class TracingServiceImpl;
35302     friend class TracingServiceImplTest;
35303     friend class TracingIntegrationTest;
35304     ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
35305     ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
35306 
35307     ProducerID const id_;
35308     const uid_t uid_;
35309     TracingServiceImpl* const service_;
35310     base::TaskRunner* const task_runner_;
35311     Producer* producer_;
35312     std::unique_ptr<SharedMemory> shared_memory_;
35313     size_t shared_buffer_page_size_kb_ = 0;
35314     SharedMemoryABI shmem_abi_;
35315     size_t shmem_size_hint_bytes_ = 0;
35316     size_t shmem_page_size_hint_bytes_ = 0;
35317     bool is_shmem_provided_by_producer_ = false;
35318     const std::string name_;
35319     bool in_process_;
35320     bool smb_scraping_enabled_;
35321 
35322     // Set of the global target_buffer IDs that the producer is configured to
35323     // write into in any active tracing session.
35324     std::set<BufferID> allowed_target_buffers_;
35325 
35326     // Maps registered TraceWriter IDs to their target buffers as registered by
35327     // the producer. Note that producers aren't required to register their
35328     // writers, so we may see commits of chunks with WriterIDs that aren't
35329     // contained in this map. However, if a producer does register a writer, the
35330     // service will prevent the writer from writing into any other buffer than
35331     // the one associated with it here. The BufferIDs stored in this map are
35332     // untrusted, so need to be verified against |allowed_target_buffers_|
35333     // before use.
35334     std::map<WriterID, BufferID> writers_;
35335 
35336     // This is used only in in-process configurations.
35337     // SharedMemoryArbiterImpl methods themselves are thread-safe.
35338     std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
35339 
35340     PERFETTO_THREAD_CHECKER(thread_checker_)
35341     base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
35342   };
35343 
35344   // The implementation behind the service endpoint exposed to each consumer.
35345   class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
35346    public:
35347     ConsumerEndpointImpl(TracingServiceImpl*,
35348                          base::TaskRunner*,
35349                          Consumer*,
35350                          uid_t uid);
35351     ~ConsumerEndpointImpl() override;
35352 
35353     void NotifyOnTracingDisabled();
35354     base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
35355 
35356     // TracingService::ConsumerEndpoint implementation.
35357     void EnableTracing(const TraceConfig&, base::ScopedFile) override;
35358     void ChangeTraceConfig(const TraceConfig& cfg) override;
35359     void StartTracing() override;
35360     void DisableTracing() override;
35361     void ReadBuffers() override;
35362     void FreeBuffers() override;
35363     void Flush(uint32_t timeout_ms, FlushCallback) override;
35364     void Detach(const std::string& key) override;
35365     void Attach(const std::string& key) override;
35366     void GetTraceStats() override;
35367     void ObserveEvents(uint32_t enabled_event_types) override;
35368     void QueryServiceState(QueryServiceStateCallback) override;
35369     void QueryCapabilities(QueryCapabilitiesCallback) override;
35370 
35371     // Will queue a task to notify the consumer about the state change.
35372     void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
35373                                          const DataSourceInstance&);
35374     void OnAllDataSourcesStarted();
35375 
35376    private:
35377     friend class TracingServiceImpl;
35378     ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
35379     ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
35380 
35381     // Returns a pointer to an ObservableEvents object that the caller can fill
35382     // and schedules a task to send the ObservableEvents to the consumer.
35383     ObservableEvents* AddObservableEvents();
35384 
35385     base::TaskRunner* const task_runner_;
35386     TracingServiceImpl* const service_;
35387     Consumer* const consumer_;
35388     uid_t const uid_;
35389     TracingSessionID tracing_session_id_ = 0;
35390 
35391     // Whether the consumer is interested in DataSourceInstance state change
35392     // events.
35393     uint32_t observable_events_mask_ = 0;
35394 
35395     // ObservableEvents that will be sent to the consumer. If set, a task to
35396     // flush the events to the consumer has been queued.
35397     std::unique_ptr<ObservableEvents> observable_events_;
35398 
35399     PERFETTO_THREAD_CHECKER(thread_checker_)
35400     base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
35401   };
35402 
35403   explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
35404                               base::TaskRunner*);
35405   ~TracingServiceImpl() override;
35406 
35407   // Called by ProducerEndpointImpl.
35408   void DisconnectProducer(ProducerID);
35409   void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
35410   void UnregisterDataSource(ProducerID, const std::string& name);
35411   void CopyProducerPageIntoLogBuffer(ProducerID,
35412                                      uid_t,
35413                                      WriterID,
35414                                      ChunkID,
35415                                      BufferID,
35416                                      uint16_t num_fragments,
35417                                      uint8_t chunk_flags,
35418                                      bool chunk_complete,
35419                                      const uint8_t* src,
35420                                      size_t size);
35421   void ApplyChunkPatches(ProducerID,
35422                          const std::vector<CommitDataRequest::ChunkToPatch>&);
35423   void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
35424   void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID);
35425   void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
35426   void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
35427 
35428   // Called by ConsumerEndpointImpl.
35429   bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
35430   bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
35431   void DisconnectConsumer(ConsumerEndpointImpl*);
35432   bool EnableTracing(ConsumerEndpointImpl*,
35433                      const TraceConfig&,
35434                      base::ScopedFile);
35435   void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
35436 
35437   bool StartTracing(TracingSessionID);
35438   void DisableTracing(TracingSessionID, bool disable_immediately = false);
35439   void Flush(TracingSessionID tsid,
35440              uint32_t timeout_ms,
35441              ConsumerEndpoint::FlushCallback);
35442   void FlushAndDisableTracing(TracingSessionID);
35443   bool ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
35444   void FreeBuffers(TracingSessionID);
35445 
35446   // Service implementation.
35447   std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
35448       Producer*,
35449       uid_t uid,
35450       const std::string& producer_name,
35451       size_t shared_memory_size_hint_bytes = 0,
35452       bool in_process = false,
35453       ProducerSMBScrapingMode smb_scraping_mode =
35454           ProducerSMBScrapingMode::kDefault,
35455       size_t shared_memory_page_size_hint_bytes = 0,
35456       std::unique_ptr<SharedMemory> shm = nullptr) override;
35457 
35458   std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
35459       Consumer*,
35460       uid_t) override;
35461 
35462   // Set whether SMB scraping should be enabled by default or not. Producers can
35463   // override this setting for their own SMBs.
SetSMBScrapingEnabled(bool enabled)35464   void SetSMBScrapingEnabled(bool enabled) override {
35465     smb_scraping_enabled_ = enabled;
35466   }
35467 
35468   // Exposed mainly for testing.
num_producers() const35469   size_t num_producers() const { return producers_.size(); }
35470   ProducerEndpointImpl* GetProducer(ProducerID) const;
35471 
35472  private:
35473   friend class TracingServiceImplTest;
35474   friend class TracingIntegrationTest;
35475 
35476   struct RegisteredDataSource {
35477     ProducerID producer_id;
35478     DataSourceDescriptor descriptor;
35479   };
35480 
35481   // Represents an active data source for a tracing session.
35482   struct DataSourceInstance {
DataSourceInstanceperfetto::TracingServiceImpl::DataSourceInstance35483     DataSourceInstance(DataSourceInstanceID id,
35484                        const DataSourceConfig& cfg,
35485                        const std::string& ds_name,
35486                        bool notify_on_start,
35487                        bool notify_on_stop,
35488                        bool handles_incremental_state_invalidation)
35489         : instance_id(id),
35490           config(cfg),
35491           data_source_name(ds_name),
35492           will_notify_on_start(notify_on_start),
35493           will_notify_on_stop(notify_on_stop),
35494           handles_incremental_state_clear(
35495               handles_incremental_state_invalidation) {}
35496     DataSourceInstance(const DataSourceInstance&) = delete;
35497     DataSourceInstance& operator=(const DataSourceInstance&) = delete;
35498 
35499     DataSourceInstanceID instance_id;
35500     DataSourceConfig config;
35501     std::string data_source_name;
35502     bool will_notify_on_start;
35503     bool will_notify_on_stop;
35504     bool handles_incremental_state_clear;
35505 
35506     enum DataSourceInstanceState {
35507       CONFIGURED,
35508       STARTING,
35509       STARTED,
35510       STOPPING,
35511       STOPPED
35512     };
35513     DataSourceInstanceState state = CONFIGURED;
35514   };
35515 
35516   struct PendingFlush {
35517     std::set<ProducerID> producers;
35518     ConsumerEndpoint::FlushCallback callback;
PendingFlushperfetto::TracingServiceImpl::PendingFlush35519     explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
35520   };
35521 
35522   // Holds the state of a tracing session. A tracing session is uniquely bound
35523   // a specific Consumer. Each Consumer can own one or more sessions.
35524   struct TracingSession {
35525     enum State {
35526       DISABLED = 0,
35527       CONFIGURED,
35528       STARTED,
35529       DISABLING_WAITING_STOP_ACKS
35530     };
35531 
35532     TracingSession(TracingSessionID, ConsumerEndpointImpl*, const TraceConfig&);
35533 
num_buffersperfetto::TracingServiceImpl::TracingSession35534     size_t num_buffers() const { return buffers_index.size(); }
35535 
delay_to_next_write_period_msperfetto::TracingServiceImpl::TracingSession35536     uint32_t delay_to_next_write_period_ms() const {
35537       PERFETTO_DCHECK(write_period_ms > 0);
35538       return write_period_ms -
35539              (base::GetWallTimeMs().count() % write_period_ms);
35540     }
35541 
flush_timeout_msperfetto::TracingServiceImpl::TracingSession35542     uint32_t flush_timeout_ms() {
35543       uint32_t timeout_ms = config.flush_timeout_ms();
35544       return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
35545     }
35546 
data_source_stop_timeout_msperfetto::TracingServiceImpl::TracingSession35547     uint32_t data_source_stop_timeout_ms() {
35548       uint32_t timeout_ms = config.data_source_stop_timeout_ms();
35549       return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
35550     }
35551 
GetPacketSequenceIDperfetto::TracingServiceImpl::TracingSession35552     PacketSequenceID GetPacketSequenceID(ProducerID producer_id,
35553                                          WriterID writer_id) {
35554       auto key = std::make_pair(producer_id, writer_id);
35555       auto it = packet_sequence_ids.find(key);
35556       if (it != packet_sequence_ids.end())
35557         return it->second;
35558       // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
35559       // are limited to 1024).
35560       static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
35561                     "PacketSequenceID value space doesn't cover service "
35562                     "sequence ID and all producer/writer ID combinations!");
35563       PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
35564       PacketSequenceID sequence_id = ++last_packet_sequence_id;
35565       packet_sequence_ids[key] = sequence_id;
35566       return sequence_id;
35567     }
35568 
GetDataSourceInstanceperfetto::TracingServiceImpl::TracingSession35569     DataSourceInstance* GetDataSourceInstance(
35570         ProducerID producer_id,
35571         DataSourceInstanceID instance_id) {
35572       for (auto& inst_kv : data_source_instances) {
35573         if (inst_kv.first != producer_id ||
35574             inst_kv.second.instance_id != instance_id) {
35575           continue;
35576         }
35577         return &inst_kv.second;
35578       }
35579       return nullptr;
35580     }
35581 
AllDataSourceInstancesStartedperfetto::TracingServiceImpl::TracingSession35582     bool AllDataSourceInstancesStarted() {
35583       return std::all_of(
35584           data_source_instances.begin(), data_source_instances.end(),
35585           [](decltype(data_source_instances)::const_reference x) {
35586             return x.second.state == DataSourceInstance::STARTED;
35587           });
35588     }
35589 
AllDataSourceInstancesStoppedperfetto::TracingServiceImpl::TracingSession35590     bool AllDataSourceInstancesStopped() {
35591       return std::all_of(
35592           data_source_instances.begin(), data_source_instances.end(),
35593           [](decltype(data_source_instances)::const_reference x) {
35594             return x.second.state == DataSourceInstance::STOPPED;
35595           });
35596     }
35597 
35598     const TracingSessionID id;
35599 
35600     // The consumer that started the session.
35601     // Can be nullptr if the consumer detached from the session.
35602     ConsumerEndpointImpl* consumer_maybe_null;
35603 
35604     // Unix uid of the consumer. This is valid even after the consumer detaches
35605     // and does not change for the entire duration of the session. It is used to
35606     // prevent that a consumer re-attaches to a session from a different uid.
35607     uid_t const consumer_uid;
35608 
35609     // The list of triggers this session received while alive and the time they
35610     // were received at. This is used to insert 'fake' packets back to the
35611     // consumer so they can tell when some event happened. The order matches the
35612     // order they were received.
35613     struct TriggerInfo {
35614       uint64_t boot_time_ns;
35615       std::string trigger_name;
35616       std::string producer_name;
35617       uid_t producer_uid;
35618     };
35619     std::vector<TriggerInfo> received_triggers;
35620 
35621     // The trace config provided by the Consumer when calling
35622     // EnableTracing(), plus any updates performed by ChangeTraceConfig.
35623     TraceConfig config;
35624 
35625     // List of data source instances that have been enabled on the various
35626     // producers for this tracing session.
35627     // TODO(rsavitski): at the time of writing, the map structure is unused
35628     // (even when the calling code has a key). This is also an opportunity to
35629     // consider an alternative data type, e.g. a map of vectors.
35630     std::multimap<ProducerID, DataSourceInstance> data_source_instances;
35631 
35632     // For each Flush(N) request, keeps track of the set of producers for which
35633     // we are still awaiting a NotifyFlushComplete(N) ack.
35634     std::map<FlushRequestID, PendingFlush> pending_flushes;
35635 
35636     // Maps a per-trace-session buffer index into the corresponding global
35637     // BufferID (shared namespace amongst all consumers). This vector has as
35638     // many entries as |config.buffers_size()|.
35639     std::vector<BufferID> buffers_index;
35640 
35641     std::map<std::pair<ProducerID, WriterID>, PacketSequenceID>
35642         packet_sequence_ids;
35643     PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
35644 
35645     // Whether we should emit the trace stats next time we reach EOF while
35646     // performing ReadBuffers.
35647     bool should_emit_stats = false;
35648 
35649     // Whether we should emit the sync marker the next time ReadBuffers() is
35650     // called.
35651     bool should_emit_sync_marker = false;
35652 
35653     // Whether we mirrored the trace config back to the trace output yet.
35654     bool did_emit_config = false;
35655 
35656     // Whether we put the system info into the trace output yet.
35657     bool did_emit_system_info = false;
35658 
35659     // The number of received triggers we've emitted into the trace output.
35660     size_t num_triggers_emitted_into_trace = 0;
35661 
35662     // Packets that failed validation of the TrustedPacket.
35663     uint64_t invalid_packets = 0;
35664 
35665     // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
35666     bool did_notify_all_data_source_started = false;
35667 
35668     // Stores all lifecycle events of a particular type (i.e. associated with a
35669     // single field id in the TracingServiceEvent proto).
35670     struct LifecycleEvent {
LifecycleEventperfetto::TracingServiceImpl::TracingSession::LifecycleEvent35671       LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
35672           : field_id(f_id), max_size(m_size), timestamps(m_size) {}
35673 
35674       // The field id of the event in the TracingServiceEvent proto.
35675       uint32_t field_id;
35676 
35677       // Stores the max size of |timestamps|. Set to 1 by default (in
35678       // the constructor) but can be overriden in TraceSession constructor
35679       // if a larger size is required.
35680       uint32_t max_size;
35681 
35682       // Stores the timestamps emitted for each event type (in nanoseconds).
35683       // Emitted into the trace and cleared when the consumer next calls
35684       // ReadBuffers.
35685       base::CircularQueue<int64_t> timestamps;
35686     };
35687     std::vector<LifecycleEvent> lifecycle_events;
35688 
35689     using ClockSnapshotData =
35690         std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>;
35691 
35692     // Initial clock snapshot, captured at trace start time (when state goes to
35693     // TracingSession::STARTED). Emitted into the trace when the consumer first
35694     // calls ReadBuffers().
35695     ClockSnapshotData initial_clock_snapshot;
35696 
35697     // Stores clock snapshots to emit into the trace as a ring buffer. This
35698     // buffer is populated both periodically and when lifecycle events happen
35699     // but only when significant clock drift is detected. Emitted into the trace
35700     // and cleared when the consumer next calls ReadBuffers().
35701     base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;
35702 
35703     State state = DISABLED;
35704 
35705     // If the consumer detached the session, this variable defines the key used
35706     // for identifying the session later when reattaching.
35707     std::string detach_key;
35708 
35709     // This is set when the Consumer calls sets |write_into_file| == true in the
35710     // TraceConfig. In this case this represents the file we should stream the
35711     // trace packets into, rather than returning it to the consumer via
35712     // OnTraceData().
35713     base::ScopedFile write_into_file;
35714     uint32_t write_period_ms = 0;
35715     uint64_t max_file_size_bytes = 0;
35716     uint64_t bytes_written_into_file = 0;
35717   };
35718 
35719   TracingServiceImpl(const TracingServiceImpl&) = delete;
35720   TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
35721 
35722   DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
35723                                       const TraceConfig::ProducerConfig&,
35724                                       const RegisteredDataSource&,
35725                                       TracingSession*);
35726 
35727   // Returns the next available ProducerID that is not in |producers_|.
35728   ProducerID GetNextProducerID();
35729 
35730   // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
35731   // session doesn't exists.
35732   TracingSession* GetTracingSession(TracingSessionID);
35733 
35734   // Returns a pointer to the |tracing_sessions_| entry, matching the given
35735   // uid and detach key, or nullptr if no such session exists.
35736   TracingSession* GetDetachedSession(uid_t, const std::string& key);
35737 
35738   // Update the memory guard rail by using the latest information from the
35739   // shared memory and trace buffers.
35740   void UpdateMemoryGuardrail();
35741 
35742   void StartDataSourceInstance(ProducerEndpointImpl* producer,
35743                                TracingSession* tracing_session,
35744                                DataSourceInstance* instance);
35745   void StopDataSourceInstance(ProducerEndpointImpl* producer,
35746                               TracingSession* tracing_session,
35747                               DataSourceInstance* instance,
35748                               bool disable_immediately);
35749   void PeriodicSnapshotTask(TracingSession* tracing_session);
35750   void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
35751   bool SnapshotClocks(TracingSession::ClockSnapshotData*);
35752   void SnapshotLifecyleEvent(TracingSession*,
35753                              uint32_t field_id,
35754                              bool snapshot_clocks);
35755   void EmitClockSnapshot(TracingSession* tracing_session,
35756                          TracingSession::ClockSnapshotData,
35757                          std::vector<TracePacket>*);
35758   void EmitSyncMarker(std::vector<TracePacket>*);
35759   void EmitStats(TracingSession*, std::vector<TracePacket>*);
35760   TraceStats GetTraceStats(TracingSession* tracing_session);
35761   void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>* packets);
35762   void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
35763   void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
35764   void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
35765   void MaybeNotifyAllDataSourcesStarted(TracingSession*);
35766   void OnFlushTimeout(TracingSessionID, FlushRequestID);
35767   void OnDisableTracingTimeout(TracingSessionID);
35768   void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
35769   void PeriodicFlushTask(TracingSessionID, bool post_next_only);
35770   void CompleteFlush(TracingSessionID tsid,
35771                      ConsumerEndpoint::FlushCallback callback,
35772                      bool success);
35773   void ScrapeSharedMemoryBuffers(TracingSession* tracing_session,
35774                                  ProducerEndpointImpl* producer);
35775   void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
35776   TraceBuffer* GetBufferByID(BufferID);
35777   void OnStartTriggersTimeout(TracingSessionID tsid);
35778 
35779   base::TaskRunner* const task_runner_;
35780   std::unique_ptr<SharedMemory::Factory> shm_factory_;
35781   ProducerID last_producer_id_ = 0;
35782   DataSourceInstanceID last_data_source_instance_id_ = 0;
35783   TracingSessionID last_tracing_session_id_ = 0;
35784   FlushRequestID last_flush_request_id_ = 0;
35785   uid_t uid_ = 0;
35786 
35787   // Buffer IDs are global across all consumers (because a Producer can produce
35788   // data for more than one trace session, hence more than one consumer).
35789   IdAllocator<BufferID> buffer_ids_;
35790 
35791   std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
35792   std::map<ProducerID, ProducerEndpointImpl*> producers_;
35793   std::set<ConsumerEndpointImpl*> consumers_;
35794   std::map<TracingSessionID, TracingSession> tracing_sessions_;
35795   std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
35796   std::map<std::string, int64_t> session_to_last_trace_s_;
35797 
35798   bool smb_scraping_enabled_ = false;
35799   bool lockdown_mode_ = false;
35800   uint32_t min_write_period_ms_ = 100;  // Overridable for testing.
35801 
35802   uint8_t sync_marker_packet_[32];  // Lazily initialized.
35803   size_t sync_marker_packet_size_ = 0;
35804 
35805   // Stats.
35806   uint64_t chunks_discarded_ = 0;
35807   uint64_t patches_discarded_ = 0;
35808 
35809   PERFETTO_THREAD_CHECKER(thread_checker_)
35810 
35811   base::WeakPtrFactory<TracingServiceImpl>
35812       weak_ptr_factory_;  // Keep at the end.
35813 };
35814 
35815 }  // namespace perfetto
35816 
35817 #endif  // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
35818 // gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_capabilities.h
35819 /*
35820  * Copyright (C) 2020 The Android Open Source Project
35821  *
35822  * Licensed under the Apache License, Version 2.0 (the "License");
35823  * you may not use this file except in compliance with the License.
35824  * You may obtain a copy of the License at
35825  *
35826  *      http://www.apache.org/licenses/LICENSE-2.0
35827  *
35828  * Unless required by applicable law or agreed to in writing, software
35829  * distributed under the License is distributed on an "AS IS" BASIS,
35830  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35831  * See the License for the specific language governing permissions and
35832  * limitations under the License.
35833  */
35834 
35835 #ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
35836 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
35837 
35838 // Creates the aliases in the ::perfetto namespace, doing things like:
35839 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
35840 // See comments in forward_decls.h for the historical reasons of this
35841 // indirection layer.
35842 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
35843 
35844 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
35845 
35846 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
35847 // gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_state.h
35848 /*
35849  * Copyright (C) 2017 The Android Open Source Project
35850  *
35851  * Licensed under the Apache License, Version 2.0 (the "License");
35852  * you may not use this file except in compliance with the License.
35853  * You may obtain a copy of the License at
35854  *
35855  *      http://www.apache.org/licenses/LICENSE-2.0
35856  *
35857  * Unless required by applicable law or agreed to in writing, software
35858  * distributed under the License is distributed on an "AS IS" BASIS,
35859  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35860  * See the License for the specific language governing permissions and
35861  * limitations under the License.
35862  */
35863 
35864 
35865 #ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
35866 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
35867 
35868 // Creates the aliases in the ::perfetto namespace, doing things like:
35869 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
35870 // See comments in forward_decls.h for the historical reasons of this
35871 // indirection layer.
35872 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
35873 
35874 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
35875 
35876 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
35877 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.pbzero.h
35878 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
35879 
35880 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
35881 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
35882 
35883 #include <stddef.h>
35884 #include <stdint.h>
35885 
35886 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
35887 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
35888 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
35889 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
35890 
35891 namespace perfetto {
35892 namespace protos {
35893 namespace pbzero {
35894 
35895 class TraceStats_BufferStats;
35896 
35897 class TraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
35898  public:
TraceStats_Decoder(const uint8_t * data,size_t len)35899   TraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_Decoder(const std::string & raw)35900   explicit TraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceStats_Decoder(const::protozero::ConstBytes & raw)35901   explicit TraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffer_stats() const35902   bool has_buffer_stats() const { return at<1>().valid(); }
buffer_stats() const35903   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffer_stats() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_producers_connected() const35904   bool has_producers_connected() const { return at<2>().valid(); }
producers_connected() const35905   uint32_t producers_connected() const { return at<2>().as_uint32(); }
has_producers_seen() const35906   bool has_producers_seen() const { return at<3>().valid(); }
producers_seen() const35907   uint64_t producers_seen() const { return at<3>().as_uint64(); }
has_data_sources_registered() const35908   bool has_data_sources_registered() const { return at<4>().valid(); }
data_sources_registered() const35909   uint32_t data_sources_registered() const { return at<4>().as_uint32(); }
has_data_sources_seen() const35910   bool has_data_sources_seen() const { return at<5>().valid(); }
data_sources_seen() const35911   uint64_t data_sources_seen() const { return at<5>().as_uint64(); }
has_tracing_sessions() const35912   bool has_tracing_sessions() const { return at<6>().valid(); }
tracing_sessions() const35913   uint32_t tracing_sessions() const { return at<6>().as_uint32(); }
has_total_buffers() const35914   bool has_total_buffers() const { return at<7>().valid(); }
total_buffers() const35915   uint32_t total_buffers() const { return at<7>().as_uint32(); }
has_chunks_discarded() const35916   bool has_chunks_discarded() const { return at<8>().valid(); }
chunks_discarded() const35917   uint64_t chunks_discarded() const { return at<8>().as_uint64(); }
has_patches_discarded() const35918   bool has_patches_discarded() const { return at<9>().valid(); }
patches_discarded() const35919   uint64_t patches_discarded() const { return at<9>().as_uint64(); }
has_invalid_packets() const35920   bool has_invalid_packets() const { return at<10>().valid(); }
invalid_packets() const35921   uint64_t invalid_packets() const { return at<10>().as_uint64(); }
35922 };
35923 
35924 class TraceStats : public ::protozero::Message {
35925  public:
35926   using Decoder = TraceStats_Decoder;
35927   enum : int32_t {
35928     kBufferStatsFieldNumber = 1,
35929     kProducersConnectedFieldNumber = 2,
35930     kProducersSeenFieldNumber = 3,
35931     kDataSourcesRegisteredFieldNumber = 4,
35932     kDataSourcesSeenFieldNumber = 5,
35933     kTracingSessionsFieldNumber = 6,
35934     kTotalBuffersFieldNumber = 7,
35935     kChunksDiscardedFieldNumber = 8,
35936     kPatchesDiscardedFieldNumber = 9,
35937     kInvalidPacketsFieldNumber = 10,
35938   };
35939   using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
add_buffer_stats()35940   template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
35941     return BeginNestedMessage<T>(1);
35942   }
35943 
set_producers_connected(uint32_t value)35944   void set_producers_connected(uint32_t value) {
35945     AppendVarInt(2, value);
35946   }
set_producers_seen(uint64_t value)35947   void set_producers_seen(uint64_t value) {
35948     AppendVarInt(3, value);
35949   }
set_data_sources_registered(uint32_t value)35950   void set_data_sources_registered(uint32_t value) {
35951     AppendVarInt(4, value);
35952   }
set_data_sources_seen(uint64_t value)35953   void set_data_sources_seen(uint64_t value) {
35954     AppendVarInt(5, value);
35955   }
set_tracing_sessions(uint32_t value)35956   void set_tracing_sessions(uint32_t value) {
35957     AppendVarInt(6, value);
35958   }
set_total_buffers(uint32_t value)35959   void set_total_buffers(uint32_t value) {
35960     AppendVarInt(7, value);
35961   }
set_chunks_discarded(uint64_t value)35962   void set_chunks_discarded(uint64_t value) {
35963     AppendVarInt(8, value);
35964   }
set_patches_discarded(uint64_t value)35965   void set_patches_discarded(uint64_t value) {
35966     AppendVarInt(9, value);
35967   }
set_invalid_packets(uint64_t value)35968   void set_invalid_packets(uint64_t value) {
35969     AppendVarInt(10, value);
35970   }
35971 };
35972 
35973 class TraceStats_BufferStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
35974  public:
TraceStats_BufferStats_Decoder(const uint8_t * data,size_t len)35975   TraceStats_BufferStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_BufferStats_Decoder(const std::string & raw)35976   explicit TraceStats_BufferStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceStats_BufferStats_Decoder(const::protozero::ConstBytes & raw)35977   explicit TraceStats_BufferStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffer_size() const35978   bool has_buffer_size() const { return at<12>().valid(); }
buffer_size() const35979   uint64_t buffer_size() const { return at<12>().as_uint64(); }
has_bytes_written() const35980   bool has_bytes_written() const { return at<1>().valid(); }
bytes_written() const35981   uint64_t bytes_written() const { return at<1>().as_uint64(); }
has_bytes_overwritten() const35982   bool has_bytes_overwritten() const { return at<13>().valid(); }
bytes_overwritten() const35983   uint64_t bytes_overwritten() const { return at<13>().as_uint64(); }
has_bytes_read() const35984   bool has_bytes_read() const { return at<14>().valid(); }
bytes_read() const35985   uint64_t bytes_read() const { return at<14>().as_uint64(); }
has_padding_bytes_written() const35986   bool has_padding_bytes_written() const { return at<15>().valid(); }
padding_bytes_written() const35987   uint64_t padding_bytes_written() const { return at<15>().as_uint64(); }
has_padding_bytes_cleared() const35988   bool has_padding_bytes_cleared() const { return at<16>().valid(); }
padding_bytes_cleared() const35989   uint64_t padding_bytes_cleared() const { return at<16>().as_uint64(); }
has_chunks_written() const35990   bool has_chunks_written() const { return at<2>().valid(); }
chunks_written() const35991   uint64_t chunks_written() const { return at<2>().as_uint64(); }
has_chunks_rewritten() const35992   bool has_chunks_rewritten() const { return at<10>().valid(); }
chunks_rewritten() const35993   uint64_t chunks_rewritten() const { return at<10>().as_uint64(); }
has_chunks_overwritten() const35994   bool has_chunks_overwritten() const { return at<3>().valid(); }
chunks_overwritten() const35995   uint64_t chunks_overwritten() const { return at<3>().as_uint64(); }
has_chunks_discarded() const35996   bool has_chunks_discarded() const { return at<18>().valid(); }
chunks_discarded() const35997   uint64_t chunks_discarded() const { return at<18>().as_uint64(); }
has_chunks_read() const35998   bool has_chunks_read() const { return at<17>().valid(); }
chunks_read() const35999   uint64_t chunks_read() const { return at<17>().as_uint64(); }
has_chunks_committed_out_of_order() const36000   bool has_chunks_committed_out_of_order() const { return at<11>().valid(); }
chunks_committed_out_of_order() const36001   uint64_t chunks_committed_out_of_order() const { return at<11>().as_uint64(); }
has_write_wrap_count() const36002   bool has_write_wrap_count() const { return at<4>().valid(); }
write_wrap_count() const36003   uint64_t write_wrap_count() const { return at<4>().as_uint64(); }
has_patches_succeeded() const36004   bool has_patches_succeeded() const { return at<5>().valid(); }
patches_succeeded() const36005   uint64_t patches_succeeded() const { return at<5>().as_uint64(); }
has_patches_failed() const36006   bool has_patches_failed() const { return at<6>().valid(); }
patches_failed() const36007   uint64_t patches_failed() const { return at<6>().as_uint64(); }
has_readaheads_succeeded() const36008   bool has_readaheads_succeeded() const { return at<7>().valid(); }
readaheads_succeeded() const36009   uint64_t readaheads_succeeded() const { return at<7>().as_uint64(); }
has_readaheads_failed() const36010   bool has_readaheads_failed() const { return at<8>().valid(); }
readaheads_failed() const36011   uint64_t readaheads_failed() const { return at<8>().as_uint64(); }
has_abi_violations() const36012   bool has_abi_violations() const { return at<9>().valid(); }
abi_violations() const36013   uint64_t abi_violations() const { return at<9>().as_uint64(); }
has_trace_writer_packet_loss() const36014   bool has_trace_writer_packet_loss() const { return at<19>().valid(); }
trace_writer_packet_loss() const36015   uint64_t trace_writer_packet_loss() const { return at<19>().as_uint64(); }
36016 };
36017 
36018 class TraceStats_BufferStats : public ::protozero::Message {
36019  public:
36020   using Decoder = TraceStats_BufferStats_Decoder;
36021   enum : int32_t {
36022     kBufferSizeFieldNumber = 12,
36023     kBytesWrittenFieldNumber = 1,
36024     kBytesOverwrittenFieldNumber = 13,
36025     kBytesReadFieldNumber = 14,
36026     kPaddingBytesWrittenFieldNumber = 15,
36027     kPaddingBytesClearedFieldNumber = 16,
36028     kChunksWrittenFieldNumber = 2,
36029     kChunksRewrittenFieldNumber = 10,
36030     kChunksOverwrittenFieldNumber = 3,
36031     kChunksDiscardedFieldNumber = 18,
36032     kChunksReadFieldNumber = 17,
36033     kChunksCommittedOutOfOrderFieldNumber = 11,
36034     kWriteWrapCountFieldNumber = 4,
36035     kPatchesSucceededFieldNumber = 5,
36036     kPatchesFailedFieldNumber = 6,
36037     kReadaheadsSucceededFieldNumber = 7,
36038     kReadaheadsFailedFieldNumber = 8,
36039     kAbiViolationsFieldNumber = 9,
36040     kTraceWriterPacketLossFieldNumber = 19,
36041   };
set_buffer_size(uint64_t value)36042   void set_buffer_size(uint64_t value) {
36043     AppendVarInt(12, value);
36044   }
set_bytes_written(uint64_t value)36045   void set_bytes_written(uint64_t value) {
36046     AppendVarInt(1, value);
36047   }
set_bytes_overwritten(uint64_t value)36048   void set_bytes_overwritten(uint64_t value) {
36049     AppendVarInt(13, value);
36050   }
set_bytes_read(uint64_t value)36051   void set_bytes_read(uint64_t value) {
36052     AppendVarInt(14, value);
36053   }
set_padding_bytes_written(uint64_t value)36054   void set_padding_bytes_written(uint64_t value) {
36055     AppendVarInt(15, value);
36056   }
set_padding_bytes_cleared(uint64_t value)36057   void set_padding_bytes_cleared(uint64_t value) {
36058     AppendVarInt(16, value);
36059   }
set_chunks_written(uint64_t value)36060   void set_chunks_written(uint64_t value) {
36061     AppendVarInt(2, value);
36062   }
set_chunks_rewritten(uint64_t value)36063   void set_chunks_rewritten(uint64_t value) {
36064     AppendVarInt(10, value);
36065   }
set_chunks_overwritten(uint64_t value)36066   void set_chunks_overwritten(uint64_t value) {
36067     AppendVarInt(3, value);
36068   }
set_chunks_discarded(uint64_t value)36069   void set_chunks_discarded(uint64_t value) {
36070     AppendVarInt(18, value);
36071   }
set_chunks_read(uint64_t value)36072   void set_chunks_read(uint64_t value) {
36073     AppendVarInt(17, value);
36074   }
set_chunks_committed_out_of_order(uint64_t value)36075   void set_chunks_committed_out_of_order(uint64_t value) {
36076     AppendVarInt(11, value);
36077   }
set_write_wrap_count(uint64_t value)36078   void set_write_wrap_count(uint64_t value) {
36079     AppendVarInt(4, value);
36080   }
set_patches_succeeded(uint64_t value)36081   void set_patches_succeeded(uint64_t value) {
36082     AppendVarInt(5, value);
36083   }
set_patches_failed(uint64_t value)36084   void set_patches_failed(uint64_t value) {
36085     AppendVarInt(6, value);
36086   }
set_readaheads_succeeded(uint64_t value)36087   void set_readaheads_succeeded(uint64_t value) {
36088     AppendVarInt(7, value);
36089   }
set_readaheads_failed(uint64_t value)36090   void set_readaheads_failed(uint64_t value) {
36091     AppendVarInt(8, value);
36092   }
set_abi_violations(uint64_t value)36093   void set_abi_violations(uint64_t value) {
36094     AppendVarInt(9, value);
36095   }
set_trace_writer_packet_loss(uint64_t value)36096   void set_trace_writer_packet_loss(uint64_t value) {
36097     AppendVarInt(19, value);
36098   }
36099 };
36100 
36101 } // Namespace.
36102 } // Namespace.
36103 } // Namespace.
36104 #endif  // Include guard.
36105 // gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.pbzero.h
36106 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36107 
36108 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
36109 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
36110 
36111 #include <stddef.h>
36112 #include <stdint.h>
36113 
36114 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36115 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36116 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36117 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36118 
36119 namespace perfetto {
36120 namespace protos {
36121 namespace pbzero {
36122 
36123 class DataSourceConfig;
36124 class TraceConfig_BufferConfig;
36125 class TraceConfig_BuiltinDataSource;
36126 class TraceConfig_DataSource;
36127 class TraceConfig_GuardrailOverrides;
36128 class TraceConfig_IncidentReportConfig;
36129 class TraceConfig_IncrementalStateConfig;
36130 class TraceConfig_ProducerConfig;
36131 class TraceConfig_StatsdMetadata;
36132 class TraceConfig_TriggerConfig;
36133 class TraceConfig_TriggerConfig_Trigger;
36134 enum BuiltinClock : int32_t;
36135 enum TraceConfig_BufferConfig_FillPolicy : int32_t;
36136 enum TraceConfig_CompressionType : int32_t;
36137 enum TraceConfig_LockdownModeOperation : int32_t;
36138 enum TraceConfig_TriggerConfig_TriggerMode : int32_t;
36139 
36140 enum TraceConfig_LockdownModeOperation : int32_t {
36141   TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
36142   TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
36143   TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
36144 };
36145 
36146 const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
36147 const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
36148 
36149 enum TraceConfig_CompressionType : int32_t {
36150   TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
36151   TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
36152 };
36153 
36154 const TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
36155 const TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
36156 
36157 enum TraceConfig_TriggerConfig_TriggerMode : int32_t {
36158   TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
36159   TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
36160   TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
36161 };
36162 
36163 const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
36164 const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
36165 
36166 enum TraceConfig_BufferConfig_FillPolicy : int32_t {
36167   TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
36168   TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
36169   TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
36170 };
36171 
36172 const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
36173 const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
36174 
36175 class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/29, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
36176  public:
TraceConfig_Decoder(const uint8_t * data,size_t len)36177   TraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_Decoder(const std::string & raw)36178   explicit TraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_Decoder(const::protozero::ConstBytes & raw)36179   explicit TraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffers() const36180   bool has_buffers() const { return at<1>().valid(); }
buffers() const36181   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffers() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_data_sources() const36182   bool has_data_sources() const { return at<2>().valid(); }
data_sources() const36183   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> data_sources() const { return GetRepeated<::protozero::ConstBytes>(2); }
has_builtin_data_sources() const36184   bool has_builtin_data_sources() const { return at<20>().valid(); }
builtin_data_sources() const36185   ::protozero::ConstBytes builtin_data_sources() const { return at<20>().as_bytes(); }
has_duration_ms() const36186   bool has_duration_ms() const { return at<3>().valid(); }
duration_ms() const36187   uint32_t duration_ms() const { return at<3>().as_uint32(); }
has_enable_extra_guardrails() const36188   bool has_enable_extra_guardrails() const { return at<4>().valid(); }
enable_extra_guardrails() const36189   bool enable_extra_guardrails() const { return at<4>().as_bool(); }
has_lockdown_mode() const36190   bool has_lockdown_mode() const { return at<5>().valid(); }
lockdown_mode() const36191   int32_t lockdown_mode() const { return at<5>().as_int32(); }
has_producers() const36192   bool has_producers() const { return at<6>().valid(); }
producers() const36193   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() const { return GetRepeated<::protozero::ConstBytes>(6); }
has_statsd_metadata() const36194   bool has_statsd_metadata() const { return at<7>().valid(); }
statsd_metadata() const36195   ::protozero::ConstBytes statsd_metadata() const { return at<7>().as_bytes(); }
has_write_into_file() const36196   bool has_write_into_file() const { return at<8>().valid(); }
write_into_file() const36197   bool write_into_file() const { return at<8>().as_bool(); }
has_output_path() const36198   bool has_output_path() const { return at<29>().valid(); }
output_path() const36199   ::protozero::ConstChars output_path() const { return at<29>().as_string(); }
has_file_write_period_ms() const36200   bool has_file_write_period_ms() const { return at<9>().valid(); }
file_write_period_ms() const36201   uint32_t file_write_period_ms() const { return at<9>().as_uint32(); }
has_max_file_size_bytes() const36202   bool has_max_file_size_bytes() const { return at<10>().valid(); }
max_file_size_bytes() const36203   uint64_t max_file_size_bytes() const { return at<10>().as_uint64(); }
has_guardrail_overrides() const36204   bool has_guardrail_overrides() const { return at<11>().valid(); }
guardrail_overrides() const36205   ::protozero::ConstBytes guardrail_overrides() const { return at<11>().as_bytes(); }
has_deferred_start() const36206   bool has_deferred_start() const { return at<12>().valid(); }
deferred_start() const36207   bool deferred_start() const { return at<12>().as_bool(); }
has_flush_period_ms() const36208   bool has_flush_period_ms() const { return at<13>().valid(); }
flush_period_ms() const36209   uint32_t flush_period_ms() const { return at<13>().as_uint32(); }
has_flush_timeout_ms() const36210   bool has_flush_timeout_ms() const { return at<14>().valid(); }
flush_timeout_ms() const36211   uint32_t flush_timeout_ms() const { return at<14>().as_uint32(); }
has_data_source_stop_timeout_ms() const36212   bool has_data_source_stop_timeout_ms() const { return at<23>().valid(); }
data_source_stop_timeout_ms() const36213   uint32_t data_source_stop_timeout_ms() const { return at<23>().as_uint32(); }
has_notify_traceur() const36214   bool has_notify_traceur() const { return at<16>().valid(); }
notify_traceur() const36215   bool notify_traceur() const { return at<16>().as_bool(); }
has_trigger_config() const36216   bool has_trigger_config() const { return at<17>().valid(); }
trigger_config() const36217   ::protozero::ConstBytes trigger_config() const { return at<17>().as_bytes(); }
has_activate_triggers() const36218   bool has_activate_triggers() const { return at<18>().valid(); }
activate_triggers() const36219   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> activate_triggers() const { return GetRepeated<::protozero::ConstChars>(18); }
has_incremental_state_config() const36220   bool has_incremental_state_config() const { return at<21>().valid(); }
incremental_state_config() const36221   ::protozero::ConstBytes incremental_state_config() const { return at<21>().as_bytes(); }
has_allow_user_build_tracing() const36222   bool has_allow_user_build_tracing() const { return at<19>().valid(); }
allow_user_build_tracing() const36223   bool allow_user_build_tracing() const { return at<19>().as_bool(); }
has_unique_session_name() const36224   bool has_unique_session_name() const { return at<22>().valid(); }
unique_session_name() const36225   ::protozero::ConstChars unique_session_name() const { return at<22>().as_string(); }
has_compression_type() const36226   bool has_compression_type() const { return at<24>().valid(); }
compression_type() const36227   int32_t compression_type() const { return at<24>().as_int32(); }
has_incident_report_config() const36228   bool has_incident_report_config() const { return at<25>().valid(); }
incident_report_config() const36229   ::protozero::ConstBytes incident_report_config() const { return at<25>().as_bytes(); }
has_trace_uuid_msb() const36230   bool has_trace_uuid_msb() const { return at<27>().valid(); }
trace_uuid_msb() const36231   int64_t trace_uuid_msb() const { return at<27>().as_int64(); }
has_trace_uuid_lsb() const36232   bool has_trace_uuid_lsb() const { return at<28>().valid(); }
trace_uuid_lsb() const36233   int64_t trace_uuid_lsb() const { return at<28>().as_int64(); }
36234 };
36235 
36236 class TraceConfig : public ::protozero::Message {
36237  public:
36238   using Decoder = TraceConfig_Decoder;
36239   enum : int32_t {
36240     kBuffersFieldNumber = 1,
36241     kDataSourcesFieldNumber = 2,
36242     kBuiltinDataSourcesFieldNumber = 20,
36243     kDurationMsFieldNumber = 3,
36244     kEnableExtraGuardrailsFieldNumber = 4,
36245     kLockdownModeFieldNumber = 5,
36246     kProducersFieldNumber = 6,
36247     kStatsdMetadataFieldNumber = 7,
36248     kWriteIntoFileFieldNumber = 8,
36249     kOutputPathFieldNumber = 29,
36250     kFileWritePeriodMsFieldNumber = 9,
36251     kMaxFileSizeBytesFieldNumber = 10,
36252     kGuardrailOverridesFieldNumber = 11,
36253     kDeferredStartFieldNumber = 12,
36254     kFlushPeriodMsFieldNumber = 13,
36255     kFlushTimeoutMsFieldNumber = 14,
36256     kDataSourceStopTimeoutMsFieldNumber = 23,
36257     kNotifyTraceurFieldNumber = 16,
36258     kTriggerConfigFieldNumber = 17,
36259     kActivateTriggersFieldNumber = 18,
36260     kIncrementalStateConfigFieldNumber = 21,
36261     kAllowUserBuildTracingFieldNumber = 19,
36262     kUniqueSessionNameFieldNumber = 22,
36263     kCompressionTypeFieldNumber = 24,
36264     kIncidentReportConfigFieldNumber = 25,
36265     kTraceUuidMsbFieldNumber = 27,
36266     kTraceUuidLsbFieldNumber = 28,
36267   };
36268   using BufferConfig = ::perfetto::protos::pbzero::TraceConfig_BufferConfig;
36269   using DataSource = ::perfetto::protos::pbzero::TraceConfig_DataSource;
36270   using BuiltinDataSource = ::perfetto::protos::pbzero::TraceConfig_BuiltinDataSource;
36271   using ProducerConfig = ::perfetto::protos::pbzero::TraceConfig_ProducerConfig;
36272   using StatsdMetadata = ::perfetto::protos::pbzero::TraceConfig_StatsdMetadata;
36273   using GuardrailOverrides = ::perfetto::protos::pbzero::TraceConfig_GuardrailOverrides;
36274   using TriggerConfig = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig;
36275   using IncrementalStateConfig = ::perfetto::protos::pbzero::TraceConfig_IncrementalStateConfig;
36276   using IncidentReportConfig = ::perfetto::protos::pbzero::TraceConfig_IncidentReportConfig;
36277   using LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
36278   using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
36279   static const LockdownModeOperation LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
36280   static const LockdownModeOperation LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
36281   static const LockdownModeOperation LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
36282   static const CompressionType COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
36283   static const CompressionType COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
add_buffers()36284   template <typename T = TraceConfig_BufferConfig> T* add_buffers() {
36285     return BeginNestedMessage<T>(1);
36286   }
36287 
add_data_sources()36288   template <typename T = TraceConfig_DataSource> T* add_data_sources() {
36289     return BeginNestedMessage<T>(2);
36290   }
36291 
set_builtin_data_sources()36292   template <typename T = TraceConfig_BuiltinDataSource> T* set_builtin_data_sources() {
36293     return BeginNestedMessage<T>(20);
36294   }
36295 
set_duration_ms(uint32_t value)36296   void set_duration_ms(uint32_t value) {
36297     AppendVarInt(3, value);
36298   }
set_enable_extra_guardrails(bool value)36299   void set_enable_extra_guardrails(bool value) {
36300     AppendTinyVarInt(4, value);
36301   }
set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value)36302   void set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
36303     AppendTinyVarInt(5, value);
36304   }
add_producers()36305   template <typename T = TraceConfig_ProducerConfig> T* add_producers() {
36306     return BeginNestedMessage<T>(6);
36307   }
36308 
set_statsd_metadata()36309   template <typename T = TraceConfig_StatsdMetadata> T* set_statsd_metadata() {
36310     return BeginNestedMessage<T>(7);
36311   }
36312 
set_write_into_file(bool value)36313   void set_write_into_file(bool value) {
36314     AppendTinyVarInt(8, value);
36315   }
set_output_path(const std::string & value)36316   void set_output_path(const std::string& value) {
36317     AppendBytes(29, value.data(), value.size());
36318   }
set_output_path(const char * data,size_t size)36319   void set_output_path(const char* data, size_t size) {
36320     AppendBytes(29, data, size);
36321   }
set_file_write_period_ms(uint32_t value)36322   void set_file_write_period_ms(uint32_t value) {
36323     AppendVarInt(9, value);
36324   }
set_max_file_size_bytes(uint64_t value)36325   void set_max_file_size_bytes(uint64_t value) {
36326     AppendVarInt(10, value);
36327   }
set_guardrail_overrides()36328   template <typename T = TraceConfig_GuardrailOverrides> T* set_guardrail_overrides() {
36329     return BeginNestedMessage<T>(11);
36330   }
36331 
set_deferred_start(bool value)36332   void set_deferred_start(bool value) {
36333     AppendTinyVarInt(12, value);
36334   }
set_flush_period_ms(uint32_t value)36335   void set_flush_period_ms(uint32_t value) {
36336     AppendVarInt(13, value);
36337   }
set_flush_timeout_ms(uint32_t value)36338   void set_flush_timeout_ms(uint32_t value) {
36339     AppendVarInt(14, value);
36340   }
set_data_source_stop_timeout_ms(uint32_t value)36341   void set_data_source_stop_timeout_ms(uint32_t value) {
36342     AppendVarInt(23, value);
36343   }
set_notify_traceur(bool value)36344   void set_notify_traceur(bool value) {
36345     AppendTinyVarInt(16, value);
36346   }
set_trigger_config()36347   template <typename T = TraceConfig_TriggerConfig> T* set_trigger_config() {
36348     return BeginNestedMessage<T>(17);
36349   }
36350 
add_activate_triggers(const std::string & value)36351   void add_activate_triggers(const std::string& value) {
36352     AppendBytes(18, value.data(), value.size());
36353   }
add_activate_triggers(const char * data,size_t size)36354   void add_activate_triggers(const char* data, size_t size) {
36355     AppendBytes(18, data, size);
36356   }
set_incremental_state_config()36357   template <typename T = TraceConfig_IncrementalStateConfig> T* set_incremental_state_config() {
36358     return BeginNestedMessage<T>(21);
36359   }
36360 
set_allow_user_build_tracing(bool value)36361   void set_allow_user_build_tracing(bool value) {
36362     AppendTinyVarInt(19, value);
36363   }
set_unique_session_name(const std::string & value)36364   void set_unique_session_name(const std::string& value) {
36365     AppendBytes(22, value.data(), value.size());
36366   }
set_unique_session_name(const char * data,size_t size)36367   void set_unique_session_name(const char* data, size_t size) {
36368     AppendBytes(22, data, size);
36369   }
set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value)36370   void set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
36371     AppendTinyVarInt(24, value);
36372   }
set_incident_report_config()36373   template <typename T = TraceConfig_IncidentReportConfig> T* set_incident_report_config() {
36374     return BeginNestedMessage<T>(25);
36375   }
36376 
set_trace_uuid_msb(int64_t value)36377   void set_trace_uuid_msb(int64_t value) {
36378     AppendVarInt(27, value);
36379   }
set_trace_uuid_lsb(int64_t value)36380   void set_trace_uuid_lsb(int64_t value) {
36381     AppendVarInt(28, value);
36382   }
36383 };
36384 
36385 class TraceConfig_IncidentReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36386  public:
TraceConfig_IncidentReportConfig_Decoder(const uint8_t * data,size_t len)36387   TraceConfig_IncidentReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_IncidentReportConfig_Decoder(const std::string & raw)36388   explicit TraceConfig_IncidentReportConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_IncidentReportConfig_Decoder(const::protozero::ConstBytes & raw)36389   explicit TraceConfig_IncidentReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_destination_package() const36390   bool has_destination_package() const { return at<1>().valid(); }
destination_package() const36391   ::protozero::ConstChars destination_package() const { return at<1>().as_string(); }
has_destination_class() const36392   bool has_destination_class() const { return at<2>().valid(); }
destination_class() const36393   ::protozero::ConstChars destination_class() const { return at<2>().as_string(); }
has_privacy_level() const36394   bool has_privacy_level() const { return at<3>().valid(); }
privacy_level() const36395   int32_t privacy_level() const { return at<3>().as_int32(); }
has_skip_dropbox() const36396   bool has_skip_dropbox() const { return at<4>().valid(); }
skip_dropbox() const36397   bool skip_dropbox() const { return at<4>().as_bool(); }
36398 };
36399 
36400 class TraceConfig_IncidentReportConfig : public ::protozero::Message {
36401  public:
36402   using Decoder = TraceConfig_IncidentReportConfig_Decoder;
36403   enum : int32_t {
36404     kDestinationPackageFieldNumber = 1,
36405     kDestinationClassFieldNumber = 2,
36406     kPrivacyLevelFieldNumber = 3,
36407     kSkipDropboxFieldNumber = 4,
36408   };
set_destination_package(const std::string & value)36409   void set_destination_package(const std::string& value) {
36410     AppendBytes(1, value.data(), value.size());
36411   }
set_destination_package(const char * data,size_t size)36412   void set_destination_package(const char* data, size_t size) {
36413     AppendBytes(1, data, size);
36414   }
set_destination_class(const std::string & value)36415   void set_destination_class(const std::string& value) {
36416     AppendBytes(2, value.data(), value.size());
36417   }
set_destination_class(const char * data,size_t size)36418   void set_destination_class(const char* data, size_t size) {
36419     AppendBytes(2, data, size);
36420   }
set_privacy_level(int32_t value)36421   void set_privacy_level(int32_t value) {
36422     AppendVarInt(3, value);
36423   }
set_skip_dropbox(bool value)36424   void set_skip_dropbox(bool value) {
36425     AppendTinyVarInt(4, value);
36426   }
36427 };
36428 
36429 class TraceConfig_IncrementalStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36430  public:
TraceConfig_IncrementalStateConfig_Decoder(const uint8_t * data,size_t len)36431   TraceConfig_IncrementalStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_IncrementalStateConfig_Decoder(const std::string & raw)36432   explicit TraceConfig_IncrementalStateConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_IncrementalStateConfig_Decoder(const::protozero::ConstBytes & raw)36433   explicit TraceConfig_IncrementalStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clear_period_ms() const36434   bool has_clear_period_ms() const { return at<1>().valid(); }
clear_period_ms() const36435   uint32_t clear_period_ms() const { return at<1>().as_uint32(); }
36436 };
36437 
36438 class TraceConfig_IncrementalStateConfig : public ::protozero::Message {
36439  public:
36440   using Decoder = TraceConfig_IncrementalStateConfig_Decoder;
36441   enum : int32_t {
36442     kClearPeriodMsFieldNumber = 1,
36443   };
set_clear_period_ms(uint32_t value)36444   void set_clear_period_ms(uint32_t value) {
36445     AppendVarInt(1, value);
36446   }
36447 };
36448 
36449 class TraceConfig_TriggerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
36450  public:
TraceConfig_TriggerConfig_Decoder(const uint8_t * data,size_t len)36451   TraceConfig_TriggerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TriggerConfig_Decoder(const std::string & raw)36452   explicit TraceConfig_TriggerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_TriggerConfig_Decoder(const::protozero::ConstBytes & raw)36453   explicit TraceConfig_TriggerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_trigger_mode() const36454   bool has_trigger_mode() const { return at<1>().valid(); }
trigger_mode() const36455   int32_t trigger_mode() const { return at<1>().as_int32(); }
has_triggers() const36456   bool has_triggers() const { return at<2>().valid(); }
triggers() const36457   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> triggers() const { return GetRepeated<::protozero::ConstBytes>(2); }
has_trigger_timeout_ms() const36458   bool has_trigger_timeout_ms() const { return at<3>().valid(); }
trigger_timeout_ms() const36459   uint32_t trigger_timeout_ms() const { return at<3>().as_uint32(); }
36460 };
36461 
36462 class TraceConfig_TriggerConfig : public ::protozero::Message {
36463  public:
36464   using Decoder = TraceConfig_TriggerConfig_Decoder;
36465   enum : int32_t {
36466     kTriggerModeFieldNumber = 1,
36467     kTriggersFieldNumber = 2,
36468     kTriggerTimeoutMsFieldNumber = 3,
36469   };
36470   using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
36471   using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
36472   static const TriggerMode UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
36473   static const TriggerMode START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
36474   static const TriggerMode STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value)36475   void set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
36476     AppendTinyVarInt(1, value);
36477   }
add_triggers()36478   template <typename T = TraceConfig_TriggerConfig_Trigger> T* add_triggers() {
36479     return BeginNestedMessage<T>(2);
36480   }
36481 
set_trigger_timeout_ms(uint32_t value)36482   void set_trigger_timeout_ms(uint32_t value) {
36483     AppendVarInt(3, value);
36484   }
36485 };
36486 
36487 class TraceConfig_TriggerConfig_Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36488  public:
TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t * data,size_t len)36489   TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TriggerConfig_Trigger_Decoder(const std::string & raw)36490   explicit TraceConfig_TriggerConfig_Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_TriggerConfig_Trigger_Decoder(const::protozero::ConstBytes & raw)36491   explicit TraceConfig_TriggerConfig_Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_name() const36492   bool has_name() const { return at<1>().valid(); }
name() const36493   ::protozero::ConstChars name() const { return at<1>().as_string(); }
has_producer_name_regex() const36494   bool has_producer_name_regex() const { return at<2>().valid(); }
producer_name_regex() const36495   ::protozero::ConstChars producer_name_regex() const { return at<2>().as_string(); }
has_stop_delay_ms() const36496   bool has_stop_delay_ms() const { return at<3>().valid(); }
stop_delay_ms() const36497   uint32_t stop_delay_ms() const { return at<3>().as_uint32(); }
36498 };
36499 
36500 class TraceConfig_TriggerConfig_Trigger : public ::protozero::Message {
36501  public:
36502   using Decoder = TraceConfig_TriggerConfig_Trigger_Decoder;
36503   enum : int32_t {
36504     kNameFieldNumber = 1,
36505     kProducerNameRegexFieldNumber = 2,
36506     kStopDelayMsFieldNumber = 3,
36507   };
set_name(const std::string & value)36508   void set_name(const std::string& value) {
36509     AppendBytes(1, value.data(), value.size());
36510   }
set_name(const char * data,size_t size)36511   void set_name(const char* data, size_t size) {
36512     AppendBytes(1, data, size);
36513   }
set_producer_name_regex(const std::string & value)36514   void set_producer_name_regex(const std::string& value) {
36515     AppendBytes(2, value.data(), value.size());
36516   }
set_producer_name_regex(const char * data,size_t size)36517   void set_producer_name_regex(const char* data, size_t size) {
36518     AppendBytes(2, data, size);
36519   }
set_stop_delay_ms(uint32_t value)36520   void set_stop_delay_ms(uint32_t value) {
36521     AppendVarInt(3, value);
36522   }
36523 };
36524 
36525 class TraceConfig_GuardrailOverrides_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36526  public:
TraceConfig_GuardrailOverrides_Decoder(const uint8_t * data,size_t len)36527   TraceConfig_GuardrailOverrides_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_GuardrailOverrides_Decoder(const std::string & raw)36528   explicit TraceConfig_GuardrailOverrides_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_GuardrailOverrides_Decoder(const::protozero::ConstBytes & raw)36529   explicit TraceConfig_GuardrailOverrides_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_max_upload_per_day_bytes() const36530   bool has_max_upload_per_day_bytes() const { return at<1>().valid(); }
max_upload_per_day_bytes() const36531   uint64_t max_upload_per_day_bytes() const { return at<1>().as_uint64(); }
36532 };
36533 
36534 class TraceConfig_GuardrailOverrides : public ::protozero::Message {
36535  public:
36536   using Decoder = TraceConfig_GuardrailOverrides_Decoder;
36537   enum : int32_t {
36538     kMaxUploadPerDayBytesFieldNumber = 1,
36539   };
set_max_upload_per_day_bytes(uint64_t value)36540   void set_max_upload_per_day_bytes(uint64_t value) {
36541     AppendVarInt(1, value);
36542   }
36543 };
36544 
36545 class TraceConfig_StatsdMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36546  public:
TraceConfig_StatsdMetadata_Decoder(const uint8_t * data,size_t len)36547   TraceConfig_StatsdMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_StatsdMetadata_Decoder(const std::string & raw)36548   explicit TraceConfig_StatsdMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_StatsdMetadata_Decoder(const::protozero::ConstBytes & raw)36549   explicit TraceConfig_StatsdMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_triggering_alert_id() const36550   bool has_triggering_alert_id() const { return at<1>().valid(); }
triggering_alert_id() const36551   int64_t triggering_alert_id() const { return at<1>().as_int64(); }
has_triggering_config_uid() const36552   bool has_triggering_config_uid() const { return at<2>().valid(); }
triggering_config_uid() const36553   int32_t triggering_config_uid() const { return at<2>().as_int32(); }
has_triggering_config_id() const36554   bool has_triggering_config_id() const { return at<3>().valid(); }
triggering_config_id() const36555   int64_t triggering_config_id() const { return at<3>().as_int64(); }
has_triggering_subscription_id() const36556   bool has_triggering_subscription_id() const { return at<4>().valid(); }
triggering_subscription_id() const36557   int64_t triggering_subscription_id() const { return at<4>().as_int64(); }
36558 };
36559 
36560 class TraceConfig_StatsdMetadata : public ::protozero::Message {
36561  public:
36562   using Decoder = TraceConfig_StatsdMetadata_Decoder;
36563   enum : int32_t {
36564     kTriggeringAlertIdFieldNumber = 1,
36565     kTriggeringConfigUidFieldNumber = 2,
36566     kTriggeringConfigIdFieldNumber = 3,
36567     kTriggeringSubscriptionIdFieldNumber = 4,
36568   };
set_triggering_alert_id(int64_t value)36569   void set_triggering_alert_id(int64_t value) {
36570     AppendVarInt(1, value);
36571   }
set_triggering_config_uid(int32_t value)36572   void set_triggering_config_uid(int32_t value) {
36573     AppendVarInt(2, value);
36574   }
set_triggering_config_id(int64_t value)36575   void set_triggering_config_id(int64_t value) {
36576     AppendVarInt(3, value);
36577   }
set_triggering_subscription_id(int64_t value)36578   void set_triggering_subscription_id(int64_t value) {
36579     AppendVarInt(4, value);
36580   }
36581 };
36582 
36583 class TraceConfig_ProducerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36584  public:
TraceConfig_ProducerConfig_Decoder(const uint8_t * data,size_t len)36585   TraceConfig_ProducerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_ProducerConfig_Decoder(const std::string & raw)36586   explicit TraceConfig_ProducerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_ProducerConfig_Decoder(const::protozero::ConstBytes & raw)36587   explicit TraceConfig_ProducerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_producer_name() const36588   bool has_producer_name() const { return at<1>().valid(); }
producer_name() const36589   ::protozero::ConstChars producer_name() const { return at<1>().as_string(); }
has_shm_size_kb() const36590   bool has_shm_size_kb() const { return at<2>().valid(); }
shm_size_kb() const36591   uint32_t shm_size_kb() const { return at<2>().as_uint32(); }
has_page_size_kb() const36592   bool has_page_size_kb() const { return at<3>().valid(); }
page_size_kb() const36593   uint32_t page_size_kb() const { return at<3>().as_uint32(); }
36594 };
36595 
36596 class TraceConfig_ProducerConfig : public ::protozero::Message {
36597  public:
36598   using Decoder = TraceConfig_ProducerConfig_Decoder;
36599   enum : int32_t {
36600     kProducerNameFieldNumber = 1,
36601     kShmSizeKbFieldNumber = 2,
36602     kPageSizeKbFieldNumber = 3,
36603   };
set_producer_name(const std::string & value)36604   void set_producer_name(const std::string& value) {
36605     AppendBytes(1, value.data(), value.size());
36606   }
set_producer_name(const char * data,size_t size)36607   void set_producer_name(const char* data, size_t size) {
36608     AppendBytes(1, data, size);
36609   }
set_shm_size_kb(uint32_t value)36610   void set_shm_size_kb(uint32_t value) {
36611     AppendVarInt(2, value);
36612   }
set_page_size_kb(uint32_t value)36613   void set_page_size_kb(uint32_t value) {
36614     AppendVarInt(3, value);
36615   }
36616 };
36617 
36618 class TraceConfig_BuiltinDataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36619  public:
TraceConfig_BuiltinDataSource_Decoder(const uint8_t * data,size_t len)36620   TraceConfig_BuiltinDataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_BuiltinDataSource_Decoder(const std::string & raw)36621   explicit TraceConfig_BuiltinDataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_BuiltinDataSource_Decoder(const::protozero::ConstBytes & raw)36622   explicit TraceConfig_BuiltinDataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_disable_clock_snapshotting() const36623   bool has_disable_clock_snapshotting() const { return at<1>().valid(); }
disable_clock_snapshotting() const36624   bool disable_clock_snapshotting() const { return at<1>().as_bool(); }
has_disable_trace_config() const36625   bool has_disable_trace_config() const { return at<2>().valid(); }
disable_trace_config() const36626   bool disable_trace_config() const { return at<2>().as_bool(); }
has_disable_system_info() const36627   bool has_disable_system_info() const { return at<3>().valid(); }
disable_system_info() const36628   bool disable_system_info() const { return at<3>().as_bool(); }
has_disable_service_events() const36629   bool has_disable_service_events() const { return at<4>().valid(); }
disable_service_events() const36630   bool disable_service_events() const { return at<4>().as_bool(); }
has_primary_trace_clock() const36631   bool has_primary_trace_clock() const { return at<5>().valid(); }
primary_trace_clock() const36632   int32_t primary_trace_clock() const { return at<5>().as_int32(); }
has_snapshot_interval_ms() const36633   bool has_snapshot_interval_ms() const { return at<6>().valid(); }
snapshot_interval_ms() const36634   uint32_t snapshot_interval_ms() const { return at<6>().as_uint32(); }
36635 };
36636 
36637 class TraceConfig_BuiltinDataSource : public ::protozero::Message {
36638  public:
36639   using Decoder = TraceConfig_BuiltinDataSource_Decoder;
36640   enum : int32_t {
36641     kDisableClockSnapshottingFieldNumber = 1,
36642     kDisableTraceConfigFieldNumber = 2,
36643     kDisableSystemInfoFieldNumber = 3,
36644     kDisableServiceEventsFieldNumber = 4,
36645     kPrimaryTraceClockFieldNumber = 5,
36646     kSnapshotIntervalMsFieldNumber = 6,
36647   };
set_disable_clock_snapshotting(bool value)36648   void set_disable_clock_snapshotting(bool value) {
36649     AppendTinyVarInt(1, value);
36650   }
set_disable_trace_config(bool value)36651   void set_disable_trace_config(bool value) {
36652     AppendTinyVarInt(2, value);
36653   }
set_disable_system_info(bool value)36654   void set_disable_system_info(bool value) {
36655     AppendTinyVarInt(3, value);
36656   }
set_disable_service_events(bool value)36657   void set_disable_service_events(bool value) {
36658     AppendTinyVarInt(4, value);
36659   }
set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)36660   void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
36661     AppendTinyVarInt(5, value);
36662   }
set_snapshot_interval_ms(uint32_t value)36663   void set_snapshot_interval_ms(uint32_t value) {
36664     AppendVarInt(6, value);
36665   }
36666 };
36667 
36668 class TraceConfig_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
36669  public:
TraceConfig_DataSource_Decoder(const uint8_t * data,size_t len)36670   TraceConfig_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_DataSource_Decoder(const std::string & raw)36671   explicit TraceConfig_DataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_DataSource_Decoder(const::protozero::ConstBytes & raw)36672   explicit TraceConfig_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_config() const36673   bool has_config() const { return at<1>().valid(); }
config() const36674   ::protozero::ConstBytes config() const { return at<1>().as_bytes(); }
has_producer_name_filter() const36675   bool has_producer_name_filter() const { return at<2>().valid(); }
producer_name_filter() const36676   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_filter() const { return GetRepeated<::protozero::ConstChars>(2); }
has_producer_name_regex_filter() const36677   bool has_producer_name_regex_filter() const { return at<3>().valid(); }
producer_name_regex_filter() const36678   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_regex_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
36679 };
36680 
36681 class TraceConfig_DataSource : public ::protozero::Message {
36682  public:
36683   using Decoder = TraceConfig_DataSource_Decoder;
36684   enum : int32_t {
36685     kConfigFieldNumber = 1,
36686     kProducerNameFilterFieldNumber = 2,
36687     kProducerNameRegexFilterFieldNumber = 3,
36688   };
set_config()36689   template <typename T = DataSourceConfig> T* set_config() {
36690     return BeginNestedMessage<T>(1);
36691   }
36692 
add_producer_name_filter(const std::string & value)36693   void add_producer_name_filter(const std::string& value) {
36694     AppendBytes(2, value.data(), value.size());
36695   }
add_producer_name_filter(const char * data,size_t size)36696   void add_producer_name_filter(const char* data, size_t size) {
36697     AppendBytes(2, data, size);
36698   }
add_producer_name_regex_filter(const std::string & value)36699   void add_producer_name_regex_filter(const std::string& value) {
36700     AppendBytes(3, value.data(), value.size());
36701   }
add_producer_name_regex_filter(const char * data,size_t size)36702   void add_producer_name_regex_filter(const char* data, size_t size) {
36703     AppendBytes(3, data, size);
36704   }
36705 };
36706 
36707 class TraceConfig_BufferConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36708  public:
TraceConfig_BufferConfig_Decoder(const uint8_t * data,size_t len)36709   TraceConfig_BufferConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_BufferConfig_Decoder(const std::string & raw)36710   explicit TraceConfig_BufferConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_BufferConfig_Decoder(const::protozero::ConstBytes & raw)36711   explicit TraceConfig_BufferConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_size_kb() const36712   bool has_size_kb() const { return at<1>().valid(); }
size_kb() const36713   uint32_t size_kb() const { return at<1>().as_uint32(); }
has_fill_policy() const36714   bool has_fill_policy() const { return at<4>().valid(); }
fill_policy() const36715   int32_t fill_policy() const { return at<4>().as_int32(); }
36716 };
36717 
36718 class TraceConfig_BufferConfig : public ::protozero::Message {
36719  public:
36720   using Decoder = TraceConfig_BufferConfig_Decoder;
36721   enum : int32_t {
36722     kSizeKbFieldNumber = 1,
36723     kFillPolicyFieldNumber = 4,
36724   };
36725   using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
36726   static const FillPolicy UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
36727   static const FillPolicy RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
36728   static const FillPolicy DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
set_size_kb(uint32_t value)36729   void set_size_kb(uint32_t value) {
36730     AppendVarInt(1, value);
36731   }
set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value)36732   void set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
36733     AppendTinyVarInt(4, value);
36734   }
36735 };
36736 
36737 } // Namespace.
36738 } // Namespace.
36739 } // Namespace.
36740 #endif  // Include guard.
36741 // gen_amalgamated begin header: gen/protos/perfetto/trace/clock_snapshot.pbzero.h
36742 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36743 
36744 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
36745 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
36746 
36747 #include <stddef.h>
36748 #include <stdint.h>
36749 
36750 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36751 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36752 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36753 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36754 
36755 namespace perfetto {
36756 namespace protos {
36757 namespace pbzero {
36758 
36759 class ClockSnapshot_Clock;
36760 enum BuiltinClock : int32_t;
36761 
36762 enum ClockSnapshot_Clock_BuiltinClocks : int32_t {
36763   ClockSnapshot_Clock_BuiltinClocks_UNKNOWN = 0,
36764   ClockSnapshot_Clock_BuiltinClocks_REALTIME = 1,
36765   ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE = 2,
36766   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC = 3,
36767   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE = 4,
36768   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW = 5,
36769   ClockSnapshot_Clock_BuiltinClocks_BOOTTIME = 6,
36770   ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID = 63,
36771 };
36772 
36773 const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
36774 const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
36775 
36776 class ClockSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
36777  public:
ClockSnapshot_Decoder(const uint8_t * data,size_t len)36778   ClockSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ClockSnapshot_Decoder(const std::string & raw)36779   explicit ClockSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ClockSnapshot_Decoder(const::protozero::ConstBytes & raw)36780   explicit ClockSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clocks() const36781   bool has_clocks() const { return at<1>().valid(); }
clocks() const36782   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> clocks() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_primary_trace_clock() const36783   bool has_primary_trace_clock() const { return at<2>().valid(); }
primary_trace_clock() const36784   int32_t primary_trace_clock() const { return at<2>().as_int32(); }
36785 };
36786 
36787 class ClockSnapshot : public ::protozero::Message {
36788  public:
36789   using Decoder = ClockSnapshot_Decoder;
36790   enum : int32_t {
36791     kClocksFieldNumber = 1,
36792     kPrimaryTraceClockFieldNumber = 2,
36793   };
36794   using Clock = ::perfetto::protos::pbzero::ClockSnapshot_Clock;
add_clocks()36795   template <typename T = ClockSnapshot_Clock> T* add_clocks() {
36796     return BeginNestedMessage<T>(1);
36797   }
36798 
set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)36799   void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
36800     AppendTinyVarInt(2, value);
36801   }
36802 };
36803 
36804 class ClockSnapshot_Clock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36805  public:
ClockSnapshot_Clock_Decoder(const uint8_t * data,size_t len)36806   ClockSnapshot_Clock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ClockSnapshot_Clock_Decoder(const std::string & raw)36807   explicit ClockSnapshot_Clock_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ClockSnapshot_Clock_Decoder(const::protozero::ConstBytes & raw)36808   explicit ClockSnapshot_Clock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clock_id() const36809   bool has_clock_id() const { return at<1>().valid(); }
clock_id() const36810   uint32_t clock_id() const { return at<1>().as_uint32(); }
has_timestamp() const36811   bool has_timestamp() const { return at<2>().valid(); }
timestamp() const36812   uint64_t timestamp() const { return at<2>().as_uint64(); }
has_is_incremental() const36813   bool has_is_incremental() const { return at<3>().valid(); }
is_incremental() const36814   bool is_incremental() const { return at<3>().as_bool(); }
has_unit_multiplier_ns() const36815   bool has_unit_multiplier_ns() const { return at<4>().valid(); }
unit_multiplier_ns() const36816   uint64_t unit_multiplier_ns() const { return at<4>().as_uint64(); }
36817 };
36818 
36819 class ClockSnapshot_Clock : public ::protozero::Message {
36820  public:
36821   using Decoder = ClockSnapshot_Clock_Decoder;
36822   enum : int32_t {
36823     kClockIdFieldNumber = 1,
36824     kTimestampFieldNumber = 2,
36825     kIsIncrementalFieldNumber = 3,
36826     kUnitMultiplierNsFieldNumber = 4,
36827   };
36828   using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
36829   static const BuiltinClocks UNKNOWN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
36830   static const BuiltinClocks REALTIME = ClockSnapshot_Clock_BuiltinClocks_REALTIME;
36831   static const BuiltinClocks REALTIME_COARSE = ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE;
36832   static const BuiltinClocks MONOTONIC = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC;
36833   static const BuiltinClocks MONOTONIC_COARSE = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE;
36834   static const BuiltinClocks MONOTONIC_RAW = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW;
36835   static const BuiltinClocks BOOTTIME = ClockSnapshot_Clock_BuiltinClocks_BOOTTIME;
36836   static const BuiltinClocks BUILTIN_CLOCK_MAX_ID = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
set_clock_id(uint32_t value)36837   void set_clock_id(uint32_t value) {
36838     AppendVarInt(1, value);
36839   }
set_timestamp(uint64_t value)36840   void set_timestamp(uint64_t value) {
36841     AppendVarInt(2, value);
36842   }
set_is_incremental(bool value)36843   void set_is_incremental(bool value) {
36844     AppendTinyVarInt(3, value);
36845   }
set_unit_multiplier_ns(uint64_t value)36846   void set_unit_multiplier_ns(uint64_t value) {
36847     AppendVarInt(4, value);
36848   }
36849 };
36850 
36851 } // Namespace.
36852 } // Namespace.
36853 } // Namespace.
36854 #endif  // Include guard.
36855 // gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h
36856 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36857 
36858 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
36859 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
36860 
36861 #include <stddef.h>
36862 #include <stdint.h>
36863 
36864 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36865 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36866 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36867 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36868 
36869 namespace perfetto {
36870 namespace protos {
36871 namespace pbzero {
36872 
36873 
36874 class TracingServiceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36875  public:
TracingServiceEvent_Decoder(const uint8_t * data,size_t len)36876   TracingServiceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TracingServiceEvent_Decoder(const std::string & raw)36877   explicit TracingServiceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TracingServiceEvent_Decoder(const::protozero::ConstBytes & raw)36878   explicit TracingServiceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_tracing_started() const36879   bool has_tracing_started() const { return at<2>().valid(); }
tracing_started() const36880   bool tracing_started() const { return at<2>().as_bool(); }
has_all_data_sources_started() const36881   bool has_all_data_sources_started() const { return at<1>().valid(); }
all_data_sources_started() const36882   bool all_data_sources_started() const { return at<1>().as_bool(); }
has_all_data_sources_flushed() const36883   bool has_all_data_sources_flushed() const { return at<3>().valid(); }
all_data_sources_flushed() const36884   bool all_data_sources_flushed() const { return at<3>().as_bool(); }
has_read_tracing_buffers_completed() const36885   bool has_read_tracing_buffers_completed() const { return at<4>().valid(); }
read_tracing_buffers_completed() const36886   bool read_tracing_buffers_completed() const { return at<4>().as_bool(); }
has_tracing_disabled() const36887   bool has_tracing_disabled() const { return at<5>().valid(); }
tracing_disabled() const36888   bool tracing_disabled() const { return at<5>().as_bool(); }
36889 };
36890 
36891 class TracingServiceEvent : public ::protozero::Message {
36892  public:
36893   using Decoder = TracingServiceEvent_Decoder;
36894   enum : int32_t {
36895     kTracingStartedFieldNumber = 2,
36896     kAllDataSourcesStartedFieldNumber = 1,
36897     kAllDataSourcesFlushedFieldNumber = 3,
36898     kReadTracingBuffersCompletedFieldNumber = 4,
36899     kTracingDisabledFieldNumber = 5,
36900   };
set_tracing_started(bool value)36901   void set_tracing_started(bool value) {
36902     AppendTinyVarInt(2, value);
36903   }
set_all_data_sources_started(bool value)36904   void set_all_data_sources_started(bool value) {
36905     AppendTinyVarInt(1, value);
36906   }
set_all_data_sources_flushed(bool value)36907   void set_all_data_sources_flushed(bool value) {
36908     AppendTinyVarInt(3, value);
36909   }
set_read_tracing_buffers_completed(bool value)36910   void set_read_tracing_buffers_completed(bool value) {
36911     AppendTinyVarInt(4, value);
36912   }
set_tracing_disabled(bool value)36913   void set_tracing_disabled(bool value) {
36914     AppendTinyVarInt(5, value);
36915   }
36916 };
36917 
36918 } // Namespace.
36919 } // Namespace.
36920 } // Namespace.
36921 #endif  // Include guard.
36922 // gen_amalgamated begin header: gen/protos/perfetto/trace/system_info.pbzero.h
36923 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
36924 
36925 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
36926 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
36927 
36928 #include <stddef.h>
36929 #include <stdint.h>
36930 
36931 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
36932 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
36933 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
36934 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36935 
36936 namespace perfetto {
36937 namespace protos {
36938 namespace pbzero {
36939 
36940 class Utsname;
36941 
36942 class SystemInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36943  public:
SystemInfo_Decoder(const uint8_t * data,size_t len)36944   SystemInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
SystemInfo_Decoder(const std::string & raw)36945   explicit SystemInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
SystemInfo_Decoder(const::protozero::ConstBytes & raw)36946   explicit SystemInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_utsname() const36947   bool has_utsname() const { return at<1>().valid(); }
utsname() const36948   ::protozero::ConstBytes utsname() const { return at<1>().as_bytes(); }
has_android_build_fingerprint() const36949   bool has_android_build_fingerprint() const { return at<2>().valid(); }
android_build_fingerprint() const36950   ::protozero::ConstChars android_build_fingerprint() const { return at<2>().as_string(); }
has_hz() const36951   bool has_hz() const { return at<3>().valid(); }
hz() const36952   int64_t hz() const { return at<3>().as_int64(); }
36953 };
36954 
36955 class SystemInfo : public ::protozero::Message {
36956  public:
36957   using Decoder = SystemInfo_Decoder;
36958   enum : int32_t {
36959     kUtsnameFieldNumber = 1,
36960     kAndroidBuildFingerprintFieldNumber = 2,
36961     kHzFieldNumber = 3,
36962   };
set_utsname()36963   template <typename T = Utsname> T* set_utsname() {
36964     return BeginNestedMessage<T>(1);
36965   }
36966 
set_android_build_fingerprint(const std::string & value)36967   void set_android_build_fingerprint(const std::string& value) {
36968     AppendBytes(2, value.data(), value.size());
36969   }
set_android_build_fingerprint(const char * data,size_t size)36970   void set_android_build_fingerprint(const char* data, size_t size) {
36971     AppendBytes(2, data, size);
36972   }
set_hz(int64_t value)36973   void set_hz(int64_t value) {
36974     AppendVarInt(3, value);
36975   }
36976 };
36977 
36978 class Utsname_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
36979  public:
Utsname_Decoder(const uint8_t * data,size_t len)36980   Utsname_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
Utsname_Decoder(const std::string & raw)36981   explicit Utsname_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
Utsname_Decoder(const::protozero::ConstBytes & raw)36982   explicit Utsname_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_sysname() const36983   bool has_sysname() const { return at<1>().valid(); }
sysname() const36984   ::protozero::ConstChars sysname() const { return at<1>().as_string(); }
has_version() const36985   bool has_version() const { return at<2>().valid(); }
version() const36986   ::protozero::ConstChars version() const { return at<2>().as_string(); }
has_release() const36987   bool has_release() const { return at<3>().valid(); }
release() const36988   ::protozero::ConstChars release() const { return at<3>().as_string(); }
has_machine() const36989   bool has_machine() const { return at<4>().valid(); }
machine() const36990   ::protozero::ConstChars machine() const { return at<4>().as_string(); }
36991 };
36992 
36993 class Utsname : public ::protozero::Message {
36994  public:
36995   using Decoder = Utsname_Decoder;
36996   enum : int32_t {
36997     kSysnameFieldNumber = 1,
36998     kVersionFieldNumber = 2,
36999     kReleaseFieldNumber = 3,
37000     kMachineFieldNumber = 4,
37001   };
set_sysname(const std::string & value)37002   void set_sysname(const std::string& value) {
37003     AppendBytes(1, value.data(), value.size());
37004   }
set_sysname(const char * data,size_t size)37005   void set_sysname(const char* data, size_t size) {
37006     AppendBytes(1, data, size);
37007   }
set_version(const std::string & value)37008   void set_version(const std::string& value) {
37009     AppendBytes(2, value.data(), value.size());
37010   }
set_version(const char * data,size_t size)37011   void set_version(const char* data, size_t size) {
37012     AppendBytes(2, data, size);
37013   }
set_release(const std::string & value)37014   void set_release(const std::string& value) {
37015     AppendBytes(3, value.data(), value.size());
37016   }
set_release(const char * data,size_t size)37017   void set_release(const char* data, size_t size) {
37018     AppendBytes(3, data, size);
37019   }
set_machine(const std::string & value)37020   void set_machine(const std::string& value) {
37021     AppendBytes(4, value.data(), value.size());
37022   }
set_machine(const char * data,size_t size)37023   void set_machine(const char* data, size_t size) {
37024     AppendBytes(4, data, size);
37025   }
37026 };
37027 
37028 } // Namespace.
37029 } // Namespace.
37030 } // Namespace.
37031 #endif  // Include guard.
37032 // gen_amalgamated begin header: gen/protos/perfetto/trace/trigger.pbzero.h
37033 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
37034 
37035 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
37036 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
37037 
37038 #include <stddef.h>
37039 #include <stdint.h>
37040 
37041 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
37042 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
37043 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
37044 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
37045 
37046 namespace perfetto {
37047 namespace protos {
37048 namespace pbzero {
37049 
37050 
37051 class Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
37052  public:
Trigger_Decoder(const uint8_t * data,size_t len)37053   Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
Trigger_Decoder(const std::string & raw)37054   explicit Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
Trigger_Decoder(const::protozero::ConstBytes & raw)37055   explicit Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_trigger_name() const37056   bool has_trigger_name() const { return at<1>().valid(); }
trigger_name() const37057   ::protozero::ConstChars trigger_name() const { return at<1>().as_string(); }
has_producer_name() const37058   bool has_producer_name() const { return at<2>().valid(); }
producer_name() const37059   ::protozero::ConstChars producer_name() const { return at<2>().as_string(); }
has_trusted_producer_uid() const37060   bool has_trusted_producer_uid() const { return at<3>().valid(); }
trusted_producer_uid() const37061   int32_t trusted_producer_uid() const { return at<3>().as_int32(); }
37062 };
37063 
37064 class Trigger : public ::protozero::Message {
37065  public:
37066   using Decoder = Trigger_Decoder;
37067   enum : int32_t {
37068     kTriggerNameFieldNumber = 1,
37069     kProducerNameFieldNumber = 2,
37070     kTrustedProducerUidFieldNumber = 3,
37071   };
set_trigger_name(const std::string & value)37072   void set_trigger_name(const std::string& value) {
37073     AppendBytes(1, value.data(), value.size());
37074   }
set_trigger_name(const char * data,size_t size)37075   void set_trigger_name(const char* data, size_t size) {
37076     AppendBytes(1, data, size);
37077   }
set_producer_name(const std::string & value)37078   void set_producer_name(const std::string& value) {
37079     AppendBytes(2, value.data(), value.size());
37080   }
set_producer_name(const char * data,size_t size)37081   void set_producer_name(const char* data, size_t size) {
37082     AppendBytes(2, data, size);
37083   }
set_trusted_producer_uid(int32_t value)37084   void set_trusted_producer_uid(int32_t value) {
37085     AppendVarInt(3, value);
37086   }
37087 };
37088 
37089 } // Namespace.
37090 } // Namespace.
37091 } // Namespace.
37092 #endif  // Include guard.
37093 /*
37094  * Copyright (C) 2017 The Android Open Source Project
37095  *
37096  * Licensed under the Apache License, Version 2.0 (the "License");
37097  * you may not use this file except in compliance with the License.
37098  * You may obtain a copy of the License at
37099  *
37100  *      http://www.apache.org/licenses/LICENSE-2.0
37101  *
37102  * Unless required by applicable law or agreed to in writing, software
37103  * distributed under the License is distributed on an "AS IS" BASIS,
37104  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37105  * See the License for the specific language governing permissions and
37106  * limitations under the License.
37107  */
37108 
37109 // gen_amalgamated expanded: #include "src/tracing/core/tracing_service_impl.h"
37110 
37111 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
37112 
37113 #include <errno.h>
37114 #include <inttypes.h>
37115 #include <limits.h>
37116 #include <string.h>
37117 #include <regex>
37118 #include <unordered_set>
37119 
37120 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
37121     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
37122 #include <sys/uio.h>
37123 #include <sys/utsname.h>
37124 #include <unistd.h>
37125 #endif
37126 
37127 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
37128 #include <sys/system_properties.h>
37129 #endif
37130 
37131 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
37132     PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
37133     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
37134 #define PERFETTO_HAS_CHMOD
37135 #include <sys/stat.h>
37136 #endif
37137 
37138 #include <algorithm>
37139 
37140 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
37141 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
37142 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
37143 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
37144 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
37145 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
37146 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
37147 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
37148 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
37149 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
37150 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
37151 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
37152 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
37153 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
37154 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
37155 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
37156 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
37157 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
37158 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
37159 // gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
37160 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
37161 // gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
37162 
37163 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
37164 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
37165 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.pbzero.h"
37166 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.pbzero.h"
37167 // gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
37168 // gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
37169 // gen_amalgamated expanded: #include "protos/perfetto/trace/system_info.pbzero.h"
37170 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
37171 // gen_amalgamated expanded: #include "protos/perfetto/trace/trigger.pbzero.h"
37172 
37173 // General note: this class must assume that Producers are malicious and will
37174 // try to crash / exploit this class. We can trust pointers because they come
37175 // from the IPC layer, but we should never assume that that the producer calls
37176 // come in the right order or their arguments are sane / within bounds.
37177 
37178 namespace perfetto {
37179 
37180 namespace {
37181 constexpr int kMaxBuffersPerConsumer = 128;
37182 constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
37183 constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
37184 constexpr int kMaxConcurrentTracingSessions = 15;
37185 constexpr int kMaxConcurrentTracingSessionsPerUid = 5;
37186 constexpr int kMaxConcurrentTracingSessionsForStatsdUid = 10;
37187 constexpr int64_t kMinSecondsBetweenTracesGuardrail = 5 * 60;
37188 
37189 constexpr uint32_t kMillisPerHour = 3600000;
37190 constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;
37191 
37192 // These apply only if enable_extra_guardrails is true.
37193 constexpr uint32_t kGuardrailsMaxTracingBufferSizeKb = 128 * 1024;
37194 constexpr uint32_t kGuardrailsMaxTracingDurationMillis = 24 * kMillisPerHour;
37195 
37196 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
37197 struct iovec {
37198   void* iov_base;  // Address
37199   size_t iov_len;  // Block size
37200 };
37201 
37202 // Simple implementation of writev. Note that this does not give the atomicity
37203 // guarantees of a real writev, but we don't depend on these (we aren't writing
37204 // to the same file from another thread).
writev(int fd,const struct iovec * iov,int iovcnt)37205 ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
37206   ssize_t total_size = 0;
37207   for (int i = 0; i < iovcnt; ++i) {
37208     ssize_t current_size = base::WriteAll(fd, iov[i].iov_base, iov[i].iov_len);
37209     if (current_size != static_cast<ssize_t>(iov[i].iov_len))
37210       return -1;
37211     total_size += current_size;
37212   }
37213   return total_size;
37214 }
37215 
37216 #define IOV_MAX 1024  // Linux compatible limit.
37217 
37218 // uid checking is a NOP on Windows.
getuid()37219 uid_t getuid() {
37220   return 0;
37221 }
geteuid()37222 uid_t geteuid() {
37223   return 0;
37224 }
37225 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
37226         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
37227 
37228 // Partially encodes a CommitDataRequest in an int32 for the purposes of
37229 // metatracing. Note that it encodes only the bottom 10 bits of the producer id
37230 // (which is technically 16 bits wide).
37231 //
37232 // Format (by bit range):
37233 // [   31 ][         30 ][             29:20 ][            19:10 ][        9:0]
37234 // [unused][has flush id][num chunks to patch][num chunks to move][producer id]
EncodeCommitDataRequest(ProducerID producer_id,const CommitDataRequest & req_untrusted)37235 static int32_t EncodeCommitDataRequest(ProducerID producer_id,
37236                                        const CommitDataRequest& req_untrusted) {
37237   uint32_t cmov = static_cast<uint32_t>(req_untrusted.chunks_to_move_size());
37238   uint32_t cpatch = static_cast<uint32_t>(req_untrusted.chunks_to_patch_size());
37239   uint32_t has_flush_id = req_untrusted.flush_request_id() != 0;
37240 
37241   uint32_t mask = (1 << 10) - 1;
37242   uint32_t acc = 0;
37243   acc |= has_flush_id << 30;
37244   acc |= (cpatch & mask) << 20;
37245   acc |= (cmov & mask) << 10;
37246   acc |= (producer_id & mask);
37247   return static_cast<int32_t>(acc);
37248 }
37249 
SerializeAndAppendPacket(std::vector<TracePacket> * packets,std::vector<uint8_t> packet)37250 void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
37251                               std::vector<uint8_t> packet) {
37252   Slice slice = Slice::Allocate(packet.size());
37253   memcpy(slice.own_data(), packet.data(), packet.size());
37254   packets->emplace_back();
37255   packets->back().AddSlice(std::move(slice));
37256 }
37257 
EnsureValidShmSizes(size_t shm_size,size_t page_size)37258 std::tuple<size_t /*shm_size*/, size_t /*page_size*/> EnsureValidShmSizes(
37259     size_t shm_size,
37260     size_t page_size) {
37261   // Theoretically the max page size supported by the ABI is 64KB.
37262   // However, the current implementation of TraceBuffer (the non-shared
37263   // userspace buffer where the service copies data) supports at most
37264   // 32K. Setting 64K "works" from the producer<>consumer viewpoint
37265   // but then causes the data to be discarded when copying it into
37266   // TraceBuffer.
37267   constexpr size_t kMaxPageSize = 32 * 1024;
37268   static_assert(kMaxPageSize <= SharedMemoryABI::kMaxPageSize, "");
37269 
37270   if (page_size == 0)
37271     page_size = TracingServiceImpl::kDefaultShmPageSize;
37272   if (shm_size == 0)
37273     shm_size = TracingServiceImpl::kDefaultShmSize;
37274 
37275   page_size = std::min<size_t>(page_size, kMaxPageSize);
37276   shm_size = std::min<size_t>(shm_size, TracingServiceImpl::kMaxShmSize);
37277 
37278   // The tracing page size has to be multiple of 4K. On some systems (e.g. Mac
37279   // on Arm64) the system page size can be larger (e.g., 16K). That doesn't
37280   // matter here, because the tracing page size is just a logical partitioning
37281   // and does not have any dependencies on kernel mm syscalls (read: it's fine
37282   // to have trace page sizes of 4K on a system where the kernel page size is
37283   // 16K).
37284   bool page_size_is_valid = page_size >= SharedMemoryABI::kMinPageSize;
37285   page_size_is_valid &= page_size % SharedMemoryABI::kMinPageSize == 0;
37286 
37287   // Only allow power of two numbers of pages, i.e. 1, 2, 4, 8 pages.
37288   size_t num_pages = page_size / SharedMemoryABI::kMinPageSize;
37289   page_size_is_valid &= (num_pages & (num_pages - 1)) == 0;
37290 
37291   if (!page_size_is_valid || shm_size < page_size ||
37292       shm_size % page_size != 0) {
37293     return std::make_tuple(TracingServiceImpl::kDefaultShmSize,
37294                            TracingServiceImpl::kDefaultShmPageSize);
37295   }
37296   return std::make_tuple(shm_size, page_size);
37297 }
37298 
NameMatchesFilter(const std::string & name,const std::vector<std::string> & name_filter,const std::vector<std::string> & name_regex_filter)37299 bool NameMatchesFilter(const std::string& name,
37300                        const std::vector<std::string>& name_filter,
37301                        const std::vector<std::string>& name_regex_filter) {
37302   bool filter_is_set = !name_filter.empty() || !name_regex_filter.empty();
37303   if (!filter_is_set)
37304     return true;
37305   bool filter_matches = std::find(name_filter.begin(), name_filter.end(),
37306                                   name) != name_filter.end();
37307   bool filter_regex_matches =
37308       std::find_if(name_regex_filter.begin(), name_regex_filter.end(),
37309                    [&](const std::string& regex) {
37310                      return std::regex_match(
37311                          name, std::regex(regex, std::regex::extended));
37312                    }) != name_regex_filter.end();
37313   return filter_matches || filter_regex_matches;
37314 }
37315 
37316 // Used when write_into_file == true and output_path is not empty.
CreateTraceFile(const std::string & path)37317 base::ScopedFile CreateTraceFile(const std::string& path) {
37318 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
37319   static const char kBase[] = "/data/misc/perfetto-traces/";
37320   if (!base::StartsWith(path, kBase) || path.rfind('/') != strlen(kBase) - 1) {
37321     PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
37322                   path.c_str(), kBase);
37323     return base::ScopedFile();
37324   }
37325 #endif
37326   // O_CREAT | O_EXCL will fail if the file exists already.
37327   auto fd = base::OpenFile(path, O_RDWR | O_CREAT | O_EXCL, 0600);
37328   if (!fd)
37329     PERFETTO_PLOG("Failed to create %s", path.c_str());
37330 #if defined(PERFETTO_HAS_CHMOD)
37331   // Passing 0644 directly above won't work because of umask.
37332   PERFETTO_CHECK(fchmod(*fd, 0644) == 0);
37333 #endif
37334   return fd;
37335 }
37336 
37337 }  // namespace
37338 
37339 // These constants instead are defined in the header because are used by tests.
37340 constexpr size_t TracingServiceImpl::kDefaultShmSize;
37341 constexpr size_t TracingServiceImpl::kDefaultShmPageSize;
37342 
37343 constexpr size_t TracingServiceImpl::kMaxShmSize;
37344 constexpr uint32_t TracingServiceImpl::kDataSourceStopTimeoutMs;
37345 constexpr uint8_t TracingServiceImpl::kSyncMarker[];
37346 
37347 // static
CreateInstance(std::unique_ptr<SharedMemory::Factory> shm_factory,base::TaskRunner * task_runner)37348 std::unique_ptr<TracingService> TracingService::CreateInstance(
37349     std::unique_ptr<SharedMemory::Factory> shm_factory,
37350     base::TaskRunner* task_runner) {
37351   return std::unique_ptr<TracingService>(
37352       new TracingServiceImpl(std::move(shm_factory), task_runner));
37353 }
37354 
TracingServiceImpl(std::unique_ptr<SharedMemory::Factory> shm_factory,base::TaskRunner * task_runner)37355 TracingServiceImpl::TracingServiceImpl(
37356     std::unique_ptr<SharedMemory::Factory> shm_factory,
37357     base::TaskRunner* task_runner)
37358     : task_runner_(task_runner),
37359       shm_factory_(std::move(shm_factory)),
37360       uid_(getuid()),
37361       buffer_ids_(kMaxTraceBufferID),
37362       weak_ptr_factory_(this) {
37363   PERFETTO_DCHECK(task_runner_);
37364 }
37365 
~TracingServiceImpl()37366 TracingServiceImpl::~TracingServiceImpl() {
37367   // TODO(fmayer): handle teardown of all Producer.
37368 }
37369 
37370 std::unique_ptr<TracingService::ProducerEndpoint>
ConnectProducer(Producer * producer,uid_t uid,const std::string & producer_name,size_t shared_memory_size_hint_bytes,bool in_process,ProducerSMBScrapingMode smb_scraping_mode,size_t shared_memory_page_size_hint_bytes,std::unique_ptr<SharedMemory> shm)37371 TracingServiceImpl::ConnectProducer(Producer* producer,
37372                                     uid_t uid,
37373                                     const std::string& producer_name,
37374                                     size_t shared_memory_size_hint_bytes,
37375                                     bool in_process,
37376                                     ProducerSMBScrapingMode smb_scraping_mode,
37377                                     size_t shared_memory_page_size_hint_bytes,
37378                                     std::unique_ptr<SharedMemory> shm) {
37379   PERFETTO_DCHECK_THREAD(thread_checker_);
37380 
37381   if (lockdown_mode_ && uid != geteuid()) {
37382     PERFETTO_DLOG("Lockdown mode. Rejecting producer with UID %ld",
37383                   static_cast<unsigned long>(uid));
37384     return nullptr;
37385   }
37386 
37387   if (producers_.size() >= kMaxProducerID) {
37388     PERFETTO_DFATAL("Too many producers.");
37389     return nullptr;
37390   }
37391   const ProducerID id = GetNextProducerID();
37392   PERFETTO_DLOG("Producer %" PRIu16 " connected", id);
37393 
37394   bool smb_scraping_enabled = smb_scraping_enabled_;
37395   switch (smb_scraping_mode) {
37396     case ProducerSMBScrapingMode::kDefault:
37397       break;
37398     case ProducerSMBScrapingMode::kEnabled:
37399       smb_scraping_enabled = true;
37400       break;
37401     case ProducerSMBScrapingMode::kDisabled:
37402       smb_scraping_enabled = false;
37403       break;
37404   }
37405 
37406   std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
37407       id, uid, this, task_runner_, producer, producer_name, in_process,
37408       smb_scraping_enabled));
37409   auto it_and_inserted = producers_.emplace(id, endpoint.get());
37410   PERFETTO_DCHECK(it_and_inserted.second);
37411   endpoint->shmem_size_hint_bytes_ = shared_memory_size_hint_bytes;
37412   endpoint->shmem_page_size_hint_bytes_ = shared_memory_page_size_hint_bytes;
37413 
37414   // Producer::OnConnect() should run before Producer::OnTracingSetup(). The
37415   // latter may be posted by SetupSharedMemory() below, so post OnConnect() now.
37416   task_runner_->PostTask(std::bind(&Producer::OnConnect, endpoint->producer_));
37417 
37418   if (shm) {
37419     // The producer supplied an SMB. This is used only by Chrome; in the most
37420     // common cases the SMB is created by the service and passed via
37421     // OnTracingSetup(). Verify that it is correctly sized before we attempt to
37422     // use it. The transport layer has to verify the integrity of the SMB (e.g.
37423     // ensure that the producer can't resize if after the fact).
37424     size_t shm_size, page_size;
37425     std::tie(shm_size, page_size) =
37426         EnsureValidShmSizes(shm->size(), endpoint->shmem_page_size_hint_bytes_);
37427     if (shm_size == shm->size() &&
37428         page_size == endpoint->shmem_page_size_hint_bytes_) {
37429       PERFETTO_DLOG(
37430           "Adopting producer-provided SMB of %zu kB for producer \"%s\"",
37431           shm_size / 1024, endpoint->name_.c_str());
37432       endpoint->SetupSharedMemory(std::move(shm), page_size,
37433                                   /*provided_by_producer=*/true);
37434     } else {
37435       PERFETTO_LOG(
37436           "Discarding incorrectly sized producer-provided SMB for producer "
37437           "\"%s\", falling back to service-provided SMB. Requested sizes: %zu "
37438           "B total, %zu B page size; suggested corrected sizes: %zu B total, "
37439           "%zu B page size",
37440           endpoint->name_.c_str(), shm->size(),
37441           endpoint->shmem_page_size_hint_bytes_, shm_size, page_size);
37442       shm.reset();
37443     }
37444   }
37445 
37446   return std::unique_ptr<ProducerEndpoint>(std::move(endpoint));
37447 }
37448 
DisconnectProducer(ProducerID id)37449 void TracingServiceImpl::DisconnectProducer(ProducerID id) {
37450   PERFETTO_DCHECK_THREAD(thread_checker_);
37451   PERFETTO_DLOG("Producer %" PRIu16 " disconnected", id);
37452   PERFETTO_DCHECK(producers_.count(id));
37453 
37454   // Scrape remaining chunks for this producer to ensure we don't lose data.
37455   if (auto* producer = GetProducer(id)) {
37456     for (auto& session_id_and_session : tracing_sessions_)
37457       ScrapeSharedMemoryBuffers(&session_id_and_session.second, producer);
37458   }
37459 
37460   for (auto it = data_sources_.begin(); it != data_sources_.end();) {
37461     auto next = it;
37462     next++;
37463     if (it->second.producer_id == id)
37464       UnregisterDataSource(id, it->second.descriptor.name());
37465     it = next;
37466   }
37467 
37468   producers_.erase(id);
37469   UpdateMemoryGuardrail();
37470 }
37471 
GetProducer(ProducerID id) const37472 TracingServiceImpl::ProducerEndpointImpl* TracingServiceImpl::GetProducer(
37473     ProducerID id) const {
37474   PERFETTO_DCHECK_THREAD(thread_checker_);
37475   auto it = producers_.find(id);
37476   if (it == producers_.end())
37477     return nullptr;
37478   return it->second;
37479 }
37480 
37481 std::unique_ptr<TracingService::ConsumerEndpoint>
ConnectConsumer(Consumer * consumer,uid_t uid)37482 TracingServiceImpl::ConnectConsumer(Consumer* consumer, uid_t uid) {
37483   PERFETTO_DCHECK_THREAD(thread_checker_);
37484   PERFETTO_DLOG("Consumer %p connected", reinterpret_cast<void*>(consumer));
37485   std::unique_ptr<ConsumerEndpointImpl> endpoint(
37486       new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
37487   auto it_and_inserted = consumers_.emplace(endpoint.get());
37488   PERFETTO_DCHECK(it_and_inserted.second);
37489   // Consumer might go away before we're able to send the connect notification,
37490   // if that is the case just bail out.
37491   auto weak_ptr = endpoint->GetWeakPtr();
37492   task_runner_->PostTask([weak_ptr] {
37493     if (!weak_ptr) {
37494       return;
37495     }
37496     weak_ptr->consumer_->OnConnect();
37497   });
37498   return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
37499 }
37500 
DisconnectConsumer(ConsumerEndpointImpl * consumer)37501 void TracingServiceImpl::DisconnectConsumer(ConsumerEndpointImpl* consumer) {
37502   PERFETTO_DCHECK_THREAD(thread_checker_);
37503   PERFETTO_DLOG("Consumer %p disconnected", reinterpret_cast<void*>(consumer));
37504   PERFETTO_DCHECK(consumers_.count(consumer));
37505 
37506   // TODO(primiano) : Check that this is safe (what happens if there are
37507   // ReadBuffers() calls posted in the meantime? They need to become noop).
37508   if (consumer->tracing_session_id_)
37509     FreeBuffers(consumer->tracing_session_id_);  // Will also DisableTracing().
37510   consumers_.erase(consumer);
37511 
37512   // At this point no more pointers to |consumer| should be around.
37513   PERFETTO_DCHECK(!std::any_of(
37514       tracing_sessions_.begin(), tracing_sessions_.end(),
37515       [consumer](const std::pair<const TracingSessionID, TracingSession>& kv) {
37516         return kv.second.consumer_maybe_null == consumer;
37517       }));
37518 }
37519 
DetachConsumer(ConsumerEndpointImpl * consumer,const std::string & key)37520 bool TracingServiceImpl::DetachConsumer(ConsumerEndpointImpl* consumer,
37521                                         const std::string& key) {
37522   PERFETTO_DCHECK_THREAD(thread_checker_);
37523   PERFETTO_DLOG("Consumer %p detached", reinterpret_cast<void*>(consumer));
37524   PERFETTO_DCHECK(consumers_.count(consumer));
37525 
37526   TracingSessionID tsid = consumer->tracing_session_id_;
37527   TracingSession* tracing_session;
37528   if (!tsid || !(tracing_session = GetTracingSession(tsid)))
37529     return false;
37530 
37531   if (GetDetachedSession(consumer->uid_, key)) {
37532     PERFETTO_ELOG("Another session has been detached with the same key \"%s\"",
37533                   key.c_str());
37534     return false;
37535   }
37536 
37537   PERFETTO_DCHECK(tracing_session->consumer_maybe_null == consumer);
37538   tracing_session->consumer_maybe_null = nullptr;
37539   tracing_session->detach_key = key;
37540   consumer->tracing_session_id_ = 0;
37541   return true;
37542 }
37543 
AttachConsumer(ConsumerEndpointImpl * consumer,const std::string & key)37544 bool TracingServiceImpl::AttachConsumer(ConsumerEndpointImpl* consumer,
37545                                         const std::string& key) {
37546   PERFETTO_DCHECK_THREAD(thread_checker_);
37547   PERFETTO_DLOG("Consumer %p attaching to session %s",
37548                 reinterpret_cast<void*>(consumer), key.c_str());
37549   PERFETTO_DCHECK(consumers_.count(consumer));
37550 
37551   if (consumer->tracing_session_id_) {
37552     PERFETTO_ELOG(
37553         "Cannot reattach consumer to session %s"
37554         " while it already attached tracing session ID %" PRIu64,
37555         key.c_str(), consumer->tracing_session_id_);
37556     return false;
37557   }
37558 
37559   auto* tracing_session = GetDetachedSession(consumer->uid_, key);
37560   if (!tracing_session) {
37561     PERFETTO_ELOG(
37562         "Failed to attach consumer, session '%s' not found for uid %d",
37563         key.c_str(), static_cast<int>(consumer->uid_));
37564     return false;
37565   }
37566 
37567   consumer->tracing_session_id_ = tracing_session->id;
37568   tracing_session->consumer_maybe_null = consumer;
37569   tracing_session->detach_key.clear();
37570   return true;
37571 }
37572 
EnableTracing(ConsumerEndpointImpl * consumer,const TraceConfig & cfg,base::ScopedFile fd)37573 bool TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
37574                                        const TraceConfig& cfg,
37575                                        base::ScopedFile fd) {
37576   PERFETTO_DCHECK_THREAD(thread_checker_);
37577   PERFETTO_DLOG("Enabling tracing for consumer %p",
37578                 reinterpret_cast<void*>(consumer));
37579   if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_SET)
37580     lockdown_mode_ = true;
37581   if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_CLEAR)
37582     lockdown_mode_ = false;
37583   TracingSession* tracing_session =
37584       GetTracingSession(consumer->tracing_session_id_);
37585   if (tracing_session) {
37586     PERFETTO_DLOG(
37587         "A Consumer is trying to EnableTracing() but another tracing session "
37588         "is already active (forgot a call to FreeBuffers() ?)");
37589     return false;
37590   }
37591 
37592   const uint32_t max_duration_ms = cfg.enable_extra_guardrails()
37593                                        ? kGuardrailsMaxTracingDurationMillis
37594                                        : kMaxTracingDurationMillis;
37595   if (cfg.duration_ms() > max_duration_ms) {
37596     PERFETTO_ELOG("Requested too long trace (%" PRIu32 "ms  > %" PRIu32 " ms)",
37597                   cfg.duration_ms(), max_duration_ms);
37598     return false;
37599   }
37600 
37601   const bool has_trigger_config = cfg.trigger_config().trigger_mode() !=
37602                                   TraceConfig::TriggerConfig::UNSPECIFIED;
37603   if (has_trigger_config && (cfg.trigger_config().trigger_timeout_ms() == 0 ||
37604                              cfg.trigger_config().trigger_timeout_ms() >
37605                                  kGuardrailsMaxTracingDurationMillis)) {
37606     PERFETTO_ELOG(
37607         "Traces with START_TRACING triggers must provide a positive "
37608         "trigger_timeout_ms < 7 days (received %" PRIu32 "ms)",
37609         cfg.trigger_config().trigger_timeout_ms());
37610     return false;
37611   }
37612 
37613   if (has_trigger_config && cfg.duration_ms() != 0) {
37614     PERFETTO_ELOG(
37615         "duration_ms was set, this must not be set for traces with triggers.");
37616     return false;
37617   }
37618 
37619   if (cfg.trigger_config().trigger_mode() ==
37620           TraceConfig::TriggerConfig::STOP_TRACING &&
37621       cfg.write_into_file()) {
37622     // We don't support this usecase because there are subtle assumptions which
37623     // break around TracingServiceEvents and windowed sorting (i.e. if we don't
37624     // drain the events in ReadBuffers because we are waiting for STOP_TRACING,
37625     // we can end up queueing up a lot of TracingServiceEvents and emitting them
37626     // wildy out of order breaking windowed sorting in trace processor).
37627     PERFETTO_ELOG(
37628         "Specifying trigger mode STOP_TRACING and write_into_file together is "
37629         "unsupported");
37630     return false;
37631   }
37632 
37633   std::unordered_set<std::string> triggers;
37634   for (const auto& trigger : cfg.trigger_config().triggers()) {
37635     if (!triggers.insert(trigger.name()).second) {
37636       PERFETTO_ELOG("Duplicate trigger name: %s", trigger.name().c_str());
37637       return false;
37638     }
37639   }
37640 
37641   if (cfg.enable_extra_guardrails()) {
37642     if (cfg.deferred_start()) {
37643       PERFETTO_ELOG(
37644           "deferred_start=true is not supported in unsupervised traces");
37645       return false;
37646     }
37647     uint64_t buf_size_sum = 0;
37648     for (const auto& buf : cfg.buffers()) {
37649       if (buf.size_kb() % 4 != 0) {
37650         PERFETTO_ELOG("buffers.size_kb must be a multiple of 4, got %" PRIu32,
37651                       buf.size_kb());
37652         return false;
37653       }
37654       buf_size_sum += buf.size_kb();
37655     }
37656     if (buf_size_sum > kGuardrailsMaxTracingBufferSizeKb) {
37657       PERFETTO_ELOG("Requested too large trace buffer (%" PRIu64
37658                     "kB  > %" PRIu32 " kB)",
37659                     buf_size_sum, kGuardrailsMaxTracingBufferSizeKb);
37660       return false;
37661     }
37662   }
37663 
37664   if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
37665     PERFETTO_ELOG("Too many buffers configured (%d)", cfg.buffers_size());
37666     return false;
37667   }
37668 
37669   if (!cfg.unique_session_name().empty()) {
37670     const std::string& name = cfg.unique_session_name();
37671     for (auto& kv : tracing_sessions_) {
37672       if (kv.second.config.unique_session_name() == name) {
37673         PERFETTO_ELOG(
37674             "A trace with this unique session name (%s) already exists",
37675             name.c_str());
37676         return false;
37677       }
37678     }
37679   }
37680 
37681   if (cfg.enable_extra_guardrails()) {
37682     // unique_session_name can be empty
37683     const std::string& name = cfg.unique_session_name();
37684     int64_t now_s = base::GetBootTimeS().count();
37685 
37686     // Remove any entries where the time limit has passed so this map doesn't
37687     // grow indefinitely:
37688     std::map<std::string, int64_t>& sessions = session_to_last_trace_s_;
37689     for (auto it = sessions.cbegin(); it != sessions.cend();) {
37690       if (now_s - it->second > kMinSecondsBetweenTracesGuardrail) {
37691         it = sessions.erase(it);
37692       } else {
37693         ++it;
37694       }
37695     }
37696 
37697     int64_t& previous_s = session_to_last_trace_s_[name];
37698     if (previous_s == 0) {
37699       previous_s = now_s;
37700     } else {
37701       PERFETTO_ELOG(
37702           "A trace with unique session name \"%s\" began less than %" PRId64
37703           "s ago (%" PRId64 "s)",
37704           name.c_str(), kMinSecondsBetweenTracesGuardrail, now_s - previous_s);
37705       return false;
37706     }
37707   }
37708 
37709   const long sessions_for_uid = std::count_if(
37710       tracing_sessions_.begin(), tracing_sessions_.end(),
37711       [consumer](const decltype(tracing_sessions_)::value_type& s) {
37712         return s.second.consumer_uid == consumer->uid_;
37713       });
37714 
37715   int per_uid_limit = kMaxConcurrentTracingSessionsPerUid;
37716   if (consumer->uid_ == 1066 /* AID_STATSD*/) {
37717     per_uid_limit = kMaxConcurrentTracingSessionsForStatsdUid;
37718   }
37719   if (sessions_for_uid >= per_uid_limit) {
37720     PERFETTO_ELOG(
37721         "Too many concurrent tracing sesions (%ld) for uid %d limit is %d",
37722         sessions_for_uid, static_cast<int>(consumer->uid_), per_uid_limit);
37723     return false;
37724   }
37725 
37726   // TODO(primiano): This is a workaround to prevent that a producer gets stuck
37727   // in a state where it stalls by design by having more TraceWriterImpl
37728   // instances than free pages in the buffer. This is really a bug in
37729   // trace_probes and the way it handles stalls in the shmem buffer.
37730   if (tracing_sessions_.size() >= kMaxConcurrentTracingSessions) {
37731     PERFETTO_ELOG("Too many concurrent tracing sesions (%zu)",
37732                   tracing_sessions_.size());
37733     return false;
37734   }
37735 
37736   const TracingSessionID tsid = ++last_tracing_session_id_;
37737   tracing_session =
37738       &tracing_sessions_.emplace(tsid, TracingSession(tsid, consumer, cfg))
37739            .first->second;
37740 
37741   if (cfg.write_into_file()) {
37742     if (!fd ^ !cfg.output_path().empty()) {
37743       PERFETTO_ELOG(
37744           "When write_into_file==true either a FD needs to be passed or "
37745           "output_path must be populated (but not both)");
37746       tracing_sessions_.erase(tsid);
37747       return false;
37748     }
37749     if (!cfg.output_path().empty()) {
37750       fd = CreateTraceFile(cfg.output_path());
37751       if (!fd) {
37752         tracing_sessions_.erase(tsid);
37753         return false;
37754       }
37755     }
37756     tracing_session->write_into_file = std::move(fd);
37757     uint32_t write_period_ms = cfg.file_write_period_ms();
37758     if (write_period_ms == 0)
37759       write_period_ms = kDefaultWriteIntoFilePeriodMs;
37760     if (write_period_ms < min_write_period_ms_)
37761       write_period_ms = min_write_period_ms_;
37762     tracing_session->write_period_ms = write_period_ms;
37763     tracing_session->max_file_size_bytes = cfg.max_file_size_bytes();
37764     tracing_session->bytes_written_into_file = 0;
37765   }
37766 
37767   // Initialize the log buffers.
37768   bool did_allocate_all_buffers = true;
37769 
37770   // Allocate the trace buffers. Also create a map to translate a consumer
37771   // relative index (TraceConfig.DataSourceConfig.target_buffer) into the
37772   // corresponding BufferID, which is a global ID namespace for the service and
37773   // all producers.
37774   size_t total_buf_size_kb = 0;
37775   const size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
37776   tracing_session->buffers_index.reserve(num_buffers);
37777   for (size_t i = 0; i < num_buffers; i++) {
37778     const TraceConfig::BufferConfig& buffer_cfg = cfg.buffers()[i];
37779     BufferID global_id = buffer_ids_.Allocate();
37780     if (!global_id) {
37781       did_allocate_all_buffers = false;  // We ran out of IDs.
37782       break;
37783     }
37784     tracing_session->buffers_index.push_back(global_id);
37785     const size_t buf_size_bytes = buffer_cfg.size_kb() * 1024u;
37786     total_buf_size_kb += buffer_cfg.size_kb();
37787     TraceBuffer::OverwritePolicy policy =
37788         buffer_cfg.fill_policy() == TraceConfig::BufferConfig::DISCARD
37789             ? TraceBuffer::kDiscard
37790             : TraceBuffer::kOverwrite;
37791     auto it_and_inserted = buffers_.emplace(
37792         global_id, TraceBuffer::Create(buf_size_bytes, policy));
37793     PERFETTO_DCHECK(it_and_inserted.second);  // buffers_.count(global_id) == 0.
37794     std::unique_ptr<TraceBuffer>& trace_buffer = it_and_inserted.first->second;
37795     if (!trace_buffer) {
37796       did_allocate_all_buffers = false;
37797       break;
37798     }
37799   }
37800 
37801   UpdateMemoryGuardrail();
37802 
37803   // This can happen if either:
37804   // - All the kMaxTraceBufferID slots are taken.
37805   // - OOM, or, more relistically, we exhausted virtual memory.
37806   // In any case, free all the previously allocated buffers and abort.
37807   // TODO(fmayer): add a test to cover this case, this is quite subtle.
37808   if (!did_allocate_all_buffers) {
37809     for (BufferID global_id : tracing_session->buffers_index) {
37810       buffer_ids_.Free(global_id);
37811       buffers_.erase(global_id);
37812     }
37813     tracing_sessions_.erase(tsid);
37814     return false;
37815   }
37816 
37817   consumer->tracing_session_id_ = tsid;
37818 
37819   // Setup the data sources on the producers without starting them.
37820   for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
37821     // Scan all the registered data sources with a matching name.
37822     auto range = data_sources_.equal_range(cfg_data_source.config().name());
37823     for (auto it = range.first; it != range.second; it++) {
37824       TraceConfig::ProducerConfig producer_config;
37825       for (auto& config : cfg.producers()) {
37826         if (GetProducer(it->second.producer_id)->name_ ==
37827             config.producer_name()) {
37828           producer_config = config;
37829           break;
37830         }
37831       }
37832       SetupDataSource(cfg_data_source, producer_config, it->second,
37833                       tracing_session);
37834     }
37835   }
37836 
37837   bool has_start_trigger = false;
37838   auto weak_this = weak_ptr_factory_.GetWeakPtr();
37839   switch (cfg.trigger_config().trigger_mode()) {
37840     case TraceConfig::TriggerConfig::UNSPECIFIED:
37841       // no triggers are specified so this isn't a trace that is using triggers.
37842       PERFETTO_DCHECK(!has_trigger_config);
37843       break;
37844     case TraceConfig::TriggerConfig::START_TRACING:
37845       // For traces which use START_TRACE triggers we need to ensure that the
37846       // tracing session will be cleaned up when it times out.
37847       has_start_trigger = true;
37848       task_runner_->PostDelayedTask(
37849           [weak_this, tsid]() {
37850             if (weak_this)
37851               weak_this->OnStartTriggersTimeout(tsid);
37852           },
37853           cfg.trigger_config().trigger_timeout_ms());
37854       break;
37855     case TraceConfig::TriggerConfig::STOP_TRACING:
37856       // Update the tracing_session's duration_ms to ensure that if no trigger
37857       // is received the session will end and be cleaned up equal to the
37858       // timeout.
37859       //
37860       // TODO(nuskos): Refactor this so that rather then modifying the config we
37861       // have a field we look at on the tracing_session.
37862       tracing_session->config.set_duration_ms(
37863           cfg.trigger_config().trigger_timeout_ms());
37864       break;
37865   }
37866 
37867   tracing_session->state = TracingSession::CONFIGURED;
37868   PERFETTO_LOG(
37869       "Configured tracing session %" PRIu64
37870       ", #sources:%zu, duration:%d ms, #buffers:%d, total "
37871       "buffer size:%zu KB, total sessions:%zu, uid:%d session name: \"%s\"",
37872       tsid, cfg.data_sources().size(), tracing_session->config.duration_ms(),
37873       cfg.buffers_size(), total_buf_size_kb, tracing_sessions_.size(),
37874       static_cast<unsigned int>(consumer->uid_),
37875       cfg.unique_session_name().c_str());
37876 
37877   // Start the data sources, unless this is a case of early setup + fast
37878   // triggering, either through TraceConfig.deferred_start or
37879   // TraceConfig.trigger_config(). If both are specified which ever one occurs
37880   // first will initiate the trace.
37881   if (!cfg.deferred_start() && !has_start_trigger)
37882     return StartTracing(tsid);
37883 
37884   return true;
37885 }
37886 
ChangeTraceConfig(ConsumerEndpointImpl * consumer,const TraceConfig & updated_cfg)37887 void TracingServiceImpl::ChangeTraceConfig(ConsumerEndpointImpl* consumer,
37888                                            const TraceConfig& updated_cfg) {
37889   PERFETTO_DCHECK_THREAD(thread_checker_);
37890   TracingSession* tracing_session =
37891       GetTracingSession(consumer->tracing_session_id_);
37892   PERFETTO_DCHECK(tracing_session);
37893 
37894   if ((tracing_session->state != TracingSession::STARTED) &&
37895       (tracing_session->state != TracingSession::CONFIGURED)) {
37896     PERFETTO_ELOG(
37897         "ChangeTraceConfig() was called for a tracing session which isn't "
37898         "running.");
37899     return;
37900   }
37901 
37902   // We only support updating producer_name_{,regex}_filter (and pass-through
37903   // configs) for now; null out any changeable fields and make sure the rest are
37904   // identical.
37905   TraceConfig new_config_copy(updated_cfg);
37906   for (auto& ds_cfg : *new_config_copy.mutable_data_sources()) {
37907     ds_cfg.clear_producer_name_filter();
37908     ds_cfg.clear_producer_name_regex_filter();
37909   }
37910 
37911   TraceConfig current_config_copy(tracing_session->config);
37912   for (auto& ds_cfg : *current_config_copy.mutable_data_sources()) {
37913     ds_cfg.clear_producer_name_filter();
37914     ds_cfg.clear_producer_name_regex_filter();
37915   }
37916 
37917   if (new_config_copy != current_config_copy) {
37918     PERFETTO_LOG(
37919         "ChangeTraceConfig() was called with a config containing unsupported "
37920         "changes; only adding to the producer_name_{,regex}_filter is "
37921         "currently supported and will have an effect.");
37922   }
37923 
37924   for (TraceConfig::DataSource& cfg_data_source :
37925        *tracing_session->config.mutable_data_sources()) {
37926     // Find the updated producer_filter in the new config.
37927     std::vector<std::string> new_producer_name_filter;
37928     std::vector<std::string> new_producer_name_regex_filter;
37929     bool found_data_source = false;
37930     for (auto it : updated_cfg.data_sources()) {
37931       if (cfg_data_source.config().name() == it.config().name()) {
37932         new_producer_name_filter = it.producer_name_filter();
37933         new_producer_name_regex_filter = it.producer_name_regex_filter();
37934         found_data_source = true;
37935         break;
37936       }
37937     }
37938 
37939     // Bail out if data source not present in the new config.
37940     if (!found_data_source) {
37941       PERFETTO_ELOG(
37942           "ChangeTraceConfig() called without a current data source also "
37943           "present in the new config: %s",
37944           cfg_data_source.config().name().c_str());
37945       continue;
37946     }
37947 
37948     // TODO(oysteine): Just replacing the filter means that if
37949     // there are any filter entries which were present in the original config,
37950     // but removed from the config passed to ChangeTraceConfig, any matching
37951     // producers will keep producing but newly added producers after this
37952     // point will never start.
37953     *cfg_data_source.mutable_producer_name_filter() = new_producer_name_filter;
37954     *cfg_data_source.mutable_producer_name_regex_filter() =
37955         new_producer_name_regex_filter;
37956 
37957     // Scan all the registered data sources with a matching name.
37958     auto range = data_sources_.equal_range(cfg_data_source.config().name());
37959     for (auto it = range.first; it != range.second; it++) {
37960       ProducerEndpointImpl* producer = GetProducer(it->second.producer_id);
37961       PERFETTO_DCHECK(producer);
37962 
37963       // Check if the producer name of this data source is present
37964       // in the name filters. We currently only support new filters, not
37965       // removing old ones.
37966       if (!NameMatchesFilter(producer->name_, new_producer_name_filter,
37967                              new_producer_name_regex_filter)) {
37968         continue;
37969       }
37970 
37971       bool already_setup = false;
37972       auto& ds_instances = tracing_session->data_source_instances;
37973       for (auto instance_it = ds_instances.begin();
37974            instance_it != ds_instances.end(); ++instance_it) {
37975         if (instance_it->first == it->second.producer_id &&
37976             instance_it->second.data_source_name ==
37977                 cfg_data_source.config().name()) {
37978           already_setup = true;
37979           break;
37980         }
37981       }
37982 
37983       if (already_setup)
37984         continue;
37985 
37986       // If it wasn't previously setup, set it up now.
37987       // (The per-producer config is optional).
37988       TraceConfig::ProducerConfig producer_config;
37989       for (auto& config : tracing_session->config.producers()) {
37990         if (producer->name_ == config.producer_name()) {
37991           producer_config = config;
37992           break;
37993         }
37994       }
37995 
37996       DataSourceInstance* ds_inst = SetupDataSource(
37997           cfg_data_source, producer_config, it->second, tracing_session);
37998 
37999       if (ds_inst && tracing_session->state == TracingSession::STARTED)
38000         StartDataSourceInstance(producer, tracing_session, ds_inst);
38001     }
38002   }
38003 }
38004 
StartTracing(TracingSessionID tsid)38005 bool TracingServiceImpl::StartTracing(TracingSessionID tsid) {
38006   PERFETTO_DCHECK_THREAD(thread_checker_);
38007   TracingSession* tracing_session = GetTracingSession(tsid);
38008   if (!tracing_session) {
38009     PERFETTO_DLOG("StartTracing() failed, invalid session ID %" PRIu64, tsid);
38010     return false;
38011   }
38012 
38013   if (tracing_session->state != TracingSession::CONFIGURED) {
38014     PERFETTO_DLOG("StartTracing() failed, invalid session state: %d",
38015                   tracing_session->state);
38016     return false;
38017   }
38018 
38019   tracing_session->state = TracingSession::STARTED;
38020 
38021   // We store the start of trace snapshot separately as it's important to make
38022   // sure we can interpret all the data in the trace and storing it in the ring
38023   // buffer means it could be overwritten by a later snapshot.
38024   if (!tracing_session->config.builtin_data_sources()
38025            .disable_clock_snapshotting()) {
38026     SnapshotClocks(&tracing_session->initial_clock_snapshot);
38027   }
38028 
38029   // We don't snapshot the clocks here because we just did this above.
38030   SnapshotLifecyleEvent(
38031       tracing_session,
38032       protos::pbzero::TracingServiceEvent::kTracingStartedFieldNumber,
38033       false /* snapshot_clocks */);
38034 
38035   // Periodically snapshot clocks, stats, sync markers while the trace is
38036   // active. The snapshots are emitted on the future ReadBuffers() calls, which
38037   // means that:
38038   //  (a) If we're streaming to a file (or to a consumer) while tracing, we
38039   //      write snapshots periodically into the trace.
38040   //  (b) If ReadBuffers() is only called after tracing ends, we emit the latest
38041   //      snapshot into the trace. For clock snapshots, we keep track of the
38042   //      snapshot recorded at the beginning of the session
38043   //      (initial_clock_snapshot above), as well as the most recent sampled
38044   //      snapshots that showed significant new drift between different clocks.
38045   //      The latter clock snapshots are sampled periodically and at lifecycle
38046   //      events.
38047   PeriodicSnapshotTask(tracing_session);
38048 
38049   // Trigger delayed task if the trace is time limited.
38050   const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
38051   if (trace_duration_ms > 0) {
38052     auto weak_this = weak_ptr_factory_.GetWeakPtr();
38053     task_runner_->PostDelayedTask(
38054         [weak_this, tsid] {
38055           // Skip entirely the flush if the trace session doesn't exist anymore.
38056           // This is to prevent misleading error messages to be logged.
38057           if (!weak_this)
38058             return;
38059           auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
38060           if (!tracing_session_ptr)
38061             return;
38062           // If this trace was using STOP_TRACING triggers and we've seen
38063           // one, then the trigger overrides the normal timeout. In this
38064           // case we just return and let the other task clean up this trace.
38065           if (tracing_session_ptr->config.trigger_config().trigger_mode() ==
38066                   TraceConfig::TriggerConfig::STOP_TRACING &&
38067               !tracing_session_ptr->received_triggers.empty())
38068             return;
38069           // In all other cases (START_TRACING or no triggers) we flush
38070           // after |trace_duration_ms| unconditionally.
38071           weak_this->FlushAndDisableTracing(tsid);
38072         },
38073         trace_duration_ms);
38074   }
38075 
38076   // Start the periodic drain tasks if we should to save the trace into a file.
38077   if (tracing_session->config.write_into_file()) {
38078     auto weak_this = weak_ptr_factory_.GetWeakPtr();
38079     task_runner_->PostDelayedTask(
38080         [weak_this, tsid] {
38081           if (weak_this)
38082             weak_this->ReadBuffers(tsid, nullptr);
38083         },
38084         tracing_session->delay_to_next_write_period_ms());
38085   }
38086 
38087   // Start the periodic flush tasks if the config specified a flush period.
38088   if (tracing_session->config.flush_period_ms())
38089     PeriodicFlushTask(tsid, /*post_next_only=*/true);
38090 
38091   // Start the periodic incremental state clear tasks if the config specified a
38092   // period.
38093   if (tracing_session->config.incremental_state_config().clear_period_ms()) {
38094     PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
38095   }
38096 
38097   for (auto& kv : tracing_session->data_source_instances) {
38098     ProducerID producer_id = kv.first;
38099     DataSourceInstance& data_source = kv.second;
38100     ProducerEndpointImpl* producer = GetProducer(producer_id);
38101     if (!producer) {
38102       PERFETTO_DFATAL("Producer does not exist.");
38103       continue;
38104     }
38105     StartDataSourceInstance(producer, tracing_session, &data_source);
38106   }
38107   return true;
38108 }
38109 
StartDataSourceInstance(ProducerEndpointImpl * producer,TracingSession * tracing_session,TracingServiceImpl::DataSourceInstance * instance)38110 void TracingServiceImpl::StartDataSourceInstance(
38111     ProducerEndpointImpl* producer,
38112     TracingSession* tracing_session,
38113     TracingServiceImpl::DataSourceInstance* instance) {
38114   PERFETTO_DCHECK(instance->state == DataSourceInstance::CONFIGURED);
38115   if (instance->will_notify_on_start) {
38116     instance->state = DataSourceInstance::STARTING;
38117   } else {
38118     instance->state = DataSourceInstance::STARTED;
38119   }
38120   if (tracing_session->consumer_maybe_null) {
38121     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
38122         *producer, *instance);
38123   }
38124   producer->StartDataSource(instance->instance_id, instance->config);
38125 
38126   // If all data sources are started, notify the consumer.
38127   if (instance->state == DataSourceInstance::STARTED)
38128     MaybeNotifyAllDataSourcesStarted(tracing_session);
38129 }
38130 
38131 // DisableTracing just stops the data sources but doesn't free up any buffer.
38132 // This is to allow the consumer to freeze the buffers (by stopping the trace)
38133 // and then drain the buffers. The actual teardown of the TracingSession happens
38134 // in FreeBuffers().
DisableTracing(TracingSessionID tsid,bool disable_immediately)38135 void TracingServiceImpl::DisableTracing(TracingSessionID tsid,
38136                                         bool disable_immediately) {
38137   PERFETTO_DCHECK_THREAD(thread_checker_);
38138   TracingSession* tracing_session = GetTracingSession(tsid);
38139   if (!tracing_session) {
38140     // Can happen if the consumer calls this before EnableTracing() or after
38141     // FreeBuffers().
38142     PERFETTO_DLOG("DisableTracing() failed, invalid session ID %" PRIu64, tsid);
38143     return;
38144   }
38145 
38146   switch (tracing_session->state) {
38147     // Spurious call to DisableTracing() while already disabled, nothing to do.
38148     case TracingSession::DISABLED:
38149       PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
38150       return;
38151 
38152     // This is either:
38153     // A) The case of a graceful DisableTracing() call followed by a call to
38154     //    FreeBuffers(), iff |disable_immediately| == true. In this case we want
38155     //    to forcefully transition in the disabled state without waiting for the
38156     //    outstanding acks because the buffers are going to be destroyed soon.
38157     // B) A spurious call, iff |disable_immediately| == false, in which case
38158     //    there is nothing to do.
38159     case TracingSession::DISABLING_WAITING_STOP_ACKS:
38160       PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
38161       if (disable_immediately)
38162         DisableTracingNotifyConsumerAndFlushFile(tracing_session);
38163       return;
38164 
38165     // Continues below.
38166     case TracingSession::CONFIGURED:
38167       // If the session didn't even start there is no need to orchestrate a
38168       // graceful stop of data sources.
38169       disable_immediately = true;
38170       break;
38171 
38172     // This is the nominal case, continues below.
38173     case TracingSession::STARTED:
38174       break;
38175   }
38176 
38177   for (auto& data_source_inst : tracing_session->data_source_instances) {
38178     const ProducerID producer_id = data_source_inst.first;
38179     DataSourceInstance& instance = data_source_inst.second;
38180     ProducerEndpointImpl* producer = GetProducer(producer_id);
38181     PERFETTO_DCHECK(producer);
38182     PERFETTO_DCHECK(instance.state == DataSourceInstance::CONFIGURED ||
38183                     instance.state == DataSourceInstance::STARTING ||
38184                     instance.state == DataSourceInstance::STARTED);
38185     StopDataSourceInstance(producer, tracing_session, &instance,
38186                            disable_immediately);
38187   }
38188 
38189   // Either this request is flagged with |disable_immediately| or there are no
38190   // data sources that are requesting a final handshake. In both cases just mark
38191   // the session as disabled immediately, notify the consumer and flush the
38192   // trace file (if used).
38193   if (tracing_session->AllDataSourceInstancesStopped())
38194     return DisableTracingNotifyConsumerAndFlushFile(tracing_session);
38195 
38196   tracing_session->state = TracingSession::DISABLING_WAITING_STOP_ACKS;
38197   auto weak_this = weak_ptr_factory_.GetWeakPtr();
38198   task_runner_->PostDelayedTask(
38199       [weak_this, tsid] {
38200         if (weak_this)
38201           weak_this->OnDisableTracingTimeout(tsid);
38202       },
38203       tracing_session->data_source_stop_timeout_ms());
38204 
38205   // Deliberately NOT removing the session from |tracing_session_|, it's still
38206   // needed to call ReadBuffers(). FreeBuffers() will erase() the session.
38207 }
38208 
NotifyDataSourceStarted(ProducerID producer_id,DataSourceInstanceID instance_id)38209 void TracingServiceImpl::NotifyDataSourceStarted(
38210     ProducerID producer_id,
38211     DataSourceInstanceID instance_id) {
38212   PERFETTO_DCHECK_THREAD(thread_checker_);
38213   for (auto& kv : tracing_sessions_) {
38214     TracingSession& tracing_session = kv.second;
38215     DataSourceInstance* instance =
38216         tracing_session.GetDataSourceInstance(producer_id, instance_id);
38217 
38218     if (!instance)
38219       continue;
38220 
38221     // If the tracing session was already stopped, ignore this notification.
38222     if (tracing_session.state != TracingSession::STARTED)
38223       continue;
38224 
38225     if (instance->state != DataSourceInstance::STARTING) {
38226       PERFETTO_ELOG("Started data source instance in incorrect state: %d",
38227                     instance->state);
38228       continue;
38229     }
38230 
38231     instance->state = DataSourceInstance::STARTED;
38232 
38233     ProducerEndpointImpl* producer = GetProducer(producer_id);
38234     PERFETTO_DCHECK(producer);
38235     if (tracing_session.consumer_maybe_null) {
38236       tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
38237           *producer, *instance);
38238     }
38239 
38240     // If all data sources are started, notify the consumer.
38241     MaybeNotifyAllDataSourcesStarted(&tracing_session);
38242   }  // for (tracing_session)
38243 }
38244 
MaybeNotifyAllDataSourcesStarted(TracingSession * tracing_session)38245 void TracingServiceImpl::MaybeNotifyAllDataSourcesStarted(
38246     TracingSession* tracing_session) {
38247   if (!tracing_session->consumer_maybe_null)
38248     return;
38249 
38250   if (!tracing_session->AllDataSourceInstancesStarted())
38251     return;
38252 
38253   // In some rare cases, we can get in this state more than once. Consider the
38254   // following scenario: 3 data sources are registered -> trace starts ->
38255   // all 3 data sources ack -> OnAllDataSourcesStarted() is called.
38256   // Imagine now that a 4th data source registers while the trace is ongoing.
38257   // This would hit the AllDataSourceInstancesStarted() condition again.
38258   // In this case, however, we don't want to re-notify the consumer again.
38259   // That would be unexpected (even if, perhaps, technically correct) and
38260   // trigger bugs in the consumer.
38261   if (tracing_session->did_notify_all_data_source_started)
38262     return;
38263 
38264   PERFETTO_DLOG("All data sources started");
38265 
38266   SnapshotLifecyleEvent(
38267       tracing_session,
38268       protos::pbzero::TracingServiceEvent::kAllDataSourcesStartedFieldNumber,
38269       true /* snapshot_clocks */);
38270 
38271   tracing_session->did_notify_all_data_source_started = true;
38272   tracing_session->consumer_maybe_null->OnAllDataSourcesStarted();
38273 }
38274 
NotifyDataSourceStopped(ProducerID producer_id,DataSourceInstanceID instance_id)38275 void TracingServiceImpl::NotifyDataSourceStopped(
38276     ProducerID producer_id,
38277     DataSourceInstanceID instance_id) {
38278   PERFETTO_DCHECK_THREAD(thread_checker_);
38279   for (auto& kv : tracing_sessions_) {
38280     TracingSession& tracing_session = kv.second;
38281     DataSourceInstance* instance =
38282         tracing_session.GetDataSourceInstance(producer_id, instance_id);
38283 
38284     if (!instance)
38285       continue;
38286 
38287     if (instance->state != DataSourceInstance::STOPPING) {
38288       PERFETTO_ELOG("Stopped data source instance in incorrect state: %d",
38289                     instance->state);
38290       continue;
38291     }
38292 
38293     instance->state = DataSourceInstance::STOPPED;
38294 
38295     ProducerEndpointImpl* producer = GetProducer(producer_id);
38296     PERFETTO_DCHECK(producer);
38297     if (tracing_session.consumer_maybe_null) {
38298       tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
38299           *producer, *instance);
38300     }
38301 
38302     if (!tracing_session.AllDataSourceInstancesStopped())
38303       continue;
38304 
38305     if (tracing_session.state != TracingSession::DISABLING_WAITING_STOP_ACKS)
38306       continue;
38307 
38308     // All data sources acked the termination.
38309     DisableTracingNotifyConsumerAndFlushFile(&tracing_session);
38310   }  // for (tracing_session)
38311 }
38312 
ActivateTriggers(ProducerID producer_id,const std::vector<std::string> & triggers)38313 void TracingServiceImpl::ActivateTriggers(
38314     ProducerID producer_id,
38315     const std::vector<std::string>& triggers) {
38316   PERFETTO_DCHECK_THREAD(thread_checker_);
38317   auto* producer = GetProducer(producer_id);
38318   PERFETTO_DCHECK(producer);
38319   for (const auto& trigger_name : triggers) {
38320     for (auto& id_and_tracing_session : tracing_sessions_) {
38321       auto& tracing_session = id_and_tracing_session.second;
38322       TracingSessionID tsid = id_and_tracing_session.first;
38323       auto iter = std::find_if(
38324           tracing_session.config.trigger_config().triggers().begin(),
38325           tracing_session.config.trigger_config().triggers().end(),
38326           [&trigger_name](const TraceConfig::TriggerConfig::Trigger& trigger) {
38327             return trigger.name() == trigger_name;
38328           });
38329       if (iter == tracing_session.config.trigger_config().triggers().end()) {
38330         continue;
38331       }
38332 
38333       // If this trigger requires a certain producer to have sent it
38334       // (non-empty producer_name()) ensure the producer who sent this trigger
38335       // matches.
38336       if (!iter->producer_name_regex().empty() &&
38337           !std::regex_match(
38338               producer->name_,
38339               std::regex(iter->producer_name_regex(), std::regex::extended))) {
38340         continue;
38341       }
38342 
38343       const bool triggers_already_received =
38344           !tracing_session.received_triggers.empty();
38345       tracing_session.received_triggers.push_back(
38346           {static_cast<uint64_t>(base::GetBootTimeNs().count()), iter->name(),
38347            producer->name_, producer->uid_});
38348       auto weak_this = weak_ptr_factory_.GetWeakPtr();
38349       switch (tracing_session.config.trigger_config().trigger_mode()) {
38350         case TraceConfig::TriggerConfig::START_TRACING:
38351           // If the session has already been triggered and moved past
38352           // CONFIGURED then we don't need to repeat StartTracing. This would
38353           // work fine (StartTracing would return false) but would add error
38354           // logs.
38355           if (tracing_session.state != TracingSession::CONFIGURED)
38356             break;
38357 
38358           PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
38359                         " with duration of %" PRIu32 "ms.",
38360                         iter->name().c_str(), tsid, iter->stop_delay_ms());
38361           // We override the trace duration to be the trigger's requested
38362           // value, this ensures that the trace will end after this amount
38363           // of time has passed.
38364           tracing_session.config.set_duration_ms(iter->stop_delay_ms());
38365           StartTracing(tsid);
38366           break;
38367         case TraceConfig::TriggerConfig::STOP_TRACING:
38368           // Only stop the trace once to avoid confusing log messages. I.E.
38369           // when we've already hit the first trigger we've already Posted the
38370           // task to FlushAndDisable. So all future triggers will just break
38371           // out.
38372           if (triggers_already_received)
38373             break;
38374 
38375           PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
38376                         " with duration of %" PRIu32 "ms.",
38377                         iter->name().c_str(), tsid, iter->stop_delay_ms());
38378           // Now that we've seen a trigger we need to stop, flush, and disable
38379           // this session after the configured |stop_delay_ms|.
38380           task_runner_->PostDelayedTask(
38381               [weak_this, tsid] {
38382                 // Skip entirely the flush if the trace session doesn't exist
38383                 // anymore. This is to prevent misleading error messages to be
38384                 // logged.
38385                 if (weak_this && weak_this->GetTracingSession(tsid))
38386                   weak_this->FlushAndDisableTracing(tsid);
38387               },
38388               // If this trigger is zero this will immediately executable and
38389               // will happen shortly.
38390               iter->stop_delay_ms());
38391           break;
38392         case TraceConfig::TriggerConfig::UNSPECIFIED:
38393           PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
38394           break;
38395       }
38396     }
38397   }
38398 }
38399 
38400 // Always invoked kDataSourceStopTimeoutMs after DisableTracing(). In nominal
38401 // conditions all data sources should have acked the stop and this will early
38402 // out.
OnDisableTracingTimeout(TracingSessionID tsid)38403 void TracingServiceImpl::OnDisableTracingTimeout(TracingSessionID tsid) {
38404   PERFETTO_DCHECK_THREAD(thread_checker_);
38405   TracingSession* tracing_session = GetTracingSession(tsid);
38406   if (!tracing_session ||
38407       tracing_session->state != TracingSession::DISABLING_WAITING_STOP_ACKS) {
38408     return;  // Tracing session was successfully disabled.
38409   }
38410 
38411   PERFETTO_ILOG("Timeout while waiting for ACKs for tracing session %" PRIu64,
38412                 tsid);
38413   PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
38414   DisableTracingNotifyConsumerAndFlushFile(tracing_session);
38415 }
38416 
DisableTracingNotifyConsumerAndFlushFile(TracingSession * tracing_session)38417 void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
38418     TracingSession* tracing_session) {
38419   PERFETTO_DCHECK(tracing_session->state != TracingSession::DISABLED);
38420   for (auto& inst_kv : tracing_session->data_source_instances) {
38421     if (inst_kv.second.state == DataSourceInstance::STOPPED)
38422       continue;
38423     inst_kv.second.state = DataSourceInstance::STOPPED;
38424     ProducerEndpointImpl* producer = GetProducer(inst_kv.first);
38425     PERFETTO_DCHECK(producer);
38426     if (tracing_session->consumer_maybe_null) {
38427       tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
38428           *producer, inst_kv.second);
38429     }
38430   }
38431   tracing_session->state = TracingSession::DISABLED;
38432 
38433   // Scrape any remaining chunks that weren't flushed by the producers.
38434   for (auto& producer_id_and_producer : producers_)
38435     ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
38436 
38437   SnapshotLifecyleEvent(
38438       tracing_session,
38439       protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
38440       true /* snapshot_clocks */);
38441 
38442   if (tracing_session->write_into_file) {
38443     tracing_session->write_period_ms = 0;
38444     ReadBuffers(tracing_session->id, nullptr);
38445   }
38446 
38447   if (tracing_session->consumer_maybe_null)
38448     tracing_session->consumer_maybe_null->NotifyOnTracingDisabled();
38449 }
38450 
Flush(TracingSessionID tsid,uint32_t timeout_ms,ConsumerEndpoint::FlushCallback callback)38451 void TracingServiceImpl::Flush(TracingSessionID tsid,
38452                                uint32_t timeout_ms,
38453                                ConsumerEndpoint::FlushCallback callback) {
38454   PERFETTO_DCHECK_THREAD(thread_checker_);
38455   TracingSession* tracing_session = GetTracingSession(tsid);
38456   if (!tracing_session) {
38457     PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
38458     return;
38459   }
38460 
38461   if (!timeout_ms)
38462     timeout_ms = tracing_session->flush_timeout_ms();
38463 
38464   if (tracing_session->pending_flushes.size() > 1000) {
38465     PERFETTO_ELOG("Too many flushes (%zu) pending for the tracing session",
38466                   tracing_session->pending_flushes.size());
38467     callback(false);
38468     return;
38469   }
38470 
38471   FlushRequestID flush_request_id = ++last_flush_request_id_;
38472   PendingFlush& pending_flush =
38473       tracing_session->pending_flushes
38474           .emplace_hint(tracing_session->pending_flushes.end(),
38475                         flush_request_id, PendingFlush(std::move(callback)))
38476           ->second;
38477 
38478   // Send a flush request to each producer involved in the tracing session. In
38479   // order to issue a flush request we have to build a map of all data source
38480   // instance ids enabled for each producer.
38481   std::map<ProducerID, std::vector<DataSourceInstanceID>> flush_map;
38482   for (const auto& data_source_inst : tracing_session->data_source_instances) {
38483     const ProducerID producer_id = data_source_inst.first;
38484     const DataSourceInstanceID ds_inst_id = data_source_inst.second.instance_id;
38485     flush_map[producer_id].push_back(ds_inst_id);
38486   }
38487 
38488   for (const auto& kv : flush_map) {
38489     ProducerID producer_id = kv.first;
38490     ProducerEndpointImpl* producer = GetProducer(producer_id);
38491     const std::vector<DataSourceInstanceID>& data_sources = kv.second;
38492     producer->Flush(flush_request_id, data_sources);
38493     pending_flush.producers.insert(producer_id);
38494   }
38495 
38496   // If there are no producers to flush (realistically this happens only in
38497   // some tests) fire OnFlushTimeout() straight away, without waiting.
38498   if (flush_map.empty())
38499     timeout_ms = 0;
38500 
38501   auto weak_this = weak_ptr_factory_.GetWeakPtr();
38502   task_runner_->PostDelayedTask(
38503       [weak_this, tsid, flush_request_id] {
38504         if (weak_this)
38505           weak_this->OnFlushTimeout(tsid, flush_request_id);
38506       },
38507       timeout_ms);
38508 }
38509 
NotifyFlushDoneForProducer(ProducerID producer_id,FlushRequestID flush_request_id)38510 void TracingServiceImpl::NotifyFlushDoneForProducer(
38511     ProducerID producer_id,
38512     FlushRequestID flush_request_id) {
38513   for (auto& kv : tracing_sessions_) {
38514     // Remove all pending flushes <= |flush_request_id| for |producer_id|.
38515     auto& pending_flushes = kv.second.pending_flushes;
38516     auto end_it = pending_flushes.upper_bound(flush_request_id);
38517     for (auto it = pending_flushes.begin(); it != end_it;) {
38518       PendingFlush& pending_flush = it->second;
38519       pending_flush.producers.erase(producer_id);
38520       if (pending_flush.producers.empty()) {
38521         auto weak_this = weak_ptr_factory_.GetWeakPtr();
38522         TracingSessionID tsid = kv.first;
38523         auto callback = std::move(pending_flush.callback);
38524         task_runner_->PostTask([weak_this, tsid, callback]() {
38525           if (weak_this) {
38526             weak_this->CompleteFlush(tsid, std::move(callback),
38527                                      /*success=*/true);
38528           }
38529         });
38530         it = pending_flushes.erase(it);
38531       } else {
38532         it++;
38533       }
38534     }  // for (pending_flushes)
38535   }    // for (tracing_session)
38536 }
38537 
OnFlushTimeout(TracingSessionID tsid,FlushRequestID flush_request_id)38538 void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
38539                                         FlushRequestID flush_request_id) {
38540   TracingSession* tracing_session = GetTracingSession(tsid);
38541   if (!tracing_session)
38542     return;
38543   auto it = tracing_session->pending_flushes.find(flush_request_id);
38544   if (it == tracing_session->pending_flushes.end())
38545     return;  // Nominal case: flush was completed and acked on time.
38546 
38547   // If there were no producers to flush, consider it a success.
38548   bool success = it->second.producers.empty();
38549 
38550   auto callback = std::move(it->second.callback);
38551   tracing_session->pending_flushes.erase(it);
38552   CompleteFlush(tsid, std::move(callback), success);
38553 }
38554 
CompleteFlush(TracingSessionID tsid,ConsumerEndpoint::FlushCallback callback,bool success)38555 void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
38556                                        ConsumerEndpoint::FlushCallback callback,
38557                                        bool success) {
38558   TracingSession* tracing_session = GetTracingSession(tsid);
38559   if (tracing_session) {
38560     // Producers may not have been able to flush all their data, even if they
38561     // indicated flush completion. If possible, also collect uncommitted chunks
38562     // to make sure we have everything they wrote so far.
38563     for (auto& producer_id_and_producer : producers_) {
38564       ScrapeSharedMemoryBuffers(tracing_session,
38565                                 producer_id_and_producer.second);
38566     }
38567   }
38568   SnapshotLifecyleEvent(
38569       tracing_session,
38570       protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
38571       true /* snapshot_clocks */);
38572   callback(success);
38573 }
38574 
ScrapeSharedMemoryBuffers(TracingSession * tracing_session,ProducerEndpointImpl * producer)38575 void TracingServiceImpl::ScrapeSharedMemoryBuffers(
38576     TracingSession* tracing_session,
38577     ProducerEndpointImpl* producer) {
38578   if (!producer->smb_scraping_enabled_)
38579     return;
38580 
38581   // Can't copy chunks if we don't know about any trace writers.
38582   if (producer->writers_.empty())
38583     return;
38584 
38585   // Performance optimization: On flush or session disconnect, this method is
38586   // called for each producer. If the producer doesn't participate in the
38587   // session, there's no need to scape its chunks right now. We can tell if a
38588   // producer participates in the session by checking if the producer is allowed
38589   // to write into the session's log buffers.
38590   const auto& session_buffers = tracing_session->buffers_index;
38591   bool producer_in_session =
38592       std::any_of(session_buffers.begin(), session_buffers.end(),
38593                   [producer](BufferID buffer_id) {
38594                     return producer->allowed_target_buffers_.count(buffer_id);
38595                   });
38596   if (!producer_in_session)
38597     return;
38598 
38599   PERFETTO_DLOG("Scraping SMB for producer %" PRIu16, producer->id_);
38600 
38601   // Find and copy any uncommitted chunks from the SMB.
38602   //
38603   // In nominal conditions, the page layout of the used SMB pages should never
38604   // change because the service is the only one who is supposed to modify used
38605   // pages (to make them free again).
38606   //
38607   // However, the code here needs to deal with the case of a malicious producer
38608   // altering the SMB in unpredictable ways. Thankfully the SMB size is
38609   // immutable, so a chunk will always point to some valid memory, even if the
38610   // producer alters the intended layout and chunk header concurrently.
38611   // Ultimately a malicious producer altering the SMB's chunk layout while we
38612   // are iterating in this function is not any different from the case of a
38613   // malicious producer asking to commit a chunk made of random data, which is
38614   // something this class has to deal with regardless.
38615   //
38616   // The only legitimate mutations that can happen from sane producers,
38617   // concurrently to this function, are:
38618   //   A. free pages being partitioned,
38619   //   B. free chunks being migrated to kChunkBeingWritten,
38620   //   C. kChunkBeingWritten chunks being migrated to kChunkCompleted.
38621 
38622   SharedMemoryABI* abi = &producer->shmem_abi_;
38623   // num_pages() is immutable after the SMB is initialized and cannot be changed
38624   // even by a producer even if malicious.
38625   for (size_t page_idx = 0; page_idx < abi->num_pages(); page_idx++) {
38626     uint32_t layout = abi->GetPageLayout(page_idx);
38627 
38628     uint32_t used_chunks = abi->GetUsedChunks(layout);  // Returns a bitmap.
38629     // Skip empty pages.
38630     if (used_chunks == 0)
38631       continue;
38632 
38633     // Scrape the chunks that are currently used. These should be either in
38634     // state kChunkBeingWritten or kChunkComplete.
38635     for (uint32_t chunk_idx = 0; used_chunks; chunk_idx++, used_chunks >>= 1) {
38636       if (!(used_chunks & 1))
38637         continue;
38638 
38639       SharedMemoryABI::ChunkState state =
38640           SharedMemoryABI::GetChunkStateFromLayout(layout, chunk_idx);
38641       PERFETTO_DCHECK(state == SharedMemoryABI::kChunkBeingWritten ||
38642                       state == SharedMemoryABI::kChunkComplete);
38643       bool chunk_complete = state == SharedMemoryABI::kChunkComplete;
38644 
38645       SharedMemoryABI::Chunk chunk =
38646           abi->GetChunkUnchecked(page_idx, layout, chunk_idx);
38647 
38648       uint16_t packet_count;
38649       uint8_t flags;
38650       // GetPacketCountAndFlags has acquire_load semantics.
38651       std::tie(packet_count, flags) = chunk.GetPacketCountAndFlags();
38652 
38653       // It only makes sense to copy an incomplete chunk if there's at least
38654       // one full packet available. (The producer may not have completed the
38655       // last packet in it yet, so we need at least 2.)
38656       if (!chunk_complete && packet_count < 2)
38657         continue;
38658 
38659       // At this point, it is safe to access the remaining header fields of
38660       // the chunk. Even if the chunk was only just transferred from
38661       // kChunkFree into kChunkBeingWritten state, the header should be
38662       // written completely once the packet count increased above 1 (it was
38663       // reset to 0 by the service when the chunk was freed).
38664 
38665       WriterID writer_id = chunk.writer_id();
38666       base::Optional<BufferID> target_buffer_id =
38667           producer->buffer_id_for_writer(writer_id);
38668 
38669       // We can only scrape this chunk if we know which log buffer to copy it
38670       // into.
38671       if (!target_buffer_id)
38672         continue;
38673 
38674       // Skip chunks that don't belong to the requested tracing session.
38675       bool target_buffer_belongs_to_session =
38676           std::find(session_buffers.begin(), session_buffers.end(),
38677                     *target_buffer_id) != session_buffers.end();
38678       if (!target_buffer_belongs_to_session)
38679         continue;
38680 
38681       uint32_t chunk_id =
38682           chunk.header()->chunk_id.load(std::memory_order_relaxed);
38683 
38684       CopyProducerPageIntoLogBuffer(
38685           producer->id_, producer->uid_, writer_id, chunk_id, *target_buffer_id,
38686           packet_count, flags, chunk_complete, chunk.payload_begin(),
38687           chunk.payload_size());
38688     }
38689   }
38690 }
38691 
FlushAndDisableTracing(TracingSessionID tsid)38692 void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
38693   PERFETTO_DCHECK_THREAD(thread_checker_);
38694   PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
38695   auto weak_this = weak_ptr_factory_.GetWeakPtr();
38696   Flush(tsid, 0, [weak_this, tsid](bool success) {
38697     PERFETTO_DLOG("Flush done (success: %d), disabling trace session %" PRIu64,
38698                   success, tsid);
38699     if (!weak_this)
38700       return;
38701     TracingSession* session = weak_this->GetTracingSession(tsid);
38702     if (session->consumer_maybe_null) {
38703       // If the consumer is still attached, just disable the session but give it
38704       // a chance to read the contents.
38705       weak_this->DisableTracing(tsid);
38706     } else {
38707       // If the consumer detached, destroy the session. If the consumer did
38708       // start the session in long-tracing mode, the service will have saved
38709       // the contents to the passed file. If not, the contents will be
38710       // destroyed.
38711       weak_this->FreeBuffers(tsid);
38712     }
38713   });
38714 }
38715 
PeriodicFlushTask(TracingSessionID tsid,bool post_next_only)38716 void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
38717                                            bool post_next_only) {
38718   PERFETTO_DCHECK_THREAD(thread_checker_);
38719   TracingSession* tracing_session = GetTracingSession(tsid);
38720   if (!tracing_session || tracing_session->state != TracingSession::STARTED)
38721     return;
38722 
38723   uint32_t flush_period_ms = tracing_session->config.flush_period_ms();
38724   auto weak_this = weak_ptr_factory_.GetWeakPtr();
38725   task_runner_->PostDelayedTask(
38726       [weak_this, tsid] {
38727         if (weak_this)
38728           weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
38729       },
38730       flush_period_ms - (base::GetWallTimeMs().count() % flush_period_ms));
38731 
38732   if (post_next_only)
38733     return;
38734 
38735   PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
38736   Flush(tsid, 0, [](bool success) {
38737     if (!success)
38738       PERFETTO_ELOG("Periodic flush timed out");
38739   });
38740 }
38741 
PeriodicClearIncrementalStateTask(TracingSessionID tsid,bool post_next_only)38742 void TracingServiceImpl::PeriodicClearIncrementalStateTask(
38743     TracingSessionID tsid,
38744     bool post_next_only) {
38745   PERFETTO_DCHECK_THREAD(thread_checker_);
38746   TracingSession* tracing_session = GetTracingSession(tsid);
38747   if (!tracing_session || tracing_session->state != TracingSession::STARTED)
38748     return;
38749 
38750   uint32_t clear_period_ms =
38751       tracing_session->config.incremental_state_config().clear_period_ms();
38752   auto weak_this = weak_ptr_factory_.GetWeakPtr();
38753   task_runner_->PostDelayedTask(
38754       [weak_this, tsid] {
38755         if (weak_this)
38756           weak_this->PeriodicClearIncrementalStateTask(
38757               tsid, /*post_next_only=*/false);
38758       },
38759       clear_period_ms - (base::GetWallTimeMs().count() % clear_period_ms));
38760 
38761   if (post_next_only)
38762     return;
38763 
38764   PERFETTO_DLOG(
38765       "Performing periodic incremental state clear for trace session %" PRIu64,
38766       tsid);
38767 
38768   // Queue the IPCs to producers with active data sources that opted in.
38769   std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
38770   for (const auto& kv : tracing_session->data_source_instances) {
38771     ProducerID producer_id = kv.first;
38772     const DataSourceInstance& data_source = kv.second;
38773     if (data_source.handles_incremental_state_clear)
38774       clear_map[producer_id].push_back(data_source.instance_id);
38775   }
38776 
38777   for (const auto& kv : clear_map) {
38778     ProducerID producer_id = kv.first;
38779     const std::vector<DataSourceInstanceID>& data_sources = kv.second;
38780     ProducerEndpointImpl* producer = GetProducer(producer_id);
38781     if (!producer) {
38782       PERFETTO_DFATAL("Producer does not exist.");
38783       continue;
38784     }
38785     producer->ClearIncrementalState(data_sources);
38786   }
38787 }
38788 
38789 // Note: when this is called to write into a file passed when starting tracing
38790 // |consumer| will be == nullptr (as opposite to the case of a consumer asking
38791 // to send the trace data back over IPC).
ReadBuffers(TracingSessionID tsid,ConsumerEndpointImpl * consumer)38792 bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
38793                                      ConsumerEndpointImpl* consumer) {
38794   PERFETTO_DCHECK_THREAD(thread_checker_);
38795   TracingSession* tracing_session = GetTracingSession(tsid);
38796   if (!tracing_session) {
38797     // This will be hit systematically from the PostDelayedTask when directly
38798     // writing into the file (in which case consumer == nullptr). Suppress the
38799     // log in this case as it's just spam.
38800     if (consumer) {
38801       PERFETTO_DLOG("Cannot ReadBuffers(): no tracing session is active");
38802     }
38803     return false;
38804   }
38805 
38806   // When a tracing session is waiting for a trigger it is considered empty. If
38807   // a tracing session finishes and moves into DISABLED without ever receiving a
38808   // trigger the trace should never return any data. This includes the synthetic
38809   // packets like TraceConfig and Clock snapshots. So we bail out early and let
38810   // the consumer know there is no data.
38811   if (!tracing_session->config.trigger_config().triggers().empty() &&
38812       tracing_session->received_triggers.empty()) {
38813     PERFETTO_DLOG(
38814         "ReadBuffers(): tracing session has not received a trigger yet.");
38815     return false;
38816   }
38817 
38818   // This can happen if the file is closed by a previous task because it reaches
38819   // |max_file_size_bytes|.
38820   if (!tracing_session->write_into_file && !consumer)
38821     return false;
38822 
38823   if (tracing_session->write_into_file && consumer) {
38824     // If the consumer enabled tracing and asked to save the contents into the
38825     // passed file makes little sense to also try to read the buffers over IPC,
38826     // as that would just steal data from the periodic draining task.
38827     PERFETTO_DFATAL("Consumer trying to read from write_into_file session.");
38828     return false;
38829   }
38830 
38831   std::vector<TracePacket> packets;
38832   packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.
38833 
38834   if (!tracing_session->initial_clock_snapshot.empty()) {
38835     EmitClockSnapshot(tracing_session,
38836                       std::move(tracing_session->initial_clock_snapshot),
38837                       &packets);
38838   }
38839 
38840   for (auto& snapshot : tracing_session->clock_snapshot_ring_buffer) {
38841     PERFETTO_DCHECK(!snapshot.empty());
38842     EmitClockSnapshot(tracing_session, std::move(snapshot), &packets);
38843   }
38844   tracing_session->clock_snapshot_ring_buffer.clear();
38845 
38846   if (tracing_session->should_emit_sync_marker) {
38847     EmitSyncMarker(&packets);
38848     tracing_session->should_emit_sync_marker = false;
38849   }
38850 
38851   if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
38852     MaybeEmitTraceConfig(tracing_session, &packets);
38853     MaybeEmitReceivedTriggers(tracing_session, &packets);
38854   }
38855   if (!tracing_session->config.builtin_data_sources().disable_system_info())
38856     MaybeEmitSystemInfo(tracing_session, &packets);
38857 
38858   // Note that in the proto comment, we guarantee that the tracing_started
38859   // lifecycle event will be emitted before any data packets so make sure to
38860   // keep this before reading the tracing buffers.
38861   if (!tracing_session->config.builtin_data_sources().disable_service_events())
38862     EmitLifecycleEvents(tracing_session, &packets);
38863 
38864   size_t packets_bytes = 0;  // SUM(slice.size() for each slice in |packets|).
38865   size_t total_slices = 0;   // SUM(#slices in |packets|).
38866 
38867   // Add up size for packets added by the Maybe* calls above.
38868   for (const TracePacket& packet : packets) {
38869     packets_bytes += packet.size();
38870     total_slices += packet.slices().size();
38871   }
38872 
38873   // This is a rough threshold to determine how much to read from the buffer in
38874   // each task. This is to avoid executing a single huge sending task for too
38875   // long and risk to hit the watchdog. This is *not* an upper bound: we just
38876   // stop accumulating new packets and PostTask *after* we cross this threshold.
38877   // This constant essentially balances the PostTask and IPC overhead vs the
38878   // responsiveness of the service. An extremely small value will cause one IPC
38879   // and one PostTask for each slice but will keep the service extremely
38880   // responsive. An extremely large value will batch the send for the full
38881   // buffer in one large task, will hit the blocking send() once the socket
38882   // buffers are full and hang the service for a bit (until the consumer
38883   // catches up).
38884   static constexpr size_t kApproxBytesPerTask = 32768;
38885   bool did_hit_threshold = false;
38886 
38887   // TODO(primiano): Extend the ReadBuffers API to allow reading only some
38888   // buffers, not all of them in one go.
38889   for (size_t buf_idx = 0;
38890        buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
38891        buf_idx++) {
38892     auto tbuf_iter = buffers_.find(tracing_session->buffers_index[buf_idx]);
38893     if (tbuf_iter == buffers_.end()) {
38894       PERFETTO_DFATAL("Buffer not found.");
38895       continue;
38896     }
38897     TraceBuffer& tbuf = *tbuf_iter->second;
38898     tbuf.BeginRead();
38899     while (!did_hit_threshold) {
38900       TracePacket packet;
38901       TraceBuffer::PacketSequenceProperties sequence_properties{};
38902       bool previous_packet_dropped;
38903       if (!tbuf.ReadNextTracePacket(&packet, &sequence_properties,
38904                                     &previous_packet_dropped)) {
38905         break;
38906       }
38907       PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
38908       PERFETTO_DCHECK(sequence_properties.writer_id != 0);
38909       PERFETTO_DCHECK(sequence_properties.producer_uid_trusted != kInvalidUid);
38910       PERFETTO_DCHECK(packet.size() > 0);
38911       if (!PacketStreamValidator::Validate(packet.slices())) {
38912         tracing_session->invalid_packets++;
38913         PERFETTO_DLOG("Dropping invalid packet");
38914         continue;
38915       }
38916 
38917       // Append a slice with the trusted field data. This can't be spoofed
38918       // because above we validated that the existing slices don't contain any
38919       // trusted fields. For added safety we append instead of prepending
38920       // because according to protobuf semantics, if the same field is
38921       // encountered multiple times the last instance takes priority. Note that
38922       // truncated packets are also rejected, so the producer can't give us a
38923       // partial packet (e.g., a truncated string) which only becomes valid when
38924       // the trusted data is appended here.
38925       Slice slice = Slice::Allocate(32);
38926       protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
38927           slice.own_data(), slice.size);
38928       trusted_packet->set_trusted_uid(
38929           static_cast<int32_t>(sequence_properties.producer_uid_trusted));
38930       trusted_packet->set_trusted_packet_sequence_id(
38931           tracing_session->GetPacketSequenceID(
38932               sequence_properties.producer_id_trusted,
38933               sequence_properties.writer_id));
38934       if (previous_packet_dropped)
38935         trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
38936       slice.size = trusted_packet.Finalize();
38937       packet.AddSlice(std::move(slice));
38938 
38939       // Append the packet (inclusive of the trusted uid) to |packets|.
38940       packets_bytes += packet.size();
38941       total_slices += packet.slices().size();
38942       did_hit_threshold = packets_bytes >= kApproxBytesPerTask &&
38943                           !tracing_session->write_into_file;
38944       packets.emplace_back(std::move(packet));
38945     }  // for(packets...)
38946   }    // for(buffers...)
38947 
38948   const bool has_more = did_hit_threshold;
38949 
38950   size_t prev_packets_size = packets.size();
38951   if (!tracing_session->config.builtin_data_sources()
38952            .disable_service_events()) {
38953     // We don't bother snapshotting clocks here because we wouldn't be able to
38954     // emit it and we shouldn't have significant drift from the last snapshot in
38955     // any case.
38956     SnapshotLifecyleEvent(tracing_session,
38957                           protos::pbzero::TracingServiceEvent::
38958                               kReadTracingBuffersCompletedFieldNumber,
38959                           false /* snapshot_clocks */);
38960     EmitLifecycleEvents(tracing_session, &packets);
38961   }
38962 
38963   // Only emit the stats when there is no more trace data is available to read.
38964   // That way, any problems that occur while reading from the buffers are
38965   // reflected in the emitted stats. This is particularly important for use
38966   // cases where ReadBuffers is only ever called after the tracing session is
38967   // stopped.
38968   if (!has_more && tracing_session->should_emit_stats) {
38969     EmitStats(tracing_session, &packets);
38970     tracing_session->should_emit_stats = false;
38971   }
38972 
38973   // Add sizes of packets emitted by the EmitLifecycleEvents + EmitStats.
38974   for (size_t i = prev_packets_size; i < packets.size(); ++i) {
38975     packets_bytes += packets[i].size();
38976     total_slices += packets[i].slices().size();
38977   }
38978 
38979   // If the caller asked us to write into a file by setting
38980   // |write_into_file| == true in the trace config, drain the packets read
38981   // (if any) into the given file descriptor.
38982   if (tracing_session->write_into_file) {
38983     const uint64_t max_size = tracing_session->max_file_size_bytes
38984                                   ? tracing_session->max_file_size_bytes
38985                                   : std::numeric_limits<size_t>::max();
38986 
38987     // When writing into a file, the file should look like a root trace.proto
38988     // message. Each packet should be prepended with a proto preamble stating
38989     // its field id (within trace.proto) and size. Hence the addition below.
38990     const size_t max_iovecs = total_slices + packets.size();
38991 
38992     size_t num_iovecs = 0;
38993     bool stop_writing_into_file = tracing_session->write_period_ms == 0;
38994     std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
38995     size_t num_iovecs_at_last_packet = 0;
38996     uint64_t bytes_about_to_be_written = 0;
38997     for (TracePacket& packet : packets) {
38998       std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
38999           packet.GetProtoPreamble();
39000       bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
39001       num_iovecs++;
39002       for (const Slice& slice : packet.slices()) {
39003         // writev() doesn't change the passed pointer. However, struct iovec
39004         // take a non-const ptr because it's the same struct used by readv().
39005         // Hence the const_cast here.
39006         char* start = static_cast<char*>(const_cast<void*>(slice.start));
39007         bytes_about_to_be_written += slice.size;
39008         iovecs[num_iovecs++] = {start, slice.size};
39009       }
39010 
39011       if (tracing_session->bytes_written_into_file +
39012               bytes_about_to_be_written >=
39013           max_size) {
39014         stop_writing_into_file = true;
39015         num_iovecs = num_iovecs_at_last_packet;
39016         break;
39017       }
39018 
39019       num_iovecs_at_last_packet = num_iovecs;
39020     }
39021     PERFETTO_DCHECK(num_iovecs <= max_iovecs);
39022     int fd = *tracing_session->write_into_file;
39023 
39024     uint64_t total_wr_size = 0;
39025 
39026     // writev() can take at most IOV_MAX entries per call. Batch them.
39027     constexpr size_t kIOVMax = IOV_MAX;
39028     for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
39029       int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
39030       ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
39031       if (wr_size <= 0) {
39032         PERFETTO_PLOG("writev() failed");
39033         stop_writing_into_file = true;
39034         break;
39035       }
39036       total_wr_size += static_cast<size_t>(wr_size);
39037     }
39038 
39039     tracing_session->bytes_written_into_file += total_wr_size;
39040 
39041     PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
39042                   (total_wr_size + 1023) / 1024, stop_writing_into_file);
39043     if (stop_writing_into_file) {
39044       // Ensure all data was written to the file before we close it.
39045       base::FlushFile(fd);
39046       tracing_session->write_into_file.reset();
39047       tracing_session->write_period_ms = 0;
39048       if (tracing_session->state == TracingSession::STARTED)
39049         DisableTracing(tsid);
39050       return true;
39051     }
39052 
39053     auto weak_this = weak_ptr_factory_.GetWeakPtr();
39054     task_runner_->PostDelayedTask(
39055         [weak_this, tsid] {
39056           if (weak_this)
39057             weak_this->ReadBuffers(tsid, nullptr);
39058         },
39059         tracing_session->delay_to_next_write_period_ms());
39060     return true;
39061   }  // if (tracing_session->write_into_file)
39062 
39063   if (has_more) {
39064     auto weak_consumer = consumer->GetWeakPtr();
39065     auto weak_this = weak_ptr_factory_.GetWeakPtr();
39066     task_runner_->PostTask([weak_this, weak_consumer, tsid] {
39067       if (!weak_this || !weak_consumer)
39068         return;
39069       weak_this->ReadBuffers(tsid, weak_consumer.get());
39070     });
39071   }
39072 
39073   // Keep this as tail call, just in case the consumer re-enters.
39074   consumer->consumer_->OnTraceData(std::move(packets), has_more);
39075   return true;
39076 }
39077 
FreeBuffers(TracingSessionID tsid)39078 void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
39079   PERFETTO_DCHECK_THREAD(thread_checker_);
39080   PERFETTO_DLOG("Freeing buffers for session %" PRIu64, tsid);
39081   TracingSession* tracing_session = GetTracingSession(tsid);
39082   if (!tracing_session) {
39083     PERFETTO_DLOG("FreeBuffers() failed, invalid session ID %" PRIu64, tsid);
39084     return;  // TODO(primiano): signal failure?
39085   }
39086   DisableTracing(tsid, /*disable_immediately=*/true);
39087 
39088   PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
39089   tracing_session->data_source_instances.clear();
39090 
39091   for (auto& producer_entry : producers_) {
39092     ProducerEndpointImpl* producer = producer_entry.second;
39093     producer->OnFreeBuffers(tracing_session->buffers_index);
39094   }
39095 
39096   for (BufferID buffer_id : tracing_session->buffers_index) {
39097     buffer_ids_.Free(buffer_id);
39098     PERFETTO_DCHECK(buffers_.count(buffer_id) == 1);
39099     buffers_.erase(buffer_id);
39100   }
39101   bool notify_traceur = tracing_session->config.notify_traceur();
39102   tracing_sessions_.erase(tsid);
39103   UpdateMemoryGuardrail();
39104 
39105   PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
39106                tracing_sessions_.size());
39107 
39108 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
39109   static const char kTraceurProp[] = "sys.trace.trace_end_signal";
39110   if (notify_traceur && __system_property_set(kTraceurProp, "1"))
39111     PERFETTO_ELOG("Failed to setprop %s=1", kTraceurProp);
39112 #else
39113   base::ignore_result(notify_traceur);
39114 #endif
39115 }
39116 
RegisterDataSource(ProducerID producer_id,const DataSourceDescriptor & desc)39117 void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
39118                                             const DataSourceDescriptor& desc) {
39119   PERFETTO_DCHECK_THREAD(thread_checker_);
39120   PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
39121                 producer_id, desc.name().c_str());
39122 
39123   PERFETTO_DCHECK(!desc.name().empty());
39124   auto reg_ds = data_sources_.emplace(desc.name(),
39125                                       RegisteredDataSource{producer_id, desc});
39126 
39127   // If there are existing tracing sessions, we need to check if the new
39128   // data source is enabled by any of them.
39129   if (tracing_sessions_.empty())
39130     return;
39131 
39132   ProducerEndpointImpl* producer = GetProducer(producer_id);
39133   if (!producer) {
39134     PERFETTO_DFATAL("Producer not found.");
39135     return;
39136   }
39137 
39138   for (auto& iter : tracing_sessions_) {
39139     TracingSession& tracing_session = iter.second;
39140     if (tracing_session.state != TracingSession::STARTED &&
39141         tracing_session.state != TracingSession::CONFIGURED) {
39142       continue;
39143     }
39144 
39145     TraceConfig::ProducerConfig producer_config;
39146     for (auto& config : tracing_session.config.producers()) {
39147       if (producer->name_ == config.producer_name()) {
39148         producer_config = config;
39149         break;
39150       }
39151     }
39152     for (const TraceConfig::DataSource& cfg_data_source :
39153          tracing_session.config.data_sources()) {
39154       if (cfg_data_source.config().name() != desc.name())
39155         continue;
39156       DataSourceInstance* ds_inst = SetupDataSource(
39157           cfg_data_source, producer_config, reg_ds->second, &tracing_session);
39158       if (ds_inst && tracing_session.state == TracingSession::STARTED)
39159         StartDataSourceInstance(producer, &tracing_session, ds_inst);
39160     }
39161   }
39162 }
39163 
StopDataSourceInstance(ProducerEndpointImpl * producer,TracingSession * tracing_session,DataSourceInstance * instance,bool disable_immediately)39164 void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
39165                                                 TracingSession* tracing_session,
39166                                                 DataSourceInstance* instance,
39167                                                 bool disable_immediately) {
39168   const DataSourceInstanceID ds_inst_id = instance->instance_id;
39169   if (instance->will_notify_on_stop && !disable_immediately) {
39170     instance->state = DataSourceInstance::STOPPING;
39171   } else {
39172     instance->state = DataSourceInstance::STOPPED;
39173   }
39174   if (tracing_session->consumer_maybe_null) {
39175     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
39176         *producer, *instance);
39177   }
39178   producer->StopDataSource(ds_inst_id);
39179 }
39180 
UnregisterDataSource(ProducerID producer_id,const std::string & name)39181 void TracingServiceImpl::UnregisterDataSource(ProducerID producer_id,
39182                                               const std::string& name) {
39183   PERFETTO_DCHECK_THREAD(thread_checker_);
39184   PERFETTO_DLOG("Producer %" PRIu16 " unregistered data source \"%s\"",
39185                 producer_id, name.c_str());
39186   PERFETTO_CHECK(producer_id);
39187   ProducerEndpointImpl* producer = GetProducer(producer_id);
39188   PERFETTO_DCHECK(producer);
39189   for (auto& kv : tracing_sessions_) {
39190     auto& ds_instances = kv.second.data_source_instances;
39191     bool removed = false;
39192     for (auto it = ds_instances.begin(); it != ds_instances.end();) {
39193       if (it->first == producer_id && it->second.data_source_name == name) {
39194         DataSourceInstanceID ds_inst_id = it->second.instance_id;
39195         if (it->second.state != DataSourceInstance::STOPPED) {
39196           if (it->second.state != DataSourceInstance::STOPPING)
39197             StopDataSourceInstance(producer, &kv.second, &it->second,
39198                                    /* disable_immediately = */ false);
39199           // Mark the instance as stopped immediately, since we are
39200           // unregistering it below.
39201           if (it->second.state == DataSourceInstance::STOPPING)
39202             NotifyDataSourceStopped(producer_id, ds_inst_id);
39203         }
39204         it = ds_instances.erase(it);
39205         removed = true;
39206       } else {
39207         ++it;
39208       }
39209     }  // for (data_source_instances)
39210     if (removed)
39211       MaybeNotifyAllDataSourcesStarted(&kv.second);
39212   }  // for (tracing_session)
39213 
39214   for (auto it = data_sources_.begin(); it != data_sources_.end(); ++it) {
39215     if (it->second.producer_id == producer_id &&
39216         it->second.descriptor.name() == name) {
39217       data_sources_.erase(it);
39218       return;
39219     }
39220   }
39221 
39222   PERFETTO_DFATAL(
39223       "Tried to unregister a non-existent data source \"%s\" for "
39224       "producer %" PRIu16,
39225       name.c_str(), producer_id);
39226 }
39227 
SetupDataSource(const TraceConfig::DataSource & cfg_data_source,const TraceConfig::ProducerConfig & producer_config,const RegisteredDataSource & data_source,TracingSession * tracing_session)39228 TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
39229     const TraceConfig::DataSource& cfg_data_source,
39230     const TraceConfig::ProducerConfig& producer_config,
39231     const RegisteredDataSource& data_source,
39232     TracingSession* tracing_session) {
39233   PERFETTO_DCHECK_THREAD(thread_checker_);
39234   ProducerEndpointImpl* producer = GetProducer(data_source.producer_id);
39235   PERFETTO_DCHECK(producer);
39236   // An existing producer that is not ftrace could have registered itself as
39237   // ftrace, we must not enable it in that case.
39238   if (lockdown_mode_ && producer->uid_ != uid_) {
39239     PERFETTO_DLOG("Lockdown mode: not enabling producer %hu", producer->id_);
39240     return nullptr;
39241   }
39242   // TODO(primiano): Add tests for registration ordering (data sources vs
39243   // consumers).
39244   if (!NameMatchesFilter(producer->name_,
39245                          cfg_data_source.producer_name_filter(),
39246                          cfg_data_source.producer_name_regex_filter())) {
39247     PERFETTO_DLOG("Data source: %s is filtered out for producer: %s",
39248                   cfg_data_source.config().name().c_str(),
39249                   producer->name_.c_str());
39250     return nullptr;
39251   }
39252 
39253   auto relative_buffer_id = cfg_data_source.config().target_buffer();
39254   if (relative_buffer_id >= tracing_session->num_buffers()) {
39255     PERFETTO_LOG(
39256         "The TraceConfig for DataSource %s specified a target_buffer out of "
39257         "bound (%d). Skipping it.",
39258         cfg_data_source.config().name().c_str(), relative_buffer_id);
39259     return nullptr;
39260   }
39261 
39262   // Create a copy of the DataSourceConfig specified in the trace config. This
39263   // will be passed to the producer after translating the |target_buffer| id.
39264   // The |target_buffer| parameter passed by the consumer in the trace config is
39265   // relative to the buffers declared in the same trace config. This has to be
39266   // translated to the global BufferID before passing it to the producers, which
39267   // don't know anything about tracing sessions and consumers.
39268 
39269   DataSourceInstanceID inst_id = ++last_data_source_instance_id_;
39270   auto insert_iter = tracing_session->data_source_instances.emplace(
39271       std::piecewise_construct,  //
39272       std::forward_as_tuple(producer->id_),
39273       std::forward_as_tuple(
39274           inst_id,
39275           cfg_data_source.config(),  //  Deliberate copy.
39276           data_source.descriptor.name(),
39277           data_source.descriptor.will_notify_on_start(),
39278           data_source.descriptor.will_notify_on_stop(),
39279           data_source.descriptor.handles_incremental_state_clear()));
39280   DataSourceInstance* ds_instance = &insert_iter->second;
39281 
39282   // New data source instance starts out in CONFIGURED state.
39283   if (tracing_session->consumer_maybe_null) {
39284     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
39285         *producer, *ds_instance);
39286   }
39287 
39288   DataSourceConfig& ds_config = ds_instance->config;
39289   ds_config.set_trace_duration_ms(tracing_session->config.duration_ms());
39290   ds_config.set_stop_timeout_ms(tracing_session->data_source_stop_timeout_ms());
39291   ds_config.set_enable_extra_guardrails(
39292       tracing_session->config.enable_extra_guardrails());
39293   ds_config.set_tracing_session_id(tracing_session->id);
39294   BufferID global_id = tracing_session->buffers_index[relative_buffer_id];
39295   PERFETTO_DCHECK(global_id);
39296   ds_config.set_target_buffer(global_id);
39297 
39298   PERFETTO_DLOG("Setting up data source %s with target buffer %" PRIu16,
39299                 ds_config.name().c_str(), global_id);
39300   if (!producer->shared_memory()) {
39301     // Determine the SMB page size. Must be an integer multiple of 4k.
39302     // As for the SMB size below, the decision tree is as follows:
39303     // 1. Give priority to what is defined in the trace config.
39304     // 2. If unset give priority to the hint passed by the producer.
39305     // 3. Keep within bounds and ensure it's a multiple of 4k.
39306     size_t page_size = producer_config.page_size_kb() * 1024;
39307     if (page_size == 0)
39308       page_size = producer->shmem_page_size_hint_bytes_;
39309 
39310     // Determine the SMB size. Must be an integer multiple of the SMB page size.
39311     // The decision tree is as follows:
39312     // 1. Give priority to what defined in the trace config.
39313     // 2. If unset give priority to the hint passed by the producer.
39314     // 3. Keep within bounds and ensure it's a multiple of the page size.
39315     size_t shm_size = producer_config.shm_size_kb() * 1024;
39316     if (shm_size == 0)
39317       shm_size = producer->shmem_size_hint_bytes_;
39318 
39319     auto valid_sizes = EnsureValidShmSizes(shm_size, page_size);
39320     if (valid_sizes != std::tie(shm_size, page_size)) {
39321       PERFETTO_DLOG(
39322           "Invalid configured SMB sizes: shm_size %zu page_size %zu. Falling "
39323           "back to shm_size %zu page_size %zu.",
39324           shm_size, page_size, std::get<0>(valid_sizes),
39325           std::get<1>(valid_sizes));
39326     }
39327     std::tie(shm_size, page_size) = valid_sizes;
39328 
39329     // TODO(primiano): right now Create() will suicide in case of OOM if the
39330     // mmap fails. We should instead gracefully fail the request and tell the
39331     // client to go away.
39332     PERFETTO_DLOG("Creating SMB of %zu KB for producer \"%s\"", shm_size / 1024,
39333                   producer->name_.c_str());
39334     auto shared_memory = shm_factory_->CreateSharedMemory(shm_size);
39335     producer->SetupSharedMemory(std::move(shared_memory), page_size,
39336                                 /*provided_by_producer=*/false);
39337   }
39338   producer->SetupDataSource(inst_id, ds_config);
39339   return ds_instance;
39340 }
39341 
39342 // Note: all the fields % *_trusted ones are untrusted, as in, the Producer
39343 // might be lying / returning garbage contents. |src| and |size| can be trusted
39344 // in terms of being a valid pointer, but not the contents.
CopyProducerPageIntoLogBuffer(ProducerID producer_id_trusted,uid_t producer_uid_trusted,WriterID writer_id,ChunkID chunk_id,BufferID buffer_id,uint16_t num_fragments,uint8_t chunk_flags,bool chunk_complete,const uint8_t * src,size_t size)39345 void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
39346     ProducerID producer_id_trusted,
39347     uid_t producer_uid_trusted,
39348     WriterID writer_id,
39349     ChunkID chunk_id,
39350     BufferID buffer_id,
39351     uint16_t num_fragments,
39352     uint8_t chunk_flags,
39353     bool chunk_complete,
39354     const uint8_t* src,
39355     size_t size) {
39356   PERFETTO_DCHECK_THREAD(thread_checker_);
39357 
39358   ProducerEndpointImpl* producer = GetProducer(producer_id_trusted);
39359   if (!producer) {
39360     PERFETTO_DFATAL("Producer not found.");
39361     chunks_discarded_++;
39362     return;
39363   }
39364 
39365   TraceBuffer* buf = GetBufferByID(buffer_id);
39366   if (!buf) {
39367     PERFETTO_DLOG("Could not find target buffer %" PRIu16
39368                   " for producer %" PRIu16,
39369                   buffer_id, producer_id_trusted);
39370     chunks_discarded_++;
39371     return;
39372   }
39373 
39374   // Verify that the producer is actually allowed to write into the target
39375   // buffer specified in the request. This prevents a malicious producer from
39376   // injecting data into a log buffer that belongs to a tracing session the
39377   // producer is not part of.
39378   if (!producer->is_allowed_target_buffer(buffer_id)) {
39379     PERFETTO_ELOG("Producer %" PRIu16
39380                   " tried to write into forbidden target buffer %" PRIu16,
39381                   producer_id_trusted, buffer_id);
39382     PERFETTO_DFATAL("Forbidden target buffer");
39383     chunks_discarded_++;
39384     return;
39385   }
39386 
39387   // If the writer was registered by the producer, it should only write into the
39388   // buffer it was registered with.
39389   base::Optional<BufferID> associated_buffer =
39390       producer->buffer_id_for_writer(writer_id);
39391   if (associated_buffer && *associated_buffer != buffer_id) {
39392     PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
39393                   " was registered to write into target buffer %" PRIu16
39394                   ", but tried to write into buffer %" PRIu16,
39395                   writer_id, producer_id_trusted, *associated_buffer,
39396                   buffer_id);
39397     PERFETTO_DFATAL("Wrong target buffer");
39398     chunks_discarded_++;
39399     return;
39400   }
39401 
39402   buf->CopyChunkUntrusted(producer_id_trusted, producer_uid_trusted, writer_id,
39403                           chunk_id, num_fragments, chunk_flags, chunk_complete,
39404                           src, size);
39405 }
39406 
ApplyChunkPatches(ProducerID producer_id_trusted,const std::vector<CommitDataRequest::ChunkToPatch> & chunks_to_patch)39407 void TracingServiceImpl::ApplyChunkPatches(
39408     ProducerID producer_id_trusted,
39409     const std::vector<CommitDataRequest::ChunkToPatch>& chunks_to_patch) {
39410   PERFETTO_DCHECK_THREAD(thread_checker_);
39411 
39412   for (const auto& chunk : chunks_to_patch) {
39413     const ChunkID chunk_id = static_cast<ChunkID>(chunk.chunk_id());
39414     const WriterID writer_id = static_cast<WriterID>(chunk.writer_id());
39415     TraceBuffer* buf =
39416         GetBufferByID(static_cast<BufferID>(chunk.target_buffer()));
39417     static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
39418                   "Add a '|| chunk_id > kMaxChunkID' below if this fails");
39419     if (!writer_id || writer_id > kMaxWriterID || !buf) {
39420       // This can genuinely happen when the trace is stopped. The producers
39421       // might see the stop signal with some delay and try to keep sending
39422       // patches left soon after.
39423       PERFETTO_DLOG(
39424           "Received invalid chunks_to_patch request from Producer: %" PRIu16
39425           ", BufferID: %" PRIu32 " ChunkdID: %" PRIu32 " WriterID: %" PRIu16,
39426           producer_id_trusted, chunk.target_buffer(), chunk_id, writer_id);
39427       patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
39428       continue;
39429     }
39430 
39431     // Note, there's no need to validate that the producer is allowed to write
39432     // to the specified buffer ID (or that it's the correct buffer ID for a
39433     // registered TraceWriter). That's because TraceBuffer uses the producer ID
39434     // and writer ID to look up the chunk to patch. If the producer specifies an
39435     // incorrect buffer, this lookup will fail and TraceBuffer will ignore the
39436     // patches. Because the producer ID is trusted, there's also no way for a
39437     // malicious producer to patch another producer's data.
39438 
39439     // Speculate on the fact that there are going to be a limited amount of
39440     // patches per request, so we can allocate the |patches| array on the stack.
39441     std::array<TraceBuffer::Patch, 1024> patches;  // Uninitialized.
39442     if (chunk.patches().size() > patches.size()) {
39443       PERFETTO_ELOG("Too many patches (%zu) batched in the same request",
39444                     patches.size());
39445       PERFETTO_DFATAL("Too many patches");
39446       patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
39447       continue;
39448     }
39449 
39450     size_t i = 0;
39451     for (const auto& patch : chunk.patches()) {
39452       const std::string& patch_data = patch.data();
39453       if (patch_data.size() != patches[i].data.size()) {
39454         PERFETTO_ELOG("Received patch from producer: %" PRIu16
39455                       " of unexpected size %zu",
39456                       producer_id_trusted, patch_data.size());
39457         patches_discarded_++;
39458         continue;
39459       }
39460       patches[i].offset_untrusted = patch.offset();
39461       memcpy(&patches[i].data[0], patch_data.data(), patches[i].data.size());
39462       i++;
39463     }
39464     buf->TryPatchChunkContents(producer_id_trusted, writer_id, chunk_id,
39465                                &patches[0], i, chunk.has_more_patches());
39466   }
39467 }
39468 
GetDetachedSession(uid_t uid,const std::string & key)39469 TracingServiceImpl::TracingSession* TracingServiceImpl::GetDetachedSession(
39470     uid_t uid,
39471     const std::string& key) {
39472   PERFETTO_DCHECK_THREAD(thread_checker_);
39473   for (auto& kv : tracing_sessions_) {
39474     TracingSession* session = &kv.second;
39475     if (session->consumer_uid == uid && session->detach_key == key) {
39476       PERFETTO_DCHECK(session->consumer_maybe_null == nullptr);
39477       return session;
39478     }
39479   }
39480   return nullptr;
39481 }
39482 
GetTracingSession(TracingSessionID tsid)39483 TracingServiceImpl::TracingSession* TracingServiceImpl::GetTracingSession(
39484     TracingSessionID tsid) {
39485   PERFETTO_DCHECK_THREAD(thread_checker_);
39486   auto it = tsid ? tracing_sessions_.find(tsid) : tracing_sessions_.end();
39487   if (it == tracing_sessions_.end())
39488     return nullptr;
39489   return &it->second;
39490 }
39491 
GetNextProducerID()39492 ProducerID TracingServiceImpl::GetNextProducerID() {
39493   PERFETTO_DCHECK_THREAD(thread_checker_);
39494   PERFETTO_CHECK(producers_.size() < kMaxProducerID);
39495   do {
39496     ++last_producer_id_;
39497   } while (producers_.count(last_producer_id_) || last_producer_id_ == 0);
39498   PERFETTO_DCHECK(last_producer_id_ > 0 && last_producer_id_ <= kMaxProducerID);
39499   return last_producer_id_;
39500 }
39501 
GetBufferByID(BufferID buffer_id)39502 TraceBuffer* TracingServiceImpl::GetBufferByID(BufferID buffer_id) {
39503   auto buf_iter = buffers_.find(buffer_id);
39504   if (buf_iter == buffers_.end())
39505     return nullptr;
39506   return &*buf_iter->second;
39507 }
39508 
OnStartTriggersTimeout(TracingSessionID tsid)39509 void TracingServiceImpl::OnStartTriggersTimeout(TracingSessionID tsid) {
39510   // Skip entirely the flush if the trace session doesn't exist anymore.
39511   // This is to prevent misleading error messages to be logged.
39512   //
39513   // if the trace has started from the trigger we rely on
39514   // the |stop_delay_ms| from the trigger so don't flush and
39515   // disable if we've moved beyond a CONFIGURED state
39516   auto* tracing_session_ptr = GetTracingSession(tsid);
39517   if (tracing_session_ptr &&
39518       tracing_session_ptr->state == TracingSession::CONFIGURED) {
39519     PERFETTO_DLOG("Disabling TracingSession %" PRIu64
39520                   " since no triggers activated.",
39521                   tsid);
39522     // No data should be returned from ReadBuffers() regardless of if we
39523     // call FreeBuffers() or DisableTracing(). This is because in
39524     // STOP_TRACING we need this promise in either case, and using
39525     // DisableTracing() allows a graceful shutdown. Consumers can follow
39526     // their normal path and check the buffers through ReadBuffers() and
39527     // the code won't hang because the tracing session will still be
39528     // alive just disabled.
39529     DisableTracing(tsid);
39530   }
39531 }
39532 
UpdateMemoryGuardrail()39533 void TracingServiceImpl::UpdateMemoryGuardrail() {
39534 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
39535   uint64_t total_buffer_bytes = 0;
39536 
39537   // Sum up all the shared memory buffers.
39538   for (const auto& id_to_producer : producers_) {
39539     if (id_to_producer.second->shared_memory())
39540       total_buffer_bytes += id_to_producer.second->shared_memory()->size();
39541   }
39542 
39543   // Sum up all the trace buffers.
39544   for (const auto& id_to_buffer : buffers_) {
39545     total_buffer_bytes += id_to_buffer.second->size();
39546   }
39547 
39548   // Set the guard rail to 32MB + the sum of all the buffers over a 30 second
39549   // interval.
39550   uint64_t guardrail = base::kWatchdogDefaultMemorySlack + total_buffer_bytes;
39551   base::Watchdog::GetInstance()->SetMemoryLimit(guardrail, 30 * 1000);
39552 #endif
39553 }
39554 
PeriodicSnapshotTask(TracingSession * tracing_session)39555 void TracingServiceImpl::PeriodicSnapshotTask(TracingSession* tracing_session) {
39556   tracing_session->should_emit_sync_marker = true;
39557   tracing_session->should_emit_stats = true;
39558   MaybeSnapshotClocksIntoRingBuffer(tracing_session);
39559 
39560   uint32_t interval_ms =
39561       tracing_session->config.builtin_data_sources().snapshot_interval_ms();
39562   if (!interval_ms)
39563     interval_ms = kDefaultSnapshotsIntervalMs;
39564 
39565   TracingSessionID tsid = tracing_session->id;
39566   auto weak_this = weak_ptr_factory_.GetWeakPtr();
39567   task_runner_->PostDelayedTask(
39568       [weak_this, tsid] {
39569         if (!weak_this)
39570           return;
39571         auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
39572         if (!tracing_session_ptr)
39573           return;
39574         if (tracing_session_ptr->state != TracingSession::STARTED)
39575           return;
39576         weak_this->PeriodicSnapshotTask(tracing_session_ptr);
39577       },
39578       interval_ms - (base::GetWallTimeMs().count() % interval_ms));
39579 }
39580 
SnapshotLifecyleEvent(TracingSession * tracing_session,uint32_t field_id,bool snapshot_clocks)39581 void TracingServiceImpl::SnapshotLifecyleEvent(TracingSession* tracing_session,
39582                                                uint32_t field_id,
39583                                                bool snapshot_clocks) {
39584   // field_id should be an id of a field in TracingServiceEvent.
39585   auto& lifecycle_events = tracing_session->lifecycle_events;
39586   auto event_it =
39587       std::find_if(lifecycle_events.begin(), lifecycle_events.end(),
39588                    [field_id](const TracingSession::LifecycleEvent& event) {
39589                      return event.field_id == field_id;
39590                    });
39591 
39592   TracingSession::LifecycleEvent* event;
39593   if (event_it == lifecycle_events.end()) {
39594     lifecycle_events.emplace_back(field_id);
39595     event = &lifecycle_events.back();
39596   } else {
39597     event = &*event_it;
39598   }
39599 
39600   // Snapshot the clocks before capturing the timestamp for the event so we can
39601   // use this snapshot to resolve the event timestamp if necessary.
39602   if (snapshot_clocks)
39603     MaybeSnapshotClocksIntoRingBuffer(tracing_session);
39604 
39605   // Erase before emplacing to prevent a unncessary doubling of memory if
39606   // not needed.
39607   if (event->timestamps.size() >= event->max_size) {
39608     event->timestamps.erase_front(1 + event->timestamps.size() -
39609                                   event->max_size);
39610   }
39611   event->timestamps.emplace_back(base::GetBootTimeNs().count());
39612 }
39613 
MaybeSnapshotClocksIntoRingBuffer(TracingSession * tracing_session)39614 void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
39615     TracingSession* tracing_session) {
39616   if (tracing_session->config.builtin_data_sources()
39617           .disable_clock_snapshotting()) {
39618     return;
39619   }
39620 
39621   // We are making an explicit copy of the latest snapshot (if it exists)
39622   // because SnapshotClocks reads this data and computes the drift based on its
39623   // content. If the clock drift is high enough, it will update the contents of
39624   // |snapshot| and return true. Otherwise, it will return false.
39625   TracingSession::ClockSnapshotData snapshot =
39626       tracing_session->clock_snapshot_ring_buffer.empty()
39627           ? TracingSession::ClockSnapshotData()
39628           : tracing_session->clock_snapshot_ring_buffer.back();
39629   bool did_update = SnapshotClocks(&snapshot);
39630   if (did_update) {
39631     // This means clocks drifted enough since last snapshot. See the comment
39632     // in SnapshotClocks.
39633     auto* snapshot_buffer = &tracing_session->clock_snapshot_ring_buffer;
39634 
39635     // Erase before emplacing to prevent a unncessary doubling of memory if
39636     // not needed.
39637     static constexpr uint32_t kClockSnapshotRingBufferSize = 16;
39638     if (snapshot_buffer->size() >= kClockSnapshotRingBufferSize) {
39639       snapshot_buffer->erase_front(1 + snapshot_buffer->size() -
39640                                    kClockSnapshotRingBufferSize);
39641     }
39642     snapshot_buffer->emplace_back(std::move(snapshot));
39643   }
39644 }
39645 
39646 // Returns true when the data in |snapshot_data| is updated with the new state
39647 // of the clocks and false otherwise.
SnapshotClocks(TracingSession::ClockSnapshotData * snapshot_data)39648 bool TracingServiceImpl::SnapshotClocks(
39649     TracingSession::ClockSnapshotData* snapshot_data) {
39650   // Minimum drift that justifies replacing a prior clock snapshot that hasn't
39651   // been emitted into the trace yet (see comment below).
39652   static constexpr int64_t kSignificantDriftNs = 10 * 1000 * 1000;  // 10 ms
39653 
39654   TracingSession::ClockSnapshotData new_snapshot_data;
39655 
39656 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
39657     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&   \
39658     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
39659   struct {
39660     clockid_t id;
39661     protos::pbzero::BuiltinClock type;
39662     struct timespec ts;
39663   } clocks[] = {
39664       {CLOCK_BOOTTIME, protos::pbzero::BUILTIN_CLOCK_BOOTTIME, {0, 0}},
39665       {CLOCK_REALTIME_COARSE,
39666        protos::pbzero::BUILTIN_CLOCK_REALTIME_COARSE,
39667        {0, 0}},
39668       {CLOCK_MONOTONIC_COARSE,
39669        protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
39670        {0, 0}},
39671       {CLOCK_REALTIME, protos::pbzero::BUILTIN_CLOCK_REALTIME, {0, 0}},
39672       {CLOCK_MONOTONIC, protos::pbzero::BUILTIN_CLOCK_MONOTONIC, {0, 0}},
39673       {CLOCK_MONOTONIC_RAW,
39674        protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW,
39675        {0, 0}},
39676   };
39677   // First snapshot all the clocks as atomically as we can.
39678   for (auto& clock : clocks) {
39679     if (clock_gettime(clock.id, &clock.ts) == -1)
39680       PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
39681   }
39682   for (auto& clock : clocks) {
39683     new_snapshot_data.push_back(std::make_pair(
39684         static_cast<uint32_t>(clock.type),
39685         static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count())));
39686   }
39687 #else   // !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) &&
39688         // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&
39689         // !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
39690   auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
39691   // The default trace clock is boot time, so we always need to emit a path to
39692   // it. However since we don't actually have a boot time source on these
39693   // platforms, pretend that wall time equals boot time.
39694   new_snapshot_data.push_back(
39695       std::make_pair(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
39696   new_snapshot_data.push_back(
39697       std::make_pair(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
39698 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) &&
39699         // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&
39700         // !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
39701 
39702   // If we're about to update a session's latest clock snapshot that hasn't been
39703   // emitted into the trace yet, check whether the clocks have drifted enough to
39704   // warrant overriding the current snapshot values. The older snapshot would be
39705   // valid for a larger part of the currently buffered trace data because the
39706   // clock sync protocol in trace processor uses the latest clock <= timestamp
39707   // to translate times (see https://perfetto.dev/docs/concepts/clock-sync), so
39708   // we try to keep it if we can.
39709   if (!snapshot_data->empty()) {
39710     PERFETTO_DCHECK(snapshot_data->size() == new_snapshot_data.size());
39711     PERFETTO_DCHECK((*snapshot_data)[0].first ==
39712                     protos::gen::BUILTIN_CLOCK_BOOTTIME);
39713 
39714     bool update_snapshot = false;
39715     uint64_t old_boot_ns = (*snapshot_data)[0].second;
39716     uint64_t new_boot_ns = new_snapshot_data[0].second;
39717     int64_t boot_diff =
39718         static_cast<int64_t>(new_boot_ns) - static_cast<int64_t>(old_boot_ns);
39719 
39720     for (size_t i = 1; i < snapshot_data->size(); i++) {
39721       uint64_t old_ns = (*snapshot_data)[i].second;
39722       uint64_t new_ns = new_snapshot_data[i].second;
39723 
39724       int64_t diff =
39725           static_cast<int64_t>(new_ns) - static_cast<int64_t>(old_ns);
39726 
39727       // Compare the boottime delta against the delta of this clock.
39728       if (std::abs(boot_diff - diff) >= kSignificantDriftNs) {
39729         update_snapshot = true;
39730         break;
39731       }
39732     }
39733     if (!update_snapshot)
39734       return false;
39735     snapshot_data->clear();
39736   }
39737 
39738   *snapshot_data = std::move(new_snapshot_data);
39739   return true;
39740 }
39741 
EmitClockSnapshot(TracingSession * tracing_session,TracingSession::ClockSnapshotData snapshot_data,std::vector<TracePacket> * packets)39742 void TracingServiceImpl::EmitClockSnapshot(
39743     TracingSession* tracing_session,
39744     TracingSession::ClockSnapshotData snapshot_data,
39745     std::vector<TracePacket>* packets) {
39746   PERFETTO_DCHECK(!tracing_session->config.builtin_data_sources()
39747                        .disable_clock_snapshotting());
39748 
39749   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
39750   auto* snapshot = packet->set_clock_snapshot();
39751 
39752   protos::gen::BuiltinClock trace_clock =
39753       tracing_session->config.builtin_data_sources().primary_trace_clock();
39754   if (!trace_clock)
39755     trace_clock = protos::gen::BUILTIN_CLOCK_BOOTTIME;
39756   snapshot->set_primary_trace_clock(
39757       static_cast<protos::pbzero::BuiltinClock>(trace_clock));
39758 
39759   for (auto& clock_id_and_ts : snapshot_data) {
39760     auto* c = snapshot->add_clocks();
39761     c->set_clock_id(clock_id_and_ts.first);
39762     c->set_timestamp(clock_id_and_ts.second);
39763   }
39764 
39765   packet->set_trusted_uid(static_cast<int32_t>(uid_));
39766   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39767   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
39768 }
39769 
EmitSyncMarker(std::vector<TracePacket> * packets)39770 void TracingServiceImpl::EmitSyncMarker(std::vector<TracePacket>* packets) {
39771   // The sync marks are used to tokenize large traces efficiently.
39772   // See description in trace_packet.proto.
39773   if (sync_marker_packet_size_ == 0) {
39774     // The marker ABI expects that the marker is written after the uid.
39775     // Protozero guarantees that fields are written in the same order of the
39776     // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
39777     protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
39778         &sync_marker_packet_[0], sizeof(sync_marker_packet_));
39779     packet->set_trusted_uid(static_cast<int32_t>(uid_));
39780     packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39781 
39782     // Keep this last.
39783     packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
39784     sync_marker_packet_size_ = packet.Finalize();
39785   }
39786   packets->emplace_back();
39787   packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
39788 }
39789 
EmitStats(TracingSession * tracing_session,std::vector<TracePacket> * packets)39790 void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
39791                                    std::vector<TracePacket>* packets) {
39792   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
39793   packet->set_trusted_uid(static_cast<int32_t>(uid_));
39794   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39795   GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
39796   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
39797 }
39798 
GetTraceStats(TracingSession * tracing_session)39799 TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
39800   TraceStats trace_stats;
39801   trace_stats.set_producers_connected(static_cast<uint32_t>(producers_.size()));
39802   trace_stats.set_producers_seen(last_producer_id_);
39803   trace_stats.set_data_sources_registered(
39804       static_cast<uint32_t>(data_sources_.size()));
39805   trace_stats.set_data_sources_seen(last_data_source_instance_id_);
39806   trace_stats.set_tracing_sessions(
39807       static_cast<uint32_t>(tracing_sessions_.size()));
39808   trace_stats.set_total_buffers(static_cast<uint32_t>(buffers_.size()));
39809   trace_stats.set_chunks_discarded(chunks_discarded_);
39810   trace_stats.set_patches_discarded(patches_discarded_);
39811   trace_stats.set_invalid_packets(tracing_session->invalid_packets);
39812 
39813   for (BufferID buf_id : tracing_session->buffers_index) {
39814     TraceBuffer* buf = GetBufferByID(buf_id);
39815     if (!buf) {
39816       PERFETTO_DFATAL("Buffer not found.");
39817       continue;
39818     }
39819     *trace_stats.add_buffer_stats() = buf->stats();
39820   }  // for (buf in session).
39821   return trace_stats;
39822 }
39823 
MaybeEmitTraceConfig(TracingSession * tracing_session,std::vector<TracePacket> * packets)39824 void TracingServiceImpl::MaybeEmitTraceConfig(
39825     TracingSession* tracing_session,
39826     std::vector<TracePacket>* packets) {
39827   if (tracing_session->did_emit_config)
39828     return;
39829   tracing_session->did_emit_config = true;
39830   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
39831   packet->set_trusted_uid(static_cast<int32_t>(uid_));
39832   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39833   tracing_session->config.Serialize(packet->set_trace_config());
39834   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
39835 }
39836 
MaybeEmitSystemInfo(TracingSession * tracing_session,std::vector<TracePacket> * packets)39837 void TracingServiceImpl::MaybeEmitSystemInfo(
39838     TracingSession* tracing_session,
39839     std::vector<TracePacket>* packets) {
39840   if (tracing_session->did_emit_system_info)
39841     return;
39842   tracing_session->did_emit_system_info = true;
39843   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
39844   auto* info = packet->set_system_info();
39845   base::ignore_result(info);  // For PERFETTO_OS_WIN.
39846 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
39847     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
39848   struct utsname uname_info;
39849   if (uname(&uname_info) == 0) {
39850     auto* utsname_info = info->set_utsname();
39851     utsname_info->set_sysname(uname_info.sysname);
39852     utsname_info->set_version(uname_info.version);
39853     utsname_info->set_machine(uname_info.machine);
39854     utsname_info->set_release(uname_info.release);
39855   }
39856 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
39857 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
39858   char value[PROP_VALUE_MAX];
39859   if (__system_property_get("ro.build.fingerprint", value)) {
39860     info->set_android_build_fingerprint(value);
39861   } else {
39862     PERFETTO_ELOG("Unable to read ro.build.fingerprint");
39863   }
39864   info->set_hz(sysconf(_SC_CLK_TCK));
39865 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
39866   packet->set_trusted_uid(static_cast<int32_t>(uid_));
39867   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39868   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
39869 }
39870 
EmitLifecycleEvents(TracingSession * tracing_session,std::vector<TracePacket> * packets)39871 void TracingServiceImpl::EmitLifecycleEvents(
39872     TracingSession* tracing_session,
39873     std::vector<TracePacket>* packets) {
39874   using TimestampedPacket =
39875       std::pair<int64_t /* ts */, std::vector<uint8_t> /* serialized packet */>;
39876 
39877   std::vector<TimestampedPacket> timestamped_packets;
39878   for (auto& event : tracing_session->lifecycle_events) {
39879     for (int64_t ts : event.timestamps) {
39880       protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
39881       packet->set_timestamp(static_cast<uint64_t>(ts));
39882       packet->set_trusted_uid(static_cast<int32_t>(uid_));
39883       packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39884 
39885       auto* service_event = packet->set_service_event();
39886       service_event->AppendVarInt(event.field_id, 1);
39887       timestamped_packets.emplace_back(ts, packet.SerializeAsArray());
39888     }
39889     event.timestamps.clear();
39890   }
39891 
39892   // We sort by timestamp here to ensure that the "sequence" of lifecycle
39893   // packets has monotonic timestamps like other sequences in the trace.
39894   // Note that these events could still be out of order with respect to other
39895   // events on the service packet sequence (e.g. trigger received packets).
39896   std::sort(timestamped_packets.begin(), timestamped_packets.end(),
39897             [](const TimestampedPacket& a, const TimestampedPacket& b) {
39898               return a.first < b.first;
39899             });
39900 
39901   for (const auto& pair : timestamped_packets)
39902     SerializeAndAppendPacket(packets, std::move(pair.second));
39903 }
39904 
MaybeEmitReceivedTriggers(TracingSession * tracing_session,std::vector<TracePacket> * packets)39905 void TracingServiceImpl::MaybeEmitReceivedTriggers(
39906     TracingSession* tracing_session,
39907     std::vector<TracePacket>* packets) {
39908   PERFETTO_DCHECK(tracing_session->num_triggers_emitted_into_trace <=
39909                   tracing_session->received_triggers.size());
39910   for (size_t i = tracing_session->num_triggers_emitted_into_trace;
39911        i < tracing_session->received_triggers.size(); ++i) {
39912     const auto& info = tracing_session->received_triggers[i];
39913     protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
39914     auto* trigger = packet->set_trigger();
39915     trigger->set_trigger_name(info.trigger_name);
39916     trigger->set_producer_name(info.producer_name);
39917     trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));
39918 
39919     packet->set_timestamp(info.boot_time_ns);
39920     packet->set_trusted_uid(static_cast<int32_t>(uid_));
39921     packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
39922     SerializeAndAppendPacket(packets, packet.SerializeAsArray());
39923     ++tracing_session->num_triggers_emitted_into_trace;
39924   }
39925 }
39926 
39927 ////////////////////////////////////////////////////////////////////////////////
39928 // TracingServiceImpl::ConsumerEndpointImpl implementation
39929 ////////////////////////////////////////////////////////////////////////////////
39930 
ConsumerEndpointImpl(TracingServiceImpl * service,base::TaskRunner * task_runner,Consumer * consumer,uid_t uid)39931 TracingServiceImpl::ConsumerEndpointImpl::ConsumerEndpointImpl(
39932     TracingServiceImpl* service,
39933     base::TaskRunner* task_runner,
39934     Consumer* consumer,
39935     uid_t uid)
39936     : task_runner_(task_runner),
39937       service_(service),
39938       consumer_(consumer),
39939       uid_(uid),
39940       weak_ptr_factory_(this) {}
39941 
~ConsumerEndpointImpl()39942 TracingServiceImpl::ConsumerEndpointImpl::~ConsumerEndpointImpl() {
39943   service_->DisconnectConsumer(this);
39944   consumer_->OnDisconnect();
39945 }
39946 
NotifyOnTracingDisabled()39947 void TracingServiceImpl::ConsumerEndpointImpl::NotifyOnTracingDisabled() {
39948   PERFETTO_DCHECK_THREAD(thread_checker_);
39949   auto weak_this = GetWeakPtr();
39950   task_runner_->PostTask([weak_this] {
39951     if (weak_this)
39952       weak_this->consumer_->OnTracingDisabled();
39953   });
39954 }
39955 
EnableTracing(const TraceConfig & cfg,base::ScopedFile fd)39956 void TracingServiceImpl::ConsumerEndpointImpl::EnableTracing(
39957     const TraceConfig& cfg,
39958     base::ScopedFile fd) {
39959   PERFETTO_DCHECK_THREAD(thread_checker_);
39960   if (!service_->EnableTracing(this, cfg, std::move(fd)))
39961     NotifyOnTracingDisabled();
39962 }
39963 
ChangeTraceConfig(const TraceConfig & cfg)39964 void TracingServiceImpl::ConsumerEndpointImpl::ChangeTraceConfig(
39965     const TraceConfig& cfg) {
39966   if (!tracing_session_id_) {
39967     PERFETTO_LOG(
39968         "Consumer called ChangeTraceConfig() but tracing was "
39969         "not active");
39970     return;
39971   }
39972   service_->ChangeTraceConfig(this, cfg);
39973 }
39974 
StartTracing()39975 void TracingServiceImpl::ConsumerEndpointImpl::StartTracing() {
39976   PERFETTO_DCHECK_THREAD(thread_checker_);
39977   if (!tracing_session_id_) {
39978     PERFETTO_LOG("Consumer called StartTracing() but tracing was not active");
39979     return;
39980   }
39981   service_->StartTracing(tracing_session_id_);
39982 }
39983 
DisableTracing()39984 void TracingServiceImpl::ConsumerEndpointImpl::DisableTracing() {
39985   PERFETTO_DCHECK_THREAD(thread_checker_);
39986   if (!tracing_session_id_) {
39987     PERFETTO_LOG("Consumer called DisableTracing() but tracing was not active");
39988     return;
39989   }
39990   service_->DisableTracing(tracing_session_id_);
39991 }
39992 
ReadBuffers()39993 void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
39994   PERFETTO_DCHECK_THREAD(thread_checker_);
39995   if (!tracing_session_id_) {
39996     PERFETTO_LOG("Consumer called ReadBuffers() but tracing was not active");
39997     consumer_->OnTraceData({}, /* has_more = */ false);
39998     return;
39999   }
40000   if (!service_->ReadBuffers(tracing_session_id_, this)) {
40001     consumer_->OnTraceData({}, /* has_more = */ false);
40002   }
40003 }
40004 
FreeBuffers()40005 void TracingServiceImpl::ConsumerEndpointImpl::FreeBuffers() {
40006   PERFETTO_DCHECK_THREAD(thread_checker_);
40007   if (!tracing_session_id_) {
40008     PERFETTO_LOG("Consumer called FreeBuffers() but tracing was not active");
40009     return;
40010   }
40011   service_->FreeBuffers(tracing_session_id_);
40012   tracing_session_id_ = 0;
40013 }
40014 
Flush(uint32_t timeout_ms,FlushCallback callback)40015 void TracingServiceImpl::ConsumerEndpointImpl::Flush(uint32_t timeout_ms,
40016                                                      FlushCallback callback) {
40017   PERFETTO_DCHECK_THREAD(thread_checker_);
40018   if (!tracing_session_id_) {
40019     PERFETTO_LOG("Consumer called Flush() but tracing was not active");
40020     return;
40021   }
40022   service_->Flush(tracing_session_id_, timeout_ms, callback);
40023 }
40024 
Detach(const std::string & key)40025 void TracingServiceImpl::ConsumerEndpointImpl::Detach(const std::string& key) {
40026   PERFETTO_DCHECK_THREAD(thread_checker_);
40027   bool success = service_->DetachConsumer(this, key);
40028   auto weak_this = GetWeakPtr();
40029   task_runner_->PostTask([weak_this, success] {
40030     if (weak_this)
40031       weak_this->consumer_->OnDetach(success);
40032   });
40033 }
40034 
Attach(const std::string & key)40035 void TracingServiceImpl::ConsumerEndpointImpl::Attach(const std::string& key) {
40036   PERFETTO_DCHECK_THREAD(thread_checker_);
40037   bool success = service_->AttachConsumer(this, key);
40038   auto weak_this = GetWeakPtr();
40039   task_runner_->PostTask([weak_this, success] {
40040     if (!weak_this)
40041       return;
40042     Consumer* consumer = weak_this->consumer_;
40043     TracingSession* session =
40044         weak_this->service_->GetTracingSession(weak_this->tracing_session_id_);
40045     if (!session) {
40046       consumer->OnAttach(false, TraceConfig());
40047       return;
40048     }
40049     consumer->OnAttach(success, session->config);
40050   });
40051 }
40052 
GetTraceStats()40053 void TracingServiceImpl::ConsumerEndpointImpl::GetTraceStats() {
40054   PERFETTO_DCHECK_THREAD(thread_checker_);
40055   bool success = false;
40056   TraceStats stats;
40057   TracingSession* session = service_->GetTracingSession(tracing_session_id_);
40058   if (session) {
40059     success = true;
40060     stats = service_->GetTraceStats(session);
40061   }
40062   auto weak_this = GetWeakPtr();
40063   task_runner_->PostTask([weak_this, success, stats] {
40064     if (weak_this)
40065       weak_this->consumer_->OnTraceStats(success, stats);
40066   });
40067 }
40068 
ObserveEvents(uint32_t events_mask)40069 void TracingServiceImpl::ConsumerEndpointImpl::ObserveEvents(
40070     uint32_t events_mask) {
40071   PERFETTO_DCHECK_THREAD(thread_checker_);
40072   observable_events_mask_ = events_mask;
40073   TracingSession* session = service_->GetTracingSession(tracing_session_id_);
40074   if (!session)
40075     return;
40076 
40077   if (observable_events_mask_ & ObservableEvents::TYPE_DATA_SOURCES_INSTANCES) {
40078     // Issue initial states.
40079     for (const auto& kv : session->data_source_instances) {
40080       ProducerEndpointImpl* producer = service_->GetProducer(kv.first);
40081       PERFETTO_DCHECK(producer);
40082       OnDataSourceInstanceStateChange(*producer, kv.second);
40083     }
40084   }
40085 
40086   // If the ObserveEvents() call happens after data sources have acked already
40087   // notify immediately.
40088   if (observable_events_mask_ &
40089       ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED) {
40090     service_->MaybeNotifyAllDataSourcesStarted(session);
40091   }
40092 }
40093 
OnDataSourceInstanceStateChange(const ProducerEndpointImpl & producer,const DataSourceInstance & instance)40094 void TracingServiceImpl::ConsumerEndpointImpl::OnDataSourceInstanceStateChange(
40095     const ProducerEndpointImpl& producer,
40096     const DataSourceInstance& instance) {
40097   if (!(observable_events_mask_ &
40098         ObservableEvents::TYPE_DATA_SOURCES_INSTANCES)) {
40099     return;
40100   }
40101 
40102   if (instance.state != DataSourceInstance::CONFIGURED &&
40103       instance.state != DataSourceInstance::STARTED &&
40104       instance.state != DataSourceInstance::STOPPED) {
40105     return;
40106   }
40107 
40108   auto* observable_events = AddObservableEvents();
40109   auto* change = observable_events->add_instance_state_changes();
40110   change->set_producer_name(producer.name_);
40111   change->set_data_source_name(instance.data_source_name);
40112   if (instance.state == DataSourceInstance::STARTED) {
40113     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
40114   } else {
40115     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
40116   }
40117 }
40118 
OnAllDataSourcesStarted()40119 void TracingServiceImpl::ConsumerEndpointImpl::OnAllDataSourcesStarted() {
40120   if (!(observable_events_mask_ &
40121         ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED)) {
40122     return;
40123   }
40124   auto* observable_events = AddObservableEvents();
40125   observable_events->set_all_data_sources_started(true);
40126 }
40127 
40128 base::WeakPtr<TracingServiceImpl::ConsumerEndpointImpl>
GetWeakPtr()40129 TracingServiceImpl::ConsumerEndpointImpl::GetWeakPtr() {
40130   PERFETTO_DCHECK_THREAD(thread_checker_);
40131   return weak_ptr_factory_.GetWeakPtr();
40132 }
40133 
40134 ObservableEvents*
AddObservableEvents()40135 TracingServiceImpl::ConsumerEndpointImpl::AddObservableEvents() {
40136   PERFETTO_DCHECK_THREAD(thread_checker_);
40137   if (!observable_events_) {
40138     observable_events_.reset(new ObservableEvents());
40139     auto weak_this = GetWeakPtr();
40140     task_runner_->PostTask([weak_this] {
40141       if (!weak_this)
40142         return;
40143 
40144       // Move into a temporary to allow reentrancy in OnObservableEvents.
40145       auto observable_events = std::move(weak_this->observable_events_);
40146       weak_this->consumer_->OnObservableEvents(*observable_events);
40147     });
40148   }
40149   return observable_events_.get();
40150 }
40151 
QueryServiceState(QueryServiceStateCallback callback)40152 void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
40153     QueryServiceStateCallback callback) {
40154   PERFETTO_DCHECK_THREAD(thread_checker_);
40155   TracingServiceState svc_state;
40156 
40157   const auto& sessions = service_->tracing_sessions_;
40158   svc_state.set_num_sessions(static_cast<int>(sessions.size()));
40159 
40160   int num_started = 0;
40161   for (const auto& kv : sessions)
40162     num_started += kv.second.state == TracingSession::State::STARTED ? 1 : 0;
40163   svc_state.set_num_sessions_started(static_cast<int>(num_started));
40164 
40165   for (const auto& kv : service_->producers_) {
40166     auto* producer = svc_state.add_producers();
40167     producer->set_id(static_cast<int>(kv.first));
40168     producer->set_name(kv.second->name_);
40169     producer->set_uid(static_cast<int32_t>(producer->uid()));
40170   }
40171 
40172   for (const auto& kv : service_->data_sources_) {
40173     const auto& registered_data_source = kv.second;
40174     auto* data_source = svc_state.add_data_sources();
40175     *data_source->mutable_ds_descriptor() = registered_data_source.descriptor;
40176     data_source->set_producer_id(
40177         static_cast<int>(registered_data_source.producer_id));
40178   }
40179   callback(/*success=*/true, svc_state);
40180 }
40181 
QueryCapabilities(QueryCapabilitiesCallback callback)40182 void TracingServiceImpl::ConsumerEndpointImpl::QueryCapabilities(
40183     QueryCapabilitiesCallback callback) {
40184   PERFETTO_DCHECK_THREAD(thread_checker_);
40185   TracingServiceCapabilities caps;
40186   caps.set_has_query_capabilities(true);
40187   caps.set_has_trace_config_output_path(true);
40188   caps.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
40189   caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
40190   static_assert(ObservableEvents::Type_MAX ==
40191                     ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED,
40192                 "");
40193   callback(caps);
40194 }
40195 
40196 ////////////////////////////////////////////////////////////////////////////////
40197 // TracingServiceImpl::ProducerEndpointImpl implementation
40198 ////////////////////////////////////////////////////////////////////////////////
40199 
ProducerEndpointImpl(ProducerID id,uid_t uid,TracingServiceImpl * service,base::TaskRunner * task_runner,Producer * producer,const std::string & producer_name,bool in_process,bool smb_scraping_enabled)40200 TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
40201     ProducerID id,
40202     uid_t uid,
40203     TracingServiceImpl* service,
40204     base::TaskRunner* task_runner,
40205     Producer* producer,
40206     const std::string& producer_name,
40207     bool in_process,
40208     bool smb_scraping_enabled)
40209     : id_(id),
40210       uid_(uid),
40211       service_(service),
40212       task_runner_(task_runner),
40213       producer_(producer),
40214       name_(producer_name),
40215       in_process_(in_process),
40216       smb_scraping_enabled_(smb_scraping_enabled),
40217       weak_ptr_factory_(this) {}
40218 
~ProducerEndpointImpl()40219 TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
40220   service_->DisconnectProducer(id_);
40221   producer_->OnDisconnect();
40222 }
40223 
RegisterDataSource(const DataSourceDescriptor & desc)40224 void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
40225     const DataSourceDescriptor& desc) {
40226   PERFETTO_DCHECK_THREAD(thread_checker_);
40227   if (desc.name().empty()) {
40228     PERFETTO_DLOG("Received RegisterDataSource() with empty name");
40229     return;
40230   }
40231 
40232   service_->RegisterDataSource(id_, desc);
40233 }
40234 
UnregisterDataSource(const std::string & name)40235 void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
40236     const std::string& name) {
40237   PERFETTO_DCHECK_THREAD(thread_checker_);
40238   service_->UnregisterDataSource(id_, name);
40239 }
40240 
RegisterTraceWriter(uint32_t writer_id,uint32_t target_buffer)40241 void TracingServiceImpl::ProducerEndpointImpl::RegisterTraceWriter(
40242     uint32_t writer_id,
40243     uint32_t target_buffer) {
40244   PERFETTO_DCHECK_THREAD(thread_checker_);
40245   writers_[static_cast<WriterID>(writer_id)] =
40246       static_cast<BufferID>(target_buffer);
40247 }
40248 
UnregisterTraceWriter(uint32_t writer_id)40249 void TracingServiceImpl::ProducerEndpointImpl::UnregisterTraceWriter(
40250     uint32_t writer_id) {
40251   PERFETTO_DCHECK_THREAD(thread_checker_);
40252   writers_.erase(static_cast<WriterID>(writer_id));
40253 }
40254 
CommitData(const CommitDataRequest & req_untrusted,CommitDataCallback callback)40255 void TracingServiceImpl::ProducerEndpointImpl::CommitData(
40256     const CommitDataRequest& req_untrusted,
40257     CommitDataCallback callback) {
40258   PERFETTO_DCHECK_THREAD(thread_checker_);
40259 
40260   if (metatrace::IsEnabled(metatrace::TAG_TRACE_SERVICE)) {
40261     PERFETTO_METATRACE_COUNTER(TAG_TRACE_SERVICE, TRACE_SERVICE_COMMIT_DATA,
40262                                EncodeCommitDataRequest(id_, req_untrusted));
40263   }
40264 
40265   if (!shared_memory_) {
40266     PERFETTO_DLOG(
40267         "Attempted to commit data before the shared memory was allocated.");
40268     return;
40269   }
40270   PERFETTO_DCHECK(shmem_abi_.is_valid());
40271   for (const auto& entry : req_untrusted.chunks_to_move()) {
40272     const uint32_t page_idx = entry.page();
40273     if (page_idx >= shmem_abi_.num_pages())
40274       continue;  // A buggy or malicious producer.
40275 
40276     SharedMemoryABI::Chunk chunk =
40277         shmem_abi_.TryAcquireChunkForReading(page_idx, entry.chunk());
40278     if (!chunk.is_valid()) {
40279       PERFETTO_DLOG("Asked to move chunk %d:%d, but it's not complete",
40280                     entry.page(), entry.chunk());
40281       continue;
40282     }
40283 
40284     // TryAcquireChunkForReading() has load-acquire semantics. Once acquired,
40285     // the ABI contract expects the producer to not touch the chunk anymore
40286     // (until the service marks that as free). This is why all the reads below
40287     // are just memory_order_relaxed. Also, the code here assumes that all this
40288     // data can be malicious and just gives up if anything is malformed.
40289     BufferID buffer_id = static_cast<BufferID>(entry.target_buffer());
40290     const SharedMemoryABI::ChunkHeader& chunk_header = *chunk.header();
40291     WriterID writer_id = chunk_header.writer_id.load(std::memory_order_relaxed);
40292     ChunkID chunk_id = chunk_header.chunk_id.load(std::memory_order_relaxed);
40293     auto packets = chunk_header.packets.load(std::memory_order_relaxed);
40294     uint16_t num_fragments = packets.count;
40295     uint8_t chunk_flags = packets.flags;
40296 
40297     service_->CopyProducerPageIntoLogBuffer(
40298         id_, uid_, writer_id, chunk_id, buffer_id, num_fragments, chunk_flags,
40299         /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
40300 
40301     // This one has release-store semantics.
40302     shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
40303   }  // for(chunks_to_move)
40304 
40305   service_->ApplyChunkPatches(id_, req_untrusted.chunks_to_patch());
40306 
40307   if (req_untrusted.flush_request_id()) {
40308     service_->NotifyFlushDoneForProducer(id_, req_untrusted.flush_request_id());
40309   }
40310 
40311   // Keep this invocation last. ProducerIPCService::CommitData() relies on this
40312   // callback being invoked within the same callstack and not posted. If this
40313   // changes, the code there needs to be changed accordingly.
40314   if (callback)
40315     callback();
40316 }
40317 
SetupSharedMemory(std::unique_ptr<SharedMemory> shared_memory,size_t page_size_bytes,bool provided_by_producer)40318 void TracingServiceImpl::ProducerEndpointImpl::SetupSharedMemory(
40319     std::unique_ptr<SharedMemory> shared_memory,
40320     size_t page_size_bytes,
40321     bool provided_by_producer) {
40322   PERFETTO_DCHECK(!shared_memory_ && !shmem_abi_.is_valid());
40323   PERFETTO_DCHECK(page_size_bytes % 1024 == 0);
40324 
40325   shared_memory_ = std::move(shared_memory);
40326   shared_buffer_page_size_kb_ = page_size_bytes / 1024;
40327   is_shmem_provided_by_producer_ = provided_by_producer;
40328 
40329   shmem_abi_.Initialize(reinterpret_cast<uint8_t*>(shared_memory_->start()),
40330                         shared_memory_->size(),
40331                         shared_buffer_page_size_kb() * 1024);
40332   if (in_process_) {
40333     inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
40334         shared_memory_->start(), shared_memory_->size(),
40335         shared_buffer_page_size_kb_ * 1024, this, task_runner_));
40336   }
40337 
40338   OnTracingSetup();
40339   service_->UpdateMemoryGuardrail();
40340 }
40341 
shared_memory() const40342 SharedMemory* TracingServiceImpl::ProducerEndpointImpl::shared_memory() const {
40343   PERFETTO_DCHECK_THREAD(thread_checker_);
40344   return shared_memory_.get();
40345 }
40346 
shared_buffer_page_size_kb() const40347 size_t TracingServiceImpl::ProducerEndpointImpl::shared_buffer_page_size_kb()
40348     const {
40349   return shared_buffer_page_size_kb_;
40350 }
40351 
ActivateTriggers(const std::vector<std::string> & triggers)40352 void TracingServiceImpl::ProducerEndpointImpl::ActivateTriggers(
40353     const std::vector<std::string>& triggers) {
40354   service_->ActivateTriggers(id_, triggers);
40355 }
40356 
StopDataSource(DataSourceInstanceID ds_inst_id)40357 void TracingServiceImpl::ProducerEndpointImpl::StopDataSource(
40358     DataSourceInstanceID ds_inst_id) {
40359   // TODO(primiano): When we'll support tearing down the SMB, at this point we
40360   // should send the Producer a TearDownTracing if all its data sources have
40361   // been disabled (see b/77532839 and aosp/655179 PS1).
40362   PERFETTO_DCHECK_THREAD(thread_checker_);
40363   auto weak_this = weak_ptr_factory_.GetWeakPtr();
40364   task_runner_->PostTask([weak_this, ds_inst_id] {
40365     if (weak_this)
40366       weak_this->producer_->StopDataSource(ds_inst_id);
40367   });
40368 }
40369 
40370 SharedMemoryArbiter*
MaybeSharedMemoryArbiter()40371 TracingServiceImpl::ProducerEndpointImpl::MaybeSharedMemoryArbiter() {
40372   if (!inproc_shmem_arbiter_) {
40373     PERFETTO_FATAL(
40374         "The in-process SharedMemoryArbiter can only be used when "
40375         "CreateProducer has been called with in_process=true and after tracing "
40376         "has started.");
40377   }
40378 
40379   PERFETTO_DCHECK(in_process_);
40380   return inproc_shmem_arbiter_.get();
40381 }
40382 
IsShmemProvidedByProducer() const40383 bool TracingServiceImpl::ProducerEndpointImpl::IsShmemProvidedByProducer()
40384     const {
40385   return is_shmem_provided_by_producer_;
40386 }
40387 
40388 // Can be called on any thread.
40389 std::unique_ptr<TraceWriter>
CreateTraceWriter(BufferID buf_id,BufferExhaustedPolicy buffer_exhausted_policy)40390 TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
40391     BufferID buf_id,
40392     BufferExhaustedPolicy buffer_exhausted_policy) {
40393   PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
40394   return MaybeSharedMemoryArbiter()->CreateTraceWriter(buf_id,
40395                                                        buffer_exhausted_policy);
40396 }
40397 
NotifyFlushComplete(FlushRequestID id)40398 void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
40399     FlushRequestID id) {
40400   PERFETTO_DCHECK_THREAD(thread_checker_);
40401   PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
40402   return MaybeSharedMemoryArbiter()->NotifyFlushComplete(id);
40403 }
40404 
OnTracingSetup()40405 void TracingServiceImpl::ProducerEndpointImpl::OnTracingSetup() {
40406   auto weak_this = weak_ptr_factory_.GetWeakPtr();
40407   task_runner_->PostTask([weak_this] {
40408     if (weak_this)
40409       weak_this->producer_->OnTracingSetup();
40410   });
40411 }
40412 
Flush(FlushRequestID flush_request_id,const std::vector<DataSourceInstanceID> & data_sources)40413 void TracingServiceImpl::ProducerEndpointImpl::Flush(
40414     FlushRequestID flush_request_id,
40415     const std::vector<DataSourceInstanceID>& data_sources) {
40416   PERFETTO_DCHECK_THREAD(thread_checker_);
40417   auto weak_this = weak_ptr_factory_.GetWeakPtr();
40418   task_runner_->PostTask([weak_this, flush_request_id, data_sources] {
40419     if (weak_this) {
40420       weak_this->producer_->Flush(flush_request_id, data_sources.data(),
40421                                   data_sources.size());
40422     }
40423   });
40424 }
40425 
SetupDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & config)40426 void TracingServiceImpl::ProducerEndpointImpl::SetupDataSource(
40427     DataSourceInstanceID ds_id,
40428     const DataSourceConfig& config) {
40429   PERFETTO_DCHECK_THREAD(thread_checker_);
40430   allowed_target_buffers_.insert(static_cast<BufferID>(config.target_buffer()));
40431   auto weak_this = weak_ptr_factory_.GetWeakPtr();
40432   task_runner_->PostTask([weak_this, ds_id, config] {
40433     if (weak_this)
40434       weak_this->producer_->SetupDataSource(ds_id, std::move(config));
40435   });
40436 }
40437 
StartDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & config)40438 void TracingServiceImpl::ProducerEndpointImpl::StartDataSource(
40439     DataSourceInstanceID ds_id,
40440     const DataSourceConfig& config) {
40441   PERFETTO_DCHECK_THREAD(thread_checker_);
40442   auto weak_this = weak_ptr_factory_.GetWeakPtr();
40443   task_runner_->PostTask([weak_this, ds_id, config] {
40444     if (weak_this)
40445       weak_this->producer_->StartDataSource(ds_id, std::move(config));
40446   });
40447 }
40448 
NotifyDataSourceStarted(DataSourceInstanceID data_source_id)40449 void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStarted(
40450     DataSourceInstanceID data_source_id) {
40451   PERFETTO_DCHECK_THREAD(thread_checker_);
40452   service_->NotifyDataSourceStarted(id_, data_source_id);
40453 }
40454 
NotifyDataSourceStopped(DataSourceInstanceID data_source_id)40455 void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStopped(
40456     DataSourceInstanceID data_source_id) {
40457   PERFETTO_DCHECK_THREAD(thread_checker_);
40458   service_->NotifyDataSourceStopped(id_, data_source_id);
40459 }
40460 
OnFreeBuffers(const std::vector<BufferID> & target_buffers)40461 void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
40462     const std::vector<BufferID>& target_buffers) {
40463   if (allowed_target_buffers_.empty())
40464     return;
40465   for (BufferID buffer : target_buffers)
40466     allowed_target_buffers_.erase(buffer);
40467 }
40468 
ClearIncrementalState(const std::vector<DataSourceInstanceID> & data_sources)40469 void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
40470     const std::vector<DataSourceInstanceID>& data_sources) {
40471   PERFETTO_DCHECK_THREAD(thread_checker_);
40472   auto weak_this = weak_ptr_factory_.GetWeakPtr();
40473   task_runner_->PostTask([weak_this, data_sources] {
40474     if (weak_this) {
40475       weak_this->producer_->ClearIncrementalState(data_sources.data(),
40476                                                   data_sources.size());
40477     }
40478   });
40479 }
40480 
Sync(std::function<void ()> callback)40481 void TracingServiceImpl::ProducerEndpointImpl::Sync(
40482     std::function<void()> callback) {
40483   task_runner_->PostTask(callback);
40484 }
40485 
40486 ////////////////////////////////////////////////////////////////////////////////
40487 // TracingServiceImpl::TracingSession implementation
40488 ////////////////////////////////////////////////////////////////////////////////
40489 
TracingSession(TracingSessionID session_id,ConsumerEndpointImpl * consumer,const TraceConfig & new_config)40490 TracingServiceImpl::TracingSession::TracingSession(
40491     TracingSessionID session_id,
40492     ConsumerEndpointImpl* consumer,
40493     const TraceConfig& new_config)
40494     : id(session_id),
40495       consumer_maybe_null(consumer),
40496       consumer_uid(consumer->uid_),
40497       config(new_config) {
40498   // all_data_sources_flushed is special because we store up to 64 events of
40499   // this type. Other events will go through the default case in
40500   // SnapshotLifecycleEvent() where they will be given a max history of 1.
40501   lifecycle_events.emplace_back(
40502       protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
40503       64 /* max_size */);
40504 }
40505 
40506 }  // namespace perfetto
40507 // gen_amalgamated begin source: src/tracing/internal/in_process_tracing_backend.cc
40508 /*
40509  * Copyright (C) 2019 The Android Open Source Project
40510  *
40511  * Licensed under the Apache License, Version 2.0 (the "License");
40512  * you may not use this file except in compliance with the License.
40513  * You may obtain a copy of the License at
40514  *
40515  *      http://www.apache.org/licenses/LICENSE-2.0
40516  *
40517  * Unless required by applicable law or agreed to in writing, software
40518  * distributed under the License is distributed on an "AS IS" BASIS,
40519  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40520  * See the License for the specific language governing permissions and
40521  * limitations under the License.
40522  */
40523 
40524 // gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
40525 
40526 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
40527 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
40528 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
40529 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
40530 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
40531 
40532 // TODO(primiano): When the in-process backend is used, we should never end up
40533 // in a situation where the thread where the TracingService and Producer live
40534 // writes a packet and hence can get into the GetNewChunk() stall.
40535 // This would happen only if the API client code calls Trace() from one of the
40536 // callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
40537 // hard crash or ignore traces from that thread if that happens, because it
40538 // will deadlock (the Service will never free up the SMB because won't ever get
40539 // to run the task).
40540 
40541 namespace perfetto {
40542 namespace internal {
40543 
40544 namespace {
40545 
40546 class InProcessShm : public SharedMemory {
40547  public:
40548   explicit InProcessShm(size_t size);
40549   ~InProcessShm() override;
40550   void* start() const override;
40551   size_t size() const override;
40552   int fd() const override;
40553 
40554  private:
40555   base::PagedMemory mem_;
40556 };
40557 
40558 class InProcessShmFactory : public SharedMemory::Factory {
40559  public:
40560   ~InProcessShmFactory() override;
40561   std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
40562 };
40563 
40564 InProcessShm::~InProcessShm() = default;
40565 
InProcessShm(size_t size)40566 InProcessShm::InProcessShm(size_t size)
40567     : mem_(base::PagedMemory::Allocate(size)) {}
40568 
start() const40569 void* InProcessShm::start() const {
40570   return mem_.Get();
40571 }
40572 
size() const40573 size_t InProcessShm::size() const {
40574   return mem_.size();
40575 }
40576 
fd() const40577 int InProcessShm::fd() const {
40578   return -1;
40579 }
40580 
40581 InProcessShmFactory::~InProcessShmFactory() = default;
CreateSharedMemory(size_t size)40582 std::unique_ptr<SharedMemory> InProcessShmFactory::CreateSharedMemory(
40583     size_t size) {
40584   return std::unique_ptr<SharedMemory>(new InProcessShm(size));
40585 }
40586 
40587 }  // namespace
40588 
40589 // static
GetInstance()40590 TracingBackend* InProcessTracingBackend::GetInstance() {
40591   static auto* instance = new InProcessTracingBackend();
40592   return instance;
40593 }
40594 
InProcessTracingBackend()40595 InProcessTracingBackend::InProcessTracingBackend() {}
40596 
ConnectProducer(const ConnectProducerArgs & args)40597 std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
40598     const ConnectProducerArgs& args) {
40599   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
40600 
40601   // This should never happen as we can have at most one in-process backend.
40602   if (service_)
40603     PERFETTO_FATAL("InProcessTracingBackend initialized twice");
40604 
40605   return GetOrCreateService(args.task_runner)
40606       ->ConnectProducer(args.producer, /*uid=*/0, args.producer_name,
40607                         args.shmem_size_hint_bytes,
40608                         /*in_process=*/true,
40609                         TracingService::ProducerSMBScrapingMode::kEnabled,
40610                         args.shmem_page_size_hint_bytes);
40611 }
40612 
ConnectConsumer(const ConnectConsumerArgs & args)40613 std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
40614     const ConnectConsumerArgs& args) {
40615   return GetOrCreateService(args.task_runner)
40616       ->ConnectConsumer(args.consumer, /*uid=*/0);
40617 }
40618 
GetOrCreateService(base::TaskRunner * task_runner)40619 TracingService* InProcessTracingBackend::GetOrCreateService(
40620     base::TaskRunner* task_runner) {
40621   if (!service_) {
40622     std::unique_ptr<InProcessShmFactory> shm(new InProcessShmFactory());
40623     service_ = TracingService::CreateInstance(std::move(shm), task_runner);
40624     service_->SetSMBScrapingEnabled(true);
40625   }
40626   return service_.get();
40627 }
40628 
40629 }  // namespace internal
40630 }  // namespace perfetto
40631 // gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.gen.cc
40632 // gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.gen.h
40633 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
40634 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
40635 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
40636 
40637 #include <stdint.h>
40638 #include <bitset>
40639 #include <vector>
40640 #include <string>
40641 #include <type_traits>
40642 
40643 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
40644 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
40645 // gen_amalgamated expanded: #include "perfetto/base/export.h"
40646 
40647 namespace perfetto {
40648 namespace protos {
40649 namespace gen {
40650 class QueryCapabilitiesResponse;
40651 class TracingServiceCapabilities;
40652 class QueryCapabilitiesRequest;
40653 class QueryServiceStateResponse;
40654 class TracingServiceState;
40655 class TracingServiceState_DataSource;
40656 class DataSourceDescriptor;
40657 class TracingServiceState_Producer;
40658 class QueryServiceStateRequest;
40659 class ObserveEventsResponse;
40660 class ObservableEvents;
40661 class ObservableEvents_DataSourceInstanceStateChange;
40662 class ObserveEventsRequest;
40663 class GetTraceStatsResponse;
40664 class TraceStats;
40665 class TraceStats_BufferStats;
40666 class GetTraceStatsRequest;
40667 class AttachResponse;
40668 class TraceConfig;
40669 class TraceConfig_IncidentReportConfig;
40670 class TraceConfig_IncrementalStateConfig;
40671 class TraceConfig_TriggerConfig;
40672 class TraceConfig_TriggerConfig_Trigger;
40673 class TraceConfig_GuardrailOverrides;
40674 class TraceConfig_StatsdMetadata;
40675 class TraceConfig_ProducerConfig;
40676 class TraceConfig_BuiltinDataSource;
40677 class TraceConfig_DataSource;
40678 class DataSourceConfig;
40679 class TestConfig;
40680 class TestConfig_DummyFields;
40681 class ChromeConfig;
40682 class TraceConfig_BufferConfig;
40683 class AttachRequest;
40684 class DetachResponse;
40685 class DetachRequest;
40686 class FlushResponse;
40687 class FlushRequest;
40688 class FreeBuffersResponse;
40689 class FreeBuffersRequest;
40690 class ReadBuffersResponse;
40691 class ReadBuffersResponse_Slice;
40692 class ReadBuffersRequest;
40693 class DisableTracingResponse;
40694 class DisableTracingRequest;
40695 class ChangeTraceConfigResponse;
40696 class ChangeTraceConfigRequest;
40697 class StartTracingResponse;
40698 class StartTracingRequest;
40699 class EnableTracingResponse;
40700 class EnableTracingRequest;
40701 enum ObservableEvents_Type : int;
40702 enum ObservableEvents_DataSourceInstanceState : int;
40703 enum TraceConfig_LockdownModeOperation : int;
40704 enum TraceConfig_CompressionType : int;
40705 enum TraceConfig_TriggerConfig_TriggerMode : int;
40706 enum BuiltinClock : int;
40707 enum TraceConfig_BufferConfig_FillPolicy : int;
40708 }  // namespace perfetto
40709 }  // namespace protos
40710 }  // namespace gen
40711 
40712 namespace protozero {
40713 class Message;
40714 }  // namespace protozero
40715 
40716 namespace perfetto {
40717 namespace protos {
40718 namespace gen {
40719 
40720 class PERFETTO_EXPORT QueryCapabilitiesResponse : public ::protozero::CppMessageObj {
40721  public:
40722   enum FieldNumbers {
40723     kCapabilitiesFieldNumber = 1,
40724   };
40725 
40726   QueryCapabilitiesResponse();
40727   ~QueryCapabilitiesResponse() override;
40728   QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept;
40729   QueryCapabilitiesResponse& operator=(QueryCapabilitiesResponse&&);
40730   QueryCapabilitiesResponse(const QueryCapabilitiesResponse&);
40731   QueryCapabilitiesResponse& operator=(const QueryCapabilitiesResponse&);
40732   bool operator==(const QueryCapabilitiesResponse&) const;
operator !=(const QueryCapabilitiesResponse & other) const40733   bool operator!=(const QueryCapabilitiesResponse& other) const { return !(*this == other); }
40734 
40735   bool ParseFromArray(const void*, size_t) override;
40736   std::string SerializeAsString() const override;
40737   std::vector<uint8_t> SerializeAsArray() const override;
40738   void Serialize(::protozero::Message*) const;
40739 
has_capabilities() const40740   bool has_capabilities() const { return _has_field_[1]; }
capabilities() const40741   const TracingServiceCapabilities& capabilities() const { return *capabilities_; }
mutable_capabilities()40742   TracingServiceCapabilities* mutable_capabilities() { _has_field_.set(1); return capabilities_.get(); }
40743 
40744  private:
40745   ::protozero::CopyablePtr<TracingServiceCapabilities> capabilities_;
40746 
40747   // Allows to preserve unknown protobuf fields for compatibility
40748   // with future versions of .proto files.
40749   std::string unknown_fields_;
40750 
40751   std::bitset<2> _has_field_{};
40752 };
40753 
40754 
40755 class PERFETTO_EXPORT QueryCapabilitiesRequest : public ::protozero::CppMessageObj {
40756  public:
40757   enum FieldNumbers {
40758   };
40759 
40760   QueryCapabilitiesRequest();
40761   ~QueryCapabilitiesRequest() override;
40762   QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept;
40763   QueryCapabilitiesRequest& operator=(QueryCapabilitiesRequest&&);
40764   QueryCapabilitiesRequest(const QueryCapabilitiesRequest&);
40765   QueryCapabilitiesRequest& operator=(const QueryCapabilitiesRequest&);
40766   bool operator==(const QueryCapabilitiesRequest&) const;
operator !=(const QueryCapabilitiesRequest & other) const40767   bool operator!=(const QueryCapabilitiesRequest& other) const { return !(*this == other); }
40768 
40769   bool ParseFromArray(const void*, size_t) override;
40770   std::string SerializeAsString() const override;
40771   std::vector<uint8_t> SerializeAsArray() const override;
40772   void Serialize(::protozero::Message*) const;
40773 
40774  private:
40775 
40776   // Allows to preserve unknown protobuf fields for compatibility
40777   // with future versions of .proto files.
40778   std::string unknown_fields_;
40779 
40780   std::bitset<2> _has_field_{};
40781 };
40782 
40783 
40784 class PERFETTO_EXPORT QueryServiceStateResponse : public ::protozero::CppMessageObj {
40785  public:
40786   enum FieldNumbers {
40787     kServiceStateFieldNumber = 1,
40788   };
40789 
40790   QueryServiceStateResponse();
40791   ~QueryServiceStateResponse() override;
40792   QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept;
40793   QueryServiceStateResponse& operator=(QueryServiceStateResponse&&);
40794   QueryServiceStateResponse(const QueryServiceStateResponse&);
40795   QueryServiceStateResponse& operator=(const QueryServiceStateResponse&);
40796   bool operator==(const QueryServiceStateResponse&) const;
operator !=(const QueryServiceStateResponse & other) const40797   bool operator!=(const QueryServiceStateResponse& other) const { return !(*this == other); }
40798 
40799   bool ParseFromArray(const void*, size_t) override;
40800   std::string SerializeAsString() const override;
40801   std::vector<uint8_t> SerializeAsArray() const override;
40802   void Serialize(::protozero::Message*) const;
40803 
has_service_state() const40804   bool has_service_state() const { return _has_field_[1]; }
service_state() const40805   const TracingServiceState& service_state() const { return *service_state_; }
mutable_service_state()40806   TracingServiceState* mutable_service_state() { _has_field_.set(1); return service_state_.get(); }
40807 
40808  private:
40809   ::protozero::CopyablePtr<TracingServiceState> service_state_;
40810 
40811   // Allows to preserve unknown protobuf fields for compatibility
40812   // with future versions of .proto files.
40813   std::string unknown_fields_;
40814 
40815   std::bitset<2> _has_field_{};
40816 };
40817 
40818 
40819 class PERFETTO_EXPORT QueryServiceStateRequest : public ::protozero::CppMessageObj {
40820  public:
40821   enum FieldNumbers {
40822   };
40823 
40824   QueryServiceStateRequest();
40825   ~QueryServiceStateRequest() override;
40826   QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept;
40827   QueryServiceStateRequest& operator=(QueryServiceStateRequest&&);
40828   QueryServiceStateRequest(const QueryServiceStateRequest&);
40829   QueryServiceStateRequest& operator=(const QueryServiceStateRequest&);
40830   bool operator==(const QueryServiceStateRequest&) const;
operator !=(const QueryServiceStateRequest & other) const40831   bool operator!=(const QueryServiceStateRequest& other) const { return !(*this == other); }
40832 
40833   bool ParseFromArray(const void*, size_t) override;
40834   std::string SerializeAsString() const override;
40835   std::vector<uint8_t> SerializeAsArray() const override;
40836   void Serialize(::protozero::Message*) const;
40837 
40838  private:
40839 
40840   // Allows to preserve unknown protobuf fields for compatibility
40841   // with future versions of .proto files.
40842   std::string unknown_fields_;
40843 
40844   std::bitset<2> _has_field_{};
40845 };
40846 
40847 
40848 class PERFETTO_EXPORT ObserveEventsResponse : public ::protozero::CppMessageObj {
40849  public:
40850   enum FieldNumbers {
40851     kEventsFieldNumber = 1,
40852   };
40853 
40854   ObserveEventsResponse();
40855   ~ObserveEventsResponse() override;
40856   ObserveEventsResponse(ObserveEventsResponse&&) noexcept;
40857   ObserveEventsResponse& operator=(ObserveEventsResponse&&);
40858   ObserveEventsResponse(const ObserveEventsResponse&);
40859   ObserveEventsResponse& operator=(const ObserveEventsResponse&);
40860   bool operator==(const ObserveEventsResponse&) const;
operator !=(const ObserveEventsResponse & other) const40861   bool operator!=(const ObserveEventsResponse& other) const { return !(*this == other); }
40862 
40863   bool ParseFromArray(const void*, size_t) override;
40864   std::string SerializeAsString() const override;
40865   std::vector<uint8_t> SerializeAsArray() const override;
40866   void Serialize(::protozero::Message*) const;
40867 
has_events() const40868   bool has_events() const { return _has_field_[1]; }
events() const40869   const ObservableEvents& events() const { return *events_; }
mutable_events()40870   ObservableEvents* mutable_events() { _has_field_.set(1); return events_.get(); }
40871 
40872  private:
40873   ::protozero::CopyablePtr<ObservableEvents> events_;
40874 
40875   // Allows to preserve unknown protobuf fields for compatibility
40876   // with future versions of .proto files.
40877   std::string unknown_fields_;
40878 
40879   std::bitset<2> _has_field_{};
40880 };
40881 
40882 
40883 class PERFETTO_EXPORT ObserveEventsRequest : public ::protozero::CppMessageObj {
40884  public:
40885   enum FieldNumbers {
40886     kEventsToObserveFieldNumber = 1,
40887   };
40888 
40889   ObserveEventsRequest();
40890   ~ObserveEventsRequest() override;
40891   ObserveEventsRequest(ObserveEventsRequest&&) noexcept;
40892   ObserveEventsRequest& operator=(ObserveEventsRequest&&);
40893   ObserveEventsRequest(const ObserveEventsRequest&);
40894   ObserveEventsRequest& operator=(const ObserveEventsRequest&);
40895   bool operator==(const ObserveEventsRequest&) const;
operator !=(const ObserveEventsRequest & other) const40896   bool operator!=(const ObserveEventsRequest& other) const { return !(*this == other); }
40897 
40898   bool ParseFromArray(const void*, size_t) override;
40899   std::string SerializeAsString() const override;
40900   std::vector<uint8_t> SerializeAsArray() const override;
40901   void Serialize(::protozero::Message*) const;
40902 
events_to_observe_size() const40903   int events_to_observe_size() const { return static_cast<int>(events_to_observe_.size()); }
events_to_observe() const40904   const std::vector<ObservableEvents_Type>& events_to_observe() const { return events_to_observe_; }
mutable_events_to_observe()40905   std::vector<ObservableEvents_Type>* mutable_events_to_observe() { return &events_to_observe_; }
clear_events_to_observe()40906   void clear_events_to_observe() { events_to_observe_.clear(); }
add_events_to_observe(ObservableEvents_Type value)40907   void add_events_to_observe(ObservableEvents_Type value) { events_to_observe_.emplace_back(value); }
add_events_to_observe()40908   ObservableEvents_Type* add_events_to_observe() { events_to_observe_.emplace_back(); return &events_to_observe_.back(); }
40909 
40910  private:
40911   std::vector<ObservableEvents_Type> events_to_observe_;
40912 
40913   // Allows to preserve unknown protobuf fields for compatibility
40914   // with future versions of .proto files.
40915   std::string unknown_fields_;
40916 
40917   std::bitset<2> _has_field_{};
40918 };
40919 
40920 
40921 class PERFETTO_EXPORT GetTraceStatsResponse : public ::protozero::CppMessageObj {
40922  public:
40923   enum FieldNumbers {
40924     kTraceStatsFieldNumber = 1,
40925   };
40926 
40927   GetTraceStatsResponse();
40928   ~GetTraceStatsResponse() override;
40929   GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept;
40930   GetTraceStatsResponse& operator=(GetTraceStatsResponse&&);
40931   GetTraceStatsResponse(const GetTraceStatsResponse&);
40932   GetTraceStatsResponse& operator=(const GetTraceStatsResponse&);
40933   bool operator==(const GetTraceStatsResponse&) const;
operator !=(const GetTraceStatsResponse & other) const40934   bool operator!=(const GetTraceStatsResponse& other) const { return !(*this == other); }
40935 
40936   bool ParseFromArray(const void*, size_t) override;
40937   std::string SerializeAsString() const override;
40938   std::vector<uint8_t> SerializeAsArray() const override;
40939   void Serialize(::protozero::Message*) const;
40940 
has_trace_stats() const40941   bool has_trace_stats() const { return _has_field_[1]; }
trace_stats() const40942   const TraceStats& trace_stats() const { return *trace_stats_; }
mutable_trace_stats()40943   TraceStats* mutable_trace_stats() { _has_field_.set(1); return trace_stats_.get(); }
40944 
40945  private:
40946   ::protozero::CopyablePtr<TraceStats> trace_stats_;
40947 
40948   // Allows to preserve unknown protobuf fields for compatibility
40949   // with future versions of .proto files.
40950   std::string unknown_fields_;
40951 
40952   std::bitset<2> _has_field_{};
40953 };
40954 
40955 
40956 class PERFETTO_EXPORT GetTraceStatsRequest : public ::protozero::CppMessageObj {
40957  public:
40958   enum FieldNumbers {
40959   };
40960 
40961   GetTraceStatsRequest();
40962   ~GetTraceStatsRequest() override;
40963   GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept;
40964   GetTraceStatsRequest& operator=(GetTraceStatsRequest&&);
40965   GetTraceStatsRequest(const GetTraceStatsRequest&);
40966   GetTraceStatsRequest& operator=(const GetTraceStatsRequest&);
40967   bool operator==(const GetTraceStatsRequest&) const;
operator !=(const GetTraceStatsRequest & other) const40968   bool operator!=(const GetTraceStatsRequest& other) const { return !(*this == other); }
40969 
40970   bool ParseFromArray(const void*, size_t) override;
40971   std::string SerializeAsString() const override;
40972   std::vector<uint8_t> SerializeAsArray() const override;
40973   void Serialize(::protozero::Message*) const;
40974 
40975  private:
40976 
40977   // Allows to preserve unknown protobuf fields for compatibility
40978   // with future versions of .proto files.
40979   std::string unknown_fields_;
40980 
40981   std::bitset<2> _has_field_{};
40982 };
40983 
40984 
40985 class PERFETTO_EXPORT AttachResponse : public ::protozero::CppMessageObj {
40986  public:
40987   enum FieldNumbers {
40988     kTraceConfigFieldNumber = 1,
40989   };
40990 
40991   AttachResponse();
40992   ~AttachResponse() override;
40993   AttachResponse(AttachResponse&&) noexcept;
40994   AttachResponse& operator=(AttachResponse&&);
40995   AttachResponse(const AttachResponse&);
40996   AttachResponse& operator=(const AttachResponse&);
40997   bool operator==(const AttachResponse&) const;
operator !=(const AttachResponse & other) const40998   bool operator!=(const AttachResponse& other) const { return !(*this == other); }
40999 
41000   bool ParseFromArray(const void*, size_t) override;
41001   std::string SerializeAsString() const override;
41002   std::vector<uint8_t> SerializeAsArray() const override;
41003   void Serialize(::protozero::Message*) const;
41004 
has_trace_config() const41005   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const41006   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()41007   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
41008 
41009  private:
41010   ::protozero::CopyablePtr<TraceConfig> trace_config_;
41011 
41012   // Allows to preserve unknown protobuf fields for compatibility
41013   // with future versions of .proto files.
41014   std::string unknown_fields_;
41015 
41016   std::bitset<2> _has_field_{};
41017 };
41018 
41019 
41020 class PERFETTO_EXPORT AttachRequest : public ::protozero::CppMessageObj {
41021  public:
41022   enum FieldNumbers {
41023     kKeyFieldNumber = 1,
41024   };
41025 
41026   AttachRequest();
41027   ~AttachRequest() override;
41028   AttachRequest(AttachRequest&&) noexcept;
41029   AttachRequest& operator=(AttachRequest&&);
41030   AttachRequest(const AttachRequest&);
41031   AttachRequest& operator=(const AttachRequest&);
41032   bool operator==(const AttachRequest&) const;
operator !=(const AttachRequest & other) const41033   bool operator!=(const AttachRequest& other) const { return !(*this == other); }
41034 
41035   bool ParseFromArray(const void*, size_t) override;
41036   std::string SerializeAsString() const override;
41037   std::vector<uint8_t> SerializeAsArray() const override;
41038   void Serialize(::protozero::Message*) const;
41039 
has_key() const41040   bool has_key() const { return _has_field_[1]; }
key() const41041   const std::string& key() const { return key_; }
set_key(const std::string & value)41042   void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
41043 
41044  private:
41045   std::string key_{};
41046 
41047   // Allows to preserve unknown protobuf fields for compatibility
41048   // with future versions of .proto files.
41049   std::string unknown_fields_;
41050 
41051   std::bitset<2> _has_field_{};
41052 };
41053 
41054 
41055 class PERFETTO_EXPORT DetachResponse : public ::protozero::CppMessageObj {
41056  public:
41057   enum FieldNumbers {
41058   };
41059 
41060   DetachResponse();
41061   ~DetachResponse() override;
41062   DetachResponse(DetachResponse&&) noexcept;
41063   DetachResponse& operator=(DetachResponse&&);
41064   DetachResponse(const DetachResponse&);
41065   DetachResponse& operator=(const DetachResponse&);
41066   bool operator==(const DetachResponse&) const;
operator !=(const DetachResponse & other) const41067   bool operator!=(const DetachResponse& other) const { return !(*this == other); }
41068 
41069   bool ParseFromArray(const void*, size_t) override;
41070   std::string SerializeAsString() const override;
41071   std::vector<uint8_t> SerializeAsArray() const override;
41072   void Serialize(::protozero::Message*) const;
41073 
41074  private:
41075 
41076   // Allows to preserve unknown protobuf fields for compatibility
41077   // with future versions of .proto files.
41078   std::string unknown_fields_;
41079 
41080   std::bitset<2> _has_field_{};
41081 };
41082 
41083 
41084 class PERFETTO_EXPORT DetachRequest : public ::protozero::CppMessageObj {
41085  public:
41086   enum FieldNumbers {
41087     kKeyFieldNumber = 1,
41088   };
41089 
41090   DetachRequest();
41091   ~DetachRequest() override;
41092   DetachRequest(DetachRequest&&) noexcept;
41093   DetachRequest& operator=(DetachRequest&&);
41094   DetachRequest(const DetachRequest&);
41095   DetachRequest& operator=(const DetachRequest&);
41096   bool operator==(const DetachRequest&) const;
operator !=(const DetachRequest & other) const41097   bool operator!=(const DetachRequest& other) const { return !(*this == other); }
41098 
41099   bool ParseFromArray(const void*, size_t) override;
41100   std::string SerializeAsString() const override;
41101   std::vector<uint8_t> SerializeAsArray() const override;
41102   void Serialize(::protozero::Message*) const;
41103 
has_key() const41104   bool has_key() const { return _has_field_[1]; }
key() const41105   const std::string& key() const { return key_; }
set_key(const std::string & value)41106   void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
41107 
41108  private:
41109   std::string key_{};
41110 
41111   // Allows to preserve unknown protobuf fields for compatibility
41112   // with future versions of .proto files.
41113   std::string unknown_fields_;
41114 
41115   std::bitset<2> _has_field_{};
41116 };
41117 
41118 
41119 class PERFETTO_EXPORT FlushResponse : public ::protozero::CppMessageObj {
41120  public:
41121   enum FieldNumbers {
41122   };
41123 
41124   FlushResponse();
41125   ~FlushResponse() override;
41126   FlushResponse(FlushResponse&&) noexcept;
41127   FlushResponse& operator=(FlushResponse&&);
41128   FlushResponse(const FlushResponse&);
41129   FlushResponse& operator=(const FlushResponse&);
41130   bool operator==(const FlushResponse&) const;
operator !=(const FlushResponse & other) const41131   bool operator!=(const FlushResponse& other) const { return !(*this == other); }
41132 
41133   bool ParseFromArray(const void*, size_t) override;
41134   std::string SerializeAsString() const override;
41135   std::vector<uint8_t> SerializeAsArray() const override;
41136   void Serialize(::protozero::Message*) const;
41137 
41138  private:
41139 
41140   // Allows to preserve unknown protobuf fields for compatibility
41141   // with future versions of .proto files.
41142   std::string unknown_fields_;
41143 
41144   std::bitset<2> _has_field_{};
41145 };
41146 
41147 
41148 class PERFETTO_EXPORT FlushRequest : public ::protozero::CppMessageObj {
41149  public:
41150   enum FieldNumbers {
41151     kTimeoutMsFieldNumber = 1,
41152   };
41153 
41154   FlushRequest();
41155   ~FlushRequest() override;
41156   FlushRequest(FlushRequest&&) noexcept;
41157   FlushRequest& operator=(FlushRequest&&);
41158   FlushRequest(const FlushRequest&);
41159   FlushRequest& operator=(const FlushRequest&);
41160   bool operator==(const FlushRequest&) const;
operator !=(const FlushRequest & other) const41161   bool operator!=(const FlushRequest& other) const { return !(*this == other); }
41162 
41163   bool ParseFromArray(const void*, size_t) override;
41164   std::string SerializeAsString() const override;
41165   std::vector<uint8_t> SerializeAsArray() const override;
41166   void Serialize(::protozero::Message*) const;
41167 
has_timeout_ms() const41168   bool has_timeout_ms() const { return _has_field_[1]; }
timeout_ms() const41169   uint32_t timeout_ms() const { return timeout_ms_; }
set_timeout_ms(uint32_t value)41170   void set_timeout_ms(uint32_t value) { timeout_ms_ = value; _has_field_.set(1); }
41171 
41172  private:
41173   uint32_t timeout_ms_{};
41174 
41175   // Allows to preserve unknown protobuf fields for compatibility
41176   // with future versions of .proto files.
41177   std::string unknown_fields_;
41178 
41179   std::bitset<2> _has_field_{};
41180 };
41181 
41182 
41183 class PERFETTO_EXPORT FreeBuffersResponse : public ::protozero::CppMessageObj {
41184  public:
41185   enum FieldNumbers {
41186   };
41187 
41188   FreeBuffersResponse();
41189   ~FreeBuffersResponse() override;
41190   FreeBuffersResponse(FreeBuffersResponse&&) noexcept;
41191   FreeBuffersResponse& operator=(FreeBuffersResponse&&);
41192   FreeBuffersResponse(const FreeBuffersResponse&);
41193   FreeBuffersResponse& operator=(const FreeBuffersResponse&);
41194   bool operator==(const FreeBuffersResponse&) const;
operator !=(const FreeBuffersResponse & other) const41195   bool operator!=(const FreeBuffersResponse& other) const { return !(*this == other); }
41196 
41197   bool ParseFromArray(const void*, size_t) override;
41198   std::string SerializeAsString() const override;
41199   std::vector<uint8_t> SerializeAsArray() const override;
41200   void Serialize(::protozero::Message*) const;
41201 
41202  private:
41203 
41204   // Allows to preserve unknown protobuf fields for compatibility
41205   // with future versions of .proto files.
41206   std::string unknown_fields_;
41207 
41208   std::bitset<2> _has_field_{};
41209 };
41210 
41211 
41212 class PERFETTO_EXPORT FreeBuffersRequest : public ::protozero::CppMessageObj {
41213  public:
41214   enum FieldNumbers {
41215     kBufferIdsFieldNumber = 1,
41216   };
41217 
41218   FreeBuffersRequest();
41219   ~FreeBuffersRequest() override;
41220   FreeBuffersRequest(FreeBuffersRequest&&) noexcept;
41221   FreeBuffersRequest& operator=(FreeBuffersRequest&&);
41222   FreeBuffersRequest(const FreeBuffersRequest&);
41223   FreeBuffersRequest& operator=(const FreeBuffersRequest&);
41224   bool operator==(const FreeBuffersRequest&) const;
operator !=(const FreeBuffersRequest & other) const41225   bool operator!=(const FreeBuffersRequest& other) const { return !(*this == other); }
41226 
41227   bool ParseFromArray(const void*, size_t) override;
41228   std::string SerializeAsString() const override;
41229   std::vector<uint8_t> SerializeAsArray() const override;
41230   void Serialize(::protozero::Message*) const;
41231 
buffer_ids_size() const41232   int buffer_ids_size() const { return static_cast<int>(buffer_ids_.size()); }
buffer_ids() const41233   const std::vector<uint32_t>& buffer_ids() const { return buffer_ids_; }
mutable_buffer_ids()41234   std::vector<uint32_t>* mutable_buffer_ids() { return &buffer_ids_; }
clear_buffer_ids()41235   void clear_buffer_ids() { buffer_ids_.clear(); }
add_buffer_ids(uint32_t value)41236   void add_buffer_ids(uint32_t value) { buffer_ids_.emplace_back(value); }
add_buffer_ids()41237   uint32_t* add_buffer_ids() { buffer_ids_.emplace_back(); return &buffer_ids_.back(); }
41238 
41239  private:
41240   std::vector<uint32_t> buffer_ids_;
41241 
41242   // Allows to preserve unknown protobuf fields for compatibility
41243   // with future versions of .proto files.
41244   std::string unknown_fields_;
41245 
41246   std::bitset<2> _has_field_{};
41247 };
41248 
41249 
41250 class PERFETTO_EXPORT ReadBuffersResponse : public ::protozero::CppMessageObj {
41251  public:
41252   using Slice = ReadBuffersResponse_Slice;
41253   enum FieldNumbers {
41254     kSlicesFieldNumber = 2,
41255   };
41256 
41257   ReadBuffersResponse();
41258   ~ReadBuffersResponse() override;
41259   ReadBuffersResponse(ReadBuffersResponse&&) noexcept;
41260   ReadBuffersResponse& operator=(ReadBuffersResponse&&);
41261   ReadBuffersResponse(const ReadBuffersResponse&);
41262   ReadBuffersResponse& operator=(const ReadBuffersResponse&);
41263   bool operator==(const ReadBuffersResponse&) const;
operator !=(const ReadBuffersResponse & other) const41264   bool operator!=(const ReadBuffersResponse& other) const { return !(*this == other); }
41265 
41266   bool ParseFromArray(const void*, size_t) override;
41267   std::string SerializeAsString() const override;
41268   std::vector<uint8_t> SerializeAsArray() const override;
41269   void Serialize(::protozero::Message*) const;
41270 
slices_size() const41271   int slices_size() const { return static_cast<int>(slices_.size()); }
slices() const41272   const std::vector<ReadBuffersResponse_Slice>& slices() const { return slices_; }
mutable_slices()41273   std::vector<ReadBuffersResponse_Slice>* mutable_slices() { return &slices_; }
clear_slices()41274   void clear_slices() { slices_.clear(); }
add_slices()41275   ReadBuffersResponse_Slice* add_slices() { slices_.emplace_back(); return &slices_.back(); }
41276 
41277  private:
41278   std::vector<ReadBuffersResponse_Slice> slices_;
41279 
41280   // Allows to preserve unknown protobuf fields for compatibility
41281   // with future versions of .proto files.
41282   std::string unknown_fields_;
41283 
41284   std::bitset<3> _has_field_{};
41285 };
41286 
41287 
41288 class PERFETTO_EXPORT ReadBuffersResponse_Slice : public ::protozero::CppMessageObj {
41289  public:
41290   enum FieldNumbers {
41291     kDataFieldNumber = 1,
41292     kLastSliceForPacketFieldNumber = 2,
41293   };
41294 
41295   ReadBuffersResponse_Slice();
41296   ~ReadBuffersResponse_Slice() override;
41297   ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept;
41298   ReadBuffersResponse_Slice& operator=(ReadBuffersResponse_Slice&&);
41299   ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&);
41300   ReadBuffersResponse_Slice& operator=(const ReadBuffersResponse_Slice&);
41301   bool operator==(const ReadBuffersResponse_Slice&) const;
operator !=(const ReadBuffersResponse_Slice & other) const41302   bool operator!=(const ReadBuffersResponse_Slice& other) const { return !(*this == other); }
41303 
41304   bool ParseFromArray(const void*, size_t) override;
41305   std::string SerializeAsString() const override;
41306   std::vector<uint8_t> SerializeAsArray() const override;
41307   void Serialize(::protozero::Message*) const;
41308 
has_data() const41309   bool has_data() const { return _has_field_[1]; }
data() const41310   const std::string& data() const { return data_; }
set_data(const std::string & value)41311   void set_data(const std::string& value) { data_ = value; _has_field_.set(1); }
set_data(const void * p,size_t s)41312   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
41313 
has_last_slice_for_packet() const41314   bool has_last_slice_for_packet() const { return _has_field_[2]; }
last_slice_for_packet() const41315   bool last_slice_for_packet() const { return last_slice_for_packet_; }
set_last_slice_for_packet(bool value)41316   void set_last_slice_for_packet(bool value) { last_slice_for_packet_ = value; _has_field_.set(2); }
41317 
41318  private:
41319   std::string data_{};
41320   bool last_slice_for_packet_{};
41321 
41322   // Allows to preserve unknown protobuf fields for compatibility
41323   // with future versions of .proto files.
41324   std::string unknown_fields_;
41325 
41326   std::bitset<3> _has_field_{};
41327 };
41328 
41329 
41330 class PERFETTO_EXPORT ReadBuffersRequest : public ::protozero::CppMessageObj {
41331  public:
41332   enum FieldNumbers {
41333   };
41334 
41335   ReadBuffersRequest();
41336   ~ReadBuffersRequest() override;
41337   ReadBuffersRequest(ReadBuffersRequest&&) noexcept;
41338   ReadBuffersRequest& operator=(ReadBuffersRequest&&);
41339   ReadBuffersRequest(const ReadBuffersRequest&);
41340   ReadBuffersRequest& operator=(const ReadBuffersRequest&);
41341   bool operator==(const ReadBuffersRequest&) const;
operator !=(const ReadBuffersRequest & other) const41342   bool operator!=(const ReadBuffersRequest& other) const { return !(*this == other); }
41343 
41344   bool ParseFromArray(const void*, size_t) override;
41345   std::string SerializeAsString() const override;
41346   std::vector<uint8_t> SerializeAsArray() const override;
41347   void Serialize(::protozero::Message*) const;
41348 
41349  private:
41350 
41351   // Allows to preserve unknown protobuf fields for compatibility
41352   // with future versions of .proto files.
41353   std::string unknown_fields_;
41354 
41355   std::bitset<2> _has_field_{};
41356 };
41357 
41358 
41359 class PERFETTO_EXPORT DisableTracingResponse : public ::protozero::CppMessageObj {
41360  public:
41361   enum FieldNumbers {
41362   };
41363 
41364   DisableTracingResponse();
41365   ~DisableTracingResponse() override;
41366   DisableTracingResponse(DisableTracingResponse&&) noexcept;
41367   DisableTracingResponse& operator=(DisableTracingResponse&&);
41368   DisableTracingResponse(const DisableTracingResponse&);
41369   DisableTracingResponse& operator=(const DisableTracingResponse&);
41370   bool operator==(const DisableTracingResponse&) const;
operator !=(const DisableTracingResponse & other) const41371   bool operator!=(const DisableTracingResponse& other) const { return !(*this == other); }
41372 
41373   bool ParseFromArray(const void*, size_t) override;
41374   std::string SerializeAsString() const override;
41375   std::vector<uint8_t> SerializeAsArray() const override;
41376   void Serialize(::protozero::Message*) const;
41377 
41378  private:
41379 
41380   // Allows to preserve unknown protobuf fields for compatibility
41381   // with future versions of .proto files.
41382   std::string unknown_fields_;
41383 
41384   std::bitset<2> _has_field_{};
41385 };
41386 
41387 
41388 class PERFETTO_EXPORT DisableTracingRequest : public ::protozero::CppMessageObj {
41389  public:
41390   enum FieldNumbers {
41391   };
41392 
41393   DisableTracingRequest();
41394   ~DisableTracingRequest() override;
41395   DisableTracingRequest(DisableTracingRequest&&) noexcept;
41396   DisableTracingRequest& operator=(DisableTracingRequest&&);
41397   DisableTracingRequest(const DisableTracingRequest&);
41398   DisableTracingRequest& operator=(const DisableTracingRequest&);
41399   bool operator==(const DisableTracingRequest&) const;
operator !=(const DisableTracingRequest & other) const41400   bool operator!=(const DisableTracingRequest& other) const { return !(*this == other); }
41401 
41402   bool ParseFromArray(const void*, size_t) override;
41403   std::string SerializeAsString() const override;
41404   std::vector<uint8_t> SerializeAsArray() const override;
41405   void Serialize(::protozero::Message*) const;
41406 
41407  private:
41408 
41409   // Allows to preserve unknown protobuf fields for compatibility
41410   // with future versions of .proto files.
41411   std::string unknown_fields_;
41412 
41413   std::bitset<2> _has_field_{};
41414 };
41415 
41416 
41417 class PERFETTO_EXPORT ChangeTraceConfigResponse : public ::protozero::CppMessageObj {
41418  public:
41419   enum FieldNumbers {
41420   };
41421 
41422   ChangeTraceConfigResponse();
41423   ~ChangeTraceConfigResponse() override;
41424   ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept;
41425   ChangeTraceConfigResponse& operator=(ChangeTraceConfigResponse&&);
41426   ChangeTraceConfigResponse(const ChangeTraceConfigResponse&);
41427   ChangeTraceConfigResponse& operator=(const ChangeTraceConfigResponse&);
41428   bool operator==(const ChangeTraceConfigResponse&) const;
operator !=(const ChangeTraceConfigResponse & other) const41429   bool operator!=(const ChangeTraceConfigResponse& other) const { return !(*this == other); }
41430 
41431   bool ParseFromArray(const void*, size_t) override;
41432   std::string SerializeAsString() const override;
41433   std::vector<uint8_t> SerializeAsArray() const override;
41434   void Serialize(::protozero::Message*) const;
41435 
41436  private:
41437 
41438   // Allows to preserve unknown protobuf fields for compatibility
41439   // with future versions of .proto files.
41440   std::string unknown_fields_;
41441 
41442   std::bitset<2> _has_field_{};
41443 };
41444 
41445 
41446 class PERFETTO_EXPORT ChangeTraceConfigRequest : public ::protozero::CppMessageObj {
41447  public:
41448   enum FieldNumbers {
41449     kTraceConfigFieldNumber = 1,
41450   };
41451 
41452   ChangeTraceConfigRequest();
41453   ~ChangeTraceConfigRequest() override;
41454   ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept;
41455   ChangeTraceConfigRequest& operator=(ChangeTraceConfigRequest&&);
41456   ChangeTraceConfigRequest(const ChangeTraceConfigRequest&);
41457   ChangeTraceConfigRequest& operator=(const ChangeTraceConfigRequest&);
41458   bool operator==(const ChangeTraceConfigRequest&) const;
operator !=(const ChangeTraceConfigRequest & other) const41459   bool operator!=(const ChangeTraceConfigRequest& other) const { return !(*this == other); }
41460 
41461   bool ParseFromArray(const void*, size_t) override;
41462   std::string SerializeAsString() const override;
41463   std::vector<uint8_t> SerializeAsArray() const override;
41464   void Serialize(::protozero::Message*) const;
41465 
has_trace_config() const41466   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const41467   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()41468   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
41469 
41470  private:
41471   ::protozero::CopyablePtr<TraceConfig> trace_config_;
41472 
41473   // Allows to preserve unknown protobuf fields for compatibility
41474   // with future versions of .proto files.
41475   std::string unknown_fields_;
41476 
41477   std::bitset<2> _has_field_{};
41478 };
41479 
41480 
41481 class PERFETTO_EXPORT StartTracingResponse : public ::protozero::CppMessageObj {
41482  public:
41483   enum FieldNumbers {
41484   };
41485 
41486   StartTracingResponse();
41487   ~StartTracingResponse() override;
41488   StartTracingResponse(StartTracingResponse&&) noexcept;
41489   StartTracingResponse& operator=(StartTracingResponse&&);
41490   StartTracingResponse(const StartTracingResponse&);
41491   StartTracingResponse& operator=(const StartTracingResponse&);
41492   bool operator==(const StartTracingResponse&) const;
operator !=(const StartTracingResponse & other) const41493   bool operator!=(const StartTracingResponse& other) const { return !(*this == other); }
41494 
41495   bool ParseFromArray(const void*, size_t) override;
41496   std::string SerializeAsString() const override;
41497   std::vector<uint8_t> SerializeAsArray() const override;
41498   void Serialize(::protozero::Message*) const;
41499 
41500  private:
41501 
41502   // Allows to preserve unknown protobuf fields for compatibility
41503   // with future versions of .proto files.
41504   std::string unknown_fields_;
41505 
41506   std::bitset<2> _has_field_{};
41507 };
41508 
41509 
41510 class PERFETTO_EXPORT StartTracingRequest : public ::protozero::CppMessageObj {
41511  public:
41512   enum FieldNumbers {
41513   };
41514 
41515   StartTracingRequest();
41516   ~StartTracingRequest() override;
41517   StartTracingRequest(StartTracingRequest&&) noexcept;
41518   StartTracingRequest& operator=(StartTracingRequest&&);
41519   StartTracingRequest(const StartTracingRequest&);
41520   StartTracingRequest& operator=(const StartTracingRequest&);
41521   bool operator==(const StartTracingRequest&) const;
operator !=(const StartTracingRequest & other) const41522   bool operator!=(const StartTracingRequest& other) const { return !(*this == other); }
41523 
41524   bool ParseFromArray(const void*, size_t) override;
41525   std::string SerializeAsString() const override;
41526   std::vector<uint8_t> SerializeAsArray() const override;
41527   void Serialize(::protozero::Message*) const;
41528 
41529  private:
41530 
41531   // Allows to preserve unknown protobuf fields for compatibility
41532   // with future versions of .proto files.
41533   std::string unknown_fields_;
41534 
41535   std::bitset<2> _has_field_{};
41536 };
41537 
41538 
41539 class PERFETTO_EXPORT EnableTracingResponse : public ::protozero::CppMessageObj {
41540  public:
41541   enum FieldNumbers {
41542     kDisabledFieldNumber = 1,
41543   };
41544 
41545   EnableTracingResponse();
41546   ~EnableTracingResponse() override;
41547   EnableTracingResponse(EnableTracingResponse&&) noexcept;
41548   EnableTracingResponse& operator=(EnableTracingResponse&&);
41549   EnableTracingResponse(const EnableTracingResponse&);
41550   EnableTracingResponse& operator=(const EnableTracingResponse&);
41551   bool operator==(const EnableTracingResponse&) const;
operator !=(const EnableTracingResponse & other) const41552   bool operator!=(const EnableTracingResponse& other) const { return !(*this == other); }
41553 
41554   bool ParseFromArray(const void*, size_t) override;
41555   std::string SerializeAsString() const override;
41556   std::vector<uint8_t> SerializeAsArray() const override;
41557   void Serialize(::protozero::Message*) const;
41558 
has_disabled() const41559   bool has_disabled() const { return _has_field_[1]; }
disabled() const41560   bool disabled() const { return disabled_; }
set_disabled(bool value)41561   void set_disabled(bool value) { disabled_ = value; _has_field_.set(1); }
41562 
41563  private:
41564   bool disabled_{};
41565 
41566   // Allows to preserve unknown protobuf fields for compatibility
41567   // with future versions of .proto files.
41568   std::string unknown_fields_;
41569 
41570   std::bitset<2> _has_field_{};
41571 };
41572 
41573 
41574 class PERFETTO_EXPORT EnableTracingRequest : public ::protozero::CppMessageObj {
41575  public:
41576   enum FieldNumbers {
41577     kTraceConfigFieldNumber = 1,
41578     kAttachNotificationOnlyFieldNumber = 2,
41579   };
41580 
41581   EnableTracingRequest();
41582   ~EnableTracingRequest() override;
41583   EnableTracingRequest(EnableTracingRequest&&) noexcept;
41584   EnableTracingRequest& operator=(EnableTracingRequest&&);
41585   EnableTracingRequest(const EnableTracingRequest&);
41586   EnableTracingRequest& operator=(const EnableTracingRequest&);
41587   bool operator==(const EnableTracingRequest&) const;
operator !=(const EnableTracingRequest & other) const41588   bool operator!=(const EnableTracingRequest& other) const { return !(*this == other); }
41589 
41590   bool ParseFromArray(const void*, size_t) override;
41591   std::string SerializeAsString() const override;
41592   std::vector<uint8_t> SerializeAsArray() const override;
41593   void Serialize(::protozero::Message*) const;
41594 
has_trace_config() const41595   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const41596   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()41597   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
41598 
has_attach_notification_only() const41599   bool has_attach_notification_only() const { return _has_field_[2]; }
attach_notification_only() const41600   bool attach_notification_only() const { return attach_notification_only_; }
set_attach_notification_only(bool value)41601   void set_attach_notification_only(bool value) { attach_notification_only_ = value; _has_field_.set(2); }
41602 
41603  private:
41604   ::protozero::CopyablePtr<TraceConfig> trace_config_;
41605   bool attach_notification_only_{};
41606 
41607   // Allows to preserve unknown protobuf fields for compatibility
41608   // with future versions of .proto files.
41609   std::string unknown_fields_;
41610 
41611   std::bitset<3> _has_field_{};
41612 };
41613 
41614 }  // namespace perfetto
41615 }  // namespace protos
41616 }  // namespace gen
41617 
41618 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
41619 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
41620 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
41621 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
41622 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
41623 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
41624 #pragma GCC diagnostic push
41625 #pragma GCC diagnostic ignored "-Wfloat-equal"
41626 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
41627 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
41628 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
41629 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
41630 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
41631 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
41632 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
41633 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
41634 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
41635 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
41636 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
41637 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
41638 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
41639 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
41640 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
41641 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
41642 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
41643 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
41644 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
41645 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
41646 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
41647 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
41648 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
41649 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
41650 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
41651 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
41652 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
41653 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
41654 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
41655 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
41656 
41657 namespace perfetto {
41658 namespace protos {
41659 namespace gen {
41660 
41661 QueryCapabilitiesResponse::QueryCapabilitiesResponse() = default;
41662 QueryCapabilitiesResponse::~QueryCapabilitiesResponse() = default;
41663 QueryCapabilitiesResponse::QueryCapabilitiesResponse(const QueryCapabilitiesResponse&) = default;
41664 QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(const QueryCapabilitiesResponse&) = default;
41665 QueryCapabilitiesResponse::QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept = default;
41666 QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(QueryCapabilitiesResponse&&) = default;
41667 
operator ==(const QueryCapabilitiesResponse & other) const41668 bool QueryCapabilitiesResponse::operator==(const QueryCapabilitiesResponse& other) const {
41669   return unknown_fields_ == other.unknown_fields_
41670    && capabilities_ == other.capabilities_;
41671 }
41672 
ParseFromArray(const void * raw,size_t size)41673 bool QueryCapabilitiesResponse::ParseFromArray(const void* raw, size_t size) {
41674   unknown_fields_.clear();
41675   bool packed_error = false;
41676 
41677   ::protozero::ProtoDecoder dec(raw, size);
41678   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41679     if (field.id() < _has_field_.size()) {
41680       _has_field_.set(field.id());
41681     }
41682     switch (field.id()) {
41683       case 1 /* capabilities */:
41684         (*capabilities_).ParseFromString(field.as_std_string());
41685         break;
41686       default:
41687         field.SerializeAndAppendTo(&unknown_fields_);
41688         break;
41689     }
41690   }
41691   return !packed_error && !dec.bytes_left();
41692 }
41693 
SerializeAsString() const41694 std::string QueryCapabilitiesResponse::SerializeAsString() const {
41695   ::protozero::HeapBuffered<::protozero::Message> msg;
41696   Serialize(msg.get());
41697   return msg.SerializeAsString();
41698 }
41699 
SerializeAsArray() const41700 std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
41701   ::protozero::HeapBuffered<::protozero::Message> msg;
41702   Serialize(msg.get());
41703   return msg.SerializeAsArray();
41704 }
41705 
Serialize(::protozero::Message * msg) const41706 void QueryCapabilitiesResponse::Serialize(::protozero::Message* msg) const {
41707   // Field 1: capabilities
41708   if (_has_field_[1]) {
41709     (*capabilities_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
41710   }
41711 
41712   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
41713 }
41714 
41715 
41716 QueryCapabilitiesRequest::QueryCapabilitiesRequest() = default;
41717 QueryCapabilitiesRequest::~QueryCapabilitiesRequest() = default;
41718 QueryCapabilitiesRequest::QueryCapabilitiesRequest(const QueryCapabilitiesRequest&) = default;
41719 QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(const QueryCapabilitiesRequest&) = default;
41720 QueryCapabilitiesRequest::QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept = default;
41721 QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(QueryCapabilitiesRequest&&) = default;
41722 
operator ==(const QueryCapabilitiesRequest & other) const41723 bool QueryCapabilitiesRequest::operator==(const QueryCapabilitiesRequest& other) const {
41724   return unknown_fields_ == other.unknown_fields_;
41725 }
41726 
ParseFromArray(const void * raw,size_t size)41727 bool QueryCapabilitiesRequest::ParseFromArray(const void* raw, size_t size) {
41728   unknown_fields_.clear();
41729   bool packed_error = false;
41730 
41731   ::protozero::ProtoDecoder dec(raw, size);
41732   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41733     if (field.id() < _has_field_.size()) {
41734       _has_field_.set(field.id());
41735     }
41736     switch (field.id()) {
41737       default:
41738         field.SerializeAndAppendTo(&unknown_fields_);
41739         break;
41740     }
41741   }
41742   return !packed_error && !dec.bytes_left();
41743 }
41744 
SerializeAsString() const41745 std::string QueryCapabilitiesRequest::SerializeAsString() const {
41746   ::protozero::HeapBuffered<::protozero::Message> msg;
41747   Serialize(msg.get());
41748   return msg.SerializeAsString();
41749 }
41750 
SerializeAsArray() const41751 std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
41752   ::protozero::HeapBuffered<::protozero::Message> msg;
41753   Serialize(msg.get());
41754   return msg.SerializeAsArray();
41755 }
41756 
Serialize(::protozero::Message * msg) const41757 void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
41758   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
41759 }
41760 
41761 
41762 QueryServiceStateResponse::QueryServiceStateResponse() = default;
41763 QueryServiceStateResponse::~QueryServiceStateResponse() = default;
41764 QueryServiceStateResponse::QueryServiceStateResponse(const QueryServiceStateResponse&) = default;
41765 QueryServiceStateResponse& QueryServiceStateResponse::operator=(const QueryServiceStateResponse&) = default;
41766 QueryServiceStateResponse::QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept = default;
41767 QueryServiceStateResponse& QueryServiceStateResponse::operator=(QueryServiceStateResponse&&) = default;
41768 
operator ==(const QueryServiceStateResponse & other) const41769 bool QueryServiceStateResponse::operator==(const QueryServiceStateResponse& other) const {
41770   return unknown_fields_ == other.unknown_fields_
41771    && service_state_ == other.service_state_;
41772 }
41773 
ParseFromArray(const void * raw,size_t size)41774 bool QueryServiceStateResponse::ParseFromArray(const void* raw, size_t size) {
41775   unknown_fields_.clear();
41776   bool packed_error = false;
41777 
41778   ::protozero::ProtoDecoder dec(raw, size);
41779   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41780     if (field.id() < _has_field_.size()) {
41781       _has_field_.set(field.id());
41782     }
41783     switch (field.id()) {
41784       case 1 /* service_state */:
41785         (*service_state_).ParseFromString(field.as_std_string());
41786         break;
41787       default:
41788         field.SerializeAndAppendTo(&unknown_fields_);
41789         break;
41790     }
41791   }
41792   return !packed_error && !dec.bytes_left();
41793 }
41794 
SerializeAsString() const41795 std::string QueryServiceStateResponse::SerializeAsString() const {
41796   ::protozero::HeapBuffered<::protozero::Message> msg;
41797   Serialize(msg.get());
41798   return msg.SerializeAsString();
41799 }
41800 
SerializeAsArray() const41801 std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
41802   ::protozero::HeapBuffered<::protozero::Message> msg;
41803   Serialize(msg.get());
41804   return msg.SerializeAsArray();
41805 }
41806 
Serialize(::protozero::Message * msg) const41807 void QueryServiceStateResponse::Serialize(::protozero::Message* msg) const {
41808   // Field 1: service_state
41809   if (_has_field_[1]) {
41810     (*service_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
41811   }
41812 
41813   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
41814 }
41815 
41816 
41817 QueryServiceStateRequest::QueryServiceStateRequest() = default;
41818 QueryServiceStateRequest::~QueryServiceStateRequest() = default;
41819 QueryServiceStateRequest::QueryServiceStateRequest(const QueryServiceStateRequest&) = default;
41820 QueryServiceStateRequest& QueryServiceStateRequest::operator=(const QueryServiceStateRequest&) = default;
41821 QueryServiceStateRequest::QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept = default;
41822 QueryServiceStateRequest& QueryServiceStateRequest::operator=(QueryServiceStateRequest&&) = default;
41823 
operator ==(const QueryServiceStateRequest & other) const41824 bool QueryServiceStateRequest::operator==(const QueryServiceStateRequest& other) const {
41825   return unknown_fields_ == other.unknown_fields_;
41826 }
41827 
ParseFromArray(const void * raw,size_t size)41828 bool QueryServiceStateRequest::ParseFromArray(const void* raw, size_t size) {
41829   unknown_fields_.clear();
41830   bool packed_error = false;
41831 
41832   ::protozero::ProtoDecoder dec(raw, size);
41833   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41834     if (field.id() < _has_field_.size()) {
41835       _has_field_.set(field.id());
41836     }
41837     switch (field.id()) {
41838       default:
41839         field.SerializeAndAppendTo(&unknown_fields_);
41840         break;
41841     }
41842   }
41843   return !packed_error && !dec.bytes_left();
41844 }
41845 
SerializeAsString() const41846 std::string QueryServiceStateRequest::SerializeAsString() const {
41847   ::protozero::HeapBuffered<::protozero::Message> msg;
41848   Serialize(msg.get());
41849   return msg.SerializeAsString();
41850 }
41851 
SerializeAsArray() const41852 std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
41853   ::protozero::HeapBuffered<::protozero::Message> msg;
41854   Serialize(msg.get());
41855   return msg.SerializeAsArray();
41856 }
41857 
Serialize(::protozero::Message * msg) const41858 void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
41859   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
41860 }
41861 
41862 
41863 ObserveEventsResponse::ObserveEventsResponse() = default;
41864 ObserveEventsResponse::~ObserveEventsResponse() = default;
41865 ObserveEventsResponse::ObserveEventsResponse(const ObserveEventsResponse&) = default;
41866 ObserveEventsResponse& ObserveEventsResponse::operator=(const ObserveEventsResponse&) = default;
41867 ObserveEventsResponse::ObserveEventsResponse(ObserveEventsResponse&&) noexcept = default;
41868 ObserveEventsResponse& ObserveEventsResponse::operator=(ObserveEventsResponse&&) = default;
41869 
operator ==(const ObserveEventsResponse & other) const41870 bool ObserveEventsResponse::operator==(const ObserveEventsResponse& other) const {
41871   return unknown_fields_ == other.unknown_fields_
41872    && events_ == other.events_;
41873 }
41874 
ParseFromArray(const void * raw,size_t size)41875 bool ObserveEventsResponse::ParseFromArray(const void* raw, size_t size) {
41876   unknown_fields_.clear();
41877   bool packed_error = false;
41878 
41879   ::protozero::ProtoDecoder dec(raw, size);
41880   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41881     if (field.id() < _has_field_.size()) {
41882       _has_field_.set(field.id());
41883     }
41884     switch (field.id()) {
41885       case 1 /* events */:
41886         (*events_).ParseFromString(field.as_std_string());
41887         break;
41888       default:
41889         field.SerializeAndAppendTo(&unknown_fields_);
41890         break;
41891     }
41892   }
41893   return !packed_error && !dec.bytes_left();
41894 }
41895 
SerializeAsString() const41896 std::string ObserveEventsResponse::SerializeAsString() const {
41897   ::protozero::HeapBuffered<::protozero::Message> msg;
41898   Serialize(msg.get());
41899   return msg.SerializeAsString();
41900 }
41901 
SerializeAsArray() const41902 std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
41903   ::protozero::HeapBuffered<::protozero::Message> msg;
41904   Serialize(msg.get());
41905   return msg.SerializeAsArray();
41906 }
41907 
Serialize(::protozero::Message * msg) const41908 void ObserveEventsResponse::Serialize(::protozero::Message* msg) const {
41909   // Field 1: events
41910   if (_has_field_[1]) {
41911     (*events_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
41912   }
41913 
41914   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
41915 }
41916 
41917 
41918 ObserveEventsRequest::ObserveEventsRequest() = default;
41919 ObserveEventsRequest::~ObserveEventsRequest() = default;
41920 ObserveEventsRequest::ObserveEventsRequest(const ObserveEventsRequest&) = default;
41921 ObserveEventsRequest& ObserveEventsRequest::operator=(const ObserveEventsRequest&) = default;
41922 ObserveEventsRequest::ObserveEventsRequest(ObserveEventsRequest&&) noexcept = default;
41923 ObserveEventsRequest& ObserveEventsRequest::operator=(ObserveEventsRequest&&) = default;
41924 
operator ==(const ObserveEventsRequest & other) const41925 bool ObserveEventsRequest::operator==(const ObserveEventsRequest& other) const {
41926   return unknown_fields_ == other.unknown_fields_
41927    && events_to_observe_ == other.events_to_observe_;
41928 }
41929 
ParseFromArray(const void * raw,size_t size)41930 bool ObserveEventsRequest::ParseFromArray(const void* raw, size_t size) {
41931   events_to_observe_.clear();
41932   unknown_fields_.clear();
41933   bool packed_error = false;
41934 
41935   ::protozero::ProtoDecoder dec(raw, size);
41936   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41937     if (field.id() < _has_field_.size()) {
41938       _has_field_.set(field.id());
41939     }
41940     switch (field.id()) {
41941       case 1 /* events_to_observe */:
41942         events_to_observe_.emplace_back();
41943         field.get(&events_to_observe_.back());
41944         break;
41945       default:
41946         field.SerializeAndAppendTo(&unknown_fields_);
41947         break;
41948     }
41949   }
41950   return !packed_error && !dec.bytes_left();
41951 }
41952 
SerializeAsString() const41953 std::string ObserveEventsRequest::SerializeAsString() const {
41954   ::protozero::HeapBuffered<::protozero::Message> msg;
41955   Serialize(msg.get());
41956   return msg.SerializeAsString();
41957 }
41958 
SerializeAsArray() const41959 std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
41960   ::protozero::HeapBuffered<::protozero::Message> msg;
41961   Serialize(msg.get());
41962   return msg.SerializeAsArray();
41963 }
41964 
Serialize(::protozero::Message * msg) const41965 void ObserveEventsRequest::Serialize(::protozero::Message* msg) const {
41966   // Field 1: events_to_observe
41967   for (auto& it : events_to_observe_) {
41968     msg->AppendVarInt(1, it);
41969   }
41970 
41971   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
41972 }
41973 
41974 
41975 GetTraceStatsResponse::GetTraceStatsResponse() = default;
41976 GetTraceStatsResponse::~GetTraceStatsResponse() = default;
41977 GetTraceStatsResponse::GetTraceStatsResponse(const GetTraceStatsResponse&) = default;
41978 GetTraceStatsResponse& GetTraceStatsResponse::operator=(const GetTraceStatsResponse&) = default;
41979 GetTraceStatsResponse::GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept = default;
41980 GetTraceStatsResponse& GetTraceStatsResponse::operator=(GetTraceStatsResponse&&) = default;
41981 
operator ==(const GetTraceStatsResponse & other) const41982 bool GetTraceStatsResponse::operator==(const GetTraceStatsResponse& other) const {
41983   return unknown_fields_ == other.unknown_fields_
41984    && trace_stats_ == other.trace_stats_;
41985 }
41986 
ParseFromArray(const void * raw,size_t size)41987 bool GetTraceStatsResponse::ParseFromArray(const void* raw, size_t size) {
41988   unknown_fields_.clear();
41989   bool packed_error = false;
41990 
41991   ::protozero::ProtoDecoder dec(raw, size);
41992   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
41993     if (field.id() < _has_field_.size()) {
41994       _has_field_.set(field.id());
41995     }
41996     switch (field.id()) {
41997       case 1 /* trace_stats */:
41998         (*trace_stats_).ParseFromString(field.as_std_string());
41999         break;
42000       default:
42001         field.SerializeAndAppendTo(&unknown_fields_);
42002         break;
42003     }
42004   }
42005   return !packed_error && !dec.bytes_left();
42006 }
42007 
SerializeAsString() const42008 std::string GetTraceStatsResponse::SerializeAsString() const {
42009   ::protozero::HeapBuffered<::protozero::Message> msg;
42010   Serialize(msg.get());
42011   return msg.SerializeAsString();
42012 }
42013 
SerializeAsArray() const42014 std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
42015   ::protozero::HeapBuffered<::protozero::Message> msg;
42016   Serialize(msg.get());
42017   return msg.SerializeAsArray();
42018 }
42019 
Serialize(::protozero::Message * msg) const42020 void GetTraceStatsResponse::Serialize(::protozero::Message* msg) const {
42021   // Field 1: trace_stats
42022   if (_has_field_[1]) {
42023     (*trace_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
42024   }
42025 
42026   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42027 }
42028 
42029 
42030 GetTraceStatsRequest::GetTraceStatsRequest() = default;
42031 GetTraceStatsRequest::~GetTraceStatsRequest() = default;
42032 GetTraceStatsRequest::GetTraceStatsRequest(const GetTraceStatsRequest&) = default;
42033 GetTraceStatsRequest& GetTraceStatsRequest::operator=(const GetTraceStatsRequest&) = default;
42034 GetTraceStatsRequest::GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept = default;
42035 GetTraceStatsRequest& GetTraceStatsRequest::operator=(GetTraceStatsRequest&&) = default;
42036 
operator ==(const GetTraceStatsRequest & other) const42037 bool GetTraceStatsRequest::operator==(const GetTraceStatsRequest& other) const {
42038   return unknown_fields_ == other.unknown_fields_;
42039 }
42040 
ParseFromArray(const void * raw,size_t size)42041 bool GetTraceStatsRequest::ParseFromArray(const void* raw, size_t size) {
42042   unknown_fields_.clear();
42043   bool packed_error = false;
42044 
42045   ::protozero::ProtoDecoder dec(raw, size);
42046   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42047     if (field.id() < _has_field_.size()) {
42048       _has_field_.set(field.id());
42049     }
42050     switch (field.id()) {
42051       default:
42052         field.SerializeAndAppendTo(&unknown_fields_);
42053         break;
42054     }
42055   }
42056   return !packed_error && !dec.bytes_left();
42057 }
42058 
SerializeAsString() const42059 std::string GetTraceStatsRequest::SerializeAsString() const {
42060   ::protozero::HeapBuffered<::protozero::Message> msg;
42061   Serialize(msg.get());
42062   return msg.SerializeAsString();
42063 }
42064 
SerializeAsArray() const42065 std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
42066   ::protozero::HeapBuffered<::protozero::Message> msg;
42067   Serialize(msg.get());
42068   return msg.SerializeAsArray();
42069 }
42070 
Serialize(::protozero::Message * msg) const42071 void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
42072   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42073 }
42074 
42075 
42076 AttachResponse::AttachResponse() = default;
42077 AttachResponse::~AttachResponse() = default;
42078 AttachResponse::AttachResponse(const AttachResponse&) = default;
42079 AttachResponse& AttachResponse::operator=(const AttachResponse&) = default;
42080 AttachResponse::AttachResponse(AttachResponse&&) noexcept = default;
42081 AttachResponse& AttachResponse::operator=(AttachResponse&&) = default;
42082 
operator ==(const AttachResponse & other) const42083 bool AttachResponse::operator==(const AttachResponse& other) const {
42084   return unknown_fields_ == other.unknown_fields_
42085    && trace_config_ == other.trace_config_;
42086 }
42087 
ParseFromArray(const void * raw,size_t size)42088 bool AttachResponse::ParseFromArray(const void* raw, size_t size) {
42089   unknown_fields_.clear();
42090   bool packed_error = false;
42091 
42092   ::protozero::ProtoDecoder dec(raw, size);
42093   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42094     if (field.id() < _has_field_.size()) {
42095       _has_field_.set(field.id());
42096     }
42097     switch (field.id()) {
42098       case 1 /* trace_config */:
42099         (*trace_config_).ParseFromString(field.as_std_string());
42100         break;
42101       default:
42102         field.SerializeAndAppendTo(&unknown_fields_);
42103         break;
42104     }
42105   }
42106   return !packed_error && !dec.bytes_left();
42107 }
42108 
SerializeAsString() const42109 std::string AttachResponse::SerializeAsString() const {
42110   ::protozero::HeapBuffered<::protozero::Message> msg;
42111   Serialize(msg.get());
42112   return msg.SerializeAsString();
42113 }
42114 
SerializeAsArray() const42115 std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
42116   ::protozero::HeapBuffered<::protozero::Message> msg;
42117   Serialize(msg.get());
42118   return msg.SerializeAsArray();
42119 }
42120 
Serialize(::protozero::Message * msg) const42121 void AttachResponse::Serialize(::protozero::Message* msg) const {
42122   // Field 1: trace_config
42123   if (_has_field_[1]) {
42124     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
42125   }
42126 
42127   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42128 }
42129 
42130 
42131 AttachRequest::AttachRequest() = default;
42132 AttachRequest::~AttachRequest() = default;
42133 AttachRequest::AttachRequest(const AttachRequest&) = default;
42134 AttachRequest& AttachRequest::operator=(const AttachRequest&) = default;
42135 AttachRequest::AttachRequest(AttachRequest&&) noexcept = default;
42136 AttachRequest& AttachRequest::operator=(AttachRequest&&) = default;
42137 
operator ==(const AttachRequest & other) const42138 bool AttachRequest::operator==(const AttachRequest& other) const {
42139   return unknown_fields_ == other.unknown_fields_
42140    && key_ == other.key_;
42141 }
42142 
ParseFromArray(const void * raw,size_t size)42143 bool AttachRequest::ParseFromArray(const void* raw, size_t size) {
42144   unknown_fields_.clear();
42145   bool packed_error = false;
42146 
42147   ::protozero::ProtoDecoder dec(raw, size);
42148   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42149     if (field.id() < _has_field_.size()) {
42150       _has_field_.set(field.id());
42151     }
42152     switch (field.id()) {
42153       case 1 /* key */:
42154         field.get(&key_);
42155         break;
42156       default:
42157         field.SerializeAndAppendTo(&unknown_fields_);
42158         break;
42159     }
42160   }
42161   return !packed_error && !dec.bytes_left();
42162 }
42163 
SerializeAsString() const42164 std::string AttachRequest::SerializeAsString() const {
42165   ::protozero::HeapBuffered<::protozero::Message> msg;
42166   Serialize(msg.get());
42167   return msg.SerializeAsString();
42168 }
42169 
SerializeAsArray() const42170 std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
42171   ::protozero::HeapBuffered<::protozero::Message> msg;
42172   Serialize(msg.get());
42173   return msg.SerializeAsArray();
42174 }
42175 
Serialize(::protozero::Message * msg) const42176 void AttachRequest::Serialize(::protozero::Message* msg) const {
42177   // Field 1: key
42178   if (_has_field_[1]) {
42179     msg->AppendString(1, key_);
42180   }
42181 
42182   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42183 }
42184 
42185 
42186 DetachResponse::DetachResponse() = default;
42187 DetachResponse::~DetachResponse() = default;
42188 DetachResponse::DetachResponse(const DetachResponse&) = default;
42189 DetachResponse& DetachResponse::operator=(const DetachResponse&) = default;
42190 DetachResponse::DetachResponse(DetachResponse&&) noexcept = default;
42191 DetachResponse& DetachResponse::operator=(DetachResponse&&) = default;
42192 
operator ==(const DetachResponse & other) const42193 bool DetachResponse::operator==(const DetachResponse& other) const {
42194   return unknown_fields_ == other.unknown_fields_;
42195 }
42196 
ParseFromArray(const void * raw,size_t size)42197 bool DetachResponse::ParseFromArray(const void* raw, size_t size) {
42198   unknown_fields_.clear();
42199   bool packed_error = false;
42200 
42201   ::protozero::ProtoDecoder dec(raw, size);
42202   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42203     if (field.id() < _has_field_.size()) {
42204       _has_field_.set(field.id());
42205     }
42206     switch (field.id()) {
42207       default:
42208         field.SerializeAndAppendTo(&unknown_fields_);
42209         break;
42210     }
42211   }
42212   return !packed_error && !dec.bytes_left();
42213 }
42214 
SerializeAsString() const42215 std::string DetachResponse::SerializeAsString() const {
42216   ::protozero::HeapBuffered<::protozero::Message> msg;
42217   Serialize(msg.get());
42218   return msg.SerializeAsString();
42219 }
42220 
SerializeAsArray() const42221 std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
42222   ::protozero::HeapBuffered<::protozero::Message> msg;
42223   Serialize(msg.get());
42224   return msg.SerializeAsArray();
42225 }
42226 
Serialize(::protozero::Message * msg) const42227 void DetachResponse::Serialize(::protozero::Message* msg) const {
42228   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42229 }
42230 
42231 
42232 DetachRequest::DetachRequest() = default;
42233 DetachRequest::~DetachRequest() = default;
42234 DetachRequest::DetachRequest(const DetachRequest&) = default;
42235 DetachRequest& DetachRequest::operator=(const DetachRequest&) = default;
42236 DetachRequest::DetachRequest(DetachRequest&&) noexcept = default;
42237 DetachRequest& DetachRequest::operator=(DetachRequest&&) = default;
42238 
operator ==(const DetachRequest & other) const42239 bool DetachRequest::operator==(const DetachRequest& other) const {
42240   return unknown_fields_ == other.unknown_fields_
42241    && key_ == other.key_;
42242 }
42243 
ParseFromArray(const void * raw,size_t size)42244 bool DetachRequest::ParseFromArray(const void* raw, size_t size) {
42245   unknown_fields_.clear();
42246   bool packed_error = false;
42247 
42248   ::protozero::ProtoDecoder dec(raw, size);
42249   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42250     if (field.id() < _has_field_.size()) {
42251       _has_field_.set(field.id());
42252     }
42253     switch (field.id()) {
42254       case 1 /* key */:
42255         field.get(&key_);
42256         break;
42257       default:
42258         field.SerializeAndAppendTo(&unknown_fields_);
42259         break;
42260     }
42261   }
42262   return !packed_error && !dec.bytes_left();
42263 }
42264 
SerializeAsString() const42265 std::string DetachRequest::SerializeAsString() const {
42266   ::protozero::HeapBuffered<::protozero::Message> msg;
42267   Serialize(msg.get());
42268   return msg.SerializeAsString();
42269 }
42270 
SerializeAsArray() const42271 std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
42272   ::protozero::HeapBuffered<::protozero::Message> msg;
42273   Serialize(msg.get());
42274   return msg.SerializeAsArray();
42275 }
42276 
Serialize(::protozero::Message * msg) const42277 void DetachRequest::Serialize(::protozero::Message* msg) const {
42278   // Field 1: key
42279   if (_has_field_[1]) {
42280     msg->AppendString(1, key_);
42281   }
42282 
42283   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42284 }
42285 
42286 
42287 FlushResponse::FlushResponse() = default;
42288 FlushResponse::~FlushResponse() = default;
42289 FlushResponse::FlushResponse(const FlushResponse&) = default;
42290 FlushResponse& FlushResponse::operator=(const FlushResponse&) = default;
42291 FlushResponse::FlushResponse(FlushResponse&&) noexcept = default;
42292 FlushResponse& FlushResponse::operator=(FlushResponse&&) = default;
42293 
operator ==(const FlushResponse & other) const42294 bool FlushResponse::operator==(const FlushResponse& other) const {
42295   return unknown_fields_ == other.unknown_fields_;
42296 }
42297 
ParseFromArray(const void * raw,size_t size)42298 bool FlushResponse::ParseFromArray(const void* raw, size_t size) {
42299   unknown_fields_.clear();
42300   bool packed_error = false;
42301 
42302   ::protozero::ProtoDecoder dec(raw, size);
42303   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42304     if (field.id() < _has_field_.size()) {
42305       _has_field_.set(field.id());
42306     }
42307     switch (field.id()) {
42308       default:
42309         field.SerializeAndAppendTo(&unknown_fields_);
42310         break;
42311     }
42312   }
42313   return !packed_error && !dec.bytes_left();
42314 }
42315 
SerializeAsString() const42316 std::string FlushResponse::SerializeAsString() const {
42317   ::protozero::HeapBuffered<::protozero::Message> msg;
42318   Serialize(msg.get());
42319   return msg.SerializeAsString();
42320 }
42321 
SerializeAsArray() const42322 std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
42323   ::protozero::HeapBuffered<::protozero::Message> msg;
42324   Serialize(msg.get());
42325   return msg.SerializeAsArray();
42326 }
42327 
Serialize(::protozero::Message * msg) const42328 void FlushResponse::Serialize(::protozero::Message* msg) const {
42329   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42330 }
42331 
42332 
42333 FlushRequest::FlushRequest() = default;
42334 FlushRequest::~FlushRequest() = default;
42335 FlushRequest::FlushRequest(const FlushRequest&) = default;
42336 FlushRequest& FlushRequest::operator=(const FlushRequest&) = default;
42337 FlushRequest::FlushRequest(FlushRequest&&) noexcept = default;
42338 FlushRequest& FlushRequest::operator=(FlushRequest&&) = default;
42339 
operator ==(const FlushRequest & other) const42340 bool FlushRequest::operator==(const FlushRequest& other) const {
42341   return unknown_fields_ == other.unknown_fields_
42342    && timeout_ms_ == other.timeout_ms_;
42343 }
42344 
ParseFromArray(const void * raw,size_t size)42345 bool FlushRequest::ParseFromArray(const void* raw, size_t size) {
42346   unknown_fields_.clear();
42347   bool packed_error = false;
42348 
42349   ::protozero::ProtoDecoder dec(raw, size);
42350   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42351     if (field.id() < _has_field_.size()) {
42352       _has_field_.set(field.id());
42353     }
42354     switch (field.id()) {
42355       case 1 /* timeout_ms */:
42356         field.get(&timeout_ms_);
42357         break;
42358       default:
42359         field.SerializeAndAppendTo(&unknown_fields_);
42360         break;
42361     }
42362   }
42363   return !packed_error && !dec.bytes_left();
42364 }
42365 
SerializeAsString() const42366 std::string FlushRequest::SerializeAsString() const {
42367   ::protozero::HeapBuffered<::protozero::Message> msg;
42368   Serialize(msg.get());
42369   return msg.SerializeAsString();
42370 }
42371 
SerializeAsArray() const42372 std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
42373   ::protozero::HeapBuffered<::protozero::Message> msg;
42374   Serialize(msg.get());
42375   return msg.SerializeAsArray();
42376 }
42377 
Serialize(::protozero::Message * msg) const42378 void FlushRequest::Serialize(::protozero::Message* msg) const {
42379   // Field 1: timeout_ms
42380   if (_has_field_[1]) {
42381     msg->AppendVarInt(1, timeout_ms_);
42382   }
42383 
42384   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42385 }
42386 
42387 
42388 FreeBuffersResponse::FreeBuffersResponse() = default;
42389 FreeBuffersResponse::~FreeBuffersResponse() = default;
42390 FreeBuffersResponse::FreeBuffersResponse(const FreeBuffersResponse&) = default;
42391 FreeBuffersResponse& FreeBuffersResponse::operator=(const FreeBuffersResponse&) = default;
42392 FreeBuffersResponse::FreeBuffersResponse(FreeBuffersResponse&&) noexcept = default;
42393 FreeBuffersResponse& FreeBuffersResponse::operator=(FreeBuffersResponse&&) = default;
42394 
operator ==(const FreeBuffersResponse & other) const42395 bool FreeBuffersResponse::operator==(const FreeBuffersResponse& other) const {
42396   return unknown_fields_ == other.unknown_fields_;
42397 }
42398 
ParseFromArray(const void * raw,size_t size)42399 bool FreeBuffersResponse::ParseFromArray(const void* raw, size_t size) {
42400   unknown_fields_.clear();
42401   bool packed_error = false;
42402 
42403   ::protozero::ProtoDecoder dec(raw, size);
42404   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42405     if (field.id() < _has_field_.size()) {
42406       _has_field_.set(field.id());
42407     }
42408     switch (field.id()) {
42409       default:
42410         field.SerializeAndAppendTo(&unknown_fields_);
42411         break;
42412     }
42413   }
42414   return !packed_error && !dec.bytes_left();
42415 }
42416 
SerializeAsString() const42417 std::string FreeBuffersResponse::SerializeAsString() const {
42418   ::protozero::HeapBuffered<::protozero::Message> msg;
42419   Serialize(msg.get());
42420   return msg.SerializeAsString();
42421 }
42422 
SerializeAsArray() const42423 std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
42424   ::protozero::HeapBuffered<::protozero::Message> msg;
42425   Serialize(msg.get());
42426   return msg.SerializeAsArray();
42427 }
42428 
Serialize(::protozero::Message * msg) const42429 void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
42430   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42431 }
42432 
42433 
42434 FreeBuffersRequest::FreeBuffersRequest() = default;
42435 FreeBuffersRequest::~FreeBuffersRequest() = default;
42436 FreeBuffersRequest::FreeBuffersRequest(const FreeBuffersRequest&) = default;
42437 FreeBuffersRequest& FreeBuffersRequest::operator=(const FreeBuffersRequest&) = default;
42438 FreeBuffersRequest::FreeBuffersRequest(FreeBuffersRequest&&) noexcept = default;
42439 FreeBuffersRequest& FreeBuffersRequest::operator=(FreeBuffersRequest&&) = default;
42440 
operator ==(const FreeBuffersRequest & other) const42441 bool FreeBuffersRequest::operator==(const FreeBuffersRequest& other) const {
42442   return unknown_fields_ == other.unknown_fields_
42443    && buffer_ids_ == other.buffer_ids_;
42444 }
42445 
ParseFromArray(const void * raw,size_t size)42446 bool FreeBuffersRequest::ParseFromArray(const void* raw, size_t size) {
42447   buffer_ids_.clear();
42448   unknown_fields_.clear();
42449   bool packed_error = false;
42450 
42451   ::protozero::ProtoDecoder dec(raw, size);
42452   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42453     if (field.id() < _has_field_.size()) {
42454       _has_field_.set(field.id());
42455     }
42456     switch (field.id()) {
42457       case 1 /* buffer_ids */:
42458         buffer_ids_.emplace_back();
42459         field.get(&buffer_ids_.back());
42460         break;
42461       default:
42462         field.SerializeAndAppendTo(&unknown_fields_);
42463         break;
42464     }
42465   }
42466   return !packed_error && !dec.bytes_left();
42467 }
42468 
SerializeAsString() const42469 std::string FreeBuffersRequest::SerializeAsString() const {
42470   ::protozero::HeapBuffered<::protozero::Message> msg;
42471   Serialize(msg.get());
42472   return msg.SerializeAsString();
42473 }
42474 
SerializeAsArray() const42475 std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
42476   ::protozero::HeapBuffered<::protozero::Message> msg;
42477   Serialize(msg.get());
42478   return msg.SerializeAsArray();
42479 }
42480 
Serialize(::protozero::Message * msg) const42481 void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
42482   // Field 1: buffer_ids
42483   for (auto& it : buffer_ids_) {
42484     msg->AppendVarInt(1, it);
42485   }
42486 
42487   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42488 }
42489 
42490 
42491 ReadBuffersResponse::ReadBuffersResponse() = default;
42492 ReadBuffersResponse::~ReadBuffersResponse() = default;
42493 ReadBuffersResponse::ReadBuffersResponse(const ReadBuffersResponse&) = default;
42494 ReadBuffersResponse& ReadBuffersResponse::operator=(const ReadBuffersResponse&) = default;
42495 ReadBuffersResponse::ReadBuffersResponse(ReadBuffersResponse&&) noexcept = default;
42496 ReadBuffersResponse& ReadBuffersResponse::operator=(ReadBuffersResponse&&) = default;
42497 
operator ==(const ReadBuffersResponse & other) const42498 bool ReadBuffersResponse::operator==(const ReadBuffersResponse& other) const {
42499   return unknown_fields_ == other.unknown_fields_
42500    && slices_ == other.slices_;
42501 }
42502 
ParseFromArray(const void * raw,size_t size)42503 bool ReadBuffersResponse::ParseFromArray(const void* raw, size_t size) {
42504   slices_.clear();
42505   unknown_fields_.clear();
42506   bool packed_error = false;
42507 
42508   ::protozero::ProtoDecoder dec(raw, size);
42509   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42510     if (field.id() < _has_field_.size()) {
42511       _has_field_.set(field.id());
42512     }
42513     switch (field.id()) {
42514       case 2 /* slices */:
42515         slices_.emplace_back();
42516         slices_.back().ParseFromString(field.as_std_string());
42517         break;
42518       default:
42519         field.SerializeAndAppendTo(&unknown_fields_);
42520         break;
42521     }
42522   }
42523   return !packed_error && !dec.bytes_left();
42524 }
42525 
SerializeAsString() const42526 std::string ReadBuffersResponse::SerializeAsString() const {
42527   ::protozero::HeapBuffered<::protozero::Message> msg;
42528   Serialize(msg.get());
42529   return msg.SerializeAsString();
42530 }
42531 
SerializeAsArray() const42532 std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
42533   ::protozero::HeapBuffered<::protozero::Message> msg;
42534   Serialize(msg.get());
42535   return msg.SerializeAsArray();
42536 }
42537 
Serialize(::protozero::Message * msg) const42538 void ReadBuffersResponse::Serialize(::protozero::Message* msg) const {
42539   // Field 2: slices
42540   for (auto& it : slices_) {
42541     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
42542   }
42543 
42544   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42545 }
42546 
42547 
42548 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice() = default;
42549 ReadBuffersResponse_Slice::~ReadBuffersResponse_Slice() = default;
42550 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&) = default;
42551 ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(const ReadBuffersResponse_Slice&) = default;
42552 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept = default;
42553 ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(ReadBuffersResponse_Slice&&) = default;
42554 
operator ==(const ReadBuffersResponse_Slice & other) const42555 bool ReadBuffersResponse_Slice::operator==(const ReadBuffersResponse_Slice& other) const {
42556   return unknown_fields_ == other.unknown_fields_
42557    && data_ == other.data_
42558    && last_slice_for_packet_ == other.last_slice_for_packet_;
42559 }
42560 
ParseFromArray(const void * raw,size_t size)42561 bool ReadBuffersResponse_Slice::ParseFromArray(const void* raw, size_t size) {
42562   unknown_fields_.clear();
42563   bool packed_error = false;
42564 
42565   ::protozero::ProtoDecoder dec(raw, size);
42566   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42567     if (field.id() < _has_field_.size()) {
42568       _has_field_.set(field.id());
42569     }
42570     switch (field.id()) {
42571       case 1 /* data */:
42572         field.get(&data_);
42573         break;
42574       case 2 /* last_slice_for_packet */:
42575         field.get(&last_slice_for_packet_);
42576         break;
42577       default:
42578         field.SerializeAndAppendTo(&unknown_fields_);
42579         break;
42580     }
42581   }
42582   return !packed_error && !dec.bytes_left();
42583 }
42584 
SerializeAsString() const42585 std::string ReadBuffersResponse_Slice::SerializeAsString() const {
42586   ::protozero::HeapBuffered<::protozero::Message> msg;
42587   Serialize(msg.get());
42588   return msg.SerializeAsString();
42589 }
42590 
SerializeAsArray() const42591 std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
42592   ::protozero::HeapBuffered<::protozero::Message> msg;
42593   Serialize(msg.get());
42594   return msg.SerializeAsArray();
42595 }
42596 
Serialize(::protozero::Message * msg) const42597 void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
42598   // Field 1: data
42599   if (_has_field_[1]) {
42600     msg->AppendString(1, data_);
42601   }
42602 
42603   // Field 2: last_slice_for_packet
42604   if (_has_field_[2]) {
42605     msg->AppendTinyVarInt(2, last_slice_for_packet_);
42606   }
42607 
42608   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42609 }
42610 
42611 
42612 ReadBuffersRequest::ReadBuffersRequest() = default;
42613 ReadBuffersRequest::~ReadBuffersRequest() = default;
42614 ReadBuffersRequest::ReadBuffersRequest(const ReadBuffersRequest&) = default;
42615 ReadBuffersRequest& ReadBuffersRequest::operator=(const ReadBuffersRequest&) = default;
42616 ReadBuffersRequest::ReadBuffersRequest(ReadBuffersRequest&&) noexcept = default;
42617 ReadBuffersRequest& ReadBuffersRequest::operator=(ReadBuffersRequest&&) = default;
42618 
operator ==(const ReadBuffersRequest & other) const42619 bool ReadBuffersRequest::operator==(const ReadBuffersRequest& other) const {
42620   return unknown_fields_ == other.unknown_fields_;
42621 }
42622 
ParseFromArray(const void * raw,size_t size)42623 bool ReadBuffersRequest::ParseFromArray(const void* raw, size_t size) {
42624   unknown_fields_.clear();
42625   bool packed_error = false;
42626 
42627   ::protozero::ProtoDecoder dec(raw, size);
42628   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42629     if (field.id() < _has_field_.size()) {
42630       _has_field_.set(field.id());
42631     }
42632     switch (field.id()) {
42633       default:
42634         field.SerializeAndAppendTo(&unknown_fields_);
42635         break;
42636     }
42637   }
42638   return !packed_error && !dec.bytes_left();
42639 }
42640 
SerializeAsString() const42641 std::string ReadBuffersRequest::SerializeAsString() const {
42642   ::protozero::HeapBuffered<::protozero::Message> msg;
42643   Serialize(msg.get());
42644   return msg.SerializeAsString();
42645 }
42646 
SerializeAsArray() const42647 std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
42648   ::protozero::HeapBuffered<::protozero::Message> msg;
42649   Serialize(msg.get());
42650   return msg.SerializeAsArray();
42651 }
42652 
Serialize(::protozero::Message * msg) const42653 void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
42654   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42655 }
42656 
42657 
42658 DisableTracingResponse::DisableTracingResponse() = default;
42659 DisableTracingResponse::~DisableTracingResponse() = default;
42660 DisableTracingResponse::DisableTracingResponse(const DisableTracingResponse&) = default;
42661 DisableTracingResponse& DisableTracingResponse::operator=(const DisableTracingResponse&) = default;
42662 DisableTracingResponse::DisableTracingResponse(DisableTracingResponse&&) noexcept = default;
42663 DisableTracingResponse& DisableTracingResponse::operator=(DisableTracingResponse&&) = default;
42664 
operator ==(const DisableTracingResponse & other) const42665 bool DisableTracingResponse::operator==(const DisableTracingResponse& other) const {
42666   return unknown_fields_ == other.unknown_fields_;
42667 }
42668 
ParseFromArray(const void * raw,size_t size)42669 bool DisableTracingResponse::ParseFromArray(const void* raw, size_t size) {
42670   unknown_fields_.clear();
42671   bool packed_error = false;
42672 
42673   ::protozero::ProtoDecoder dec(raw, size);
42674   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42675     if (field.id() < _has_field_.size()) {
42676       _has_field_.set(field.id());
42677     }
42678     switch (field.id()) {
42679       default:
42680         field.SerializeAndAppendTo(&unknown_fields_);
42681         break;
42682     }
42683   }
42684   return !packed_error && !dec.bytes_left();
42685 }
42686 
SerializeAsString() const42687 std::string DisableTracingResponse::SerializeAsString() const {
42688   ::protozero::HeapBuffered<::protozero::Message> msg;
42689   Serialize(msg.get());
42690   return msg.SerializeAsString();
42691 }
42692 
SerializeAsArray() const42693 std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
42694   ::protozero::HeapBuffered<::protozero::Message> msg;
42695   Serialize(msg.get());
42696   return msg.SerializeAsArray();
42697 }
42698 
Serialize(::protozero::Message * msg) const42699 void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
42700   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42701 }
42702 
42703 
42704 DisableTracingRequest::DisableTracingRequest() = default;
42705 DisableTracingRequest::~DisableTracingRequest() = default;
42706 DisableTracingRequest::DisableTracingRequest(const DisableTracingRequest&) = default;
42707 DisableTracingRequest& DisableTracingRequest::operator=(const DisableTracingRequest&) = default;
42708 DisableTracingRequest::DisableTracingRequest(DisableTracingRequest&&) noexcept = default;
42709 DisableTracingRequest& DisableTracingRequest::operator=(DisableTracingRequest&&) = default;
42710 
operator ==(const DisableTracingRequest & other) const42711 bool DisableTracingRequest::operator==(const DisableTracingRequest& other) const {
42712   return unknown_fields_ == other.unknown_fields_;
42713 }
42714 
ParseFromArray(const void * raw,size_t size)42715 bool DisableTracingRequest::ParseFromArray(const void* raw, size_t size) {
42716   unknown_fields_.clear();
42717   bool packed_error = false;
42718 
42719   ::protozero::ProtoDecoder dec(raw, size);
42720   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42721     if (field.id() < _has_field_.size()) {
42722       _has_field_.set(field.id());
42723     }
42724     switch (field.id()) {
42725       default:
42726         field.SerializeAndAppendTo(&unknown_fields_);
42727         break;
42728     }
42729   }
42730   return !packed_error && !dec.bytes_left();
42731 }
42732 
SerializeAsString() const42733 std::string DisableTracingRequest::SerializeAsString() const {
42734   ::protozero::HeapBuffered<::protozero::Message> msg;
42735   Serialize(msg.get());
42736   return msg.SerializeAsString();
42737 }
42738 
SerializeAsArray() const42739 std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
42740   ::protozero::HeapBuffered<::protozero::Message> msg;
42741   Serialize(msg.get());
42742   return msg.SerializeAsArray();
42743 }
42744 
Serialize(::protozero::Message * msg) const42745 void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
42746   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42747 }
42748 
42749 
42750 ChangeTraceConfigResponse::ChangeTraceConfigResponse() = default;
42751 ChangeTraceConfigResponse::~ChangeTraceConfigResponse() = default;
42752 ChangeTraceConfigResponse::ChangeTraceConfigResponse(const ChangeTraceConfigResponse&) = default;
42753 ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(const ChangeTraceConfigResponse&) = default;
42754 ChangeTraceConfigResponse::ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept = default;
42755 ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(ChangeTraceConfigResponse&&) = default;
42756 
operator ==(const ChangeTraceConfigResponse & other) const42757 bool ChangeTraceConfigResponse::operator==(const ChangeTraceConfigResponse& other) const {
42758   return unknown_fields_ == other.unknown_fields_;
42759 }
42760 
ParseFromArray(const void * raw,size_t size)42761 bool ChangeTraceConfigResponse::ParseFromArray(const void* raw, size_t size) {
42762   unknown_fields_.clear();
42763   bool packed_error = false;
42764 
42765   ::protozero::ProtoDecoder dec(raw, size);
42766   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42767     if (field.id() < _has_field_.size()) {
42768       _has_field_.set(field.id());
42769     }
42770     switch (field.id()) {
42771       default:
42772         field.SerializeAndAppendTo(&unknown_fields_);
42773         break;
42774     }
42775   }
42776   return !packed_error && !dec.bytes_left();
42777 }
42778 
SerializeAsString() const42779 std::string ChangeTraceConfigResponse::SerializeAsString() const {
42780   ::protozero::HeapBuffered<::protozero::Message> msg;
42781   Serialize(msg.get());
42782   return msg.SerializeAsString();
42783 }
42784 
SerializeAsArray() const42785 std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
42786   ::protozero::HeapBuffered<::protozero::Message> msg;
42787   Serialize(msg.get());
42788   return msg.SerializeAsArray();
42789 }
42790 
Serialize(::protozero::Message * msg) const42791 void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
42792   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42793 }
42794 
42795 
42796 ChangeTraceConfigRequest::ChangeTraceConfigRequest() = default;
42797 ChangeTraceConfigRequest::~ChangeTraceConfigRequest() = default;
42798 ChangeTraceConfigRequest::ChangeTraceConfigRequest(const ChangeTraceConfigRequest&) = default;
42799 ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(const ChangeTraceConfigRequest&) = default;
42800 ChangeTraceConfigRequest::ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept = default;
42801 ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(ChangeTraceConfigRequest&&) = default;
42802 
operator ==(const ChangeTraceConfigRequest & other) const42803 bool ChangeTraceConfigRequest::operator==(const ChangeTraceConfigRequest& other) const {
42804   return unknown_fields_ == other.unknown_fields_
42805    && trace_config_ == other.trace_config_;
42806 }
42807 
ParseFromArray(const void * raw,size_t size)42808 bool ChangeTraceConfigRequest::ParseFromArray(const void* raw, size_t size) {
42809   unknown_fields_.clear();
42810   bool packed_error = false;
42811 
42812   ::protozero::ProtoDecoder dec(raw, size);
42813   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42814     if (field.id() < _has_field_.size()) {
42815       _has_field_.set(field.id());
42816     }
42817     switch (field.id()) {
42818       case 1 /* trace_config */:
42819         (*trace_config_).ParseFromString(field.as_std_string());
42820         break;
42821       default:
42822         field.SerializeAndAppendTo(&unknown_fields_);
42823         break;
42824     }
42825   }
42826   return !packed_error && !dec.bytes_left();
42827 }
42828 
SerializeAsString() const42829 std::string ChangeTraceConfigRequest::SerializeAsString() const {
42830   ::protozero::HeapBuffered<::protozero::Message> msg;
42831   Serialize(msg.get());
42832   return msg.SerializeAsString();
42833 }
42834 
SerializeAsArray() const42835 std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
42836   ::protozero::HeapBuffered<::protozero::Message> msg;
42837   Serialize(msg.get());
42838   return msg.SerializeAsArray();
42839 }
42840 
Serialize(::protozero::Message * msg) const42841 void ChangeTraceConfigRequest::Serialize(::protozero::Message* msg) const {
42842   // Field 1: trace_config
42843   if (_has_field_[1]) {
42844     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
42845   }
42846 
42847   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42848 }
42849 
42850 
42851 StartTracingResponse::StartTracingResponse() = default;
42852 StartTracingResponse::~StartTracingResponse() = default;
42853 StartTracingResponse::StartTracingResponse(const StartTracingResponse&) = default;
42854 StartTracingResponse& StartTracingResponse::operator=(const StartTracingResponse&) = default;
42855 StartTracingResponse::StartTracingResponse(StartTracingResponse&&) noexcept = default;
42856 StartTracingResponse& StartTracingResponse::operator=(StartTracingResponse&&) = default;
42857 
operator ==(const StartTracingResponse & other) const42858 bool StartTracingResponse::operator==(const StartTracingResponse& other) const {
42859   return unknown_fields_ == other.unknown_fields_;
42860 }
42861 
ParseFromArray(const void * raw,size_t size)42862 bool StartTracingResponse::ParseFromArray(const void* raw, size_t size) {
42863   unknown_fields_.clear();
42864   bool packed_error = false;
42865 
42866   ::protozero::ProtoDecoder dec(raw, size);
42867   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42868     if (field.id() < _has_field_.size()) {
42869       _has_field_.set(field.id());
42870     }
42871     switch (field.id()) {
42872       default:
42873         field.SerializeAndAppendTo(&unknown_fields_);
42874         break;
42875     }
42876   }
42877   return !packed_error && !dec.bytes_left();
42878 }
42879 
SerializeAsString() const42880 std::string StartTracingResponse::SerializeAsString() const {
42881   ::protozero::HeapBuffered<::protozero::Message> msg;
42882   Serialize(msg.get());
42883   return msg.SerializeAsString();
42884 }
42885 
SerializeAsArray() const42886 std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
42887   ::protozero::HeapBuffered<::protozero::Message> msg;
42888   Serialize(msg.get());
42889   return msg.SerializeAsArray();
42890 }
42891 
Serialize(::protozero::Message * msg) const42892 void StartTracingResponse::Serialize(::protozero::Message* msg) const {
42893   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42894 }
42895 
42896 
42897 StartTracingRequest::StartTracingRequest() = default;
42898 StartTracingRequest::~StartTracingRequest() = default;
42899 StartTracingRequest::StartTracingRequest(const StartTracingRequest&) = default;
42900 StartTracingRequest& StartTracingRequest::operator=(const StartTracingRequest&) = default;
42901 StartTracingRequest::StartTracingRequest(StartTracingRequest&&) noexcept = default;
42902 StartTracingRequest& StartTracingRequest::operator=(StartTracingRequest&&) = default;
42903 
operator ==(const StartTracingRequest & other) const42904 bool StartTracingRequest::operator==(const StartTracingRequest& other) const {
42905   return unknown_fields_ == other.unknown_fields_;
42906 }
42907 
ParseFromArray(const void * raw,size_t size)42908 bool StartTracingRequest::ParseFromArray(const void* raw, size_t size) {
42909   unknown_fields_.clear();
42910   bool packed_error = false;
42911 
42912   ::protozero::ProtoDecoder dec(raw, size);
42913   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42914     if (field.id() < _has_field_.size()) {
42915       _has_field_.set(field.id());
42916     }
42917     switch (field.id()) {
42918       default:
42919         field.SerializeAndAppendTo(&unknown_fields_);
42920         break;
42921     }
42922   }
42923   return !packed_error && !dec.bytes_left();
42924 }
42925 
SerializeAsString() const42926 std::string StartTracingRequest::SerializeAsString() const {
42927   ::protozero::HeapBuffered<::protozero::Message> msg;
42928   Serialize(msg.get());
42929   return msg.SerializeAsString();
42930 }
42931 
SerializeAsArray() const42932 std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
42933   ::protozero::HeapBuffered<::protozero::Message> msg;
42934   Serialize(msg.get());
42935   return msg.SerializeAsArray();
42936 }
42937 
Serialize(::protozero::Message * msg) const42938 void StartTracingRequest::Serialize(::protozero::Message* msg) const {
42939   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42940 }
42941 
42942 
42943 EnableTracingResponse::EnableTracingResponse() = default;
42944 EnableTracingResponse::~EnableTracingResponse() = default;
42945 EnableTracingResponse::EnableTracingResponse(const EnableTracingResponse&) = default;
42946 EnableTracingResponse& EnableTracingResponse::operator=(const EnableTracingResponse&) = default;
42947 EnableTracingResponse::EnableTracingResponse(EnableTracingResponse&&) noexcept = default;
42948 EnableTracingResponse& EnableTracingResponse::operator=(EnableTracingResponse&&) = default;
42949 
operator ==(const EnableTracingResponse & other) const42950 bool EnableTracingResponse::operator==(const EnableTracingResponse& other) const {
42951   return unknown_fields_ == other.unknown_fields_
42952    && disabled_ == other.disabled_;
42953 }
42954 
ParseFromArray(const void * raw,size_t size)42955 bool EnableTracingResponse::ParseFromArray(const void* raw, size_t size) {
42956   unknown_fields_.clear();
42957   bool packed_error = false;
42958 
42959   ::protozero::ProtoDecoder dec(raw, size);
42960   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
42961     if (field.id() < _has_field_.size()) {
42962       _has_field_.set(field.id());
42963     }
42964     switch (field.id()) {
42965       case 1 /* disabled */:
42966         field.get(&disabled_);
42967         break;
42968       default:
42969         field.SerializeAndAppendTo(&unknown_fields_);
42970         break;
42971     }
42972   }
42973   return !packed_error && !dec.bytes_left();
42974 }
42975 
SerializeAsString() const42976 std::string EnableTracingResponse::SerializeAsString() const {
42977   ::protozero::HeapBuffered<::protozero::Message> msg;
42978   Serialize(msg.get());
42979   return msg.SerializeAsString();
42980 }
42981 
SerializeAsArray() const42982 std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
42983   ::protozero::HeapBuffered<::protozero::Message> msg;
42984   Serialize(msg.get());
42985   return msg.SerializeAsArray();
42986 }
42987 
Serialize(::protozero::Message * msg) const42988 void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
42989   // Field 1: disabled
42990   if (_has_field_[1]) {
42991     msg->AppendTinyVarInt(1, disabled_);
42992   }
42993 
42994   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
42995 }
42996 
42997 
42998 EnableTracingRequest::EnableTracingRequest() = default;
42999 EnableTracingRequest::~EnableTracingRequest() = default;
43000 EnableTracingRequest::EnableTracingRequest(const EnableTracingRequest&) = default;
43001 EnableTracingRequest& EnableTracingRequest::operator=(const EnableTracingRequest&) = default;
43002 EnableTracingRequest::EnableTracingRequest(EnableTracingRequest&&) noexcept = default;
43003 EnableTracingRequest& EnableTracingRequest::operator=(EnableTracingRequest&&) = default;
43004 
operator ==(const EnableTracingRequest & other) const43005 bool EnableTracingRequest::operator==(const EnableTracingRequest& other) const {
43006   return unknown_fields_ == other.unknown_fields_
43007    && trace_config_ == other.trace_config_
43008    && attach_notification_only_ == other.attach_notification_only_;
43009 }
43010 
ParseFromArray(const void * raw,size_t size)43011 bool EnableTracingRequest::ParseFromArray(const void* raw, size_t size) {
43012   unknown_fields_.clear();
43013   bool packed_error = false;
43014 
43015   ::protozero::ProtoDecoder dec(raw, size);
43016   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
43017     if (field.id() < _has_field_.size()) {
43018       _has_field_.set(field.id());
43019     }
43020     switch (field.id()) {
43021       case 1 /* trace_config */:
43022         (*trace_config_).ParseFromString(field.as_std_string());
43023         break;
43024       case 2 /* attach_notification_only */:
43025         field.get(&attach_notification_only_);
43026         break;
43027       default:
43028         field.SerializeAndAppendTo(&unknown_fields_);
43029         break;
43030     }
43031   }
43032   return !packed_error && !dec.bytes_left();
43033 }
43034 
SerializeAsString() const43035 std::string EnableTracingRequest::SerializeAsString() const {
43036   ::protozero::HeapBuffered<::protozero::Message> msg;
43037   Serialize(msg.get());
43038   return msg.SerializeAsString();
43039 }
43040 
SerializeAsArray() const43041 std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
43042   ::protozero::HeapBuffered<::protozero::Message> msg;
43043   Serialize(msg.get());
43044   return msg.SerializeAsArray();
43045 }
43046 
Serialize(::protozero::Message * msg) const43047 void EnableTracingRequest::Serialize(::protozero::Message* msg) const {
43048   // Field 1: trace_config
43049   if (_has_field_[1]) {
43050     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
43051   }
43052 
43053   // Field 2: attach_notification_only
43054   if (_has_field_[2]) {
43055     msg->AppendTinyVarInt(2, attach_notification_only_);
43056   }
43057 
43058   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
43059 }
43060 
43061 }  // namespace perfetto
43062 }  // namespace protos
43063 }  // namespace gen
43064 #pragma GCC diagnostic pop
43065 // gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.gen.cc
43066 // gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.gen.h
43067 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
43068 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
43069 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
43070 
43071 #include <stdint.h>
43072 #include <bitset>
43073 #include <vector>
43074 #include <string>
43075 #include <type_traits>
43076 
43077 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
43078 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
43079 // gen_amalgamated expanded: #include "perfetto/base/export.h"
43080 
43081 namespace perfetto {
43082 namespace protos {
43083 namespace gen {
43084 class SyncResponse;
43085 class SyncRequest;
43086 class GetAsyncCommandResponse;
43087 class GetAsyncCommandResponse_ClearIncrementalState;
43088 class GetAsyncCommandResponse_Flush;
43089 class GetAsyncCommandResponse_StopDataSource;
43090 class GetAsyncCommandResponse_StartDataSource;
43091 class DataSourceConfig;
43092 class TestConfig;
43093 class TestConfig_DummyFields;
43094 class ChromeConfig;
43095 class GetAsyncCommandResponse_SetupDataSource;
43096 class GetAsyncCommandResponse_SetupTracing;
43097 class GetAsyncCommandRequest;
43098 class ActivateTriggersResponse;
43099 class ActivateTriggersRequest;
43100 class NotifyDataSourceStoppedResponse;
43101 class NotifyDataSourceStoppedRequest;
43102 class NotifyDataSourceStartedResponse;
43103 class NotifyDataSourceStartedRequest;
43104 class CommitDataResponse;
43105 class UnregisterTraceWriterResponse;
43106 class UnregisterTraceWriterRequest;
43107 class RegisterTraceWriterResponse;
43108 class RegisterTraceWriterRequest;
43109 class UnregisterDataSourceResponse;
43110 class UnregisterDataSourceRequest;
43111 class RegisterDataSourceResponse;
43112 class RegisterDataSourceRequest;
43113 class DataSourceDescriptor;
43114 class InitializeConnectionResponse;
43115 class InitializeConnectionRequest;
43116 enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
43117 enum InitializeConnectionRequest_ProducerBuildFlags : int;
43118 }  // namespace perfetto
43119 }  // namespace protos
43120 }  // namespace gen
43121 
43122 namespace protozero {
43123 class Message;
43124 }  // namespace protozero
43125 
43126 namespace perfetto {
43127 namespace protos {
43128 namespace gen {
43129 enum InitializeConnectionRequest_ProducerSMBScrapingMode : int {
43130   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED = 0,
43131   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED = 1,
43132   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED = 2,
43133 };
43134 enum InitializeConnectionRequest_ProducerBuildFlags : int {
43135   InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED = 0,
43136   InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON = 1,
43137   InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF = 2,
43138 };
43139 
43140 class PERFETTO_EXPORT SyncResponse : public ::protozero::CppMessageObj {
43141  public:
43142   enum FieldNumbers {
43143   };
43144 
43145   SyncResponse();
43146   ~SyncResponse() override;
43147   SyncResponse(SyncResponse&&) noexcept;
43148   SyncResponse& operator=(SyncResponse&&);
43149   SyncResponse(const SyncResponse&);
43150   SyncResponse& operator=(const SyncResponse&);
43151   bool operator==(const SyncResponse&) const;
operator !=(const SyncResponse & other) const43152   bool operator!=(const SyncResponse& other) const { return !(*this == other); }
43153 
43154   bool ParseFromArray(const void*, size_t) override;
43155   std::string SerializeAsString() const override;
43156   std::vector<uint8_t> SerializeAsArray() const override;
43157   void Serialize(::protozero::Message*) const;
43158 
43159  private:
43160 
43161   // Allows to preserve unknown protobuf fields for compatibility
43162   // with future versions of .proto files.
43163   std::string unknown_fields_;
43164 
43165   std::bitset<2> _has_field_{};
43166 };
43167 
43168 
43169 class PERFETTO_EXPORT SyncRequest : public ::protozero::CppMessageObj {
43170  public:
43171   enum FieldNumbers {
43172   };
43173 
43174   SyncRequest();
43175   ~SyncRequest() override;
43176   SyncRequest(SyncRequest&&) noexcept;
43177   SyncRequest& operator=(SyncRequest&&);
43178   SyncRequest(const SyncRequest&);
43179   SyncRequest& operator=(const SyncRequest&);
43180   bool operator==(const SyncRequest&) const;
operator !=(const SyncRequest & other) const43181   bool operator!=(const SyncRequest& other) const { return !(*this == other); }
43182 
43183   bool ParseFromArray(const void*, size_t) override;
43184   std::string SerializeAsString() const override;
43185   std::vector<uint8_t> SerializeAsArray() const override;
43186   void Serialize(::protozero::Message*) const;
43187 
43188  private:
43189 
43190   // Allows to preserve unknown protobuf fields for compatibility
43191   // with future versions of .proto files.
43192   std::string unknown_fields_;
43193 
43194   std::bitset<2> _has_field_{};
43195 };
43196 
43197 
43198 class PERFETTO_EXPORT GetAsyncCommandResponse : public ::protozero::CppMessageObj {
43199  public:
43200   using SetupDataSource = GetAsyncCommandResponse_SetupDataSource;
43201   using StartDataSource = GetAsyncCommandResponse_StartDataSource;
43202   using StopDataSource = GetAsyncCommandResponse_StopDataSource;
43203   using SetupTracing = GetAsyncCommandResponse_SetupTracing;
43204   using Flush = GetAsyncCommandResponse_Flush;
43205   using ClearIncrementalState = GetAsyncCommandResponse_ClearIncrementalState;
43206   enum FieldNumbers {
43207     kSetupTracingFieldNumber = 3,
43208     kSetupDataSourceFieldNumber = 6,
43209     kStartDataSourceFieldNumber = 1,
43210     kStopDataSourceFieldNumber = 2,
43211     kFlushFieldNumber = 5,
43212     kClearIncrementalStateFieldNumber = 7,
43213   };
43214 
43215   GetAsyncCommandResponse();
43216   ~GetAsyncCommandResponse() override;
43217   GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept;
43218   GetAsyncCommandResponse& operator=(GetAsyncCommandResponse&&);
43219   GetAsyncCommandResponse(const GetAsyncCommandResponse&);
43220   GetAsyncCommandResponse& operator=(const GetAsyncCommandResponse&);
43221   bool operator==(const GetAsyncCommandResponse&) const;
operator !=(const GetAsyncCommandResponse & other) const43222   bool operator!=(const GetAsyncCommandResponse& other) const { return !(*this == other); }
43223 
43224   bool ParseFromArray(const void*, size_t) override;
43225   std::string SerializeAsString() const override;
43226   std::vector<uint8_t> SerializeAsArray() const override;
43227   void Serialize(::protozero::Message*) const;
43228 
has_setup_tracing() const43229   bool has_setup_tracing() const { return _has_field_[3]; }
setup_tracing() const43230   const GetAsyncCommandResponse_SetupTracing& setup_tracing() const { return *setup_tracing_; }
mutable_setup_tracing()43231   GetAsyncCommandResponse_SetupTracing* mutable_setup_tracing() { _has_field_.set(3); return setup_tracing_.get(); }
43232 
has_setup_data_source() const43233   bool has_setup_data_source() const { return _has_field_[6]; }
setup_data_source() const43234   const GetAsyncCommandResponse_SetupDataSource& setup_data_source() const { return *setup_data_source_; }
mutable_setup_data_source()43235   GetAsyncCommandResponse_SetupDataSource* mutable_setup_data_source() { _has_field_.set(6); return setup_data_source_.get(); }
43236 
has_start_data_source() const43237   bool has_start_data_source() const { return _has_field_[1]; }
start_data_source() const43238   const GetAsyncCommandResponse_StartDataSource& start_data_source() const { return *start_data_source_; }
mutable_start_data_source()43239   GetAsyncCommandResponse_StartDataSource* mutable_start_data_source() { _has_field_.set(1); return start_data_source_.get(); }
43240 
has_stop_data_source() const43241   bool has_stop_data_source() const { return _has_field_[2]; }
stop_data_source() const43242   const GetAsyncCommandResponse_StopDataSource& stop_data_source() const { return *stop_data_source_; }
mutable_stop_data_source()43243   GetAsyncCommandResponse_StopDataSource* mutable_stop_data_source() { _has_field_.set(2); return stop_data_source_.get(); }
43244 
has_flush() const43245   bool has_flush() const { return _has_field_[5]; }
flush() const43246   const GetAsyncCommandResponse_Flush& flush() const { return *flush_; }
mutable_flush()43247   GetAsyncCommandResponse_Flush* mutable_flush() { _has_field_.set(5); return flush_.get(); }
43248 
has_clear_incremental_state() const43249   bool has_clear_incremental_state() const { return _has_field_[7]; }
clear_incremental_state() const43250   const GetAsyncCommandResponse_ClearIncrementalState& clear_incremental_state() const { return *clear_incremental_state_; }
mutable_clear_incremental_state()43251   GetAsyncCommandResponse_ClearIncrementalState* mutable_clear_incremental_state() { _has_field_.set(7); return clear_incremental_state_.get(); }
43252 
43253  private:
43254   ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupTracing> setup_tracing_;
43255   ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupDataSource> setup_data_source_;
43256   ::protozero::CopyablePtr<GetAsyncCommandResponse_StartDataSource> start_data_source_;
43257   ::protozero::CopyablePtr<GetAsyncCommandResponse_StopDataSource> stop_data_source_;
43258   ::protozero::CopyablePtr<GetAsyncCommandResponse_Flush> flush_;
43259   ::protozero::CopyablePtr<GetAsyncCommandResponse_ClearIncrementalState> clear_incremental_state_;
43260 
43261   // Allows to preserve unknown protobuf fields for compatibility
43262   // with future versions of .proto files.
43263   std::string unknown_fields_;
43264 
43265   std::bitset<8> _has_field_{};
43266 };
43267 
43268 
43269 class PERFETTO_EXPORT GetAsyncCommandResponse_ClearIncrementalState : public ::protozero::CppMessageObj {
43270  public:
43271   enum FieldNumbers {
43272     kDataSourceIdsFieldNumber = 1,
43273   };
43274 
43275   GetAsyncCommandResponse_ClearIncrementalState();
43276   ~GetAsyncCommandResponse_ClearIncrementalState() override;
43277   GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept;
43278   GetAsyncCommandResponse_ClearIncrementalState& operator=(GetAsyncCommandResponse_ClearIncrementalState&&);
43279   GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&);
43280   GetAsyncCommandResponse_ClearIncrementalState& operator=(const GetAsyncCommandResponse_ClearIncrementalState&);
43281   bool operator==(const GetAsyncCommandResponse_ClearIncrementalState&) const;
operator !=(const GetAsyncCommandResponse_ClearIncrementalState & other) const43282   bool operator!=(const GetAsyncCommandResponse_ClearIncrementalState& other) const { return !(*this == other); }
43283 
43284   bool ParseFromArray(const void*, size_t) override;
43285   std::string SerializeAsString() const override;
43286   std::vector<uint8_t> SerializeAsArray() const override;
43287   void Serialize(::protozero::Message*) const;
43288 
data_source_ids_size() const43289   int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
data_source_ids() const43290   const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
mutable_data_source_ids()43291   std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
clear_data_source_ids()43292   void clear_data_source_ids() { data_source_ids_.clear(); }
add_data_source_ids(uint64_t value)43293   void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
add_data_source_ids()43294   uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
43295 
43296  private:
43297   std::vector<uint64_t> data_source_ids_;
43298 
43299   // Allows to preserve unknown protobuf fields for compatibility
43300   // with future versions of .proto files.
43301   std::string unknown_fields_;
43302 
43303   std::bitset<2> _has_field_{};
43304 };
43305 
43306 
43307 class PERFETTO_EXPORT GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
43308  public:
43309   enum FieldNumbers {
43310     kDataSourceIdsFieldNumber = 1,
43311     kRequestIdFieldNumber = 2,
43312   };
43313 
43314   GetAsyncCommandResponse_Flush();
43315   ~GetAsyncCommandResponse_Flush() override;
43316   GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept;
43317   GetAsyncCommandResponse_Flush& operator=(GetAsyncCommandResponse_Flush&&);
43318   GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&);
43319   GetAsyncCommandResponse_Flush& operator=(const GetAsyncCommandResponse_Flush&);
43320   bool operator==(const GetAsyncCommandResponse_Flush&) const;
operator !=(const GetAsyncCommandResponse_Flush & other) const43321   bool operator!=(const GetAsyncCommandResponse_Flush& other) const { return !(*this == other); }
43322 
43323   bool ParseFromArray(const void*, size_t) override;
43324   std::string SerializeAsString() const override;
43325   std::vector<uint8_t> SerializeAsArray() const override;
43326   void Serialize(::protozero::Message*) const;
43327 
data_source_ids_size() const43328   int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
data_source_ids() const43329   const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
mutable_data_source_ids()43330   std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
clear_data_source_ids()43331   void clear_data_source_ids() { data_source_ids_.clear(); }
add_data_source_ids(uint64_t value)43332   void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
add_data_source_ids()43333   uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
43334 
has_request_id() const43335   bool has_request_id() const { return _has_field_[2]; }
request_id() const43336   uint64_t request_id() const { return request_id_; }
set_request_id(uint64_t value)43337   void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
43338 
43339  private:
43340   std::vector<uint64_t> data_source_ids_;
43341   uint64_t request_id_{};
43342 
43343   // Allows to preserve unknown protobuf fields for compatibility
43344   // with future versions of .proto files.
43345   std::string unknown_fields_;
43346 
43347   std::bitset<3> _has_field_{};
43348 };
43349 
43350 
43351 class PERFETTO_EXPORT GetAsyncCommandResponse_StopDataSource : public ::protozero::CppMessageObj {
43352  public:
43353   enum FieldNumbers {
43354     kInstanceIdFieldNumber = 1,
43355   };
43356 
43357   GetAsyncCommandResponse_StopDataSource();
43358   ~GetAsyncCommandResponse_StopDataSource() override;
43359   GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept;
43360   GetAsyncCommandResponse_StopDataSource& operator=(GetAsyncCommandResponse_StopDataSource&&);
43361   GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&);
43362   GetAsyncCommandResponse_StopDataSource& operator=(const GetAsyncCommandResponse_StopDataSource&);
43363   bool operator==(const GetAsyncCommandResponse_StopDataSource&) const;
operator !=(const GetAsyncCommandResponse_StopDataSource & other) const43364   bool operator!=(const GetAsyncCommandResponse_StopDataSource& other) const { return !(*this == other); }
43365 
43366   bool ParseFromArray(const void*, size_t) override;
43367   std::string SerializeAsString() const override;
43368   std::vector<uint8_t> SerializeAsArray() const override;
43369   void Serialize(::protozero::Message*) const;
43370 
has_instance_id() const43371   bool has_instance_id() const { return _has_field_[1]; }
instance_id() const43372   uint64_t instance_id() const { return instance_id_; }
set_instance_id(uint64_t value)43373   void set_instance_id(uint64_t value) { instance_id_ = value; _has_field_.set(1); }
43374 
43375  private:
43376   uint64_t instance_id_{};
43377 
43378   // Allows to preserve unknown protobuf fields for compatibility
43379   // with future versions of .proto files.
43380   std::string unknown_fields_;
43381 
43382   std::bitset<2> _has_field_{};
43383 };
43384 
43385 
43386 class PERFETTO_EXPORT GetAsyncCommandResponse_StartDataSource : public ::protozero::CppMessageObj {
43387  public:
43388   enum FieldNumbers {
43389     kNewInstanceIdFieldNumber = 1,
43390     kConfigFieldNumber = 2,
43391   };
43392 
43393   GetAsyncCommandResponse_StartDataSource();
43394   ~GetAsyncCommandResponse_StartDataSource() override;
43395   GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept;
43396   GetAsyncCommandResponse_StartDataSource& operator=(GetAsyncCommandResponse_StartDataSource&&);
43397   GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&);
43398   GetAsyncCommandResponse_StartDataSource& operator=(const GetAsyncCommandResponse_StartDataSource&);
43399   bool operator==(const GetAsyncCommandResponse_StartDataSource&) const;
operator !=(const GetAsyncCommandResponse_StartDataSource & other) const43400   bool operator!=(const GetAsyncCommandResponse_StartDataSource& other) const { return !(*this == other); }
43401 
43402   bool ParseFromArray(const void*, size_t) override;
43403   std::string SerializeAsString() const override;
43404   std::vector<uint8_t> SerializeAsArray() const override;
43405   void Serialize(::protozero::Message*) const;
43406 
has_new_instance_id() const43407   bool has_new_instance_id() const { return _has_field_[1]; }
new_instance_id() const43408   uint64_t new_instance_id() const { return new_instance_id_; }
set_new_instance_id(uint64_t value)43409   void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
43410 
has_config() const43411   bool has_config() const { return _has_field_[2]; }
config() const43412   const DataSourceConfig& config() const { return *config_; }
mutable_config()43413   DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
43414 
43415  private:
43416   uint64_t new_instance_id_{};
43417   ::protozero::CopyablePtr<DataSourceConfig> config_;
43418 
43419   // Allows to preserve unknown protobuf fields for compatibility
43420   // with future versions of .proto files.
43421   std::string unknown_fields_;
43422 
43423   std::bitset<3> _has_field_{};
43424 };
43425 
43426 
43427 class PERFETTO_EXPORT GetAsyncCommandResponse_SetupDataSource : public ::protozero::CppMessageObj {
43428  public:
43429   enum FieldNumbers {
43430     kNewInstanceIdFieldNumber = 1,
43431     kConfigFieldNumber = 2,
43432   };
43433 
43434   GetAsyncCommandResponse_SetupDataSource();
43435   ~GetAsyncCommandResponse_SetupDataSource() override;
43436   GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept;
43437   GetAsyncCommandResponse_SetupDataSource& operator=(GetAsyncCommandResponse_SetupDataSource&&);
43438   GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&);
43439   GetAsyncCommandResponse_SetupDataSource& operator=(const GetAsyncCommandResponse_SetupDataSource&);
43440   bool operator==(const GetAsyncCommandResponse_SetupDataSource&) const;
operator !=(const GetAsyncCommandResponse_SetupDataSource & other) const43441   bool operator!=(const GetAsyncCommandResponse_SetupDataSource& other) const { return !(*this == other); }
43442 
43443   bool ParseFromArray(const void*, size_t) override;
43444   std::string SerializeAsString() const override;
43445   std::vector<uint8_t> SerializeAsArray() const override;
43446   void Serialize(::protozero::Message*) const;
43447 
has_new_instance_id() const43448   bool has_new_instance_id() const { return _has_field_[1]; }
new_instance_id() const43449   uint64_t new_instance_id() const { return new_instance_id_; }
set_new_instance_id(uint64_t value)43450   void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
43451 
has_config() const43452   bool has_config() const { return _has_field_[2]; }
config() const43453   const DataSourceConfig& config() const { return *config_; }
mutable_config()43454   DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
43455 
43456  private:
43457   uint64_t new_instance_id_{};
43458   ::protozero::CopyablePtr<DataSourceConfig> config_;
43459 
43460   // Allows to preserve unknown protobuf fields for compatibility
43461   // with future versions of .proto files.
43462   std::string unknown_fields_;
43463 
43464   std::bitset<3> _has_field_{};
43465 };
43466 
43467 
43468 class PERFETTO_EXPORT GetAsyncCommandResponse_SetupTracing : public ::protozero::CppMessageObj {
43469  public:
43470   enum FieldNumbers {
43471     kSharedBufferPageSizeKbFieldNumber = 1,
43472   };
43473 
43474   GetAsyncCommandResponse_SetupTracing();
43475   ~GetAsyncCommandResponse_SetupTracing() override;
43476   GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept;
43477   GetAsyncCommandResponse_SetupTracing& operator=(GetAsyncCommandResponse_SetupTracing&&);
43478   GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&);
43479   GetAsyncCommandResponse_SetupTracing& operator=(const GetAsyncCommandResponse_SetupTracing&);
43480   bool operator==(const GetAsyncCommandResponse_SetupTracing&) const;
operator !=(const GetAsyncCommandResponse_SetupTracing & other) const43481   bool operator!=(const GetAsyncCommandResponse_SetupTracing& other) const { return !(*this == other); }
43482 
43483   bool ParseFromArray(const void*, size_t) override;
43484   std::string SerializeAsString() const override;
43485   std::vector<uint8_t> SerializeAsArray() const override;
43486   void Serialize(::protozero::Message*) const;
43487 
has_shared_buffer_page_size_kb() const43488   bool has_shared_buffer_page_size_kb() const { return _has_field_[1]; }
shared_buffer_page_size_kb() const43489   uint32_t shared_buffer_page_size_kb() const { return shared_buffer_page_size_kb_; }
set_shared_buffer_page_size_kb(uint32_t value)43490   void set_shared_buffer_page_size_kb(uint32_t value) { shared_buffer_page_size_kb_ = value; _has_field_.set(1); }
43491 
43492  private:
43493   uint32_t shared_buffer_page_size_kb_{};
43494 
43495   // Allows to preserve unknown protobuf fields for compatibility
43496   // with future versions of .proto files.
43497   std::string unknown_fields_;
43498 
43499   std::bitset<2> _has_field_{};
43500 };
43501 
43502 
43503 class PERFETTO_EXPORT GetAsyncCommandRequest : public ::protozero::CppMessageObj {
43504  public:
43505   enum FieldNumbers {
43506   };
43507 
43508   GetAsyncCommandRequest();
43509   ~GetAsyncCommandRequest() override;
43510   GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept;
43511   GetAsyncCommandRequest& operator=(GetAsyncCommandRequest&&);
43512   GetAsyncCommandRequest(const GetAsyncCommandRequest&);
43513   GetAsyncCommandRequest& operator=(const GetAsyncCommandRequest&);
43514   bool operator==(const GetAsyncCommandRequest&) const;
operator !=(const GetAsyncCommandRequest & other) const43515   bool operator!=(const GetAsyncCommandRequest& other) const { return !(*this == other); }
43516 
43517   bool ParseFromArray(const void*, size_t) override;
43518   std::string SerializeAsString() const override;
43519   std::vector<uint8_t> SerializeAsArray() const override;
43520   void Serialize(::protozero::Message*) const;
43521 
43522  private:
43523 
43524   // Allows to preserve unknown protobuf fields for compatibility
43525   // with future versions of .proto files.
43526   std::string unknown_fields_;
43527 
43528   std::bitset<2> _has_field_{};
43529 };
43530 
43531 
43532 class PERFETTO_EXPORT ActivateTriggersResponse : public ::protozero::CppMessageObj {
43533  public:
43534   enum FieldNumbers {
43535   };
43536 
43537   ActivateTriggersResponse();
43538   ~ActivateTriggersResponse() override;
43539   ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept;
43540   ActivateTriggersResponse& operator=(ActivateTriggersResponse&&);
43541   ActivateTriggersResponse(const ActivateTriggersResponse&);
43542   ActivateTriggersResponse& operator=(const ActivateTriggersResponse&);
43543   bool operator==(const ActivateTriggersResponse&) const;
operator !=(const ActivateTriggersResponse & other) const43544   bool operator!=(const ActivateTriggersResponse& other) const { return !(*this == other); }
43545 
43546   bool ParseFromArray(const void*, size_t) override;
43547   std::string SerializeAsString() const override;
43548   std::vector<uint8_t> SerializeAsArray() const override;
43549   void Serialize(::protozero::Message*) const;
43550 
43551  private:
43552 
43553   // Allows to preserve unknown protobuf fields for compatibility
43554   // with future versions of .proto files.
43555   std::string unknown_fields_;
43556 
43557   std::bitset<2> _has_field_{};
43558 };
43559 
43560 
43561 class PERFETTO_EXPORT ActivateTriggersRequest : public ::protozero::CppMessageObj {
43562  public:
43563   enum FieldNumbers {
43564     kTriggerNamesFieldNumber = 1,
43565   };
43566 
43567   ActivateTriggersRequest();
43568   ~ActivateTriggersRequest() override;
43569   ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept;
43570   ActivateTriggersRequest& operator=(ActivateTriggersRequest&&);
43571   ActivateTriggersRequest(const ActivateTriggersRequest&);
43572   ActivateTriggersRequest& operator=(const ActivateTriggersRequest&);
43573   bool operator==(const ActivateTriggersRequest&) const;
operator !=(const ActivateTriggersRequest & other) const43574   bool operator!=(const ActivateTriggersRequest& other) const { return !(*this == other); }
43575 
43576   bool ParseFromArray(const void*, size_t) override;
43577   std::string SerializeAsString() const override;
43578   std::vector<uint8_t> SerializeAsArray() const override;
43579   void Serialize(::protozero::Message*) const;
43580 
trigger_names_size() const43581   int trigger_names_size() const { return static_cast<int>(trigger_names_.size()); }
trigger_names() const43582   const std::vector<std::string>& trigger_names() const { return trigger_names_; }
mutable_trigger_names()43583   std::vector<std::string>* mutable_trigger_names() { return &trigger_names_; }
clear_trigger_names()43584   void clear_trigger_names() { trigger_names_.clear(); }
add_trigger_names(std::string value)43585   void add_trigger_names(std::string value) { trigger_names_.emplace_back(value); }
add_trigger_names()43586   std::string* add_trigger_names() { trigger_names_.emplace_back(); return &trigger_names_.back(); }
43587 
43588  private:
43589   std::vector<std::string> trigger_names_;
43590 
43591   // Allows to preserve unknown protobuf fields for compatibility
43592   // with future versions of .proto files.
43593   std::string unknown_fields_;
43594 
43595   std::bitset<2> _has_field_{};
43596 };
43597 
43598 
43599 class PERFETTO_EXPORT NotifyDataSourceStoppedResponse : public ::protozero::CppMessageObj {
43600  public:
43601   enum FieldNumbers {
43602   };
43603 
43604   NotifyDataSourceStoppedResponse();
43605   ~NotifyDataSourceStoppedResponse() override;
43606   NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept;
43607   NotifyDataSourceStoppedResponse& operator=(NotifyDataSourceStoppedResponse&&);
43608   NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&);
43609   NotifyDataSourceStoppedResponse& operator=(const NotifyDataSourceStoppedResponse&);
43610   bool operator==(const NotifyDataSourceStoppedResponse&) const;
operator !=(const NotifyDataSourceStoppedResponse & other) const43611   bool operator!=(const NotifyDataSourceStoppedResponse& other) const { return !(*this == other); }
43612 
43613   bool ParseFromArray(const void*, size_t) override;
43614   std::string SerializeAsString() const override;
43615   std::vector<uint8_t> SerializeAsArray() const override;
43616   void Serialize(::protozero::Message*) const;
43617 
43618  private:
43619 
43620   // Allows to preserve unknown protobuf fields for compatibility
43621   // with future versions of .proto files.
43622   std::string unknown_fields_;
43623 
43624   std::bitset<2> _has_field_{};
43625 };
43626 
43627 
43628 class PERFETTO_EXPORT NotifyDataSourceStoppedRequest : public ::protozero::CppMessageObj {
43629  public:
43630   enum FieldNumbers {
43631     kDataSourceIdFieldNumber = 1,
43632   };
43633 
43634   NotifyDataSourceStoppedRequest();
43635   ~NotifyDataSourceStoppedRequest() override;
43636   NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept;
43637   NotifyDataSourceStoppedRequest& operator=(NotifyDataSourceStoppedRequest&&);
43638   NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&);
43639   NotifyDataSourceStoppedRequest& operator=(const NotifyDataSourceStoppedRequest&);
43640   bool operator==(const NotifyDataSourceStoppedRequest&) const;
operator !=(const NotifyDataSourceStoppedRequest & other) const43641   bool operator!=(const NotifyDataSourceStoppedRequest& other) const { return !(*this == other); }
43642 
43643   bool ParseFromArray(const void*, size_t) override;
43644   std::string SerializeAsString() const override;
43645   std::vector<uint8_t> SerializeAsArray() const override;
43646   void Serialize(::protozero::Message*) const;
43647 
has_data_source_id() const43648   bool has_data_source_id() const { return _has_field_[1]; }
data_source_id() const43649   uint64_t data_source_id() const { return data_source_id_; }
set_data_source_id(uint64_t value)43650   void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
43651 
43652  private:
43653   uint64_t data_source_id_{};
43654 
43655   // Allows to preserve unknown protobuf fields for compatibility
43656   // with future versions of .proto files.
43657   std::string unknown_fields_;
43658 
43659   std::bitset<2> _has_field_{};
43660 };
43661 
43662 
43663 class PERFETTO_EXPORT NotifyDataSourceStartedResponse : public ::protozero::CppMessageObj {
43664  public:
43665   enum FieldNumbers {
43666   };
43667 
43668   NotifyDataSourceStartedResponse();
43669   ~NotifyDataSourceStartedResponse() override;
43670   NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept;
43671   NotifyDataSourceStartedResponse& operator=(NotifyDataSourceStartedResponse&&);
43672   NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&);
43673   NotifyDataSourceStartedResponse& operator=(const NotifyDataSourceStartedResponse&);
43674   bool operator==(const NotifyDataSourceStartedResponse&) const;
operator !=(const NotifyDataSourceStartedResponse & other) const43675   bool operator!=(const NotifyDataSourceStartedResponse& other) const { return !(*this == other); }
43676 
43677   bool ParseFromArray(const void*, size_t) override;
43678   std::string SerializeAsString() const override;
43679   std::vector<uint8_t> SerializeAsArray() const override;
43680   void Serialize(::protozero::Message*) const;
43681 
43682  private:
43683 
43684   // Allows to preserve unknown protobuf fields for compatibility
43685   // with future versions of .proto files.
43686   std::string unknown_fields_;
43687 
43688   std::bitset<2> _has_field_{};
43689 };
43690 
43691 
43692 class PERFETTO_EXPORT NotifyDataSourceStartedRequest : public ::protozero::CppMessageObj {
43693  public:
43694   enum FieldNumbers {
43695     kDataSourceIdFieldNumber = 1,
43696   };
43697 
43698   NotifyDataSourceStartedRequest();
43699   ~NotifyDataSourceStartedRequest() override;
43700   NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept;
43701   NotifyDataSourceStartedRequest& operator=(NotifyDataSourceStartedRequest&&);
43702   NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&);
43703   NotifyDataSourceStartedRequest& operator=(const NotifyDataSourceStartedRequest&);
43704   bool operator==(const NotifyDataSourceStartedRequest&) const;
operator !=(const NotifyDataSourceStartedRequest & other) const43705   bool operator!=(const NotifyDataSourceStartedRequest& other) const { return !(*this == other); }
43706 
43707   bool ParseFromArray(const void*, size_t) override;
43708   std::string SerializeAsString() const override;
43709   std::vector<uint8_t> SerializeAsArray() const override;
43710   void Serialize(::protozero::Message*) const;
43711 
has_data_source_id() const43712   bool has_data_source_id() const { return _has_field_[1]; }
data_source_id() const43713   uint64_t data_source_id() const { return data_source_id_; }
set_data_source_id(uint64_t value)43714   void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
43715 
43716  private:
43717   uint64_t data_source_id_{};
43718 
43719   // Allows to preserve unknown protobuf fields for compatibility
43720   // with future versions of .proto files.
43721   std::string unknown_fields_;
43722 
43723   std::bitset<2> _has_field_{};
43724 };
43725 
43726 
43727 class PERFETTO_EXPORT CommitDataResponse : public ::protozero::CppMessageObj {
43728  public:
43729   enum FieldNumbers {
43730   };
43731 
43732   CommitDataResponse();
43733   ~CommitDataResponse() override;
43734   CommitDataResponse(CommitDataResponse&&) noexcept;
43735   CommitDataResponse& operator=(CommitDataResponse&&);
43736   CommitDataResponse(const CommitDataResponse&);
43737   CommitDataResponse& operator=(const CommitDataResponse&);
43738   bool operator==(const CommitDataResponse&) const;
operator !=(const CommitDataResponse & other) const43739   bool operator!=(const CommitDataResponse& other) const { return !(*this == other); }
43740 
43741   bool ParseFromArray(const void*, size_t) override;
43742   std::string SerializeAsString() const override;
43743   std::vector<uint8_t> SerializeAsArray() const override;
43744   void Serialize(::protozero::Message*) const;
43745 
43746  private:
43747 
43748   // Allows to preserve unknown protobuf fields for compatibility
43749   // with future versions of .proto files.
43750   std::string unknown_fields_;
43751 
43752   std::bitset<2> _has_field_{};
43753 };
43754 
43755 
43756 class PERFETTO_EXPORT UnregisterTraceWriterResponse : public ::protozero::CppMessageObj {
43757  public:
43758   enum FieldNumbers {
43759   };
43760 
43761   UnregisterTraceWriterResponse();
43762   ~UnregisterTraceWriterResponse() override;
43763   UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept;
43764   UnregisterTraceWriterResponse& operator=(UnregisterTraceWriterResponse&&);
43765   UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&);
43766   UnregisterTraceWriterResponse& operator=(const UnregisterTraceWriterResponse&);
43767   bool operator==(const UnregisterTraceWriterResponse&) const;
operator !=(const UnregisterTraceWriterResponse & other) const43768   bool operator!=(const UnregisterTraceWriterResponse& other) const { return !(*this == other); }
43769 
43770   bool ParseFromArray(const void*, size_t) override;
43771   std::string SerializeAsString() const override;
43772   std::vector<uint8_t> SerializeAsArray() const override;
43773   void Serialize(::protozero::Message*) const;
43774 
43775  private:
43776 
43777   // Allows to preserve unknown protobuf fields for compatibility
43778   // with future versions of .proto files.
43779   std::string unknown_fields_;
43780 
43781   std::bitset<2> _has_field_{};
43782 };
43783 
43784 
43785 class PERFETTO_EXPORT UnregisterTraceWriterRequest : public ::protozero::CppMessageObj {
43786  public:
43787   enum FieldNumbers {
43788     kTraceWriterIdFieldNumber = 1,
43789   };
43790 
43791   UnregisterTraceWriterRequest();
43792   ~UnregisterTraceWriterRequest() override;
43793   UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept;
43794   UnregisterTraceWriterRequest& operator=(UnregisterTraceWriterRequest&&);
43795   UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&);
43796   UnregisterTraceWriterRequest& operator=(const UnregisterTraceWriterRequest&);
43797   bool operator==(const UnregisterTraceWriterRequest&) const;
operator !=(const UnregisterTraceWriterRequest & other) const43798   bool operator!=(const UnregisterTraceWriterRequest& other) const { return !(*this == other); }
43799 
43800   bool ParseFromArray(const void*, size_t) override;
43801   std::string SerializeAsString() const override;
43802   std::vector<uint8_t> SerializeAsArray() const override;
43803   void Serialize(::protozero::Message*) const;
43804 
has_trace_writer_id() const43805   bool has_trace_writer_id() const { return _has_field_[1]; }
trace_writer_id() const43806   uint32_t trace_writer_id() const { return trace_writer_id_; }
set_trace_writer_id(uint32_t value)43807   void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
43808 
43809  private:
43810   uint32_t trace_writer_id_{};
43811 
43812   // Allows to preserve unknown protobuf fields for compatibility
43813   // with future versions of .proto files.
43814   std::string unknown_fields_;
43815 
43816   std::bitset<2> _has_field_{};
43817 };
43818 
43819 
43820 class PERFETTO_EXPORT RegisterTraceWriterResponse : public ::protozero::CppMessageObj {
43821  public:
43822   enum FieldNumbers {
43823   };
43824 
43825   RegisterTraceWriterResponse();
43826   ~RegisterTraceWriterResponse() override;
43827   RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept;
43828   RegisterTraceWriterResponse& operator=(RegisterTraceWriterResponse&&);
43829   RegisterTraceWriterResponse(const RegisterTraceWriterResponse&);
43830   RegisterTraceWriterResponse& operator=(const RegisterTraceWriterResponse&);
43831   bool operator==(const RegisterTraceWriterResponse&) const;
operator !=(const RegisterTraceWriterResponse & other) const43832   bool operator!=(const RegisterTraceWriterResponse& other) const { return !(*this == other); }
43833 
43834   bool ParseFromArray(const void*, size_t) override;
43835   std::string SerializeAsString() const override;
43836   std::vector<uint8_t> SerializeAsArray() const override;
43837   void Serialize(::protozero::Message*) const;
43838 
43839  private:
43840 
43841   // Allows to preserve unknown protobuf fields for compatibility
43842   // with future versions of .proto files.
43843   std::string unknown_fields_;
43844 
43845   std::bitset<2> _has_field_{};
43846 };
43847 
43848 
43849 class PERFETTO_EXPORT RegisterTraceWriterRequest : public ::protozero::CppMessageObj {
43850  public:
43851   enum FieldNumbers {
43852     kTraceWriterIdFieldNumber = 1,
43853     kTargetBufferFieldNumber = 2,
43854   };
43855 
43856   RegisterTraceWriterRequest();
43857   ~RegisterTraceWriterRequest() override;
43858   RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept;
43859   RegisterTraceWriterRequest& operator=(RegisterTraceWriterRequest&&);
43860   RegisterTraceWriterRequest(const RegisterTraceWriterRequest&);
43861   RegisterTraceWriterRequest& operator=(const RegisterTraceWriterRequest&);
43862   bool operator==(const RegisterTraceWriterRequest&) const;
operator !=(const RegisterTraceWriterRequest & other) const43863   bool operator!=(const RegisterTraceWriterRequest& other) const { return !(*this == other); }
43864 
43865   bool ParseFromArray(const void*, size_t) override;
43866   std::string SerializeAsString() const override;
43867   std::vector<uint8_t> SerializeAsArray() const override;
43868   void Serialize(::protozero::Message*) const;
43869 
has_trace_writer_id() const43870   bool has_trace_writer_id() const { return _has_field_[1]; }
trace_writer_id() const43871   uint32_t trace_writer_id() const { return trace_writer_id_; }
set_trace_writer_id(uint32_t value)43872   void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
43873 
has_target_buffer() const43874   bool has_target_buffer() const { return _has_field_[2]; }
target_buffer() const43875   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)43876   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
43877 
43878  private:
43879   uint32_t trace_writer_id_{};
43880   uint32_t target_buffer_{};
43881 
43882   // Allows to preserve unknown protobuf fields for compatibility
43883   // with future versions of .proto files.
43884   std::string unknown_fields_;
43885 
43886   std::bitset<3> _has_field_{};
43887 };
43888 
43889 
43890 class PERFETTO_EXPORT UnregisterDataSourceResponse : public ::protozero::CppMessageObj {
43891  public:
43892   enum FieldNumbers {
43893   };
43894 
43895   UnregisterDataSourceResponse();
43896   ~UnregisterDataSourceResponse() override;
43897   UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept;
43898   UnregisterDataSourceResponse& operator=(UnregisterDataSourceResponse&&);
43899   UnregisterDataSourceResponse(const UnregisterDataSourceResponse&);
43900   UnregisterDataSourceResponse& operator=(const UnregisterDataSourceResponse&);
43901   bool operator==(const UnregisterDataSourceResponse&) const;
operator !=(const UnregisterDataSourceResponse & other) const43902   bool operator!=(const UnregisterDataSourceResponse& other) const { return !(*this == other); }
43903 
43904   bool ParseFromArray(const void*, size_t) override;
43905   std::string SerializeAsString() const override;
43906   std::vector<uint8_t> SerializeAsArray() const override;
43907   void Serialize(::protozero::Message*) const;
43908 
43909  private:
43910 
43911   // Allows to preserve unknown protobuf fields for compatibility
43912   // with future versions of .proto files.
43913   std::string unknown_fields_;
43914 
43915   std::bitset<2> _has_field_{};
43916 };
43917 
43918 
43919 class PERFETTO_EXPORT UnregisterDataSourceRequest : public ::protozero::CppMessageObj {
43920  public:
43921   enum FieldNumbers {
43922     kDataSourceNameFieldNumber = 1,
43923   };
43924 
43925   UnregisterDataSourceRequest();
43926   ~UnregisterDataSourceRequest() override;
43927   UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept;
43928   UnregisterDataSourceRequest& operator=(UnregisterDataSourceRequest&&);
43929   UnregisterDataSourceRequest(const UnregisterDataSourceRequest&);
43930   UnregisterDataSourceRequest& operator=(const UnregisterDataSourceRequest&);
43931   bool operator==(const UnregisterDataSourceRequest&) const;
operator !=(const UnregisterDataSourceRequest & other) const43932   bool operator!=(const UnregisterDataSourceRequest& other) const { return !(*this == other); }
43933 
43934   bool ParseFromArray(const void*, size_t) override;
43935   std::string SerializeAsString() const override;
43936   std::vector<uint8_t> SerializeAsArray() const override;
43937   void Serialize(::protozero::Message*) const;
43938 
has_data_source_name() const43939   bool has_data_source_name() const { return _has_field_[1]; }
data_source_name() const43940   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)43941   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(1); }
43942 
43943  private:
43944   std::string data_source_name_{};
43945 
43946   // Allows to preserve unknown protobuf fields for compatibility
43947   // with future versions of .proto files.
43948   std::string unknown_fields_;
43949 
43950   std::bitset<2> _has_field_{};
43951 };
43952 
43953 
43954 class PERFETTO_EXPORT RegisterDataSourceResponse : public ::protozero::CppMessageObj {
43955  public:
43956   enum FieldNumbers {
43957     kErrorFieldNumber = 1,
43958   };
43959 
43960   RegisterDataSourceResponse();
43961   ~RegisterDataSourceResponse() override;
43962   RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept;
43963   RegisterDataSourceResponse& operator=(RegisterDataSourceResponse&&);
43964   RegisterDataSourceResponse(const RegisterDataSourceResponse&);
43965   RegisterDataSourceResponse& operator=(const RegisterDataSourceResponse&);
43966   bool operator==(const RegisterDataSourceResponse&) const;
operator !=(const RegisterDataSourceResponse & other) const43967   bool operator!=(const RegisterDataSourceResponse& other) const { return !(*this == other); }
43968 
43969   bool ParseFromArray(const void*, size_t) override;
43970   std::string SerializeAsString() const override;
43971   std::vector<uint8_t> SerializeAsArray() const override;
43972   void Serialize(::protozero::Message*) const;
43973 
has_error() const43974   bool has_error() const { return _has_field_[1]; }
error() const43975   const std::string& error() const { return error_; }
set_error(const std::string & value)43976   void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
43977 
43978  private:
43979   std::string error_{};
43980 
43981   // Allows to preserve unknown protobuf fields for compatibility
43982   // with future versions of .proto files.
43983   std::string unknown_fields_;
43984 
43985   std::bitset<2> _has_field_{};
43986 };
43987 
43988 
43989 class PERFETTO_EXPORT RegisterDataSourceRequest : public ::protozero::CppMessageObj {
43990  public:
43991   enum FieldNumbers {
43992     kDataSourceDescriptorFieldNumber = 1,
43993   };
43994 
43995   RegisterDataSourceRequest();
43996   ~RegisterDataSourceRequest() override;
43997   RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept;
43998   RegisterDataSourceRequest& operator=(RegisterDataSourceRequest&&);
43999   RegisterDataSourceRequest(const RegisterDataSourceRequest&);
44000   RegisterDataSourceRequest& operator=(const RegisterDataSourceRequest&);
44001   bool operator==(const RegisterDataSourceRequest&) const;
operator !=(const RegisterDataSourceRequest & other) const44002   bool operator!=(const RegisterDataSourceRequest& other) const { return !(*this == other); }
44003 
44004   bool ParseFromArray(const void*, size_t) override;
44005   std::string SerializeAsString() const override;
44006   std::vector<uint8_t> SerializeAsArray() const override;
44007   void Serialize(::protozero::Message*) const;
44008 
has_data_source_descriptor() const44009   bool has_data_source_descriptor() const { return _has_field_[1]; }
data_source_descriptor() const44010   const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
mutable_data_source_descriptor()44011   DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
44012 
44013  private:
44014   ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
44015 
44016   // Allows to preserve unknown protobuf fields for compatibility
44017   // with future versions of .proto files.
44018   std::string unknown_fields_;
44019 
44020   std::bitset<2> _has_field_{};
44021 };
44022 
44023 
44024 class PERFETTO_EXPORT InitializeConnectionResponse : public ::protozero::CppMessageObj {
44025  public:
44026   enum FieldNumbers {
44027     kUsingShmemProvidedByProducerFieldNumber = 1,
44028   };
44029 
44030   InitializeConnectionResponse();
44031   ~InitializeConnectionResponse() override;
44032   InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept;
44033   InitializeConnectionResponse& operator=(InitializeConnectionResponse&&);
44034   InitializeConnectionResponse(const InitializeConnectionResponse&);
44035   InitializeConnectionResponse& operator=(const InitializeConnectionResponse&);
44036   bool operator==(const InitializeConnectionResponse&) const;
operator !=(const InitializeConnectionResponse & other) const44037   bool operator!=(const InitializeConnectionResponse& other) const { return !(*this == other); }
44038 
44039   bool ParseFromArray(const void*, size_t) override;
44040   std::string SerializeAsString() const override;
44041   std::vector<uint8_t> SerializeAsArray() const override;
44042   void Serialize(::protozero::Message*) const;
44043 
has_using_shmem_provided_by_producer() const44044   bool has_using_shmem_provided_by_producer() const { return _has_field_[1]; }
using_shmem_provided_by_producer() const44045   bool using_shmem_provided_by_producer() const { return using_shmem_provided_by_producer_; }
set_using_shmem_provided_by_producer(bool value)44046   void set_using_shmem_provided_by_producer(bool value) { using_shmem_provided_by_producer_ = value; _has_field_.set(1); }
44047 
44048  private:
44049   bool using_shmem_provided_by_producer_{};
44050 
44051   // Allows to preserve unknown protobuf fields for compatibility
44052   // with future versions of .proto files.
44053   std::string unknown_fields_;
44054 
44055   std::bitset<2> _has_field_{};
44056 };
44057 
44058 
44059 class PERFETTO_EXPORT InitializeConnectionRequest : public ::protozero::CppMessageObj {
44060  public:
44061   using ProducerSMBScrapingMode = InitializeConnectionRequest_ProducerSMBScrapingMode;
44062   static constexpr auto SMB_SCRAPING_UNSPECIFIED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
44063   static constexpr auto SMB_SCRAPING_ENABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED;
44064   static constexpr auto SMB_SCRAPING_DISABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
44065   static constexpr auto ProducerSMBScrapingMode_MIN = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
44066   static constexpr auto ProducerSMBScrapingMode_MAX = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
44067   using ProducerBuildFlags = InitializeConnectionRequest_ProducerBuildFlags;
44068   static constexpr auto BUILD_FLAGS_UNSPECIFIED = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
44069   static constexpr auto BUILD_FLAGS_DCHECKS_ON = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_ON;
44070   static constexpr auto BUILD_FLAGS_DCHECKS_OFF = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
44071   static constexpr auto ProducerBuildFlags_MIN = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_UNSPECIFIED;
44072   static constexpr auto ProducerBuildFlags_MAX = InitializeConnectionRequest_ProducerBuildFlags_BUILD_FLAGS_DCHECKS_OFF;
44073   enum FieldNumbers {
44074     kSharedMemoryPageSizeHintBytesFieldNumber = 1,
44075     kSharedMemorySizeHintBytesFieldNumber = 2,
44076     kProducerNameFieldNumber = 3,
44077     kSmbScrapingModeFieldNumber = 4,
44078     kBuildFlagsFieldNumber = 5,
44079     kProducerProvidedShmemFieldNumber = 6,
44080   };
44081 
44082   InitializeConnectionRequest();
44083   ~InitializeConnectionRequest() override;
44084   InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept;
44085   InitializeConnectionRequest& operator=(InitializeConnectionRequest&&);
44086   InitializeConnectionRequest(const InitializeConnectionRequest&);
44087   InitializeConnectionRequest& operator=(const InitializeConnectionRequest&);
44088   bool operator==(const InitializeConnectionRequest&) const;
operator !=(const InitializeConnectionRequest & other) const44089   bool operator!=(const InitializeConnectionRequest& other) const { return !(*this == other); }
44090 
44091   bool ParseFromArray(const void*, size_t) override;
44092   std::string SerializeAsString() const override;
44093   std::vector<uint8_t> SerializeAsArray() const override;
44094   void Serialize(::protozero::Message*) const;
44095 
has_shared_memory_page_size_hint_bytes() const44096   bool has_shared_memory_page_size_hint_bytes() const { return _has_field_[1]; }
shared_memory_page_size_hint_bytes() const44097   uint32_t shared_memory_page_size_hint_bytes() const { return shared_memory_page_size_hint_bytes_; }
set_shared_memory_page_size_hint_bytes(uint32_t value)44098   void set_shared_memory_page_size_hint_bytes(uint32_t value) { shared_memory_page_size_hint_bytes_ = value; _has_field_.set(1); }
44099 
has_shared_memory_size_hint_bytes() const44100   bool has_shared_memory_size_hint_bytes() const { return _has_field_[2]; }
shared_memory_size_hint_bytes() const44101   uint32_t shared_memory_size_hint_bytes() const { return shared_memory_size_hint_bytes_; }
set_shared_memory_size_hint_bytes(uint32_t value)44102   void set_shared_memory_size_hint_bytes(uint32_t value) { shared_memory_size_hint_bytes_ = value; _has_field_.set(2); }
44103 
has_producer_name() const44104   bool has_producer_name() const { return _has_field_[3]; }
producer_name() const44105   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)44106   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(3); }
44107 
has_smb_scraping_mode() const44108   bool has_smb_scraping_mode() const { return _has_field_[4]; }
smb_scraping_mode() const44109   InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode() const { return smb_scraping_mode_; }
set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value)44110   void set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value) { smb_scraping_mode_ = value; _has_field_.set(4); }
44111 
has_build_flags() const44112   bool has_build_flags() const { return _has_field_[5]; }
build_flags() const44113   InitializeConnectionRequest_ProducerBuildFlags build_flags() const { return build_flags_; }
set_build_flags(InitializeConnectionRequest_ProducerBuildFlags value)44114   void set_build_flags(InitializeConnectionRequest_ProducerBuildFlags value) { build_flags_ = value; _has_field_.set(5); }
44115 
has_producer_provided_shmem() const44116   bool has_producer_provided_shmem() const { return _has_field_[6]; }
producer_provided_shmem() const44117   bool producer_provided_shmem() const { return producer_provided_shmem_; }
set_producer_provided_shmem(bool value)44118   void set_producer_provided_shmem(bool value) { producer_provided_shmem_ = value; _has_field_.set(6); }
44119 
44120  private:
44121   uint32_t shared_memory_page_size_hint_bytes_{};
44122   uint32_t shared_memory_size_hint_bytes_{};
44123   std::string producer_name_{};
44124   InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode_{};
44125   InitializeConnectionRequest_ProducerBuildFlags build_flags_{};
44126   bool producer_provided_shmem_{};
44127 
44128   // Allows to preserve unknown protobuf fields for compatibility
44129   // with future versions of .proto files.
44130   std::string unknown_fields_;
44131 
44132   std::bitset<7> _has_field_{};
44133 };
44134 
44135 }  // namespace perfetto
44136 }  // namespace protos
44137 }  // namespace gen
44138 
44139 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
44140 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
44141 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
44142 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
44143 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
44144 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
44145 #pragma GCC diagnostic push
44146 #pragma GCC diagnostic ignored "-Wfloat-equal"
44147 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
44148 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
44149 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
44150 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
44151 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
44152 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
44153 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
44154 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
44155 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
44156 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
44157 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
44158 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
44159 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
44160 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
44161 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
44162 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
44163 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
44164 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
44165 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
44166 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
44167 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
44168 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
44169 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
44170 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
44171 
44172 namespace perfetto {
44173 namespace protos {
44174 namespace gen {
44175 
44176 SyncResponse::SyncResponse() = default;
44177 SyncResponse::~SyncResponse() = default;
44178 SyncResponse::SyncResponse(const SyncResponse&) = default;
44179 SyncResponse& SyncResponse::operator=(const SyncResponse&) = default;
44180 SyncResponse::SyncResponse(SyncResponse&&) noexcept = default;
44181 SyncResponse& SyncResponse::operator=(SyncResponse&&) = default;
44182 
operator ==(const SyncResponse & other) const44183 bool SyncResponse::operator==(const SyncResponse& other) const {
44184   return unknown_fields_ == other.unknown_fields_;
44185 }
44186 
ParseFromArray(const void * raw,size_t size)44187 bool SyncResponse::ParseFromArray(const void* raw, size_t size) {
44188   unknown_fields_.clear();
44189   bool packed_error = false;
44190 
44191   ::protozero::ProtoDecoder dec(raw, size);
44192   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44193     if (field.id() < _has_field_.size()) {
44194       _has_field_.set(field.id());
44195     }
44196     switch (field.id()) {
44197       default:
44198         field.SerializeAndAppendTo(&unknown_fields_);
44199         break;
44200     }
44201   }
44202   return !packed_error && !dec.bytes_left();
44203 }
44204 
SerializeAsString() const44205 std::string SyncResponse::SerializeAsString() const {
44206   ::protozero::HeapBuffered<::protozero::Message> msg;
44207   Serialize(msg.get());
44208   return msg.SerializeAsString();
44209 }
44210 
SerializeAsArray() const44211 std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
44212   ::protozero::HeapBuffered<::protozero::Message> msg;
44213   Serialize(msg.get());
44214   return msg.SerializeAsArray();
44215 }
44216 
Serialize(::protozero::Message * msg) const44217 void SyncResponse::Serialize(::protozero::Message* msg) const {
44218   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44219 }
44220 
44221 
44222 SyncRequest::SyncRequest() = default;
44223 SyncRequest::~SyncRequest() = default;
44224 SyncRequest::SyncRequest(const SyncRequest&) = default;
44225 SyncRequest& SyncRequest::operator=(const SyncRequest&) = default;
44226 SyncRequest::SyncRequest(SyncRequest&&) noexcept = default;
44227 SyncRequest& SyncRequest::operator=(SyncRequest&&) = default;
44228 
operator ==(const SyncRequest & other) const44229 bool SyncRequest::operator==(const SyncRequest& other) const {
44230   return unknown_fields_ == other.unknown_fields_;
44231 }
44232 
ParseFromArray(const void * raw,size_t size)44233 bool SyncRequest::ParseFromArray(const void* raw, size_t size) {
44234   unknown_fields_.clear();
44235   bool packed_error = false;
44236 
44237   ::protozero::ProtoDecoder dec(raw, size);
44238   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44239     if (field.id() < _has_field_.size()) {
44240       _has_field_.set(field.id());
44241     }
44242     switch (field.id()) {
44243       default:
44244         field.SerializeAndAppendTo(&unknown_fields_);
44245         break;
44246     }
44247   }
44248   return !packed_error && !dec.bytes_left();
44249 }
44250 
SerializeAsString() const44251 std::string SyncRequest::SerializeAsString() const {
44252   ::protozero::HeapBuffered<::protozero::Message> msg;
44253   Serialize(msg.get());
44254   return msg.SerializeAsString();
44255 }
44256 
SerializeAsArray() const44257 std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
44258   ::protozero::HeapBuffered<::protozero::Message> msg;
44259   Serialize(msg.get());
44260   return msg.SerializeAsArray();
44261 }
44262 
Serialize(::protozero::Message * msg) const44263 void SyncRequest::Serialize(::protozero::Message* msg) const {
44264   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44265 }
44266 
44267 
44268 GetAsyncCommandResponse::GetAsyncCommandResponse() = default;
44269 GetAsyncCommandResponse::~GetAsyncCommandResponse() = default;
44270 GetAsyncCommandResponse::GetAsyncCommandResponse(const GetAsyncCommandResponse&) = default;
44271 GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(const GetAsyncCommandResponse&) = default;
44272 GetAsyncCommandResponse::GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept = default;
44273 GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(GetAsyncCommandResponse&&) = default;
44274 
operator ==(const GetAsyncCommandResponse & other) const44275 bool GetAsyncCommandResponse::operator==(const GetAsyncCommandResponse& other) const {
44276   return unknown_fields_ == other.unknown_fields_
44277    && setup_tracing_ == other.setup_tracing_
44278    && setup_data_source_ == other.setup_data_source_
44279    && start_data_source_ == other.start_data_source_
44280    && stop_data_source_ == other.stop_data_source_
44281    && flush_ == other.flush_
44282    && clear_incremental_state_ == other.clear_incremental_state_;
44283 }
44284 
ParseFromArray(const void * raw,size_t size)44285 bool GetAsyncCommandResponse::ParseFromArray(const void* raw, size_t size) {
44286   unknown_fields_.clear();
44287   bool packed_error = false;
44288 
44289   ::protozero::ProtoDecoder dec(raw, size);
44290   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44291     if (field.id() < _has_field_.size()) {
44292       _has_field_.set(field.id());
44293     }
44294     switch (field.id()) {
44295       case 3 /* setup_tracing */:
44296         (*setup_tracing_).ParseFromString(field.as_std_string());
44297         break;
44298       case 6 /* setup_data_source */:
44299         (*setup_data_source_).ParseFromString(field.as_std_string());
44300         break;
44301       case 1 /* start_data_source */:
44302         (*start_data_source_).ParseFromString(field.as_std_string());
44303         break;
44304       case 2 /* stop_data_source */:
44305         (*stop_data_source_).ParseFromString(field.as_std_string());
44306         break;
44307       case 5 /* flush */:
44308         (*flush_).ParseFromString(field.as_std_string());
44309         break;
44310       case 7 /* clear_incremental_state */:
44311         (*clear_incremental_state_).ParseFromString(field.as_std_string());
44312         break;
44313       default:
44314         field.SerializeAndAppendTo(&unknown_fields_);
44315         break;
44316     }
44317   }
44318   return !packed_error && !dec.bytes_left();
44319 }
44320 
SerializeAsString() const44321 std::string GetAsyncCommandResponse::SerializeAsString() const {
44322   ::protozero::HeapBuffered<::protozero::Message> msg;
44323   Serialize(msg.get());
44324   return msg.SerializeAsString();
44325 }
44326 
SerializeAsArray() const44327 std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
44328   ::protozero::HeapBuffered<::protozero::Message> msg;
44329   Serialize(msg.get());
44330   return msg.SerializeAsArray();
44331 }
44332 
Serialize(::protozero::Message * msg) const44333 void GetAsyncCommandResponse::Serialize(::protozero::Message* msg) const {
44334   // Field 3: setup_tracing
44335   if (_has_field_[3]) {
44336     (*setup_tracing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
44337   }
44338 
44339   // Field 6: setup_data_source
44340   if (_has_field_[6]) {
44341     (*setup_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
44342   }
44343 
44344   // Field 1: start_data_source
44345   if (_has_field_[1]) {
44346     (*start_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
44347   }
44348 
44349   // Field 2: stop_data_source
44350   if (_has_field_[2]) {
44351     (*stop_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
44352   }
44353 
44354   // Field 5: flush
44355   if (_has_field_[5]) {
44356     (*flush_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
44357   }
44358 
44359   // Field 7: clear_incremental_state
44360   if (_has_field_[7]) {
44361     (*clear_incremental_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
44362   }
44363 
44364   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44365 }
44366 
44367 
44368 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState() = default;
44369 GetAsyncCommandResponse_ClearIncrementalState::~GetAsyncCommandResponse_ClearIncrementalState() = default;
44370 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
44371 GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
44372 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept = default;
44373 GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(GetAsyncCommandResponse_ClearIncrementalState&&) = default;
44374 
operator ==(const GetAsyncCommandResponse_ClearIncrementalState & other) const44375 bool GetAsyncCommandResponse_ClearIncrementalState::operator==(const GetAsyncCommandResponse_ClearIncrementalState& other) const {
44376   return unknown_fields_ == other.unknown_fields_
44377    && data_source_ids_ == other.data_source_ids_;
44378 }
44379 
ParseFromArray(const void * raw,size_t size)44380 bool GetAsyncCommandResponse_ClearIncrementalState::ParseFromArray(const void* raw, size_t size) {
44381   data_source_ids_.clear();
44382   unknown_fields_.clear();
44383   bool packed_error = false;
44384 
44385   ::protozero::ProtoDecoder dec(raw, size);
44386   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44387     if (field.id() < _has_field_.size()) {
44388       _has_field_.set(field.id());
44389     }
44390     switch (field.id()) {
44391       case 1 /* data_source_ids */:
44392         data_source_ids_.emplace_back();
44393         field.get(&data_source_ids_.back());
44394         break;
44395       default:
44396         field.SerializeAndAppendTo(&unknown_fields_);
44397         break;
44398     }
44399   }
44400   return !packed_error && !dec.bytes_left();
44401 }
44402 
SerializeAsString() const44403 std::string GetAsyncCommandResponse_ClearIncrementalState::SerializeAsString() const {
44404   ::protozero::HeapBuffered<::protozero::Message> msg;
44405   Serialize(msg.get());
44406   return msg.SerializeAsString();
44407 }
44408 
SerializeAsArray() const44409 std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
44410   ::protozero::HeapBuffered<::protozero::Message> msg;
44411   Serialize(msg.get());
44412   return msg.SerializeAsArray();
44413 }
44414 
Serialize(::protozero::Message * msg) const44415 void GetAsyncCommandResponse_ClearIncrementalState::Serialize(::protozero::Message* msg) const {
44416   // Field 1: data_source_ids
44417   for (auto& it : data_source_ids_) {
44418     msg->AppendVarInt(1, it);
44419   }
44420 
44421   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44422 }
44423 
44424 
44425 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush() = default;
44426 GetAsyncCommandResponse_Flush::~GetAsyncCommandResponse_Flush() = default;
44427 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&) = default;
44428 GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(const GetAsyncCommandResponse_Flush&) = default;
44429 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept = default;
44430 GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(GetAsyncCommandResponse_Flush&&) = default;
44431 
operator ==(const GetAsyncCommandResponse_Flush & other) const44432 bool GetAsyncCommandResponse_Flush::operator==(const GetAsyncCommandResponse_Flush& other) const {
44433   return unknown_fields_ == other.unknown_fields_
44434    && data_source_ids_ == other.data_source_ids_
44435    && request_id_ == other.request_id_;
44436 }
44437 
ParseFromArray(const void * raw,size_t size)44438 bool GetAsyncCommandResponse_Flush::ParseFromArray(const void* raw, size_t size) {
44439   data_source_ids_.clear();
44440   unknown_fields_.clear();
44441   bool packed_error = false;
44442 
44443   ::protozero::ProtoDecoder dec(raw, size);
44444   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44445     if (field.id() < _has_field_.size()) {
44446       _has_field_.set(field.id());
44447     }
44448     switch (field.id()) {
44449       case 1 /* data_source_ids */:
44450         data_source_ids_.emplace_back();
44451         field.get(&data_source_ids_.back());
44452         break;
44453       case 2 /* request_id */:
44454         field.get(&request_id_);
44455         break;
44456       default:
44457         field.SerializeAndAppendTo(&unknown_fields_);
44458         break;
44459     }
44460   }
44461   return !packed_error && !dec.bytes_left();
44462 }
44463 
SerializeAsString() const44464 std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
44465   ::protozero::HeapBuffered<::protozero::Message> msg;
44466   Serialize(msg.get());
44467   return msg.SerializeAsString();
44468 }
44469 
SerializeAsArray() const44470 std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
44471   ::protozero::HeapBuffered<::protozero::Message> msg;
44472   Serialize(msg.get());
44473   return msg.SerializeAsArray();
44474 }
44475 
Serialize(::protozero::Message * msg) const44476 void GetAsyncCommandResponse_Flush::Serialize(::protozero::Message* msg) const {
44477   // Field 1: data_source_ids
44478   for (auto& it : data_source_ids_) {
44479     msg->AppendVarInt(1, it);
44480   }
44481 
44482   // Field 2: request_id
44483   if (_has_field_[2]) {
44484     msg->AppendVarInt(2, request_id_);
44485   }
44486 
44487   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44488 }
44489 
44490 
44491 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource() = default;
44492 GetAsyncCommandResponse_StopDataSource::~GetAsyncCommandResponse_StopDataSource() = default;
44493 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&) = default;
44494 GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(const GetAsyncCommandResponse_StopDataSource&) = default;
44495 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept = default;
44496 GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(GetAsyncCommandResponse_StopDataSource&&) = default;
44497 
operator ==(const GetAsyncCommandResponse_StopDataSource & other) const44498 bool GetAsyncCommandResponse_StopDataSource::operator==(const GetAsyncCommandResponse_StopDataSource& other) const {
44499   return unknown_fields_ == other.unknown_fields_
44500    && instance_id_ == other.instance_id_;
44501 }
44502 
ParseFromArray(const void * raw,size_t size)44503 bool GetAsyncCommandResponse_StopDataSource::ParseFromArray(const void* raw, size_t size) {
44504   unknown_fields_.clear();
44505   bool packed_error = false;
44506 
44507   ::protozero::ProtoDecoder dec(raw, size);
44508   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44509     if (field.id() < _has_field_.size()) {
44510       _has_field_.set(field.id());
44511     }
44512     switch (field.id()) {
44513       case 1 /* instance_id */:
44514         field.get(&instance_id_);
44515         break;
44516       default:
44517         field.SerializeAndAppendTo(&unknown_fields_);
44518         break;
44519     }
44520   }
44521   return !packed_error && !dec.bytes_left();
44522 }
44523 
SerializeAsString() const44524 std::string GetAsyncCommandResponse_StopDataSource::SerializeAsString() const {
44525   ::protozero::HeapBuffered<::protozero::Message> msg;
44526   Serialize(msg.get());
44527   return msg.SerializeAsString();
44528 }
44529 
SerializeAsArray() const44530 std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
44531   ::protozero::HeapBuffered<::protozero::Message> msg;
44532   Serialize(msg.get());
44533   return msg.SerializeAsArray();
44534 }
44535 
Serialize(::protozero::Message * msg) const44536 void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
44537   // Field 1: instance_id
44538   if (_has_field_[1]) {
44539     msg->AppendVarInt(1, instance_id_);
44540   }
44541 
44542   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44543 }
44544 
44545 
44546 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource() = default;
44547 GetAsyncCommandResponse_StartDataSource::~GetAsyncCommandResponse_StartDataSource() = default;
44548 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&) = default;
44549 GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(const GetAsyncCommandResponse_StartDataSource&) = default;
44550 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept = default;
44551 GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(GetAsyncCommandResponse_StartDataSource&&) = default;
44552 
operator ==(const GetAsyncCommandResponse_StartDataSource & other) const44553 bool GetAsyncCommandResponse_StartDataSource::operator==(const GetAsyncCommandResponse_StartDataSource& other) const {
44554   return unknown_fields_ == other.unknown_fields_
44555    && new_instance_id_ == other.new_instance_id_
44556    && config_ == other.config_;
44557 }
44558 
ParseFromArray(const void * raw,size_t size)44559 bool GetAsyncCommandResponse_StartDataSource::ParseFromArray(const void* raw, size_t size) {
44560   unknown_fields_.clear();
44561   bool packed_error = false;
44562 
44563   ::protozero::ProtoDecoder dec(raw, size);
44564   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44565     if (field.id() < _has_field_.size()) {
44566       _has_field_.set(field.id());
44567     }
44568     switch (field.id()) {
44569       case 1 /* new_instance_id */:
44570         field.get(&new_instance_id_);
44571         break;
44572       case 2 /* config */:
44573         (*config_).ParseFromString(field.as_std_string());
44574         break;
44575       default:
44576         field.SerializeAndAppendTo(&unknown_fields_);
44577         break;
44578     }
44579   }
44580   return !packed_error && !dec.bytes_left();
44581 }
44582 
SerializeAsString() const44583 std::string GetAsyncCommandResponse_StartDataSource::SerializeAsString() const {
44584   ::protozero::HeapBuffered<::protozero::Message> msg;
44585   Serialize(msg.get());
44586   return msg.SerializeAsString();
44587 }
44588 
SerializeAsArray() const44589 std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
44590   ::protozero::HeapBuffered<::protozero::Message> msg;
44591   Serialize(msg.get());
44592   return msg.SerializeAsArray();
44593 }
44594 
Serialize(::protozero::Message * msg) const44595 void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
44596   // Field 1: new_instance_id
44597   if (_has_field_[1]) {
44598     msg->AppendVarInt(1, new_instance_id_);
44599   }
44600 
44601   // Field 2: config
44602   if (_has_field_[2]) {
44603     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
44604   }
44605 
44606   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44607 }
44608 
44609 
44610 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource() = default;
44611 GetAsyncCommandResponse_SetupDataSource::~GetAsyncCommandResponse_SetupDataSource() = default;
44612 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&) = default;
44613 GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(const GetAsyncCommandResponse_SetupDataSource&) = default;
44614 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept = default;
44615 GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(GetAsyncCommandResponse_SetupDataSource&&) = default;
44616 
operator ==(const GetAsyncCommandResponse_SetupDataSource & other) const44617 bool GetAsyncCommandResponse_SetupDataSource::operator==(const GetAsyncCommandResponse_SetupDataSource& other) const {
44618   return unknown_fields_ == other.unknown_fields_
44619    && new_instance_id_ == other.new_instance_id_
44620    && config_ == other.config_;
44621 }
44622 
ParseFromArray(const void * raw,size_t size)44623 bool GetAsyncCommandResponse_SetupDataSource::ParseFromArray(const void* raw, size_t size) {
44624   unknown_fields_.clear();
44625   bool packed_error = false;
44626 
44627   ::protozero::ProtoDecoder dec(raw, size);
44628   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44629     if (field.id() < _has_field_.size()) {
44630       _has_field_.set(field.id());
44631     }
44632     switch (field.id()) {
44633       case 1 /* new_instance_id */:
44634         field.get(&new_instance_id_);
44635         break;
44636       case 2 /* config */:
44637         (*config_).ParseFromString(field.as_std_string());
44638         break;
44639       default:
44640         field.SerializeAndAppendTo(&unknown_fields_);
44641         break;
44642     }
44643   }
44644   return !packed_error && !dec.bytes_left();
44645 }
44646 
SerializeAsString() const44647 std::string GetAsyncCommandResponse_SetupDataSource::SerializeAsString() const {
44648   ::protozero::HeapBuffered<::protozero::Message> msg;
44649   Serialize(msg.get());
44650   return msg.SerializeAsString();
44651 }
44652 
SerializeAsArray() const44653 std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
44654   ::protozero::HeapBuffered<::protozero::Message> msg;
44655   Serialize(msg.get());
44656   return msg.SerializeAsArray();
44657 }
44658 
Serialize(::protozero::Message * msg) const44659 void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
44660   // Field 1: new_instance_id
44661   if (_has_field_[1]) {
44662     msg->AppendVarInt(1, new_instance_id_);
44663   }
44664 
44665   // Field 2: config
44666   if (_has_field_[2]) {
44667     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
44668   }
44669 
44670   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44671 }
44672 
44673 
44674 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing() = default;
44675 GetAsyncCommandResponse_SetupTracing::~GetAsyncCommandResponse_SetupTracing() = default;
44676 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&) = default;
44677 GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(const GetAsyncCommandResponse_SetupTracing&) = default;
44678 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept = default;
44679 GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(GetAsyncCommandResponse_SetupTracing&&) = default;
44680 
operator ==(const GetAsyncCommandResponse_SetupTracing & other) const44681 bool GetAsyncCommandResponse_SetupTracing::operator==(const GetAsyncCommandResponse_SetupTracing& other) const {
44682   return unknown_fields_ == other.unknown_fields_
44683    && shared_buffer_page_size_kb_ == other.shared_buffer_page_size_kb_;
44684 }
44685 
ParseFromArray(const void * raw,size_t size)44686 bool GetAsyncCommandResponse_SetupTracing::ParseFromArray(const void* raw, size_t size) {
44687   unknown_fields_.clear();
44688   bool packed_error = false;
44689 
44690   ::protozero::ProtoDecoder dec(raw, size);
44691   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44692     if (field.id() < _has_field_.size()) {
44693       _has_field_.set(field.id());
44694     }
44695     switch (field.id()) {
44696       case 1 /* shared_buffer_page_size_kb */:
44697         field.get(&shared_buffer_page_size_kb_);
44698         break;
44699       default:
44700         field.SerializeAndAppendTo(&unknown_fields_);
44701         break;
44702     }
44703   }
44704   return !packed_error && !dec.bytes_left();
44705 }
44706 
SerializeAsString() const44707 std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
44708   ::protozero::HeapBuffered<::protozero::Message> msg;
44709   Serialize(msg.get());
44710   return msg.SerializeAsString();
44711 }
44712 
SerializeAsArray() const44713 std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
44714   ::protozero::HeapBuffered<::protozero::Message> msg;
44715   Serialize(msg.get());
44716   return msg.SerializeAsArray();
44717 }
44718 
Serialize(::protozero::Message * msg) const44719 void GetAsyncCommandResponse_SetupTracing::Serialize(::protozero::Message* msg) const {
44720   // Field 1: shared_buffer_page_size_kb
44721   if (_has_field_[1]) {
44722     msg->AppendVarInt(1, shared_buffer_page_size_kb_);
44723   }
44724 
44725   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44726 }
44727 
44728 
44729 GetAsyncCommandRequest::GetAsyncCommandRequest() = default;
44730 GetAsyncCommandRequest::~GetAsyncCommandRequest() = default;
44731 GetAsyncCommandRequest::GetAsyncCommandRequest(const GetAsyncCommandRequest&) = default;
44732 GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(const GetAsyncCommandRequest&) = default;
44733 GetAsyncCommandRequest::GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept = default;
44734 GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(GetAsyncCommandRequest&&) = default;
44735 
operator ==(const GetAsyncCommandRequest & other) const44736 bool GetAsyncCommandRequest::operator==(const GetAsyncCommandRequest& other) const {
44737   return unknown_fields_ == other.unknown_fields_;
44738 }
44739 
ParseFromArray(const void * raw,size_t size)44740 bool GetAsyncCommandRequest::ParseFromArray(const void* raw, size_t size) {
44741   unknown_fields_.clear();
44742   bool packed_error = false;
44743 
44744   ::protozero::ProtoDecoder dec(raw, size);
44745   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44746     if (field.id() < _has_field_.size()) {
44747       _has_field_.set(field.id());
44748     }
44749     switch (field.id()) {
44750       default:
44751         field.SerializeAndAppendTo(&unknown_fields_);
44752         break;
44753     }
44754   }
44755   return !packed_error && !dec.bytes_left();
44756 }
44757 
SerializeAsString() const44758 std::string GetAsyncCommandRequest::SerializeAsString() const {
44759   ::protozero::HeapBuffered<::protozero::Message> msg;
44760   Serialize(msg.get());
44761   return msg.SerializeAsString();
44762 }
44763 
SerializeAsArray() const44764 std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
44765   ::protozero::HeapBuffered<::protozero::Message> msg;
44766   Serialize(msg.get());
44767   return msg.SerializeAsArray();
44768 }
44769 
Serialize(::protozero::Message * msg) const44770 void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
44771   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44772 }
44773 
44774 
44775 ActivateTriggersResponse::ActivateTriggersResponse() = default;
44776 ActivateTriggersResponse::~ActivateTriggersResponse() = default;
44777 ActivateTriggersResponse::ActivateTriggersResponse(const ActivateTriggersResponse&) = default;
44778 ActivateTriggersResponse& ActivateTriggersResponse::operator=(const ActivateTriggersResponse&) = default;
44779 ActivateTriggersResponse::ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept = default;
44780 ActivateTriggersResponse& ActivateTriggersResponse::operator=(ActivateTriggersResponse&&) = default;
44781 
operator ==(const ActivateTriggersResponse & other) const44782 bool ActivateTriggersResponse::operator==(const ActivateTriggersResponse& other) const {
44783   return unknown_fields_ == other.unknown_fields_;
44784 }
44785 
ParseFromArray(const void * raw,size_t size)44786 bool ActivateTriggersResponse::ParseFromArray(const void* raw, size_t size) {
44787   unknown_fields_.clear();
44788   bool packed_error = false;
44789 
44790   ::protozero::ProtoDecoder dec(raw, size);
44791   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44792     if (field.id() < _has_field_.size()) {
44793       _has_field_.set(field.id());
44794     }
44795     switch (field.id()) {
44796       default:
44797         field.SerializeAndAppendTo(&unknown_fields_);
44798         break;
44799     }
44800   }
44801   return !packed_error && !dec.bytes_left();
44802 }
44803 
SerializeAsString() const44804 std::string ActivateTriggersResponse::SerializeAsString() const {
44805   ::protozero::HeapBuffered<::protozero::Message> msg;
44806   Serialize(msg.get());
44807   return msg.SerializeAsString();
44808 }
44809 
SerializeAsArray() const44810 std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
44811   ::protozero::HeapBuffered<::protozero::Message> msg;
44812   Serialize(msg.get());
44813   return msg.SerializeAsArray();
44814 }
44815 
Serialize(::protozero::Message * msg) const44816 void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
44817   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44818 }
44819 
44820 
44821 ActivateTriggersRequest::ActivateTriggersRequest() = default;
44822 ActivateTriggersRequest::~ActivateTriggersRequest() = default;
44823 ActivateTriggersRequest::ActivateTriggersRequest(const ActivateTriggersRequest&) = default;
44824 ActivateTriggersRequest& ActivateTriggersRequest::operator=(const ActivateTriggersRequest&) = default;
44825 ActivateTriggersRequest::ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept = default;
44826 ActivateTriggersRequest& ActivateTriggersRequest::operator=(ActivateTriggersRequest&&) = default;
44827 
operator ==(const ActivateTriggersRequest & other) const44828 bool ActivateTriggersRequest::operator==(const ActivateTriggersRequest& other) const {
44829   return unknown_fields_ == other.unknown_fields_
44830    && trigger_names_ == other.trigger_names_;
44831 }
44832 
ParseFromArray(const void * raw,size_t size)44833 bool ActivateTriggersRequest::ParseFromArray(const void* raw, size_t size) {
44834   trigger_names_.clear();
44835   unknown_fields_.clear();
44836   bool packed_error = false;
44837 
44838   ::protozero::ProtoDecoder dec(raw, size);
44839   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44840     if (field.id() < _has_field_.size()) {
44841       _has_field_.set(field.id());
44842     }
44843     switch (field.id()) {
44844       case 1 /* trigger_names */:
44845         trigger_names_.emplace_back();
44846         field.get(&trigger_names_.back());
44847         break;
44848       default:
44849         field.SerializeAndAppendTo(&unknown_fields_);
44850         break;
44851     }
44852   }
44853   return !packed_error && !dec.bytes_left();
44854 }
44855 
SerializeAsString() const44856 std::string ActivateTriggersRequest::SerializeAsString() const {
44857   ::protozero::HeapBuffered<::protozero::Message> msg;
44858   Serialize(msg.get());
44859   return msg.SerializeAsString();
44860 }
44861 
SerializeAsArray() const44862 std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
44863   ::protozero::HeapBuffered<::protozero::Message> msg;
44864   Serialize(msg.get());
44865   return msg.SerializeAsArray();
44866 }
44867 
Serialize(::protozero::Message * msg) const44868 void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
44869   // Field 1: trigger_names
44870   for (auto& it : trigger_names_) {
44871     msg->AppendString(1, it);
44872   }
44873 
44874   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44875 }
44876 
44877 
44878 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse() = default;
44879 NotifyDataSourceStoppedResponse::~NotifyDataSourceStoppedResponse() = default;
44880 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&) = default;
44881 NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(const NotifyDataSourceStoppedResponse&) = default;
44882 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept = default;
44883 NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(NotifyDataSourceStoppedResponse&&) = default;
44884 
operator ==(const NotifyDataSourceStoppedResponse & other) const44885 bool NotifyDataSourceStoppedResponse::operator==(const NotifyDataSourceStoppedResponse& other) const {
44886   return unknown_fields_ == other.unknown_fields_;
44887 }
44888 
ParseFromArray(const void * raw,size_t size)44889 bool NotifyDataSourceStoppedResponse::ParseFromArray(const void* raw, size_t size) {
44890   unknown_fields_.clear();
44891   bool packed_error = false;
44892 
44893   ::protozero::ProtoDecoder dec(raw, size);
44894   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44895     if (field.id() < _has_field_.size()) {
44896       _has_field_.set(field.id());
44897     }
44898     switch (field.id()) {
44899       default:
44900         field.SerializeAndAppendTo(&unknown_fields_);
44901         break;
44902     }
44903   }
44904   return !packed_error && !dec.bytes_left();
44905 }
44906 
SerializeAsString() const44907 std::string NotifyDataSourceStoppedResponse::SerializeAsString() const {
44908   ::protozero::HeapBuffered<::protozero::Message> msg;
44909   Serialize(msg.get());
44910   return msg.SerializeAsString();
44911 }
44912 
SerializeAsArray() const44913 std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
44914   ::protozero::HeapBuffered<::protozero::Message> msg;
44915   Serialize(msg.get());
44916   return msg.SerializeAsArray();
44917 }
44918 
Serialize(::protozero::Message * msg) const44919 void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
44920   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44921 }
44922 
44923 
44924 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest() = default;
44925 NotifyDataSourceStoppedRequest::~NotifyDataSourceStoppedRequest() = default;
44926 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&) = default;
44927 NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(const NotifyDataSourceStoppedRequest&) = default;
44928 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept = default;
44929 NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(NotifyDataSourceStoppedRequest&&) = default;
44930 
operator ==(const NotifyDataSourceStoppedRequest & other) const44931 bool NotifyDataSourceStoppedRequest::operator==(const NotifyDataSourceStoppedRequest& other) const {
44932   return unknown_fields_ == other.unknown_fields_
44933    && data_source_id_ == other.data_source_id_;
44934 }
44935 
ParseFromArray(const void * raw,size_t size)44936 bool NotifyDataSourceStoppedRequest::ParseFromArray(const void* raw, size_t size) {
44937   unknown_fields_.clear();
44938   bool packed_error = false;
44939 
44940   ::protozero::ProtoDecoder dec(raw, size);
44941   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44942     if (field.id() < _has_field_.size()) {
44943       _has_field_.set(field.id());
44944     }
44945     switch (field.id()) {
44946       case 1 /* data_source_id */:
44947         field.get(&data_source_id_);
44948         break;
44949       default:
44950         field.SerializeAndAppendTo(&unknown_fields_);
44951         break;
44952     }
44953   }
44954   return !packed_error && !dec.bytes_left();
44955 }
44956 
SerializeAsString() const44957 std::string NotifyDataSourceStoppedRequest::SerializeAsString() const {
44958   ::protozero::HeapBuffered<::protozero::Message> msg;
44959   Serialize(msg.get());
44960   return msg.SerializeAsString();
44961 }
44962 
SerializeAsArray() const44963 std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
44964   ::protozero::HeapBuffered<::protozero::Message> msg;
44965   Serialize(msg.get());
44966   return msg.SerializeAsArray();
44967 }
44968 
Serialize(::protozero::Message * msg) const44969 void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
44970   // Field 1: data_source_id
44971   if (_has_field_[1]) {
44972     msg->AppendVarInt(1, data_source_id_);
44973   }
44974 
44975   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
44976 }
44977 
44978 
44979 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse() = default;
44980 NotifyDataSourceStartedResponse::~NotifyDataSourceStartedResponse() = default;
44981 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&) = default;
44982 NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(const NotifyDataSourceStartedResponse&) = default;
44983 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept = default;
44984 NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(NotifyDataSourceStartedResponse&&) = default;
44985 
operator ==(const NotifyDataSourceStartedResponse & other) const44986 bool NotifyDataSourceStartedResponse::operator==(const NotifyDataSourceStartedResponse& other) const {
44987   return unknown_fields_ == other.unknown_fields_;
44988 }
44989 
ParseFromArray(const void * raw,size_t size)44990 bool NotifyDataSourceStartedResponse::ParseFromArray(const void* raw, size_t size) {
44991   unknown_fields_.clear();
44992   bool packed_error = false;
44993 
44994   ::protozero::ProtoDecoder dec(raw, size);
44995   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
44996     if (field.id() < _has_field_.size()) {
44997       _has_field_.set(field.id());
44998     }
44999     switch (field.id()) {
45000       default:
45001         field.SerializeAndAppendTo(&unknown_fields_);
45002         break;
45003     }
45004   }
45005   return !packed_error && !dec.bytes_left();
45006 }
45007 
SerializeAsString() const45008 std::string NotifyDataSourceStartedResponse::SerializeAsString() const {
45009   ::protozero::HeapBuffered<::protozero::Message> msg;
45010   Serialize(msg.get());
45011   return msg.SerializeAsString();
45012 }
45013 
SerializeAsArray() const45014 std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
45015   ::protozero::HeapBuffered<::protozero::Message> msg;
45016   Serialize(msg.get());
45017   return msg.SerializeAsArray();
45018 }
45019 
Serialize(::protozero::Message * msg) const45020 void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
45021   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45022 }
45023 
45024 
45025 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest() = default;
45026 NotifyDataSourceStartedRequest::~NotifyDataSourceStartedRequest() = default;
45027 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&) = default;
45028 NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(const NotifyDataSourceStartedRequest&) = default;
45029 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept = default;
45030 NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(NotifyDataSourceStartedRequest&&) = default;
45031 
operator ==(const NotifyDataSourceStartedRequest & other) const45032 bool NotifyDataSourceStartedRequest::operator==(const NotifyDataSourceStartedRequest& other) const {
45033   return unknown_fields_ == other.unknown_fields_
45034    && data_source_id_ == other.data_source_id_;
45035 }
45036 
ParseFromArray(const void * raw,size_t size)45037 bool NotifyDataSourceStartedRequest::ParseFromArray(const void* raw, size_t size) {
45038   unknown_fields_.clear();
45039   bool packed_error = false;
45040 
45041   ::protozero::ProtoDecoder dec(raw, size);
45042   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45043     if (field.id() < _has_field_.size()) {
45044       _has_field_.set(field.id());
45045     }
45046     switch (field.id()) {
45047       case 1 /* data_source_id */:
45048         field.get(&data_source_id_);
45049         break;
45050       default:
45051         field.SerializeAndAppendTo(&unknown_fields_);
45052         break;
45053     }
45054   }
45055   return !packed_error && !dec.bytes_left();
45056 }
45057 
SerializeAsString() const45058 std::string NotifyDataSourceStartedRequest::SerializeAsString() const {
45059   ::protozero::HeapBuffered<::protozero::Message> msg;
45060   Serialize(msg.get());
45061   return msg.SerializeAsString();
45062 }
45063 
SerializeAsArray() const45064 std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
45065   ::protozero::HeapBuffered<::protozero::Message> msg;
45066   Serialize(msg.get());
45067   return msg.SerializeAsArray();
45068 }
45069 
Serialize(::protozero::Message * msg) const45070 void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
45071   // Field 1: data_source_id
45072   if (_has_field_[1]) {
45073     msg->AppendVarInt(1, data_source_id_);
45074   }
45075 
45076   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45077 }
45078 
45079 
45080 CommitDataResponse::CommitDataResponse() = default;
45081 CommitDataResponse::~CommitDataResponse() = default;
45082 CommitDataResponse::CommitDataResponse(const CommitDataResponse&) = default;
45083 CommitDataResponse& CommitDataResponse::operator=(const CommitDataResponse&) = default;
45084 CommitDataResponse::CommitDataResponse(CommitDataResponse&&) noexcept = default;
45085 CommitDataResponse& CommitDataResponse::operator=(CommitDataResponse&&) = default;
45086 
operator ==(const CommitDataResponse & other) const45087 bool CommitDataResponse::operator==(const CommitDataResponse& other) const {
45088   return unknown_fields_ == other.unknown_fields_;
45089 }
45090 
ParseFromArray(const void * raw,size_t size)45091 bool CommitDataResponse::ParseFromArray(const void* raw, size_t size) {
45092   unknown_fields_.clear();
45093   bool packed_error = false;
45094 
45095   ::protozero::ProtoDecoder dec(raw, size);
45096   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45097     if (field.id() < _has_field_.size()) {
45098       _has_field_.set(field.id());
45099     }
45100     switch (field.id()) {
45101       default:
45102         field.SerializeAndAppendTo(&unknown_fields_);
45103         break;
45104     }
45105   }
45106   return !packed_error && !dec.bytes_left();
45107 }
45108 
SerializeAsString() const45109 std::string CommitDataResponse::SerializeAsString() const {
45110   ::protozero::HeapBuffered<::protozero::Message> msg;
45111   Serialize(msg.get());
45112   return msg.SerializeAsString();
45113 }
45114 
SerializeAsArray() const45115 std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
45116   ::protozero::HeapBuffered<::protozero::Message> msg;
45117   Serialize(msg.get());
45118   return msg.SerializeAsArray();
45119 }
45120 
Serialize(::protozero::Message * msg) const45121 void CommitDataResponse::Serialize(::protozero::Message* msg) const {
45122   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45123 }
45124 
45125 
45126 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse() = default;
45127 UnregisterTraceWriterResponse::~UnregisterTraceWriterResponse() = default;
45128 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&) = default;
45129 UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(const UnregisterTraceWriterResponse&) = default;
45130 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept = default;
45131 UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(UnregisterTraceWriterResponse&&) = default;
45132 
operator ==(const UnregisterTraceWriterResponse & other) const45133 bool UnregisterTraceWriterResponse::operator==(const UnregisterTraceWriterResponse& other) const {
45134   return unknown_fields_ == other.unknown_fields_;
45135 }
45136 
ParseFromArray(const void * raw,size_t size)45137 bool UnregisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
45138   unknown_fields_.clear();
45139   bool packed_error = false;
45140 
45141   ::protozero::ProtoDecoder dec(raw, size);
45142   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45143     if (field.id() < _has_field_.size()) {
45144       _has_field_.set(field.id());
45145     }
45146     switch (field.id()) {
45147       default:
45148         field.SerializeAndAppendTo(&unknown_fields_);
45149         break;
45150     }
45151   }
45152   return !packed_error && !dec.bytes_left();
45153 }
45154 
SerializeAsString() const45155 std::string UnregisterTraceWriterResponse::SerializeAsString() const {
45156   ::protozero::HeapBuffered<::protozero::Message> msg;
45157   Serialize(msg.get());
45158   return msg.SerializeAsString();
45159 }
45160 
SerializeAsArray() const45161 std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
45162   ::protozero::HeapBuffered<::protozero::Message> msg;
45163   Serialize(msg.get());
45164   return msg.SerializeAsArray();
45165 }
45166 
Serialize(::protozero::Message * msg) const45167 void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
45168   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45169 }
45170 
45171 
45172 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest() = default;
45173 UnregisterTraceWriterRequest::~UnregisterTraceWriterRequest() = default;
45174 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&) = default;
45175 UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(const UnregisterTraceWriterRequest&) = default;
45176 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept = default;
45177 UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(UnregisterTraceWriterRequest&&) = default;
45178 
operator ==(const UnregisterTraceWriterRequest & other) const45179 bool UnregisterTraceWriterRequest::operator==(const UnregisterTraceWriterRequest& other) const {
45180   return unknown_fields_ == other.unknown_fields_
45181    && trace_writer_id_ == other.trace_writer_id_;
45182 }
45183 
ParseFromArray(const void * raw,size_t size)45184 bool UnregisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
45185   unknown_fields_.clear();
45186   bool packed_error = false;
45187 
45188   ::protozero::ProtoDecoder dec(raw, size);
45189   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45190     if (field.id() < _has_field_.size()) {
45191       _has_field_.set(field.id());
45192     }
45193     switch (field.id()) {
45194       case 1 /* trace_writer_id */:
45195         field.get(&trace_writer_id_);
45196         break;
45197       default:
45198         field.SerializeAndAppendTo(&unknown_fields_);
45199         break;
45200     }
45201   }
45202   return !packed_error && !dec.bytes_left();
45203 }
45204 
SerializeAsString() const45205 std::string UnregisterTraceWriterRequest::SerializeAsString() const {
45206   ::protozero::HeapBuffered<::protozero::Message> msg;
45207   Serialize(msg.get());
45208   return msg.SerializeAsString();
45209 }
45210 
SerializeAsArray() const45211 std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
45212   ::protozero::HeapBuffered<::protozero::Message> msg;
45213   Serialize(msg.get());
45214   return msg.SerializeAsArray();
45215 }
45216 
Serialize(::protozero::Message * msg) const45217 void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
45218   // Field 1: trace_writer_id
45219   if (_has_field_[1]) {
45220     msg->AppendVarInt(1, trace_writer_id_);
45221   }
45222 
45223   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45224 }
45225 
45226 
45227 RegisterTraceWriterResponse::RegisterTraceWriterResponse() = default;
45228 RegisterTraceWriterResponse::~RegisterTraceWriterResponse() = default;
45229 RegisterTraceWriterResponse::RegisterTraceWriterResponse(const RegisterTraceWriterResponse&) = default;
45230 RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(const RegisterTraceWriterResponse&) = default;
45231 RegisterTraceWriterResponse::RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept = default;
45232 RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(RegisterTraceWriterResponse&&) = default;
45233 
operator ==(const RegisterTraceWriterResponse & other) const45234 bool RegisterTraceWriterResponse::operator==(const RegisterTraceWriterResponse& other) const {
45235   return unknown_fields_ == other.unknown_fields_;
45236 }
45237 
ParseFromArray(const void * raw,size_t size)45238 bool RegisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
45239   unknown_fields_.clear();
45240   bool packed_error = false;
45241 
45242   ::protozero::ProtoDecoder dec(raw, size);
45243   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45244     if (field.id() < _has_field_.size()) {
45245       _has_field_.set(field.id());
45246     }
45247     switch (field.id()) {
45248       default:
45249         field.SerializeAndAppendTo(&unknown_fields_);
45250         break;
45251     }
45252   }
45253   return !packed_error && !dec.bytes_left();
45254 }
45255 
SerializeAsString() const45256 std::string RegisterTraceWriterResponse::SerializeAsString() const {
45257   ::protozero::HeapBuffered<::protozero::Message> msg;
45258   Serialize(msg.get());
45259   return msg.SerializeAsString();
45260 }
45261 
SerializeAsArray() const45262 std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
45263   ::protozero::HeapBuffered<::protozero::Message> msg;
45264   Serialize(msg.get());
45265   return msg.SerializeAsArray();
45266 }
45267 
Serialize(::protozero::Message * msg) const45268 void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
45269   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45270 }
45271 
45272 
45273 RegisterTraceWriterRequest::RegisterTraceWriterRequest() = default;
45274 RegisterTraceWriterRequest::~RegisterTraceWriterRequest() = default;
45275 RegisterTraceWriterRequest::RegisterTraceWriterRequest(const RegisterTraceWriterRequest&) = default;
45276 RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(const RegisterTraceWriterRequest&) = default;
45277 RegisterTraceWriterRequest::RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept = default;
45278 RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(RegisterTraceWriterRequest&&) = default;
45279 
operator ==(const RegisterTraceWriterRequest & other) const45280 bool RegisterTraceWriterRequest::operator==(const RegisterTraceWriterRequest& other) const {
45281   return unknown_fields_ == other.unknown_fields_
45282    && trace_writer_id_ == other.trace_writer_id_
45283    && target_buffer_ == other.target_buffer_;
45284 }
45285 
ParseFromArray(const void * raw,size_t size)45286 bool RegisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
45287   unknown_fields_.clear();
45288   bool packed_error = false;
45289 
45290   ::protozero::ProtoDecoder dec(raw, size);
45291   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45292     if (field.id() < _has_field_.size()) {
45293       _has_field_.set(field.id());
45294     }
45295     switch (field.id()) {
45296       case 1 /* trace_writer_id */:
45297         field.get(&trace_writer_id_);
45298         break;
45299       case 2 /* target_buffer */:
45300         field.get(&target_buffer_);
45301         break;
45302       default:
45303         field.SerializeAndAppendTo(&unknown_fields_);
45304         break;
45305     }
45306   }
45307   return !packed_error && !dec.bytes_left();
45308 }
45309 
SerializeAsString() const45310 std::string RegisterTraceWriterRequest::SerializeAsString() const {
45311   ::protozero::HeapBuffered<::protozero::Message> msg;
45312   Serialize(msg.get());
45313   return msg.SerializeAsString();
45314 }
45315 
SerializeAsArray() const45316 std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
45317   ::protozero::HeapBuffered<::protozero::Message> msg;
45318   Serialize(msg.get());
45319   return msg.SerializeAsArray();
45320 }
45321 
Serialize(::protozero::Message * msg) const45322 void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
45323   // Field 1: trace_writer_id
45324   if (_has_field_[1]) {
45325     msg->AppendVarInt(1, trace_writer_id_);
45326   }
45327 
45328   // Field 2: target_buffer
45329   if (_has_field_[2]) {
45330     msg->AppendVarInt(2, target_buffer_);
45331   }
45332 
45333   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45334 }
45335 
45336 
45337 UnregisterDataSourceResponse::UnregisterDataSourceResponse() = default;
45338 UnregisterDataSourceResponse::~UnregisterDataSourceResponse() = default;
45339 UnregisterDataSourceResponse::UnregisterDataSourceResponse(const UnregisterDataSourceResponse&) = default;
45340 UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(const UnregisterDataSourceResponse&) = default;
45341 UnregisterDataSourceResponse::UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept = default;
45342 UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(UnregisterDataSourceResponse&&) = default;
45343 
operator ==(const UnregisterDataSourceResponse & other) const45344 bool UnregisterDataSourceResponse::operator==(const UnregisterDataSourceResponse& other) const {
45345   return unknown_fields_ == other.unknown_fields_;
45346 }
45347 
ParseFromArray(const void * raw,size_t size)45348 bool UnregisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
45349   unknown_fields_.clear();
45350   bool packed_error = false;
45351 
45352   ::protozero::ProtoDecoder dec(raw, size);
45353   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45354     if (field.id() < _has_field_.size()) {
45355       _has_field_.set(field.id());
45356     }
45357     switch (field.id()) {
45358       default:
45359         field.SerializeAndAppendTo(&unknown_fields_);
45360         break;
45361     }
45362   }
45363   return !packed_error && !dec.bytes_left();
45364 }
45365 
SerializeAsString() const45366 std::string UnregisterDataSourceResponse::SerializeAsString() const {
45367   ::protozero::HeapBuffered<::protozero::Message> msg;
45368   Serialize(msg.get());
45369   return msg.SerializeAsString();
45370 }
45371 
SerializeAsArray() const45372 std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
45373   ::protozero::HeapBuffered<::protozero::Message> msg;
45374   Serialize(msg.get());
45375   return msg.SerializeAsArray();
45376 }
45377 
Serialize(::protozero::Message * msg) const45378 void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
45379   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45380 }
45381 
45382 
45383 UnregisterDataSourceRequest::UnregisterDataSourceRequest() = default;
45384 UnregisterDataSourceRequest::~UnregisterDataSourceRequest() = default;
45385 UnregisterDataSourceRequest::UnregisterDataSourceRequest(const UnregisterDataSourceRequest&) = default;
45386 UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(const UnregisterDataSourceRequest&) = default;
45387 UnregisterDataSourceRequest::UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept = default;
45388 UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(UnregisterDataSourceRequest&&) = default;
45389 
operator ==(const UnregisterDataSourceRequest & other) const45390 bool UnregisterDataSourceRequest::operator==(const UnregisterDataSourceRequest& other) const {
45391   return unknown_fields_ == other.unknown_fields_
45392    && data_source_name_ == other.data_source_name_;
45393 }
45394 
ParseFromArray(const void * raw,size_t size)45395 bool UnregisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
45396   unknown_fields_.clear();
45397   bool packed_error = false;
45398 
45399   ::protozero::ProtoDecoder dec(raw, size);
45400   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45401     if (field.id() < _has_field_.size()) {
45402       _has_field_.set(field.id());
45403     }
45404     switch (field.id()) {
45405       case 1 /* data_source_name */:
45406         field.get(&data_source_name_);
45407         break;
45408       default:
45409         field.SerializeAndAppendTo(&unknown_fields_);
45410         break;
45411     }
45412   }
45413   return !packed_error && !dec.bytes_left();
45414 }
45415 
SerializeAsString() const45416 std::string UnregisterDataSourceRequest::SerializeAsString() const {
45417   ::protozero::HeapBuffered<::protozero::Message> msg;
45418   Serialize(msg.get());
45419   return msg.SerializeAsString();
45420 }
45421 
SerializeAsArray() const45422 std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
45423   ::protozero::HeapBuffered<::protozero::Message> msg;
45424   Serialize(msg.get());
45425   return msg.SerializeAsArray();
45426 }
45427 
Serialize(::protozero::Message * msg) const45428 void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
45429   // Field 1: data_source_name
45430   if (_has_field_[1]) {
45431     msg->AppendString(1, data_source_name_);
45432   }
45433 
45434   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45435 }
45436 
45437 
45438 RegisterDataSourceResponse::RegisterDataSourceResponse() = default;
45439 RegisterDataSourceResponse::~RegisterDataSourceResponse() = default;
45440 RegisterDataSourceResponse::RegisterDataSourceResponse(const RegisterDataSourceResponse&) = default;
45441 RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(const RegisterDataSourceResponse&) = default;
45442 RegisterDataSourceResponse::RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept = default;
45443 RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(RegisterDataSourceResponse&&) = default;
45444 
operator ==(const RegisterDataSourceResponse & other) const45445 bool RegisterDataSourceResponse::operator==(const RegisterDataSourceResponse& other) const {
45446   return unknown_fields_ == other.unknown_fields_
45447    && error_ == other.error_;
45448 }
45449 
ParseFromArray(const void * raw,size_t size)45450 bool RegisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
45451   unknown_fields_.clear();
45452   bool packed_error = false;
45453 
45454   ::protozero::ProtoDecoder dec(raw, size);
45455   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45456     if (field.id() < _has_field_.size()) {
45457       _has_field_.set(field.id());
45458     }
45459     switch (field.id()) {
45460       case 1 /* error */:
45461         field.get(&error_);
45462         break;
45463       default:
45464         field.SerializeAndAppendTo(&unknown_fields_);
45465         break;
45466     }
45467   }
45468   return !packed_error && !dec.bytes_left();
45469 }
45470 
SerializeAsString() const45471 std::string RegisterDataSourceResponse::SerializeAsString() const {
45472   ::protozero::HeapBuffered<::protozero::Message> msg;
45473   Serialize(msg.get());
45474   return msg.SerializeAsString();
45475 }
45476 
SerializeAsArray() const45477 std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
45478   ::protozero::HeapBuffered<::protozero::Message> msg;
45479   Serialize(msg.get());
45480   return msg.SerializeAsArray();
45481 }
45482 
Serialize(::protozero::Message * msg) const45483 void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
45484   // Field 1: error
45485   if (_has_field_[1]) {
45486     msg->AppendString(1, error_);
45487   }
45488 
45489   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45490 }
45491 
45492 
45493 RegisterDataSourceRequest::RegisterDataSourceRequest() = default;
45494 RegisterDataSourceRequest::~RegisterDataSourceRequest() = default;
45495 RegisterDataSourceRequest::RegisterDataSourceRequest(const RegisterDataSourceRequest&) = default;
45496 RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(const RegisterDataSourceRequest&) = default;
45497 RegisterDataSourceRequest::RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept = default;
45498 RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(RegisterDataSourceRequest&&) = default;
45499 
operator ==(const RegisterDataSourceRequest & other) const45500 bool RegisterDataSourceRequest::operator==(const RegisterDataSourceRequest& other) const {
45501   return unknown_fields_ == other.unknown_fields_
45502    && data_source_descriptor_ == other.data_source_descriptor_;
45503 }
45504 
ParseFromArray(const void * raw,size_t size)45505 bool RegisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
45506   unknown_fields_.clear();
45507   bool packed_error = false;
45508 
45509   ::protozero::ProtoDecoder dec(raw, size);
45510   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45511     if (field.id() < _has_field_.size()) {
45512       _has_field_.set(field.id());
45513     }
45514     switch (field.id()) {
45515       case 1 /* data_source_descriptor */:
45516         (*data_source_descriptor_).ParseFromString(field.as_std_string());
45517         break;
45518       default:
45519         field.SerializeAndAppendTo(&unknown_fields_);
45520         break;
45521     }
45522   }
45523   return !packed_error && !dec.bytes_left();
45524 }
45525 
SerializeAsString() const45526 std::string RegisterDataSourceRequest::SerializeAsString() const {
45527   ::protozero::HeapBuffered<::protozero::Message> msg;
45528   Serialize(msg.get());
45529   return msg.SerializeAsString();
45530 }
45531 
SerializeAsArray() const45532 std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
45533   ::protozero::HeapBuffered<::protozero::Message> msg;
45534   Serialize(msg.get());
45535   return msg.SerializeAsArray();
45536 }
45537 
Serialize(::protozero::Message * msg) const45538 void RegisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
45539   // Field 1: data_source_descriptor
45540   if (_has_field_[1]) {
45541     (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
45542   }
45543 
45544   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45545 }
45546 
45547 
45548 InitializeConnectionResponse::InitializeConnectionResponse() = default;
45549 InitializeConnectionResponse::~InitializeConnectionResponse() = default;
45550 InitializeConnectionResponse::InitializeConnectionResponse(const InitializeConnectionResponse&) = default;
45551 InitializeConnectionResponse& InitializeConnectionResponse::operator=(const InitializeConnectionResponse&) = default;
45552 InitializeConnectionResponse::InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept = default;
45553 InitializeConnectionResponse& InitializeConnectionResponse::operator=(InitializeConnectionResponse&&) = default;
45554 
operator ==(const InitializeConnectionResponse & other) const45555 bool InitializeConnectionResponse::operator==(const InitializeConnectionResponse& other) const {
45556   return unknown_fields_ == other.unknown_fields_
45557    && using_shmem_provided_by_producer_ == other.using_shmem_provided_by_producer_;
45558 }
45559 
ParseFromArray(const void * raw,size_t size)45560 bool InitializeConnectionResponse::ParseFromArray(const void* raw, size_t size) {
45561   unknown_fields_.clear();
45562   bool packed_error = false;
45563 
45564   ::protozero::ProtoDecoder dec(raw, size);
45565   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45566     if (field.id() < _has_field_.size()) {
45567       _has_field_.set(field.id());
45568     }
45569     switch (field.id()) {
45570       case 1 /* using_shmem_provided_by_producer */:
45571         field.get(&using_shmem_provided_by_producer_);
45572         break;
45573       default:
45574         field.SerializeAndAppendTo(&unknown_fields_);
45575         break;
45576     }
45577   }
45578   return !packed_error && !dec.bytes_left();
45579 }
45580 
SerializeAsString() const45581 std::string InitializeConnectionResponse::SerializeAsString() const {
45582   ::protozero::HeapBuffered<::protozero::Message> msg;
45583   Serialize(msg.get());
45584   return msg.SerializeAsString();
45585 }
45586 
SerializeAsArray() const45587 std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
45588   ::protozero::HeapBuffered<::protozero::Message> msg;
45589   Serialize(msg.get());
45590   return msg.SerializeAsArray();
45591 }
45592 
Serialize(::protozero::Message * msg) const45593 void InitializeConnectionResponse::Serialize(::protozero::Message* msg) const {
45594   // Field 1: using_shmem_provided_by_producer
45595   if (_has_field_[1]) {
45596     msg->AppendTinyVarInt(1, using_shmem_provided_by_producer_);
45597   }
45598 
45599   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45600 }
45601 
45602 
45603 InitializeConnectionRequest::InitializeConnectionRequest() = default;
45604 InitializeConnectionRequest::~InitializeConnectionRequest() = default;
45605 InitializeConnectionRequest::InitializeConnectionRequest(const InitializeConnectionRequest&) = default;
45606 InitializeConnectionRequest& InitializeConnectionRequest::operator=(const InitializeConnectionRequest&) = default;
45607 InitializeConnectionRequest::InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept = default;
45608 InitializeConnectionRequest& InitializeConnectionRequest::operator=(InitializeConnectionRequest&&) = default;
45609 
operator ==(const InitializeConnectionRequest & other) const45610 bool InitializeConnectionRequest::operator==(const InitializeConnectionRequest& other) const {
45611   return unknown_fields_ == other.unknown_fields_
45612    && shared_memory_page_size_hint_bytes_ == other.shared_memory_page_size_hint_bytes_
45613    && shared_memory_size_hint_bytes_ == other.shared_memory_size_hint_bytes_
45614    && producer_name_ == other.producer_name_
45615    && smb_scraping_mode_ == other.smb_scraping_mode_
45616    && build_flags_ == other.build_flags_
45617    && producer_provided_shmem_ == other.producer_provided_shmem_;
45618 }
45619 
ParseFromArray(const void * raw,size_t size)45620 bool InitializeConnectionRequest::ParseFromArray(const void* raw, size_t size) {
45621   unknown_fields_.clear();
45622   bool packed_error = false;
45623 
45624   ::protozero::ProtoDecoder dec(raw, size);
45625   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
45626     if (field.id() < _has_field_.size()) {
45627       _has_field_.set(field.id());
45628     }
45629     switch (field.id()) {
45630       case 1 /* shared_memory_page_size_hint_bytes */:
45631         field.get(&shared_memory_page_size_hint_bytes_);
45632         break;
45633       case 2 /* shared_memory_size_hint_bytes */:
45634         field.get(&shared_memory_size_hint_bytes_);
45635         break;
45636       case 3 /* producer_name */:
45637         field.get(&producer_name_);
45638         break;
45639       case 4 /* smb_scraping_mode */:
45640         field.get(&smb_scraping_mode_);
45641         break;
45642       case 5 /* build_flags */:
45643         field.get(&build_flags_);
45644         break;
45645       case 6 /* producer_provided_shmem */:
45646         field.get(&producer_provided_shmem_);
45647         break;
45648       default:
45649         field.SerializeAndAppendTo(&unknown_fields_);
45650         break;
45651     }
45652   }
45653   return !packed_error && !dec.bytes_left();
45654 }
45655 
SerializeAsString() const45656 std::string InitializeConnectionRequest::SerializeAsString() const {
45657   ::protozero::HeapBuffered<::protozero::Message> msg;
45658   Serialize(msg.get());
45659   return msg.SerializeAsString();
45660 }
45661 
SerializeAsArray() const45662 std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
45663   ::protozero::HeapBuffered<::protozero::Message> msg;
45664   Serialize(msg.get());
45665   return msg.SerializeAsArray();
45666 }
45667 
Serialize(::protozero::Message * msg) const45668 void InitializeConnectionRequest::Serialize(::protozero::Message* msg) const {
45669   // Field 1: shared_memory_page_size_hint_bytes
45670   if (_has_field_[1]) {
45671     msg->AppendVarInt(1, shared_memory_page_size_hint_bytes_);
45672   }
45673 
45674   // Field 2: shared_memory_size_hint_bytes
45675   if (_has_field_[2]) {
45676     msg->AppendVarInt(2, shared_memory_size_hint_bytes_);
45677   }
45678 
45679   // Field 3: producer_name
45680   if (_has_field_[3]) {
45681     msg->AppendString(3, producer_name_);
45682   }
45683 
45684   // Field 4: smb_scraping_mode
45685   if (_has_field_[4]) {
45686     msg->AppendVarInt(4, smb_scraping_mode_);
45687   }
45688 
45689   // Field 5: build_flags
45690   if (_has_field_[5]) {
45691     msg->AppendVarInt(5, build_flags_);
45692   }
45693 
45694   // Field 6: producer_provided_shmem
45695   if (_has_field_[6]) {
45696     msg->AppendTinyVarInt(6, producer_provided_shmem_);
45697   }
45698 
45699   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
45700 }
45701 
45702 }  // namespace perfetto
45703 }  // namespace protos
45704 }  // namespace gen
45705 #pragma GCC diagnostic pop
45706 // gen_amalgamated begin source: gen/protos/perfetto/ipc/wire_protocol.gen.cc
45707 // gen_amalgamated begin header: gen/protos/perfetto/ipc/wire_protocol.gen.h
45708 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
45709 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
45710 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
45711 
45712 #include <stdint.h>
45713 #include <bitset>
45714 #include <vector>
45715 #include <string>
45716 #include <type_traits>
45717 
45718 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
45719 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
45720 // gen_amalgamated expanded: #include "perfetto/base/export.h"
45721 
45722 namespace perfetto {
45723 namespace protos {
45724 namespace gen {
45725 class IPCFrame;
45726 class IPCFrame_RequestError;
45727 class IPCFrame_InvokeMethodReply;
45728 class IPCFrame_InvokeMethod;
45729 class IPCFrame_BindServiceReply;
45730 class IPCFrame_BindServiceReply_MethodInfo;
45731 class IPCFrame_BindService;
45732 }  // namespace perfetto
45733 }  // namespace protos
45734 }  // namespace gen
45735 
45736 namespace protozero {
45737 class Message;
45738 }  // namespace protozero
45739 
45740 namespace perfetto {
45741 namespace protos {
45742 namespace gen {
45743 
45744 class PERFETTO_EXPORT IPCFrame : public ::protozero::CppMessageObj {
45745  public:
45746   using BindService = IPCFrame_BindService;
45747   using BindServiceReply = IPCFrame_BindServiceReply;
45748   using InvokeMethod = IPCFrame_InvokeMethod;
45749   using InvokeMethodReply = IPCFrame_InvokeMethodReply;
45750   using RequestError = IPCFrame_RequestError;
45751   enum FieldNumbers {
45752     kRequestIdFieldNumber = 2,
45753     kMsgBindServiceFieldNumber = 3,
45754     kMsgBindServiceReplyFieldNumber = 4,
45755     kMsgInvokeMethodFieldNumber = 5,
45756     kMsgInvokeMethodReplyFieldNumber = 6,
45757     kMsgRequestErrorFieldNumber = 7,
45758     kDataForTestingFieldNumber = 1,
45759   };
45760 
45761   IPCFrame();
45762   ~IPCFrame() override;
45763   IPCFrame(IPCFrame&&) noexcept;
45764   IPCFrame& operator=(IPCFrame&&);
45765   IPCFrame(const IPCFrame&);
45766   IPCFrame& operator=(const IPCFrame&);
45767   bool operator==(const IPCFrame&) const;
operator !=(const IPCFrame & other) const45768   bool operator!=(const IPCFrame& other) const { return !(*this == other); }
45769 
45770   bool ParseFromArray(const void*, size_t) override;
45771   std::string SerializeAsString() const override;
45772   std::vector<uint8_t> SerializeAsArray() const override;
45773   void Serialize(::protozero::Message*) const;
45774 
has_request_id() const45775   bool has_request_id() const { return _has_field_[2]; }
request_id() const45776   uint64_t request_id() const { return request_id_; }
set_request_id(uint64_t value)45777   void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
45778 
has_msg_bind_service() const45779   bool has_msg_bind_service() const { return _has_field_[3]; }
msg_bind_service() const45780   const IPCFrame_BindService& msg_bind_service() const { return *msg_bind_service_; }
mutable_msg_bind_service()45781   IPCFrame_BindService* mutable_msg_bind_service() { _has_field_.set(3); return msg_bind_service_.get(); }
45782 
has_msg_bind_service_reply() const45783   bool has_msg_bind_service_reply() const { return _has_field_[4]; }
msg_bind_service_reply() const45784   const IPCFrame_BindServiceReply& msg_bind_service_reply() const { return *msg_bind_service_reply_; }
mutable_msg_bind_service_reply()45785   IPCFrame_BindServiceReply* mutable_msg_bind_service_reply() { _has_field_.set(4); return msg_bind_service_reply_.get(); }
45786 
has_msg_invoke_method() const45787   bool has_msg_invoke_method() const { return _has_field_[5]; }
msg_invoke_method() const45788   const IPCFrame_InvokeMethod& msg_invoke_method() const { return *msg_invoke_method_; }
mutable_msg_invoke_method()45789   IPCFrame_InvokeMethod* mutable_msg_invoke_method() { _has_field_.set(5); return msg_invoke_method_.get(); }
45790 
has_msg_invoke_method_reply() const45791   bool has_msg_invoke_method_reply() const { return _has_field_[6]; }
msg_invoke_method_reply() const45792   const IPCFrame_InvokeMethodReply& msg_invoke_method_reply() const { return *msg_invoke_method_reply_; }
mutable_msg_invoke_method_reply()45793   IPCFrame_InvokeMethodReply* mutable_msg_invoke_method_reply() { _has_field_.set(6); return msg_invoke_method_reply_.get(); }
45794 
has_msg_request_error() const45795   bool has_msg_request_error() const { return _has_field_[7]; }
msg_request_error() const45796   const IPCFrame_RequestError& msg_request_error() const { return *msg_request_error_; }
mutable_msg_request_error()45797   IPCFrame_RequestError* mutable_msg_request_error() { _has_field_.set(7); return msg_request_error_.get(); }
45798 
data_for_testing_size() const45799   int data_for_testing_size() const { return static_cast<int>(data_for_testing_.size()); }
data_for_testing() const45800   const std::vector<std::string>& data_for_testing() const { return data_for_testing_; }
mutable_data_for_testing()45801   std::vector<std::string>* mutable_data_for_testing() { return &data_for_testing_; }
clear_data_for_testing()45802   void clear_data_for_testing() { data_for_testing_.clear(); }
add_data_for_testing(std::string value)45803   void add_data_for_testing(std::string value) { data_for_testing_.emplace_back(value); }
add_data_for_testing()45804   std::string* add_data_for_testing() { data_for_testing_.emplace_back(); return &data_for_testing_.back(); }
45805 
45806  private:
45807   uint64_t request_id_{};
45808   ::protozero::CopyablePtr<IPCFrame_BindService> msg_bind_service_;
45809   ::protozero::CopyablePtr<IPCFrame_BindServiceReply> msg_bind_service_reply_;
45810   ::protozero::CopyablePtr<IPCFrame_InvokeMethod> msg_invoke_method_;
45811   ::protozero::CopyablePtr<IPCFrame_InvokeMethodReply> msg_invoke_method_reply_;
45812   ::protozero::CopyablePtr<IPCFrame_RequestError> msg_request_error_;
45813   std::vector<std::string> data_for_testing_;
45814 
45815   // Allows to preserve unknown protobuf fields for compatibility
45816   // with future versions of .proto files.
45817   std::string unknown_fields_;
45818 
45819   std::bitset<8> _has_field_{};
45820 };
45821 
45822 
45823 class PERFETTO_EXPORT IPCFrame_RequestError : public ::protozero::CppMessageObj {
45824  public:
45825   enum FieldNumbers {
45826     kErrorFieldNumber = 1,
45827   };
45828 
45829   IPCFrame_RequestError();
45830   ~IPCFrame_RequestError() override;
45831   IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept;
45832   IPCFrame_RequestError& operator=(IPCFrame_RequestError&&);
45833   IPCFrame_RequestError(const IPCFrame_RequestError&);
45834   IPCFrame_RequestError& operator=(const IPCFrame_RequestError&);
45835   bool operator==(const IPCFrame_RequestError&) const;
operator !=(const IPCFrame_RequestError & other) const45836   bool operator!=(const IPCFrame_RequestError& other) const { return !(*this == other); }
45837 
45838   bool ParseFromArray(const void*, size_t) override;
45839   std::string SerializeAsString() const override;
45840   std::vector<uint8_t> SerializeAsArray() const override;
45841   void Serialize(::protozero::Message*) const;
45842 
has_error() const45843   bool has_error() const { return _has_field_[1]; }
error() const45844   const std::string& error() const { return error_; }
set_error(const std::string & value)45845   void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
45846 
45847  private:
45848   std::string error_{};
45849 
45850   // Allows to preserve unknown protobuf fields for compatibility
45851   // with future versions of .proto files.
45852   std::string unknown_fields_;
45853 
45854   std::bitset<2> _has_field_{};
45855 };
45856 
45857 
45858 class PERFETTO_EXPORT IPCFrame_InvokeMethodReply : public ::protozero::CppMessageObj {
45859  public:
45860   enum FieldNumbers {
45861     kSuccessFieldNumber = 1,
45862     kHasMoreFieldNumber = 2,
45863     kReplyProtoFieldNumber = 3,
45864   };
45865 
45866   IPCFrame_InvokeMethodReply();
45867   ~IPCFrame_InvokeMethodReply() override;
45868   IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept;
45869   IPCFrame_InvokeMethodReply& operator=(IPCFrame_InvokeMethodReply&&);
45870   IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&);
45871   IPCFrame_InvokeMethodReply& operator=(const IPCFrame_InvokeMethodReply&);
45872   bool operator==(const IPCFrame_InvokeMethodReply&) const;
operator !=(const IPCFrame_InvokeMethodReply & other) const45873   bool operator!=(const IPCFrame_InvokeMethodReply& other) const { return !(*this == other); }
45874 
45875   bool ParseFromArray(const void*, size_t) override;
45876   std::string SerializeAsString() const override;
45877   std::vector<uint8_t> SerializeAsArray() const override;
45878   void Serialize(::protozero::Message*) const;
45879 
has_success() const45880   bool has_success() const { return _has_field_[1]; }
success() const45881   bool success() const { return success_; }
set_success(bool value)45882   void set_success(bool value) { success_ = value; _has_field_.set(1); }
45883 
has_has_more() const45884   bool has_has_more() const { return _has_field_[2]; }
has_more() const45885   bool has_more() const { return has_more_; }
set_has_more(bool value)45886   void set_has_more(bool value) { has_more_ = value; _has_field_.set(2); }
45887 
has_reply_proto() const45888   bool has_reply_proto() const { return _has_field_[3]; }
reply_proto() const45889   const std::string& reply_proto() const { return reply_proto_; }
set_reply_proto(const std::string & value)45890   void set_reply_proto(const std::string& value) { reply_proto_ = value; _has_field_.set(3); }
set_reply_proto(const void * p,size_t s)45891   void set_reply_proto(const void* p, size_t s) { reply_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
45892 
45893  private:
45894   bool success_{};
45895   bool has_more_{};
45896   std::string reply_proto_{};
45897 
45898   // Allows to preserve unknown protobuf fields for compatibility
45899   // with future versions of .proto files.
45900   std::string unknown_fields_;
45901 
45902   std::bitset<4> _has_field_{};
45903 };
45904 
45905 
45906 class PERFETTO_EXPORT IPCFrame_InvokeMethod : public ::protozero::CppMessageObj {
45907  public:
45908   enum FieldNumbers {
45909     kServiceIdFieldNumber = 1,
45910     kMethodIdFieldNumber = 2,
45911     kArgsProtoFieldNumber = 3,
45912     kDropReplyFieldNumber = 4,
45913   };
45914 
45915   IPCFrame_InvokeMethod();
45916   ~IPCFrame_InvokeMethod() override;
45917   IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept;
45918   IPCFrame_InvokeMethod& operator=(IPCFrame_InvokeMethod&&);
45919   IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&);
45920   IPCFrame_InvokeMethod& operator=(const IPCFrame_InvokeMethod&);
45921   bool operator==(const IPCFrame_InvokeMethod&) const;
operator !=(const IPCFrame_InvokeMethod & other) const45922   bool operator!=(const IPCFrame_InvokeMethod& other) const { return !(*this == other); }
45923 
45924   bool ParseFromArray(const void*, size_t) override;
45925   std::string SerializeAsString() const override;
45926   std::vector<uint8_t> SerializeAsArray() const override;
45927   void Serialize(::protozero::Message*) const;
45928 
has_service_id() const45929   bool has_service_id() const { return _has_field_[1]; }
service_id() const45930   uint32_t service_id() const { return service_id_; }
set_service_id(uint32_t value)45931   void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(1); }
45932 
has_method_id() const45933   bool has_method_id() const { return _has_field_[2]; }
method_id() const45934   uint32_t method_id() const { return method_id_; }
set_method_id(uint32_t value)45935   void set_method_id(uint32_t value) { method_id_ = value; _has_field_.set(2); }
45936 
has_args_proto() const45937   bool has_args_proto() const { return _has_field_[3]; }
args_proto() const45938   const std::string& args_proto() const { return args_proto_; }
set_args_proto(const std::string & value)45939   void set_args_proto(const std::string& value) { args_proto_ = value; _has_field_.set(3); }
set_args_proto(const void * p,size_t s)45940   void set_args_proto(const void* p, size_t s) { args_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
45941 
has_drop_reply() const45942   bool has_drop_reply() const { return _has_field_[4]; }
drop_reply() const45943   bool drop_reply() const { return drop_reply_; }
set_drop_reply(bool value)45944   void set_drop_reply(bool value) { drop_reply_ = value; _has_field_.set(4); }
45945 
45946  private:
45947   uint32_t service_id_{};
45948   uint32_t method_id_{};
45949   std::string args_proto_{};
45950   bool drop_reply_{};
45951 
45952   // Allows to preserve unknown protobuf fields for compatibility
45953   // with future versions of .proto files.
45954   std::string unknown_fields_;
45955 
45956   std::bitset<5> _has_field_{};
45957 };
45958 
45959 
45960 class PERFETTO_EXPORT IPCFrame_BindServiceReply : public ::protozero::CppMessageObj {
45961  public:
45962   using MethodInfo = IPCFrame_BindServiceReply_MethodInfo;
45963   enum FieldNumbers {
45964     kSuccessFieldNumber = 1,
45965     kServiceIdFieldNumber = 2,
45966     kMethodsFieldNumber = 3,
45967   };
45968 
45969   IPCFrame_BindServiceReply();
45970   ~IPCFrame_BindServiceReply() override;
45971   IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept;
45972   IPCFrame_BindServiceReply& operator=(IPCFrame_BindServiceReply&&);
45973   IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&);
45974   IPCFrame_BindServiceReply& operator=(const IPCFrame_BindServiceReply&);
45975   bool operator==(const IPCFrame_BindServiceReply&) const;
operator !=(const IPCFrame_BindServiceReply & other) const45976   bool operator!=(const IPCFrame_BindServiceReply& other) const { return !(*this == other); }
45977 
45978   bool ParseFromArray(const void*, size_t) override;
45979   std::string SerializeAsString() const override;
45980   std::vector<uint8_t> SerializeAsArray() const override;
45981   void Serialize(::protozero::Message*) const;
45982 
has_success() const45983   bool has_success() const { return _has_field_[1]; }
success() const45984   bool success() const { return success_; }
set_success(bool value)45985   void set_success(bool value) { success_ = value; _has_field_.set(1); }
45986 
has_service_id() const45987   bool has_service_id() const { return _has_field_[2]; }
service_id() const45988   uint32_t service_id() const { return service_id_; }
set_service_id(uint32_t value)45989   void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(2); }
45990 
methods_size() const45991   int methods_size() const { return static_cast<int>(methods_.size()); }
methods() const45992   const std::vector<IPCFrame_BindServiceReply_MethodInfo>& methods() const { return methods_; }
mutable_methods()45993   std::vector<IPCFrame_BindServiceReply_MethodInfo>* mutable_methods() { return &methods_; }
clear_methods()45994   void clear_methods() { methods_.clear(); }
add_methods()45995   IPCFrame_BindServiceReply_MethodInfo* add_methods() { methods_.emplace_back(); return &methods_.back(); }
45996 
45997  private:
45998   bool success_{};
45999   uint32_t service_id_{};
46000   std::vector<IPCFrame_BindServiceReply_MethodInfo> methods_;
46001 
46002   // Allows to preserve unknown protobuf fields for compatibility
46003   // with future versions of .proto files.
46004   std::string unknown_fields_;
46005 
46006   std::bitset<4> _has_field_{};
46007 };
46008 
46009 
46010 class PERFETTO_EXPORT IPCFrame_BindServiceReply_MethodInfo : public ::protozero::CppMessageObj {
46011  public:
46012   enum FieldNumbers {
46013     kIdFieldNumber = 1,
46014     kNameFieldNumber = 2,
46015   };
46016 
46017   IPCFrame_BindServiceReply_MethodInfo();
46018   ~IPCFrame_BindServiceReply_MethodInfo() override;
46019   IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept;
46020   IPCFrame_BindServiceReply_MethodInfo& operator=(IPCFrame_BindServiceReply_MethodInfo&&);
46021   IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&);
46022   IPCFrame_BindServiceReply_MethodInfo& operator=(const IPCFrame_BindServiceReply_MethodInfo&);
46023   bool operator==(const IPCFrame_BindServiceReply_MethodInfo&) const;
operator !=(const IPCFrame_BindServiceReply_MethodInfo & other) const46024   bool operator!=(const IPCFrame_BindServiceReply_MethodInfo& other) const { return !(*this == other); }
46025 
46026   bool ParseFromArray(const void*, size_t) override;
46027   std::string SerializeAsString() const override;
46028   std::vector<uint8_t> SerializeAsArray() const override;
46029   void Serialize(::protozero::Message*) const;
46030 
has_id() const46031   bool has_id() const { return _has_field_[1]; }
id() const46032   uint32_t id() const { return id_; }
set_id(uint32_t value)46033   void set_id(uint32_t value) { id_ = value; _has_field_.set(1); }
46034 
has_name() const46035   bool has_name() const { return _has_field_[2]; }
name() const46036   const std::string& name() const { return name_; }
set_name(const std::string & value)46037   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
46038 
46039  private:
46040   uint32_t id_{};
46041   std::string name_{};
46042 
46043   // Allows to preserve unknown protobuf fields for compatibility
46044   // with future versions of .proto files.
46045   std::string unknown_fields_;
46046 
46047   std::bitset<3> _has_field_{};
46048 };
46049 
46050 
46051 class PERFETTO_EXPORT IPCFrame_BindService : public ::protozero::CppMessageObj {
46052  public:
46053   enum FieldNumbers {
46054     kServiceNameFieldNumber = 1,
46055   };
46056 
46057   IPCFrame_BindService();
46058   ~IPCFrame_BindService() override;
46059   IPCFrame_BindService(IPCFrame_BindService&&) noexcept;
46060   IPCFrame_BindService& operator=(IPCFrame_BindService&&);
46061   IPCFrame_BindService(const IPCFrame_BindService&);
46062   IPCFrame_BindService& operator=(const IPCFrame_BindService&);
46063   bool operator==(const IPCFrame_BindService&) const;
operator !=(const IPCFrame_BindService & other) const46064   bool operator!=(const IPCFrame_BindService& other) const { return !(*this == other); }
46065 
46066   bool ParseFromArray(const void*, size_t) override;
46067   std::string SerializeAsString() const override;
46068   std::vector<uint8_t> SerializeAsArray() const override;
46069   void Serialize(::protozero::Message*) const;
46070 
has_service_name() const46071   bool has_service_name() const { return _has_field_[1]; }
service_name() const46072   const std::string& service_name() const { return service_name_; }
set_service_name(const std::string & value)46073   void set_service_name(const std::string& value) { service_name_ = value; _has_field_.set(1); }
46074 
46075  private:
46076   std::string service_name_{};
46077 
46078   // Allows to preserve unknown protobuf fields for compatibility
46079   // with future versions of .proto files.
46080   std::string unknown_fields_;
46081 
46082   std::bitset<2> _has_field_{};
46083 };
46084 
46085 }  // namespace perfetto
46086 }  // namespace protos
46087 }  // namespace gen
46088 
46089 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
46090 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
46091 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
46092 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
46093 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
46094 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
46095 #pragma GCC diagnostic push
46096 #pragma GCC diagnostic ignored "-Wfloat-equal"
46097 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
46098 
46099 namespace perfetto {
46100 namespace protos {
46101 namespace gen {
46102 
46103 IPCFrame::IPCFrame() = default;
46104 IPCFrame::~IPCFrame() = default;
46105 IPCFrame::IPCFrame(const IPCFrame&) = default;
46106 IPCFrame& IPCFrame::operator=(const IPCFrame&) = default;
46107 IPCFrame::IPCFrame(IPCFrame&&) noexcept = default;
46108 IPCFrame& IPCFrame::operator=(IPCFrame&&) = default;
46109 
operator ==(const IPCFrame & other) const46110 bool IPCFrame::operator==(const IPCFrame& other) const {
46111   return unknown_fields_ == other.unknown_fields_
46112    && request_id_ == other.request_id_
46113    && msg_bind_service_ == other.msg_bind_service_
46114    && msg_bind_service_reply_ == other.msg_bind_service_reply_
46115    && msg_invoke_method_ == other.msg_invoke_method_
46116    && msg_invoke_method_reply_ == other.msg_invoke_method_reply_
46117    && msg_request_error_ == other.msg_request_error_
46118    && data_for_testing_ == other.data_for_testing_;
46119 }
46120 
ParseFromArray(const void * raw,size_t size)46121 bool IPCFrame::ParseFromArray(const void* raw, size_t size) {
46122   data_for_testing_.clear();
46123   unknown_fields_.clear();
46124   bool packed_error = false;
46125 
46126   ::protozero::ProtoDecoder dec(raw, size);
46127   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46128     if (field.id() < _has_field_.size()) {
46129       _has_field_.set(field.id());
46130     }
46131     switch (field.id()) {
46132       case 2 /* request_id */:
46133         field.get(&request_id_);
46134         break;
46135       case 3 /* msg_bind_service */:
46136         (*msg_bind_service_).ParseFromString(field.as_std_string());
46137         break;
46138       case 4 /* msg_bind_service_reply */:
46139         (*msg_bind_service_reply_).ParseFromString(field.as_std_string());
46140         break;
46141       case 5 /* msg_invoke_method */:
46142         (*msg_invoke_method_).ParseFromString(field.as_std_string());
46143         break;
46144       case 6 /* msg_invoke_method_reply */:
46145         (*msg_invoke_method_reply_).ParseFromString(field.as_std_string());
46146         break;
46147       case 7 /* msg_request_error */:
46148         (*msg_request_error_).ParseFromString(field.as_std_string());
46149         break;
46150       case 1 /* data_for_testing */:
46151         data_for_testing_.emplace_back();
46152         field.get(&data_for_testing_.back());
46153         break;
46154       default:
46155         field.SerializeAndAppendTo(&unknown_fields_);
46156         break;
46157     }
46158   }
46159   return !packed_error && !dec.bytes_left();
46160 }
46161 
SerializeAsString() const46162 std::string IPCFrame::SerializeAsString() const {
46163   ::protozero::HeapBuffered<::protozero::Message> msg;
46164   Serialize(msg.get());
46165   return msg.SerializeAsString();
46166 }
46167 
SerializeAsArray() const46168 std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
46169   ::protozero::HeapBuffered<::protozero::Message> msg;
46170   Serialize(msg.get());
46171   return msg.SerializeAsArray();
46172 }
46173 
Serialize(::protozero::Message * msg) const46174 void IPCFrame::Serialize(::protozero::Message* msg) const {
46175   // Field 2: request_id
46176   if (_has_field_[2]) {
46177     msg->AppendVarInt(2, request_id_);
46178   }
46179 
46180   // Field 3: msg_bind_service
46181   if (_has_field_[3]) {
46182     (*msg_bind_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
46183   }
46184 
46185   // Field 4: msg_bind_service_reply
46186   if (_has_field_[4]) {
46187     (*msg_bind_service_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
46188   }
46189 
46190   // Field 5: msg_invoke_method
46191   if (_has_field_[5]) {
46192     (*msg_invoke_method_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
46193   }
46194 
46195   // Field 6: msg_invoke_method_reply
46196   if (_has_field_[6]) {
46197     (*msg_invoke_method_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
46198   }
46199 
46200   // Field 7: msg_request_error
46201   if (_has_field_[7]) {
46202     (*msg_request_error_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
46203   }
46204 
46205   // Field 1: data_for_testing
46206   for (auto& it : data_for_testing_) {
46207     msg->AppendString(1, it);
46208   }
46209 
46210   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46211 }
46212 
46213 
46214 IPCFrame_RequestError::IPCFrame_RequestError() = default;
46215 IPCFrame_RequestError::~IPCFrame_RequestError() = default;
46216 IPCFrame_RequestError::IPCFrame_RequestError(const IPCFrame_RequestError&) = default;
46217 IPCFrame_RequestError& IPCFrame_RequestError::operator=(const IPCFrame_RequestError&) = default;
46218 IPCFrame_RequestError::IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept = default;
46219 IPCFrame_RequestError& IPCFrame_RequestError::operator=(IPCFrame_RequestError&&) = default;
46220 
operator ==(const IPCFrame_RequestError & other) const46221 bool IPCFrame_RequestError::operator==(const IPCFrame_RequestError& other) const {
46222   return unknown_fields_ == other.unknown_fields_
46223    && error_ == other.error_;
46224 }
46225 
ParseFromArray(const void * raw,size_t size)46226 bool IPCFrame_RequestError::ParseFromArray(const void* raw, size_t size) {
46227   unknown_fields_.clear();
46228   bool packed_error = false;
46229 
46230   ::protozero::ProtoDecoder dec(raw, size);
46231   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46232     if (field.id() < _has_field_.size()) {
46233       _has_field_.set(field.id());
46234     }
46235     switch (field.id()) {
46236       case 1 /* error */:
46237         field.get(&error_);
46238         break;
46239       default:
46240         field.SerializeAndAppendTo(&unknown_fields_);
46241         break;
46242     }
46243   }
46244   return !packed_error && !dec.bytes_left();
46245 }
46246 
SerializeAsString() const46247 std::string IPCFrame_RequestError::SerializeAsString() const {
46248   ::protozero::HeapBuffered<::protozero::Message> msg;
46249   Serialize(msg.get());
46250   return msg.SerializeAsString();
46251 }
46252 
SerializeAsArray() const46253 std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
46254   ::protozero::HeapBuffered<::protozero::Message> msg;
46255   Serialize(msg.get());
46256   return msg.SerializeAsArray();
46257 }
46258 
Serialize(::protozero::Message * msg) const46259 void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
46260   // Field 1: error
46261   if (_has_field_[1]) {
46262     msg->AppendString(1, error_);
46263   }
46264 
46265   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46266 }
46267 
46268 
46269 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply() = default;
46270 IPCFrame_InvokeMethodReply::~IPCFrame_InvokeMethodReply() = default;
46271 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&) = default;
46272 IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(const IPCFrame_InvokeMethodReply&) = default;
46273 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept = default;
46274 IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(IPCFrame_InvokeMethodReply&&) = default;
46275 
operator ==(const IPCFrame_InvokeMethodReply & other) const46276 bool IPCFrame_InvokeMethodReply::operator==(const IPCFrame_InvokeMethodReply& other) const {
46277   return unknown_fields_ == other.unknown_fields_
46278    && success_ == other.success_
46279    && has_more_ == other.has_more_
46280    && reply_proto_ == other.reply_proto_;
46281 }
46282 
ParseFromArray(const void * raw,size_t size)46283 bool IPCFrame_InvokeMethodReply::ParseFromArray(const void* raw, size_t size) {
46284   unknown_fields_.clear();
46285   bool packed_error = false;
46286 
46287   ::protozero::ProtoDecoder dec(raw, size);
46288   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46289     if (field.id() < _has_field_.size()) {
46290       _has_field_.set(field.id());
46291     }
46292     switch (field.id()) {
46293       case 1 /* success */:
46294         field.get(&success_);
46295         break;
46296       case 2 /* has_more */:
46297         field.get(&has_more_);
46298         break;
46299       case 3 /* reply_proto */:
46300         field.get(&reply_proto_);
46301         break;
46302       default:
46303         field.SerializeAndAppendTo(&unknown_fields_);
46304         break;
46305     }
46306   }
46307   return !packed_error && !dec.bytes_left();
46308 }
46309 
SerializeAsString() const46310 std::string IPCFrame_InvokeMethodReply::SerializeAsString() const {
46311   ::protozero::HeapBuffered<::protozero::Message> msg;
46312   Serialize(msg.get());
46313   return msg.SerializeAsString();
46314 }
46315 
SerializeAsArray() const46316 std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
46317   ::protozero::HeapBuffered<::protozero::Message> msg;
46318   Serialize(msg.get());
46319   return msg.SerializeAsArray();
46320 }
46321 
Serialize(::protozero::Message * msg) const46322 void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
46323   // Field 1: success
46324   if (_has_field_[1]) {
46325     msg->AppendTinyVarInt(1, success_);
46326   }
46327 
46328   // Field 2: has_more
46329   if (_has_field_[2]) {
46330     msg->AppendTinyVarInt(2, has_more_);
46331   }
46332 
46333   // Field 3: reply_proto
46334   if (_has_field_[3]) {
46335     msg->AppendString(3, reply_proto_);
46336   }
46337 
46338   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46339 }
46340 
46341 
46342 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod() = default;
46343 IPCFrame_InvokeMethod::~IPCFrame_InvokeMethod() = default;
46344 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&) = default;
46345 IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(const IPCFrame_InvokeMethod&) = default;
46346 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept = default;
46347 IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(IPCFrame_InvokeMethod&&) = default;
46348 
operator ==(const IPCFrame_InvokeMethod & other) const46349 bool IPCFrame_InvokeMethod::operator==(const IPCFrame_InvokeMethod& other) const {
46350   return unknown_fields_ == other.unknown_fields_
46351    && service_id_ == other.service_id_
46352    && method_id_ == other.method_id_
46353    && args_proto_ == other.args_proto_
46354    && drop_reply_ == other.drop_reply_;
46355 }
46356 
ParseFromArray(const void * raw,size_t size)46357 bool IPCFrame_InvokeMethod::ParseFromArray(const void* raw, size_t size) {
46358   unknown_fields_.clear();
46359   bool packed_error = false;
46360 
46361   ::protozero::ProtoDecoder dec(raw, size);
46362   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46363     if (field.id() < _has_field_.size()) {
46364       _has_field_.set(field.id());
46365     }
46366     switch (field.id()) {
46367       case 1 /* service_id */:
46368         field.get(&service_id_);
46369         break;
46370       case 2 /* method_id */:
46371         field.get(&method_id_);
46372         break;
46373       case 3 /* args_proto */:
46374         field.get(&args_proto_);
46375         break;
46376       case 4 /* drop_reply */:
46377         field.get(&drop_reply_);
46378         break;
46379       default:
46380         field.SerializeAndAppendTo(&unknown_fields_);
46381         break;
46382     }
46383   }
46384   return !packed_error && !dec.bytes_left();
46385 }
46386 
SerializeAsString() const46387 std::string IPCFrame_InvokeMethod::SerializeAsString() const {
46388   ::protozero::HeapBuffered<::protozero::Message> msg;
46389   Serialize(msg.get());
46390   return msg.SerializeAsString();
46391 }
46392 
SerializeAsArray() const46393 std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
46394   ::protozero::HeapBuffered<::protozero::Message> msg;
46395   Serialize(msg.get());
46396   return msg.SerializeAsArray();
46397 }
46398 
Serialize(::protozero::Message * msg) const46399 void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
46400   // Field 1: service_id
46401   if (_has_field_[1]) {
46402     msg->AppendVarInt(1, service_id_);
46403   }
46404 
46405   // Field 2: method_id
46406   if (_has_field_[2]) {
46407     msg->AppendVarInt(2, method_id_);
46408   }
46409 
46410   // Field 3: args_proto
46411   if (_has_field_[3]) {
46412     msg->AppendString(3, args_proto_);
46413   }
46414 
46415   // Field 4: drop_reply
46416   if (_has_field_[4]) {
46417     msg->AppendTinyVarInt(4, drop_reply_);
46418   }
46419 
46420   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46421 }
46422 
46423 
46424 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply() = default;
46425 IPCFrame_BindServiceReply::~IPCFrame_BindServiceReply() = default;
46426 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&) = default;
46427 IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(const IPCFrame_BindServiceReply&) = default;
46428 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept = default;
46429 IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(IPCFrame_BindServiceReply&&) = default;
46430 
operator ==(const IPCFrame_BindServiceReply & other) const46431 bool IPCFrame_BindServiceReply::operator==(const IPCFrame_BindServiceReply& other) const {
46432   return unknown_fields_ == other.unknown_fields_
46433    && success_ == other.success_
46434    && service_id_ == other.service_id_
46435    && methods_ == other.methods_;
46436 }
46437 
ParseFromArray(const void * raw,size_t size)46438 bool IPCFrame_BindServiceReply::ParseFromArray(const void* raw, size_t size) {
46439   methods_.clear();
46440   unknown_fields_.clear();
46441   bool packed_error = false;
46442 
46443   ::protozero::ProtoDecoder dec(raw, size);
46444   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46445     if (field.id() < _has_field_.size()) {
46446       _has_field_.set(field.id());
46447     }
46448     switch (field.id()) {
46449       case 1 /* success */:
46450         field.get(&success_);
46451         break;
46452       case 2 /* service_id */:
46453         field.get(&service_id_);
46454         break;
46455       case 3 /* methods */:
46456         methods_.emplace_back();
46457         methods_.back().ParseFromString(field.as_std_string());
46458         break;
46459       default:
46460         field.SerializeAndAppendTo(&unknown_fields_);
46461         break;
46462     }
46463   }
46464   return !packed_error && !dec.bytes_left();
46465 }
46466 
SerializeAsString() const46467 std::string IPCFrame_BindServiceReply::SerializeAsString() const {
46468   ::protozero::HeapBuffered<::protozero::Message> msg;
46469   Serialize(msg.get());
46470   return msg.SerializeAsString();
46471 }
46472 
SerializeAsArray() const46473 std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
46474   ::protozero::HeapBuffered<::protozero::Message> msg;
46475   Serialize(msg.get());
46476   return msg.SerializeAsArray();
46477 }
46478 
Serialize(::protozero::Message * msg) const46479 void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
46480   // Field 1: success
46481   if (_has_field_[1]) {
46482     msg->AppendTinyVarInt(1, success_);
46483   }
46484 
46485   // Field 2: service_id
46486   if (_has_field_[2]) {
46487     msg->AppendVarInt(2, service_id_);
46488   }
46489 
46490   // Field 3: methods
46491   for (auto& it : methods_) {
46492     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
46493   }
46494 
46495   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46496 }
46497 
46498 
46499 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo() = default;
46500 IPCFrame_BindServiceReply_MethodInfo::~IPCFrame_BindServiceReply_MethodInfo() = default;
46501 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&) = default;
46502 IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(const IPCFrame_BindServiceReply_MethodInfo&) = default;
46503 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept = default;
46504 IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(IPCFrame_BindServiceReply_MethodInfo&&) = default;
46505 
operator ==(const IPCFrame_BindServiceReply_MethodInfo & other) const46506 bool IPCFrame_BindServiceReply_MethodInfo::operator==(const IPCFrame_BindServiceReply_MethodInfo& other) const {
46507   return unknown_fields_ == other.unknown_fields_
46508    && id_ == other.id_
46509    && name_ == other.name_;
46510 }
46511 
ParseFromArray(const void * raw,size_t size)46512 bool IPCFrame_BindServiceReply_MethodInfo::ParseFromArray(const void* raw, size_t size) {
46513   unknown_fields_.clear();
46514   bool packed_error = false;
46515 
46516   ::protozero::ProtoDecoder dec(raw, size);
46517   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46518     if (field.id() < _has_field_.size()) {
46519       _has_field_.set(field.id());
46520     }
46521     switch (field.id()) {
46522       case 1 /* id */:
46523         field.get(&id_);
46524         break;
46525       case 2 /* name */:
46526         field.get(&name_);
46527         break;
46528       default:
46529         field.SerializeAndAppendTo(&unknown_fields_);
46530         break;
46531     }
46532   }
46533   return !packed_error && !dec.bytes_left();
46534 }
46535 
SerializeAsString() const46536 std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
46537   ::protozero::HeapBuffered<::protozero::Message> msg;
46538   Serialize(msg.get());
46539   return msg.SerializeAsString();
46540 }
46541 
SerializeAsArray() const46542 std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
46543   ::protozero::HeapBuffered<::protozero::Message> msg;
46544   Serialize(msg.get());
46545   return msg.SerializeAsArray();
46546 }
46547 
Serialize(::protozero::Message * msg) const46548 void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
46549   // Field 1: id
46550   if (_has_field_[1]) {
46551     msg->AppendVarInt(1, id_);
46552   }
46553 
46554   // Field 2: name
46555   if (_has_field_[2]) {
46556     msg->AppendString(2, name_);
46557   }
46558 
46559   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46560 }
46561 
46562 
46563 IPCFrame_BindService::IPCFrame_BindService() = default;
46564 IPCFrame_BindService::~IPCFrame_BindService() = default;
46565 IPCFrame_BindService::IPCFrame_BindService(const IPCFrame_BindService&) = default;
46566 IPCFrame_BindService& IPCFrame_BindService::operator=(const IPCFrame_BindService&) = default;
46567 IPCFrame_BindService::IPCFrame_BindService(IPCFrame_BindService&&) noexcept = default;
46568 IPCFrame_BindService& IPCFrame_BindService::operator=(IPCFrame_BindService&&) = default;
46569 
operator ==(const IPCFrame_BindService & other) const46570 bool IPCFrame_BindService::operator==(const IPCFrame_BindService& other) const {
46571   return unknown_fields_ == other.unknown_fields_
46572    && service_name_ == other.service_name_;
46573 }
46574 
ParseFromArray(const void * raw,size_t size)46575 bool IPCFrame_BindService::ParseFromArray(const void* raw, size_t size) {
46576   unknown_fields_.clear();
46577   bool packed_error = false;
46578 
46579   ::protozero::ProtoDecoder dec(raw, size);
46580   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
46581     if (field.id() < _has_field_.size()) {
46582       _has_field_.set(field.id());
46583     }
46584     switch (field.id()) {
46585       case 1 /* service_name */:
46586         field.get(&service_name_);
46587         break;
46588       default:
46589         field.SerializeAndAppendTo(&unknown_fields_);
46590         break;
46591     }
46592   }
46593   return !packed_error && !dec.bytes_left();
46594 }
46595 
SerializeAsString() const46596 std::string IPCFrame_BindService::SerializeAsString() const {
46597   ::protozero::HeapBuffered<::protozero::Message> msg;
46598   Serialize(msg.get());
46599   return msg.SerializeAsString();
46600 }
46601 
SerializeAsArray() const46602 std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
46603   ::protozero::HeapBuffered<::protozero::Message> msg;
46604   Serialize(msg.get());
46605   return msg.SerializeAsArray();
46606 }
46607 
Serialize(::protozero::Message * msg) const46608 void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
46609   // Field 1: service_name
46610   if (_has_field_[1]) {
46611     msg->AppendString(1, service_name_);
46612   }
46613 
46614   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
46615 }
46616 
46617 }  // namespace perfetto
46618 }  // namespace protos
46619 }  // namespace gen
46620 #pragma GCC diagnostic pop
46621 // gen_amalgamated begin source: src/ipc/buffered_frame_deserializer.cc
46622 // gen_amalgamated begin header: src/ipc/buffered_frame_deserializer.h
46623 // gen_amalgamated begin header: include/perfetto/ext/ipc/basic_types.h
46624 /*
46625  * Copyright (C) 2017 The Android Open Source Project
46626  *
46627  * Licensed under the Apache License, Version 2.0 (the "License");
46628  * you may not use this file except in compliance with the License.
46629  * You may obtain a copy of the License at
46630  *
46631  *      http://www.apache.org/licenses/LICENSE-2.0
46632  *
46633  * Unless required by applicable law or agreed to in writing, software
46634  * distributed under the License is distributed on an "AS IS" BASIS,
46635  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46636  * See the License for the specific language governing permissions and
46637  * limitations under the License.
46638  */
46639 
46640 #ifndef INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
46641 #define INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
46642 
46643 #include <stddef.h>
46644 #include <stdint.h>
46645 #include <sys/types.h>
46646 
46647 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
46648 
46649 namespace perfetto {
46650 namespace ipc {
46651 
46652 using ProtoMessage = ::protozero::CppMessageObj;
46653 using ServiceID = uint32_t;
46654 using MethodID = uint32_t;
46655 using ClientID = uint64_t;
46656 using RequestID = uint64_t;
46657 
46658 // This determines the maximum size allowed for an IPC message. Trying to send
46659 // or receive a larger message will hit DCHECK(s) and auto-disconnect.
46660 constexpr size_t kIPCBufferSize = 128 * 1024;
46661 
46662 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
46663 
46664 }  // namespace ipc
46665 }  // namespace perfetto
46666 
46667 #endif  // INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
46668 /*
46669  * Copyright (C) 2017 The Android Open Source Project
46670  *
46671  * Licensed under the Apache License, Version 2.0 (the "License");
46672  * you may not use this file except in compliance with the License.
46673  * You may obtain a copy of the License at
46674  *
46675  *      http://www.apache.org/licenses/LICENSE-2.0
46676  *
46677  * Unless required by applicable law or agreed to in writing, software
46678  * distributed under the License is distributed on an "AS IS" BASIS,
46679  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46680  * See the License for the specific language governing permissions and
46681  * limitations under the License.
46682  */
46683 
46684 #ifndef SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
46685 #define SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
46686 
46687 #include <stddef.h>
46688 
46689 #include <list>
46690 #include <memory>
46691 
46692 #include <sys/mman.h>
46693 
46694 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
46695 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
46696 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
46697 
46698 namespace perfetto {
46699 
46700 namespace protos {
46701 namespace gen {
46702 class IPCFrame;
46703 }  // namespace gen
46704 }  // namespace protos
46705 
46706 namespace ipc {
46707 
46708 using Frame = ::perfetto::protos::gen::IPCFrame;
46709 
46710 // Deserializes incoming frames, taking care of buffering and tokenization.
46711 // Used by both host and client to decode incoming frames.
46712 //
46713 // Which problem does it solve?
46714 // ----------------------------
46715 // The wire protocol is as follows:
46716 // [32-bit frame size][proto-encoded Frame], e.g:
46717 // [06 00 00 00][00 11 22 33 44 55 66]
46718 // [02 00 00 00][AA BB]
46719 // [04 00 00 00][CC DD EE FF]
46720 // However, given that the socket works in SOCK_STREAM mode, the recv() calls
46721 // might see the following:
46722 // 06 00 00
46723 // 00 00 11 22 33 44 55
46724 // 66 02 00 00 00 ...
46725 // This class takes care of buffering efficiently the data received, without
46726 // making any assumption on how the incoming data will be chunked by the socket.
46727 // For instance, it is possible that a recv() doesn't produce any frame (because
46728 // it received only a part of the frame) or produces more than one frame.
46729 //
46730 // Usage
46731 // -----
46732 // Both host and client use this as follows:
46733 //
46734 // auto buf = rpc_frame_decoder.BeginReceive();
46735 // size_t rsize = socket.recv(buf.first, buf.second);
46736 // rpc_frame_decoder.EndReceive(rsize);
46737 // while (Frame frame = rpc_frame_decoder.PopNextFrame()) {
46738 //   ... process |frame|
46739 // }
46740 //
46741 // Design goals:
46742 // -------------
46743 // - Optimize for the realistic case of each recv() receiving one or more
46744 //   whole frames. In this case no memmove is performed.
46745 // - Guarantee that frames lay in a virtually contiguous memory area.
46746 //   This allows to use the protobuf-lite deserialization API (scattered
46747 //   deserialization is supported only by libprotobuf-full).
46748 // - Put a hard boundary to the size of the incoming buffer. This is to prevent
46749 //   that a malicious sends an abnormally large frame and OOMs us.
46750 // - Simplicity: just use a linear mmap region. No reallocations or scattering.
46751 //   Takes care of madvise()-ing unused memory.
46752 
46753 class BufferedFrameDeserializer {
46754  public:
46755   struct ReceiveBuffer {
46756     char* data;
46757     size_t size;
46758   };
46759 
46760   // |max_capacity| is overridable only for tests.
46761   explicit BufferedFrameDeserializer(size_t max_capacity = kIPCBufferSize);
46762   ~BufferedFrameDeserializer();
46763 
46764   // This function doesn't really belong here as it does Serialization, unlike
46765   // the rest of this class. However it is so small and has so many dependencies
46766   // in common that doesn't justify having its own class.
46767   static std::string Serialize(const Frame&);
46768 
46769   // Returns a buffer that can be passed to recv(). The buffer is deliberately
46770   // not initialized.
46771   ReceiveBuffer BeginReceive();
46772 
46773   // Must be called soon after BeginReceive().
46774   // |recv_size| is the number of valid bytes that have been written into the
46775   // buffer previously returned by BeginReceive() (the return value of recv()).
46776   // Returns false if a header > |max_capacity| is received, in which case the
46777   // caller is expected to shutdown the socket and terminate the ipc.
46778   bool EndReceive(size_t recv_size) PERFETTO_WARN_UNUSED_RESULT;
46779 
46780   // Decodes and returns the next decoded frame in the buffer if any, nullptr
46781   // if no further frames have been decoded.
46782   std::unique_ptr<Frame> PopNextFrame();
46783 
capacity() const46784   size_t capacity() const { return capacity_; }
size() const46785   size_t size() const { return size_; }
46786 
46787  private:
46788   BufferedFrameDeserializer(const BufferedFrameDeserializer&) = delete;
46789   BufferedFrameDeserializer& operator=(const BufferedFrameDeserializer&) =
46790       delete;
46791 
46792   // If a valid frame is decoded it is added to |decoded_frames_|.
46793   void DecodeFrame(const char*, size_t);
46794 
buf()46795   char* buf() { return reinterpret_cast<char*>(buf_.Get()); }
46796 
46797   base::PagedMemory buf_;
46798   const size_t capacity_ = 0;  // sizeof(|buf_|).
46799 
46800   // THe number of bytes in |buf_| that contain valid data (as a result of
46801   // EndReceive()). This is always <= |capacity_|.
46802   size_t size_ = 0;
46803 
46804   std::list<std::unique_ptr<Frame>> decoded_frames_;
46805 };
46806 
46807 }  // namespace ipc
46808 }  // namespace perfetto
46809 
46810 #endif  // SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
46811 /*
46812  * Copyright (C) 2017 The Android Open Source Project
46813  *
46814  * Licensed under the Apache License, Version 2.0 (the "License");
46815  * you may not use this file except in compliance with the License.
46816  * You may obtain a copy of the License at
46817  *
46818  *      http://www.apache.org/licenses/LICENSE-2.0
46819  *
46820  * Unless required by applicable law or agreed to in writing, software
46821  * distributed under the License is distributed on an "AS IS" BASIS,
46822  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46823  * See the License for the specific language governing permissions and
46824  * limitations under the License.
46825  */
46826 
46827 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
46828 
46829 #include <inttypes.h>
46830 
46831 #include <algorithm>
46832 #include <type_traits>
46833 #include <utility>
46834 
46835 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
46836 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
46837 
46838 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
46839 
46840 namespace perfetto {
46841 namespace ipc {
46842 
46843 namespace {
46844 
46845 // The header is just the number of bytes of the Frame protobuf message.
46846 constexpr size_t kHeaderSize = sizeof(uint32_t);
46847 }  // namespace
46848 
BufferedFrameDeserializer(size_t max_capacity)46849 BufferedFrameDeserializer::BufferedFrameDeserializer(size_t max_capacity)
46850     : capacity_(max_capacity) {
46851   PERFETTO_CHECK(max_capacity % base::GetSysPageSize() == 0);
46852   PERFETTO_CHECK(max_capacity > base::GetSysPageSize());
46853 }
46854 
46855 BufferedFrameDeserializer::~BufferedFrameDeserializer() = default;
46856 
46857 BufferedFrameDeserializer::ReceiveBuffer
BeginReceive()46858 BufferedFrameDeserializer::BeginReceive() {
46859   // Upon the first recv initialize the buffer to the max message size but
46860   // release the physical memory for all but the first page. The kernel will
46861   // automatically give us physical pages back as soon as we page-fault on them.
46862   if (!buf_.IsValid()) {
46863     PERFETTO_DCHECK(size_ == 0);
46864     // TODO(eseckler): Don't commit all of the buffer at once on Windows.
46865     buf_ = base::PagedMemory::Allocate(capacity_);
46866 
46867     // Surely we are going to use at least the first page, but we may not need
46868     // the rest for a bit.
46869     const auto page_size = base::GetSysPageSize();
46870     buf_.AdviseDontNeed(buf() + page_size, capacity_ - page_size);
46871   }
46872 
46873   PERFETTO_CHECK(capacity_ > size_);
46874   return ReceiveBuffer{buf() + size_, capacity_ - size_};
46875 }
46876 
EndReceive(size_t recv_size)46877 bool BufferedFrameDeserializer::EndReceive(size_t recv_size) {
46878   const auto page_size = base::GetSysPageSize();
46879   PERFETTO_CHECK(recv_size + size_ <= capacity_);
46880   size_ += recv_size;
46881 
46882   // At this point the contents buf_ can contain:
46883   // A) Only a fragment of the header (the size of the frame). E.g.,
46884   //    03 00 00 (the header is 4 bytes, one is missing).
46885   //
46886   // B) A header and a part of the frame. E.g.,
46887   //     05 00 00 00         11 22 33
46888   //    [ header, size=5 ]  [ Partial frame ]
46889   //
46890   // C) One or more complete header+frame. E.g.,
46891   //     05 00 00 00         11 22 33 44 55   03 00 00 00        AA BB CC
46892   //    [ header, size=5 ]  [ Whole frame ]  [ header, size=3 ] [ Whole frame ]
46893   //
46894   // D) Some complete header+frame(s) and a partial header or frame (C + A/B).
46895   //
46896   // C Is the more likely case and the one we are optimizing for. A, B, D can
46897   // happen because of the streaming nature of the socket.
46898   // The invariant of this function is that, when it returns, buf_ is either
46899   // empty (we drained all the complete frames) or starts with the header of the
46900   // next, still incomplete, frame.
46901 
46902   size_t consumed_size = 0;
46903   for (;;) {
46904     if (size_ < consumed_size + kHeaderSize)
46905       break;  // Case A, not enough data to read even the header.
46906 
46907     // Read the header into |payload_size|.
46908     uint32_t payload_size = 0;
46909     const char* rd_ptr = buf() + consumed_size;
46910     memcpy(base::AssumeLittleEndian(&payload_size), rd_ptr, kHeaderSize);
46911 
46912     // Saturate the |payload_size| to prevent overflows. The > capacity_ check
46913     // below will abort the parsing.
46914     size_t next_frame_size =
46915         std::min(static_cast<size_t>(payload_size), capacity_);
46916     next_frame_size += kHeaderSize;
46917     rd_ptr += kHeaderSize;
46918 
46919     if (size_ < consumed_size + next_frame_size) {
46920       // Case B. We got the header but not the whole frame.
46921       if (next_frame_size > capacity_) {
46922         // The caller is expected to shut down the socket and give up at this
46923         // point. If it doesn't do that and insists going on at some point it
46924         // will hit the capacity check in BeginReceive().
46925         PERFETTO_LOG("IPC Frame too large (size %zu)", next_frame_size);
46926         return false;
46927       }
46928       break;
46929     }
46930 
46931     // Case C. We got at least one header and whole frame.
46932     DecodeFrame(rd_ptr, payload_size);
46933     consumed_size += next_frame_size;
46934   }
46935 
46936   PERFETTO_DCHECK(consumed_size <= size_);
46937   if (consumed_size > 0) {
46938     // Shift out the consumed data from the buffer. In the typical case (C)
46939     // there is nothing to shift really, just setting size_ = 0 is enough.
46940     // Shifting is only for the (unlikely) case D.
46941     size_ -= consumed_size;
46942     if (size_ > 0) {
46943       // Case D. We consumed some frames but there is a leftover at the end of
46944       // the buffer. Shift out the consumed bytes, so that on the next round
46945       // |buf_| starts with the header of the next unconsumed frame.
46946       const char* move_begin = buf() + consumed_size;
46947       PERFETTO_CHECK(move_begin > buf());
46948       PERFETTO_CHECK(move_begin + size_ <= buf() + capacity_);
46949       memmove(buf(), move_begin, size_);
46950     }
46951     // If we just finished decoding a large frame that used more than one page,
46952     // release the extra memory in the buffer. Large frames should be quite
46953     // rare.
46954     if (consumed_size > page_size) {
46955       size_t size_rounded_up = (size_ / page_size + 1) * page_size;
46956       if (size_rounded_up < capacity_) {
46957         char* madvise_begin = buf() + size_rounded_up;
46958         const size_t madvise_size = capacity_ - size_rounded_up;
46959         PERFETTO_CHECK(madvise_begin > buf() + size_);
46960         PERFETTO_CHECK(madvise_begin + madvise_size <= buf() + capacity_);
46961         buf_.AdviseDontNeed(madvise_begin, madvise_size);
46962       }
46963     }
46964   }
46965   // At this point |size_| == 0 for case C, > 0 for cases A, B, D.
46966   return true;
46967 }
46968 
PopNextFrame()46969 std::unique_ptr<Frame> BufferedFrameDeserializer::PopNextFrame() {
46970   if (decoded_frames_.empty())
46971     return nullptr;
46972   std::unique_ptr<Frame> frame = std::move(decoded_frames_.front());
46973   decoded_frames_.pop_front();
46974   return frame;
46975 }
46976 
DecodeFrame(const char * data,size_t size)46977 void BufferedFrameDeserializer::DecodeFrame(const char* data, size_t size) {
46978   if (size == 0)
46979     return;
46980   std::unique_ptr<Frame> frame(new Frame);
46981   if (frame->ParseFromArray(data, size))
46982     decoded_frames_.push_back(std::move(frame));
46983 }
46984 
46985 // static
Serialize(const Frame & frame)46986 std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
46987   std::vector<uint8_t> payload = frame.SerializeAsArray();
46988   const uint32_t payload_size = static_cast<uint32_t>(payload.size());
46989   std::string buf;
46990   buf.resize(kHeaderSize + payload_size);
46991   memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
46992   memcpy(&buf[kHeaderSize], payload.data(), payload.size());
46993   return buf;
46994 }
46995 
46996 }  // namespace ipc
46997 }  // namespace perfetto
46998 // gen_amalgamated begin source: src/ipc/deferred.cc
46999 // gen_amalgamated begin header: include/perfetto/ext/ipc/deferred.h
47000 // gen_amalgamated begin header: include/perfetto/ext/ipc/async_result.h
47001 /*
47002  * Copyright (C) 2017 The Android Open Source Project
47003  *
47004  * Licensed under the Apache License, Version 2.0 (the "License");
47005  * you may not use this file except in compliance with the License.
47006  * You may obtain a copy of the License at
47007  *
47008  *      http://www.apache.org/licenses/LICENSE-2.0
47009  *
47010  * Unless required by applicable law or agreed to in writing, software
47011  * distributed under the License is distributed on an "AS IS" BASIS,
47012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47013  * See the License for the specific language governing permissions and
47014  * limitations under the License.
47015  */
47016 
47017 #ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
47018 #define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
47019 
47020 #include <memory>
47021 #include <type_traits>
47022 #include <utility>
47023 
47024 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47025 
47026 namespace perfetto {
47027 namespace ipc {
47028 
47029 // Wraps the result of an asynchronous invocation. This is the equivalent of a
47030 // std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
47031 // argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
47032 template <typename T>
47033 class AsyncResult {
47034  public:
Create()47035   static AsyncResult Create() {
47036     return AsyncResult(std::unique_ptr<T>(new T()));
47037   }
47038 
AsyncResult(std::unique_ptr<T> msg=nullptr,bool has_more=false,int fd=-1)47039   AsyncResult(std::unique_ptr<T> msg = nullptr,
47040               bool has_more = false,
47041               int fd = -1)
47042       : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
47043     static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
47044   }
47045   AsyncResult(AsyncResult&&) noexcept = default;
47046   AsyncResult& operator=(AsyncResult&&) = default;
47047 
success() const47048   bool success() const { return !!msg_; }
operator bool() const47049   explicit operator bool() const { return success(); }
47050 
has_more() const47051   bool has_more() const { return has_more_; }
set_has_more(bool has_more)47052   void set_has_more(bool has_more) { has_more_ = has_more; }
47053 
set_msg(std::unique_ptr<T> msg)47054   void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
release_msg()47055   T* release_msg() { return msg_.release(); }
operator ->()47056   T* operator->() { return msg_.get(); }
operator *()47057   T& operator*() { return *msg_; }
47058 
set_fd(int fd)47059   void set_fd(int fd) { fd_ = fd; }
fd() const47060   int fd() const { return fd_; }
47061 
47062  private:
47063   std::unique_ptr<T> msg_;
47064   bool has_more_ = false;
47065 
47066   // Optional. Only for messages that convey a file descriptor, for sharing
47067   // memory across processes.
47068   int fd_ = -1;
47069 };
47070 
47071 }  // namespace ipc
47072 }  // namespace perfetto
47073 
47074 #endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
47075 /*
47076  * Copyright (C) 2017 The Android Open Source Project
47077  *
47078  * Licensed under the Apache License, Version 2.0 (the "License");
47079  * you may not use this file except in compliance with the License.
47080  * You may obtain a copy of the License at
47081  *
47082  *      http://www.apache.org/licenses/LICENSE-2.0
47083  *
47084  * Unless required by applicable law or agreed to in writing, software
47085  * distributed under the License is distributed on an "AS IS" BASIS,
47086  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47087  * See the License for the specific language governing permissions and
47088  * limitations under the License.
47089  */
47090 
47091 #ifndef INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
47092 #define INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
47093 
47094 #include <functional>
47095 #include <memory>
47096 #include <utility>
47097 
47098 // gen_amalgamated expanded: #include "perfetto/ext/ipc/async_result.h"
47099 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47100 
47101 namespace perfetto {
47102 namespace ipc {
47103 
47104 // This class is a wrapper for a callback handling async results.
47105 // The problem this is solving is the following: For each result argument of the
47106 // methods generated from the .proto file:
47107 // - The client wants to see something on which it can Bind() a callback, which
47108 //   is invoked asynchronously once reply is received from the host.
47109 // - The host wants to expose something to user code that implements the IPC
47110 //   methods to allow them to provide an asynchronous reply back to the client.
47111 //   Eventually even more than once, for the case streaming replies.
47112 //
47113 // In both cases we want to make sure that callbacks don't get lost along the
47114 // way. To address this, this class will automatically reject the callbacks
47115 // if they are not resolved at destructor time (or the object is std::move()'d).
47116 //
47117 // The client is supposed to use this class as follows:
47118 //   class GreeterProxy {
47119 //      void SayHello(const HelloRequest&, Deferred<HelloReply> reply)
47120 //   }
47121 //  ...
47122 //  Deferred<HelloReply> reply;
47123 //  reply.Bind([] (AsyncResult<HelloReply> reply) {
47124 //    std::cout << reply.success() ? reply->message : "failure";
47125 //  });
47126 //  host_proxy_instance.SayHello(req, std::move(reply));
47127 //
47128 // The host instead is supposed to use this as follows:
47129 //   class GreeterImpl : public Greeter {
47130 //     void SayHello(const HelloRequest& req, Deferred<HelloReply> reply) {
47131 //        AsyncResult<HelloReply> reply = AsyncResult<HelloReply>::Create();
47132 //        reply->set_greeting("Hello " + req.name)
47133 //        reply.Resolve(std::move(reply));
47134 //     }
47135 //   }
47136 // Or for more complex cases, the deferred object can be std::move()'d outside
47137 // and the reply can continue asynchronously later.
47138 
47139 template <typename T>
47140 class Deferred;
47141 
47142 class DeferredBase {
47143  public:
47144   explicit DeferredBase(
47145       std::function<void(AsyncResult<ProtoMessage>)> callback = nullptr);
47146 
47147   template <typename T>
DeferredBase(Deferred<T> other)47148   explicit DeferredBase(Deferred<T> other)
47149       : callback_(std::move(other.callback_)) {}
47150 
47151   ~DeferredBase();
47152   DeferredBase(DeferredBase&&) noexcept;
47153   DeferredBase& operator=(DeferredBase&&);
47154   void Bind(std::function<void(AsyncResult<ProtoMessage>)> callback);
47155   bool IsBound() const;
47156   void Resolve(AsyncResult<ProtoMessage>);
47157   void Reject();
47158 
47159  protected:
47160   template <typename T>
47161   friend class Deferred;
47162   void Move(DeferredBase&);
47163 
47164   std::function<void(AsyncResult<ProtoMessage>)> callback_;
47165 };
47166 
47167 template <typename T>  // T : ProtoMessage subclass
47168 class Deferred : public DeferredBase {
47169  public:
Deferred(std::function<void (AsyncResult<T>)> callback=nullptr)47170   explicit Deferred(std::function<void(AsyncResult<T>)> callback = nullptr) {
47171     Bind(std::move(callback));
47172   }
47173 
47174   // This move constructor (and the similar one in DeferredBase) is meant to be
47175   // called only by the autogenerated code. The caller has to guarantee that the
47176   // moved-from and moved-to types match. The behavior is otherwise undefined.
Deferred(DeferredBase && other)47177   explicit Deferred(DeferredBase&& other) {
47178     callback_ = std::move(other.callback_);
47179     other.callback_ = nullptr;
47180   }
47181 
Bind(std::function<void (AsyncResult<T>)> callback)47182   void Bind(std::function<void(AsyncResult<T>)> callback) {
47183     if (!callback)
47184       return;
47185 
47186     // Here we need a callback adapter to downcast the callback to a generic
47187     // callback that takes an AsyncResult<ProtoMessage>, so that it can be
47188     // stored in the base class |callback_|.
47189     auto callback_adapter = [callback](
47190                                 AsyncResult<ProtoMessage> async_result_base) {
47191       // Upcast the async_result from <ProtoMessage> -> <T : ProtoMessage>.
47192       static_assert(std::is_base_of<ProtoMessage, T>::value, "T:ProtoMessage");
47193       AsyncResult<T> async_result(
47194           std::unique_ptr<T>(static_cast<T*>(async_result_base.release_msg())),
47195           async_result_base.has_more(), async_result_base.fd());
47196       callback(std::move(async_result));
47197     };
47198     DeferredBase::Bind(callback_adapter);
47199   }
47200 
47201   // If no more messages are expected, |callback_| is released.
Resolve(AsyncResult<T> async_result)47202   void Resolve(AsyncResult<T> async_result) {
47203     // Convert the |async_result| to the generic base one (T -> ProtoMessage).
47204     AsyncResult<ProtoMessage> async_result_base(
47205         std::unique_ptr<ProtoMessage>(async_result.release_msg()),
47206         async_result.has_more(), async_result.fd());
47207     DeferredBase::Resolve(std::move(async_result_base));
47208   }
47209 };
47210 
47211 }  // namespace ipc
47212 }  // namespace perfetto
47213 
47214 #endif  // INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
47215 /*
47216  * Copyright (C) 2017 The Android Open Source Project
47217  *
47218  * Licensed under the Apache License, Version 2.0 (the "License");
47219  * you may not use this file except in compliance with the License.
47220  * You may obtain a copy of the License at
47221  *
47222  *      http://www.apache.org/licenses/LICENSE-2.0
47223  *
47224  * Unless required by applicable law or agreed to in writing, software
47225  * distributed under the License is distributed on an "AS IS" BASIS,
47226  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47227  * See the License for the specific language governing permissions and
47228  * limitations under the License.
47229  */
47230 
47231 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
47232 
47233 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
47234 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
47235 
47236 namespace perfetto {
47237 namespace ipc {
47238 
DeferredBase(std::function<void (AsyncResult<ProtoMessage>)> callback)47239 DeferredBase::DeferredBase(
47240     std::function<void(AsyncResult<ProtoMessage>)> callback)
47241     : callback_(std::move(callback)) {}
47242 
~DeferredBase()47243 DeferredBase::~DeferredBase() {
47244   if (callback_)
47245     Reject();
47246 }
47247 
47248 // Can't just use "= default" here because the default move operator for
47249 // std::function doesn't necessarily swap and hence can leave a copy of the
47250 // bind state around, which is undesirable.
DeferredBase(DeferredBase && other)47251 DeferredBase::DeferredBase(DeferredBase&& other) noexcept {
47252   Move(other);
47253 }
47254 
operator =(DeferredBase && other)47255 DeferredBase& DeferredBase::operator=(DeferredBase&& other) {
47256   if (callback_)
47257     Reject();
47258   Move(other);
47259   return *this;
47260 }
47261 
Move(DeferredBase & other)47262 void DeferredBase::Move(DeferredBase& other) {
47263   callback_ = std::move(other.callback_);
47264   other.callback_ = nullptr;
47265 }
47266 
Bind(std::function<void (AsyncResult<ProtoMessage>)> callback)47267 void DeferredBase::Bind(
47268     std::function<void(AsyncResult<ProtoMessage>)> callback) {
47269   callback_ = std::move(callback);
47270 }
47271 
IsBound() const47272 bool DeferredBase::IsBound() const {
47273   return !!callback_;
47274 }
47275 
Resolve(AsyncResult<ProtoMessage> async_result)47276 void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) {
47277   if (!callback_) {
47278     PERFETTO_DFATAL("No callback set.");
47279     return;
47280   }
47281   bool has_more = async_result.has_more();
47282   callback_(std::move(async_result));
47283   if (!has_more)
47284     callback_ = nullptr;
47285 }
47286 
47287 // Resolves with a nullptr |msg_|, signalling failure to |callback_|.
Reject()47288 void DeferredBase::Reject() {
47289   Resolve(AsyncResult<ProtoMessage>());
47290 }
47291 
47292 }  // namespace ipc
47293 }  // namespace perfetto
47294 // gen_amalgamated begin source: src/ipc/virtual_destructors.cc
47295 // gen_amalgamated begin header: include/perfetto/ext/ipc/client.h
47296 /*
47297  * Copyright (C) 2017 The Android Open Source Project
47298  *
47299  * Licensed under the Apache License, Version 2.0 (the "License");
47300  * you may not use this file except in compliance with the License.
47301  * You may obtain a copy of the License at
47302  *
47303  *      http://www.apache.org/licenses/LICENSE-2.0
47304  *
47305  * Unless required by applicable law or agreed to in writing, software
47306  * distributed under the License is distributed on an "AS IS" BASIS,
47307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47308  * See the License for the specific language governing permissions and
47309  * limitations under the License.
47310  */
47311 
47312 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
47313 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
47314 
47315 #include <functional>
47316 #include <memory>
47317 
47318 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
47319 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
47320 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47321 
47322 namespace perfetto {
47323 
47324 namespace base {
47325 class TaskRunner;
47326 }  // namespace base
47327 
47328 namespace ipc {
47329 class ServiceProxy;
47330 
47331 // The client-side class that talks to the host over the socket and multiplexes
47332 // requests coming from the various autogenerated ServiceProxy stubs.
47333 // This is meant to be used by the user code as follows:
47334 // auto client = Client::CreateInstance("socket_name", task_runner);
47335 // std::unique_ptr<GreeterService> svc(new GreeterService());
47336 // client.BindService(svc);
47337 // svc.OnConnect([] () {
47338 //    svc.SayHello(..., ...);
47339 // });
47340 class Client {
47341  public:
47342   static std::unique_ptr<Client> CreateInstance(const char* socket_name,
47343                                                 bool socket_retry,
47344                                                 base::TaskRunner*);
47345   virtual ~Client();
47346 
47347   virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;
47348 
47349   // There is no need to call this method explicitly. Destroying the
47350   // ServiceProxy instance is sufficient and will automatically unbind it. This
47351   // method is exposed only for the ServiceProxy destructor.
47352   virtual void UnbindService(ServiceID) = 0;
47353 
47354   // Returns (with move semantics) the last file descriptor received on the IPC
47355   // channel. No buffering is performed: if a service sends two file descriptors
47356   // and the caller doesn't read them immediately, the first one will be
47357   // automatically closed when the second is received (and will hit a DCHECK in
47358   // debug builds).
47359   virtual base::ScopedFile TakeReceivedFD() = 0;
47360 };
47361 
47362 }  // namespace ipc
47363 }  // namespace perfetto
47364 
47365 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
47366 // gen_amalgamated begin header: include/perfetto/ext/ipc/host.h
47367 /*
47368  * Copyright (C) 2017 The Android Open Source Project
47369  *
47370  * Licensed under the Apache License, Version 2.0 (the "License");
47371  * you may not use this file except in compliance with the License.
47372  * You may obtain a copy of the License at
47373  *
47374  *      http://www.apache.org/licenses/LICENSE-2.0
47375  *
47376  * Unless required by applicable law or agreed to in writing, software
47377  * distributed under the License is distributed on an "AS IS" BASIS,
47378  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47379  * See the License for the specific language governing permissions and
47380  * limitations under the License.
47381  */
47382 
47383 #ifndef INCLUDE_PERFETTO_EXT_IPC_HOST_H_
47384 #define INCLUDE_PERFETTO_EXT_IPC_HOST_H_
47385 
47386 #include <memory>
47387 
47388 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
47389 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47390 
47391 namespace perfetto {
47392 
47393 namespace base {
47394 class TaskRunner;
47395 }  // namespace base
47396 
47397 namespace ipc {
47398 
47399 class Service;
47400 
47401 // The host-side of the IPC layer. This class acts as a registry and request
47402 // dispatcher. It listen on the UnixSocket |socket_name| for incoming requests
47403 // (coming Client instances) and dispatches their requests to the various
47404 // Services exposed.
47405 class Host {
47406  public:
47407   // Creates an instance and starts listening on the given |socket_name|.
47408   // Returns nullptr if listening on the socket fails.
47409   static std::unique_ptr<Host> CreateInstance(const char* socket_name,
47410                                               base::TaskRunner*);
47411 
47412   // Like the above but takes a file descriptor to a pre-bound unix socket.
47413   // Returns nullptr if listening on the socket fails.
47414   static std::unique_ptr<Host> CreateInstance(base::ScopedFile socket_fd,
47415                                               base::TaskRunner*);
47416 
47417   virtual ~Host();
47418 
47419   // Registers a new service and makes it available to remote IPC peers.
47420   // All the exposed Service instances will be destroyed when destroying the
47421   // Host instance if ExposeService succeeds and returns true, or immediately
47422   // after the call in case of failure.
47423   // Returns true if the register has been successfully registered, false in
47424   // case of errors (e.g., another service with the same name is already
47425   // registered).
47426   virtual bool ExposeService(std::unique_ptr<Service>) = 0;
47427 };
47428 
47429 }  // namespace ipc
47430 }  // namespace perfetto
47431 
47432 #endif  // INCLUDE_PERFETTO_EXT_IPC_HOST_H_
47433 // gen_amalgamated begin header: include/perfetto/ext/ipc/service.h
47434 // gen_amalgamated begin header: include/perfetto/ext/ipc/client_info.h
47435 /*
47436  * Copyright (C) 2017 The Android Open Source Project
47437  *
47438  * Licensed under the Apache License, Version 2.0 (the "License");
47439  * you may not use this file except in compliance with the License.
47440  * You may obtain a copy of the License at
47441  *
47442  *      http://www.apache.org/licenses/LICENSE-2.0
47443  *
47444  * Unless required by applicable law or agreed to in writing, software
47445  * distributed under the License is distributed on an "AS IS" BASIS,
47446  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47447  * See the License for the specific language governing permissions and
47448  * limitations under the License.
47449  */
47450 
47451 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
47452 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
47453 
47454 #include <unistd.h>
47455 
47456 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
47457 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47458 
47459 namespace perfetto {
47460 namespace ipc {
47461 
47462 // Passed to Service(s) to identify remote clients.
47463 class ClientInfo {
47464  public:
47465   ClientInfo() = default;
ClientInfo(ClientID client_id,uid_t uid)47466   ClientInfo(ClientID client_id, uid_t uid)
47467       : client_id_(client_id), uid_(uid) {}
47468 
operator ==(const ClientInfo & other) const47469   bool operator==(const ClientInfo& other) const {
47470     return (client_id_ == other.client_id_ && uid_ == other.uid_);
47471   }
operator !=(const ClientInfo & other) const47472   bool operator!=(const ClientInfo& other) const { return !(*this == other); }
47473 
47474   // For map<> and other sorted containers.
operator <(const ClientInfo & other) const47475   bool operator<(const ClientInfo& other) const {
47476     PERFETTO_DCHECK(client_id_ != other.client_id_ || *this == other);
47477     return client_id_ < other.client_id_;
47478   }
47479 
is_valid() const47480   bool is_valid() const { return client_id_ != 0; }
47481 
47482   // A monotonic counter.
client_id() const47483   ClientID client_id() const { return client_id_; }
47484 
47485   // Posix User ID. Comes from the kernel, can be trusted.
uid() const47486   uid_t uid() const { return uid_; }
47487 
47488  private:
47489   ClientID client_id_ = 0;
47490   uid_t uid_ = kInvalidUid;
47491 };
47492 
47493 }  // namespace ipc
47494 }  // namespace perfetto
47495 
47496 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
47497 /*
47498  * Copyright (C) 2017 The Android Open Source Project
47499  *
47500  * Licensed under the Apache License, Version 2.0 (the "License");
47501  * you may not use this file except in compliance with the License.
47502  * You may obtain a copy of the License at
47503  *
47504  *      http://www.apache.org/licenses/LICENSE-2.0
47505  *
47506  * Unless required by applicable law or agreed to in writing, software
47507  * distributed under the License is distributed on an "AS IS" BASIS,
47508  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47509  * See the License for the specific language governing permissions and
47510  * limitations under the License.
47511  */
47512 
47513 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
47514 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
47515 
47516 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
47517 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
47518 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client_info.h"
47519 
47520 namespace perfetto {
47521 namespace ipc {
47522 
47523 class ServiceDescriptor;
47524 
47525 // The base class for all the autogenerated host-side service interfaces.
47526 class Service {
47527  public:
47528   virtual ~Service();
47529 
47530   // Overridden by the auto-generated class. Provides the list of methods and
47531   // the protobuf (de)serialization functions for their arguments.
47532   virtual const ServiceDescriptor& GetDescriptor() = 0;
47533 
47534   // Invoked when a remote client disconnects. Use client_info() to obtain
47535   // details about the client that disconnected.
OnClientDisconnected()47536   virtual void OnClientDisconnected() {}
47537 
47538   // Returns the ClientInfo for the current IPC request. Returns an invalid
47539   // ClientInfo if called outside the scope of an IPC method.
client_info()47540   const ClientInfo& client_info() {
47541     PERFETTO_DCHECK(client_info_.is_valid());
47542     return client_info_;
47543   }
47544 
TakeReceivedFD()47545   base::ScopedFile TakeReceivedFD() {
47546     if (received_fd_)
47547       return std::move(*received_fd_);
47548     return base::ScopedFile();
47549   }
47550 
47551  private:
47552   friend class HostImpl;
47553   ClientInfo client_info_;
47554   // This is a pointer because the received fd needs to remain owned by the
47555   // ClientConnection, as we will provide it to all method invocations
47556   // for that client until one of them calls Service::TakeReceivedFD.
47557   //
47558   // Different clients might have sent different FDs so this cannot be owned
47559   // here.
47560   //
47561   // Note that this means that there can always only be one outstanding
47562   // invocation per client that supplies an FD and the client needs to
47563   // wait for this one to return before calling another one.
47564   base::ScopedFile* received_fd_;
47565 };
47566 
47567 }  // namespace ipc
47568 }  // namespace perfetto
47569 
47570 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
47571 // gen_amalgamated begin header: include/perfetto/ext/ipc/service_proxy.h
47572 /*
47573  * Copyright (C) 2017 The Android Open Source Project
47574  *
47575  * Licensed under the Apache License, Version 2.0 (the "License");
47576  * you may not use this file except in compliance with the License.
47577  * You may obtain a copy of the License at
47578  *
47579  *      http://www.apache.org/licenses/LICENSE-2.0
47580  *
47581  * Unless required by applicable law or agreed to in writing, software
47582  * distributed under the License is distributed on an "AS IS" BASIS,
47583  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47584  * See the License for the specific language governing permissions and
47585  * limitations under the License.
47586  */
47587 
47588 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
47589 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
47590 
47591 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47592 
47593 #include <assert.h>
47594 
47595 #include <functional>
47596 #include <map>
47597 #include <memory>
47598 #include <string>
47599 
47600 // gen_amalgamated expanded: #include "perfetto/base/export.h"
47601 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
47602 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
47603 
47604 namespace perfetto {
47605 namespace ipc {
47606 
47607 class Client;
47608 class ServiceDescriptor;
47609 
47610 // The base class for the client-side autogenerated stubs that forward method
47611 // invocations to the host. All the methods of this class are meant to be called
47612 // only by the autogenerated code.
47613 class PERFETTO_EXPORT ServiceProxy {
47614  public:
47615   class EventListener {
47616    public:
47617     virtual ~EventListener();
47618 
47619     // Called once after Client::BindService() if the ServiceProxy has been
47620     // successfully bound to the host. It is possible to start sending IPC
47621     // requests soon after this.
OnConnect()47622     virtual void OnConnect() {}
47623 
47624     // Called if the connection fails to be established or drops after having
47625     // been established.
OnDisconnect()47626     virtual void OnDisconnect() {}
47627   };
47628 
47629   // Guarantees that no callback will happen after this object has been
47630   // destroyed. The caller has to guarantee that the |event_listener| stays
47631   // alive at least as long as the ServiceProxy instance.
47632   explicit ServiceProxy(EventListener*);
47633   virtual ~ServiceProxy();
47634 
47635   void InitializeBinding(base::WeakPtr<Client>,
47636                          ServiceID,
47637                          std::map<std::string, MethodID>);
47638 
47639   // Called by the IPC methods in the autogenerated classes.
47640   void BeginInvoke(const std::string& method_name,
47641                    const ProtoMessage& request,
47642                    DeferredBase reply,
47643                    int fd = -1);
47644 
47645   // Called by ClientImpl.
47646   // |reply_args| == nullptr means request failure.
47647   void EndInvoke(RequestID,
47648                  std::unique_ptr<ProtoMessage> reply_arg,
47649                  bool has_more);
47650 
47651   // Called by ClientImpl.
47652   void OnConnect(bool success);
47653   void OnDisconnect();
connected() const47654   bool connected() const { return service_id_ != 0; }
47655 
47656   base::WeakPtr<ServiceProxy> GetWeakPtr() const;
47657 
47658   // Implemented by the autogenerated class.
47659   virtual const ServiceDescriptor& GetDescriptor() = 0;
47660 
47661  private:
47662   base::WeakPtr<Client> client_;
47663   ServiceID service_id_ = 0;
47664   std::map<std::string, MethodID> remote_method_ids_;
47665   std::map<RequestID, DeferredBase> pending_callbacks_;
47666   EventListener* const event_listener_;
47667   base::WeakPtrFactory<ServiceProxy> weak_ptr_factory_;  // Keep last.
47668 };
47669 
47670 }  // namespace ipc
47671 }  // namespace perfetto
47672 
47673 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
47674 /*
47675  * Copyright (C) 2018 The Android Open Source Project
47676  *
47677  * Licensed under the Apache License, Version 2.0 (the "License");
47678  * you may not use this file except in compliance with the License.
47679  * You may obtain a copy of the License at
47680  *
47681  *      http://www.apache.org/licenses/LICENSE-2.0
47682  *
47683  * Unless required by applicable law or agreed to in writing, software
47684  * distributed under the License is distributed on an "AS IS" BASIS,
47685  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47686  * See the License for the specific language governing permissions and
47687  * limitations under the License.
47688  */
47689 
47690 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
47691 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
47692 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
47693 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
47694 
47695 // This translation unit contains the definitions for the destructor of pure
47696 // virtual interfaces for the current build target. The alternative would be
47697 // introducing a one-liner .cc file for each pure virtual interface, which is
47698 // overkill. This is for compliance with -Wweak-vtables.
47699 
47700 namespace perfetto {
47701 namespace ipc {
47702 
47703 Client::~Client() = default;
47704 Host::~Host() = default;
47705 Service::~Service() = default;
47706 ServiceProxy::EventListener::~EventListener() = default;
47707 
47708 }  // namespace ipc
47709 }  // namespace perfetto
47710 // gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.ipc.cc
47711 // gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.ipc.h
47712 // gen_amalgamated begin header: include/perfetto/ext/ipc/service_descriptor.h
47713 /*
47714  * Copyright (C) 2017 The Android Open Source Project
47715  *
47716  * Licensed under the Apache License, Version 2.0 (the "License");
47717  * you may not use this file except in compliance with the License.
47718  * You may obtain a copy of the License at
47719  *
47720  *      http://www.apache.org/licenses/LICENSE-2.0
47721  *
47722  * Unless required by applicable law or agreed to in writing, software
47723  * distributed under the License is distributed on an "AS IS" BASIS,
47724  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47725  * See the License for the specific language governing permissions and
47726  * limitations under the License.
47727  */
47728 
47729 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
47730 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
47731 
47732 #include <functional>
47733 #include <string>
47734 #include <utility>
47735 #include <vector>
47736 
47737 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47738 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
47739 
47740 namespace perfetto {
47741 namespace ipc {
47742 
47743 class Service;
47744 
47745 // This is a pure data structure which holds factory methods and strings for the
47746 // services and their methods that get generated in the .h/.cc files.
47747 // Each autogenerated class has a GetDescriptor() method that returns one
47748 // instance of these and allows both client and hosts to map service and method
47749 // names to IDs and provide function pointers to the protobuf decoder fuctions.
47750 class ServiceDescriptor {
47751  public:
47752   struct Method {
47753     const char* name;
47754 
47755     // DecoderFunc is pointer to a function that takes a string in input
47756     // containing protobuf encoded data and returns a decoded protobuf message.
47757     using DecoderFunc = std::unique_ptr<ProtoMessage> (*)(const std::string&);
47758 
47759     // Function pointer to decode the request argument of the method.
47760     DecoderFunc request_proto_decoder;
47761 
47762     // Function pointer to decoded the reply argument of the method.
47763     DecoderFunc reply_proto_decoder;
47764 
47765     // Function pointer that dispatches the generic request to the corresponding
47766     // method implementation.
47767     using InvokerFunc = void (*)(Service*,
47768                                  const ProtoMessage& /* request_args */,
47769                                  DeferredBase /* deferred_reply */);
47770     InvokerFunc invoker;
47771   };
47772 
47773   const char* service_name = nullptr;
47774 
47775   // Note that methods order is not stable. Client and Host might have different
47776   // method indexes, depending on their versions. The Client can't just rely
47777   // on the indexes and has to keep a [string -> remote index] translation map.
47778   std::vector<Method> methods;
47779 };
47780 
47781 }  // namespace ipc
47782 }  // namespace perfetto
47783 
47784 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
47785 // DO NOT EDIT. Autogenerated by Perfetto IPC
47786 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
47787 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
47788 
47789 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
47790 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
47791 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
47792 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
47793 
47794 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
47795 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
47796 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
47797 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
47798 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
47799 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
47800 
47801 namespace perfetto {
47802 namespace protos {
47803 namespace gen {
47804 
47805 class ConsumerPort : public ::perfetto::ipc::Service {
47806  private:
47807   static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
47808 
47809  public:
47810   ~ConsumerPort() override;
47811 
47812   static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
47813 
47814   // Service implementation.
47815   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
47816 
47817   // Methods from the .proto file
47818   using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
47819   virtual void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse) = 0;
47820 
47821   using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
47822   virtual void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse) = 0;
47823 
47824   using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
47825   virtual void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse) = 0;
47826 
47827   using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
47828   virtual void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse) = 0;
47829 
47830   using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
47831   virtual void Flush(const FlushRequest&, DeferredFlushResponse) = 0;
47832 
47833   using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
47834   virtual void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse) = 0;
47835 
47836   using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
47837   virtual void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse) = 0;
47838 
47839   using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
47840   virtual void Detach(const DetachRequest&, DeferredDetachResponse) = 0;
47841 
47842   using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
47843   virtual void Attach(const AttachRequest&, DeferredAttachResponse) = 0;
47844 
47845   using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
47846   virtual void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse) = 0;
47847 
47848   using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
47849   virtual void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse) = 0;
47850 
47851   using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
47852   virtual void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse) = 0;
47853 
47854   using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
47855   virtual void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse) = 0;
47856 
47857 };
47858 
47859 
47860 class ConsumerPortProxy : public ::perfetto::ipc::ServiceProxy {
47861  public:
47862    explicit ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
47863    ~ConsumerPortProxy() override;
47864 
47865   // ServiceProxy implementation.
47866   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
47867 
47868   // Methods from the .proto file
47869   using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
47870   void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse, int fd = -1);
47871 
47872   using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
47873   void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse, int fd = -1);
47874 
47875   using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
47876   void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse, int fd = -1);
47877 
47878   using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
47879   void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse, int fd = -1);
47880 
47881   using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
47882   void Flush(const FlushRequest&, DeferredFlushResponse, int fd = -1);
47883 
47884   using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
47885   void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse, int fd = -1);
47886 
47887   using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
47888   void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse, int fd = -1);
47889 
47890   using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
47891   void Detach(const DetachRequest&, DeferredDetachResponse, int fd = -1);
47892 
47893   using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
47894   void Attach(const AttachRequest&, DeferredAttachResponse, int fd = -1);
47895 
47896   using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
47897   void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse, int fd = -1);
47898 
47899   using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
47900   void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse, int fd = -1);
47901 
47902   using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
47903   void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse, int fd = -1);
47904 
47905   using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
47906   void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse, int fd = -1);
47907 
47908 };
47909 
47910 }  // namespace perfetto
47911 }  // namespace protos
47912 }  // namespace gen
47913 
47914 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
47915 // gen_amalgamated begin header: include/perfetto/ext/ipc/codegen_helpers.h
47916 /*
47917  * Copyright (C) 2017 The Android Open Source Project
47918  *
47919  * Licensed under the Apache License, Version 2.0 (the "License");
47920  * you may not use this file except in compliance with the License.
47921  * You may obtain a copy of the License at
47922  *
47923  *      http://www.apache.org/licenses/LICENSE-2.0
47924  *
47925  * Unless required by applicable law or agreed to in writing, software
47926  * distributed under the License is distributed on an "AS IS" BASIS,
47927  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47928  * See the License for the specific language governing permissions and
47929  * limitations under the License.
47930  */
47931 
47932 // This file is only meant to be included in autogenerated .cc files.
47933 
47934 #ifndef INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
47935 #define INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
47936 
47937 #include <memory>
47938 
47939 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
47940 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
47941 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
47942 
47943 // A templated protobuf message decoder. Returns nullptr in case of failure.
47944 template <typename T>
_IPC_Decoder(const std::string & proto_data)47945 ::std::unique_ptr<::perfetto::ipc::ProtoMessage> _IPC_Decoder(
47946     const std::string& proto_data) {
47947   ::std::unique_ptr<::perfetto::ipc::ProtoMessage> msg(new T());
47948   if (msg->ParseFromString(proto_data))
47949     return msg;
47950   return nullptr;
47951 }
47952 
47953 // Templated method dispatcher. Used to obtain a function pointer to a given
47954 // IPC method (Method) of a given service (TSvc) that can be invoked by the
47955 // host-side machinery starting from a generic Service pointer and a generic
47956 // ProtoMessage request argument.
47957 template <typename TSvc,    // Type of the actual Service subclass.
47958           typename TReq,    // Type of the request argument.
47959           typename TReply,  // Type of the reply argument.
47960           void (TSvc::*Method)(const TReq&, ::perfetto::ipc::Deferred<TReply>)>
_IPC_Invoker(::perfetto::ipc::Service * s,const::perfetto::ipc::ProtoMessage & req,::perfetto::ipc::DeferredBase reply)47961 void _IPC_Invoker(::perfetto::ipc::Service* s,
47962                   const ::perfetto::ipc::ProtoMessage& req,
47963                   ::perfetto::ipc::DeferredBase reply) {
47964   (*static_cast<TSvc*>(s).*Method)(
47965       static_cast<const TReq&>(req),
47966       ::perfetto::ipc::Deferred<TReply>(::std::move(reply)));
47967 }
47968 
47969 #endif  // INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
47970 // DO NOT EDIT. Autogenerated by Perfetto IPC
47971 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
47972 // gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
47973 
47974 #include <memory>
47975 
47976 namespace perfetto {
47977 namespace protos {
47978 namespace gen {
NewDescriptor()47979 ::perfetto::ipc::ServiceDescriptor* ConsumerPort::NewDescriptor() {
47980   auto* desc = new ::perfetto::ipc::ServiceDescriptor();
47981   desc->service_name = "ConsumerPort";
47982 
47983   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
47984      "EnableTracing",
47985      &_IPC_Decoder<EnableTracingRequest>,
47986      &_IPC_Decoder<EnableTracingResponse>,
47987      &_IPC_Invoker<ConsumerPort, EnableTracingRequest, EnableTracingResponse, &ConsumerPort::EnableTracing>});
47988 
47989   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
47990      "DisableTracing",
47991      &_IPC_Decoder<DisableTracingRequest>,
47992      &_IPC_Decoder<DisableTracingResponse>,
47993      &_IPC_Invoker<ConsumerPort, DisableTracingRequest, DisableTracingResponse, &ConsumerPort::DisableTracing>});
47994 
47995   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
47996      "ReadBuffers",
47997      &_IPC_Decoder<ReadBuffersRequest>,
47998      &_IPC_Decoder<ReadBuffersResponse>,
47999      &_IPC_Invoker<ConsumerPort, ReadBuffersRequest, ReadBuffersResponse, &ConsumerPort::ReadBuffers>});
48000 
48001   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48002      "FreeBuffers",
48003      &_IPC_Decoder<FreeBuffersRequest>,
48004      &_IPC_Decoder<FreeBuffersResponse>,
48005      &_IPC_Invoker<ConsumerPort, FreeBuffersRequest, FreeBuffersResponse, &ConsumerPort::FreeBuffers>});
48006 
48007   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48008      "Flush",
48009      &_IPC_Decoder<FlushRequest>,
48010      &_IPC_Decoder<FlushResponse>,
48011      &_IPC_Invoker<ConsumerPort, FlushRequest, FlushResponse, &ConsumerPort::Flush>});
48012 
48013   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48014      "StartTracing",
48015      &_IPC_Decoder<StartTracingRequest>,
48016      &_IPC_Decoder<StartTracingResponse>,
48017      &_IPC_Invoker<ConsumerPort, StartTracingRequest, StartTracingResponse, &ConsumerPort::StartTracing>});
48018 
48019   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48020      "ChangeTraceConfig",
48021      &_IPC_Decoder<ChangeTraceConfigRequest>,
48022      &_IPC_Decoder<ChangeTraceConfigResponse>,
48023      &_IPC_Invoker<ConsumerPort, ChangeTraceConfigRequest, ChangeTraceConfigResponse, &ConsumerPort::ChangeTraceConfig>});
48024 
48025   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48026      "Detach",
48027      &_IPC_Decoder<DetachRequest>,
48028      &_IPC_Decoder<DetachResponse>,
48029      &_IPC_Invoker<ConsumerPort, DetachRequest, DetachResponse, &ConsumerPort::Detach>});
48030 
48031   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48032      "Attach",
48033      &_IPC_Decoder<AttachRequest>,
48034      &_IPC_Decoder<AttachResponse>,
48035      &_IPC_Invoker<ConsumerPort, AttachRequest, AttachResponse, &ConsumerPort::Attach>});
48036 
48037   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48038      "GetTraceStats",
48039      &_IPC_Decoder<GetTraceStatsRequest>,
48040      &_IPC_Decoder<GetTraceStatsResponse>,
48041      &_IPC_Invoker<ConsumerPort, GetTraceStatsRequest, GetTraceStatsResponse, &ConsumerPort::GetTraceStats>});
48042 
48043   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48044      "ObserveEvents",
48045      &_IPC_Decoder<ObserveEventsRequest>,
48046      &_IPC_Decoder<ObserveEventsResponse>,
48047      &_IPC_Invoker<ConsumerPort, ObserveEventsRequest, ObserveEventsResponse, &ConsumerPort::ObserveEvents>});
48048 
48049   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48050      "QueryServiceState",
48051      &_IPC_Decoder<QueryServiceStateRequest>,
48052      &_IPC_Decoder<QueryServiceStateResponse>,
48053      &_IPC_Invoker<ConsumerPort, QueryServiceStateRequest, QueryServiceStateResponse, &ConsumerPort::QueryServiceState>});
48054 
48055   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48056      "QueryCapabilities",
48057      &_IPC_Decoder<QueryCapabilitiesRequest>,
48058      &_IPC_Decoder<QueryCapabilitiesResponse>,
48059      &_IPC_Invoker<ConsumerPort, QueryCapabilitiesRequest, QueryCapabilitiesResponse, &ConsumerPort::QueryCapabilities>});
48060   desc->methods.shrink_to_fit();
48061   return desc;
48062 }
48063 
48064 
GetDescriptorStatic()48065 const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptorStatic() {
48066   static auto* instance = NewDescriptor();
48067   return *instance;
48068 }
48069 
48070 // Host-side definitions.
48071 ConsumerPort::~ConsumerPort() = default;
48072 
GetDescriptor()48073 const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptor() {
48074   return GetDescriptorStatic();
48075 }
48076 
48077 // Client-side definitions.
ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener * event_listener)48078 ConsumerPortProxy::ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
48079     : ::perfetto::ipc::ServiceProxy(event_listener) {}
48080 
48081 ConsumerPortProxy::~ConsumerPortProxy() = default;
48082 
GetDescriptor()48083 const ::perfetto::ipc::ServiceDescriptor& ConsumerPortProxy::GetDescriptor() {
48084   return ConsumerPort::GetDescriptorStatic();
48085 }
48086 
EnableTracing(const EnableTracingRequest & request,DeferredEnableTracingResponse reply,int fd)48087 void ConsumerPortProxy::EnableTracing(const EnableTracingRequest& request, DeferredEnableTracingResponse reply, int fd) {
48088   BeginInvoke("EnableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48089               fd);
48090 }
48091 
DisableTracing(const DisableTracingRequest & request,DeferredDisableTracingResponse reply,int fd)48092 void ConsumerPortProxy::DisableTracing(const DisableTracingRequest& request, DeferredDisableTracingResponse reply, int fd) {
48093   BeginInvoke("DisableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48094               fd);
48095 }
48096 
ReadBuffers(const ReadBuffersRequest & request,DeferredReadBuffersResponse reply,int fd)48097 void ConsumerPortProxy::ReadBuffers(const ReadBuffersRequest& request, DeferredReadBuffersResponse reply, int fd) {
48098   BeginInvoke("ReadBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48099               fd);
48100 }
48101 
FreeBuffers(const FreeBuffersRequest & request,DeferredFreeBuffersResponse reply,int fd)48102 void ConsumerPortProxy::FreeBuffers(const FreeBuffersRequest& request, DeferredFreeBuffersResponse reply, int fd) {
48103   BeginInvoke("FreeBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48104               fd);
48105 }
48106 
Flush(const FlushRequest & request,DeferredFlushResponse reply,int fd)48107 void ConsumerPortProxy::Flush(const FlushRequest& request, DeferredFlushResponse reply, int fd) {
48108   BeginInvoke("Flush", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48109               fd);
48110 }
48111 
StartTracing(const StartTracingRequest & request,DeferredStartTracingResponse reply,int fd)48112 void ConsumerPortProxy::StartTracing(const StartTracingRequest& request, DeferredStartTracingResponse reply, int fd) {
48113   BeginInvoke("StartTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48114               fd);
48115 }
48116 
ChangeTraceConfig(const ChangeTraceConfigRequest & request,DeferredChangeTraceConfigResponse reply,int fd)48117 void ConsumerPortProxy::ChangeTraceConfig(const ChangeTraceConfigRequest& request, DeferredChangeTraceConfigResponse reply, int fd) {
48118   BeginInvoke("ChangeTraceConfig", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48119               fd);
48120 }
48121 
Detach(const DetachRequest & request,DeferredDetachResponse reply,int fd)48122 void ConsumerPortProxy::Detach(const DetachRequest& request, DeferredDetachResponse reply, int fd) {
48123   BeginInvoke("Detach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48124               fd);
48125 }
48126 
Attach(const AttachRequest & request,DeferredAttachResponse reply,int fd)48127 void ConsumerPortProxy::Attach(const AttachRequest& request, DeferredAttachResponse reply, int fd) {
48128   BeginInvoke("Attach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48129               fd);
48130 }
48131 
GetTraceStats(const GetTraceStatsRequest & request,DeferredGetTraceStatsResponse reply,int fd)48132 void ConsumerPortProxy::GetTraceStats(const GetTraceStatsRequest& request, DeferredGetTraceStatsResponse reply, int fd) {
48133   BeginInvoke("GetTraceStats", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48134               fd);
48135 }
48136 
ObserveEvents(const ObserveEventsRequest & request,DeferredObserveEventsResponse reply,int fd)48137 void ConsumerPortProxy::ObserveEvents(const ObserveEventsRequest& request, DeferredObserveEventsResponse reply, int fd) {
48138   BeginInvoke("ObserveEvents", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48139               fd);
48140 }
48141 
QueryServiceState(const QueryServiceStateRequest & request,DeferredQueryServiceStateResponse reply,int fd)48142 void ConsumerPortProxy::QueryServiceState(const QueryServiceStateRequest& request, DeferredQueryServiceStateResponse reply, int fd) {
48143   BeginInvoke("QueryServiceState", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48144               fd);
48145 }
48146 
QueryCapabilities(const QueryCapabilitiesRequest & request,DeferredQueryCapabilitiesResponse reply,int fd)48147 void ConsumerPortProxy::QueryCapabilities(const QueryCapabilitiesRequest& request, DeferredQueryCapabilitiesResponse reply, int fd) {
48148   BeginInvoke("QueryCapabilities", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48149               fd);
48150 }
48151 }  // namespace perfetto
48152 }  // namespace protos
48153 }  // namespace gen
48154 // gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.ipc.cc
48155 // gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.ipc.h
48156 // DO NOT EDIT. Autogenerated by Perfetto IPC
48157 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
48158 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
48159 
48160 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
48161 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
48162 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
48163 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
48164 
48165 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
48166 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
48167 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
48168 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
48169 
48170 namespace perfetto {
48171 namespace protos {
48172 namespace gen {
48173 
48174 class ProducerPort : public ::perfetto::ipc::Service {
48175  private:
48176   static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
48177 
48178  public:
48179   ~ProducerPort() override;
48180 
48181   static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
48182 
48183   // Service implementation.
48184   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
48185 
48186   // Methods from the .proto file
48187   using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
48188   virtual void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse) = 0;
48189 
48190   using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
48191   virtual void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse) = 0;
48192 
48193   using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
48194   virtual void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse) = 0;
48195 
48196   using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
48197   virtual void CommitData(const CommitDataRequest&, DeferredCommitDataResponse) = 0;
48198 
48199   using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
48200   virtual void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse) = 0;
48201 
48202   using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
48203   virtual void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse) = 0;
48204 
48205   using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
48206   virtual void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse) = 0;
48207 
48208   using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
48209   virtual void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse) = 0;
48210 
48211   using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
48212   virtual void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse) = 0;
48213 
48214   using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
48215   virtual void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse) = 0;
48216 
48217   using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
48218   virtual void Sync(const SyncRequest&, DeferredSyncResponse) = 0;
48219 
48220 };
48221 
48222 
48223 class ProducerPortProxy : public ::perfetto::ipc::ServiceProxy {
48224  public:
48225    explicit ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
48226    ~ProducerPortProxy() override;
48227 
48228   // ServiceProxy implementation.
48229   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
48230 
48231   // Methods from the .proto file
48232   using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
48233   void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse, int fd = -1);
48234 
48235   using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
48236   void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse, int fd = -1);
48237 
48238   using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
48239   void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse, int fd = -1);
48240 
48241   using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
48242   void CommitData(const CommitDataRequest&, DeferredCommitDataResponse, int fd = -1);
48243 
48244   using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
48245   void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse, int fd = -1);
48246 
48247   using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
48248   void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse, int fd = -1);
48249 
48250   using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
48251   void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse, int fd = -1);
48252 
48253   using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
48254   void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse, int fd = -1);
48255 
48256   using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
48257   void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse, int fd = -1);
48258 
48259   using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
48260   void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse, int fd = -1);
48261 
48262   using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
48263   void Sync(const SyncRequest&, DeferredSyncResponse, int fd = -1);
48264 
48265 };
48266 
48267 }  // namespace perfetto
48268 }  // namespace protos
48269 }  // namespace gen
48270 
48271 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
48272 // DO NOT EDIT. Autogenerated by Perfetto IPC
48273 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
48274 // gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
48275 
48276 #include <memory>
48277 
48278 namespace perfetto {
48279 namespace protos {
48280 namespace gen {
NewDescriptor()48281 ::perfetto::ipc::ServiceDescriptor* ProducerPort::NewDescriptor() {
48282   auto* desc = new ::perfetto::ipc::ServiceDescriptor();
48283   desc->service_name = "ProducerPort";
48284 
48285   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48286      "InitializeConnection",
48287      &_IPC_Decoder<InitializeConnectionRequest>,
48288      &_IPC_Decoder<InitializeConnectionResponse>,
48289      &_IPC_Invoker<ProducerPort, InitializeConnectionRequest, InitializeConnectionResponse, &ProducerPort::InitializeConnection>});
48290 
48291   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48292      "RegisterDataSource",
48293      &_IPC_Decoder<RegisterDataSourceRequest>,
48294      &_IPC_Decoder<RegisterDataSourceResponse>,
48295      &_IPC_Invoker<ProducerPort, RegisterDataSourceRequest, RegisterDataSourceResponse, &ProducerPort::RegisterDataSource>});
48296 
48297   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48298      "UnregisterDataSource",
48299      &_IPC_Decoder<UnregisterDataSourceRequest>,
48300      &_IPC_Decoder<UnregisterDataSourceResponse>,
48301      &_IPC_Invoker<ProducerPort, UnregisterDataSourceRequest, UnregisterDataSourceResponse, &ProducerPort::UnregisterDataSource>});
48302 
48303   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48304      "CommitData",
48305      &_IPC_Decoder<CommitDataRequest>,
48306      &_IPC_Decoder<CommitDataResponse>,
48307      &_IPC_Invoker<ProducerPort, CommitDataRequest, CommitDataResponse, &ProducerPort::CommitData>});
48308 
48309   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48310      "GetAsyncCommand",
48311      &_IPC_Decoder<GetAsyncCommandRequest>,
48312      &_IPC_Decoder<GetAsyncCommandResponse>,
48313      &_IPC_Invoker<ProducerPort, GetAsyncCommandRequest, GetAsyncCommandResponse, &ProducerPort::GetAsyncCommand>});
48314 
48315   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48316      "RegisterTraceWriter",
48317      &_IPC_Decoder<RegisterTraceWriterRequest>,
48318      &_IPC_Decoder<RegisterTraceWriterResponse>,
48319      &_IPC_Invoker<ProducerPort, RegisterTraceWriterRequest, RegisterTraceWriterResponse, &ProducerPort::RegisterTraceWriter>});
48320 
48321   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48322      "UnregisterTraceWriter",
48323      &_IPC_Decoder<UnregisterTraceWriterRequest>,
48324      &_IPC_Decoder<UnregisterTraceWriterResponse>,
48325      &_IPC_Invoker<ProducerPort, UnregisterTraceWriterRequest, UnregisterTraceWriterResponse, &ProducerPort::UnregisterTraceWriter>});
48326 
48327   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48328      "NotifyDataSourceStarted",
48329      &_IPC_Decoder<NotifyDataSourceStartedRequest>,
48330      &_IPC_Decoder<NotifyDataSourceStartedResponse>,
48331      &_IPC_Invoker<ProducerPort, NotifyDataSourceStartedRequest, NotifyDataSourceStartedResponse, &ProducerPort::NotifyDataSourceStarted>});
48332 
48333   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48334      "NotifyDataSourceStopped",
48335      &_IPC_Decoder<NotifyDataSourceStoppedRequest>,
48336      &_IPC_Decoder<NotifyDataSourceStoppedResponse>,
48337      &_IPC_Invoker<ProducerPort, NotifyDataSourceStoppedRequest, NotifyDataSourceStoppedResponse, &ProducerPort::NotifyDataSourceStopped>});
48338 
48339   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48340      "ActivateTriggers",
48341      &_IPC_Decoder<ActivateTriggersRequest>,
48342      &_IPC_Decoder<ActivateTriggersResponse>,
48343      &_IPC_Invoker<ProducerPort, ActivateTriggersRequest, ActivateTriggersResponse, &ProducerPort::ActivateTriggers>});
48344 
48345   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
48346      "Sync",
48347      &_IPC_Decoder<SyncRequest>,
48348      &_IPC_Decoder<SyncResponse>,
48349      &_IPC_Invoker<ProducerPort, SyncRequest, SyncResponse, &ProducerPort::Sync>});
48350   desc->methods.shrink_to_fit();
48351   return desc;
48352 }
48353 
48354 
GetDescriptorStatic()48355 const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptorStatic() {
48356   static auto* instance = NewDescriptor();
48357   return *instance;
48358 }
48359 
48360 // Host-side definitions.
48361 ProducerPort::~ProducerPort() = default;
48362 
GetDescriptor()48363 const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptor() {
48364   return GetDescriptorStatic();
48365 }
48366 
48367 // Client-side definitions.
ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener * event_listener)48368 ProducerPortProxy::ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
48369     : ::perfetto::ipc::ServiceProxy(event_listener) {}
48370 
48371 ProducerPortProxy::~ProducerPortProxy() = default;
48372 
GetDescriptor()48373 const ::perfetto::ipc::ServiceDescriptor& ProducerPortProxy::GetDescriptor() {
48374   return ProducerPort::GetDescriptorStatic();
48375 }
48376 
InitializeConnection(const InitializeConnectionRequest & request,DeferredInitializeConnectionResponse reply,int fd)48377 void ProducerPortProxy::InitializeConnection(const InitializeConnectionRequest& request, DeferredInitializeConnectionResponse reply, int fd) {
48378   BeginInvoke("InitializeConnection", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48379               fd);
48380 }
48381 
RegisterDataSource(const RegisterDataSourceRequest & request,DeferredRegisterDataSourceResponse reply,int fd)48382 void ProducerPortProxy::RegisterDataSource(const RegisterDataSourceRequest& request, DeferredRegisterDataSourceResponse reply, int fd) {
48383   BeginInvoke("RegisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48384               fd);
48385 }
48386 
UnregisterDataSource(const UnregisterDataSourceRequest & request,DeferredUnregisterDataSourceResponse reply,int fd)48387 void ProducerPortProxy::UnregisterDataSource(const UnregisterDataSourceRequest& request, DeferredUnregisterDataSourceResponse reply, int fd) {
48388   BeginInvoke("UnregisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48389               fd);
48390 }
48391 
CommitData(const CommitDataRequest & request,DeferredCommitDataResponse reply,int fd)48392 void ProducerPortProxy::CommitData(const CommitDataRequest& request, DeferredCommitDataResponse reply, int fd) {
48393   BeginInvoke("CommitData", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48394               fd);
48395 }
48396 
GetAsyncCommand(const GetAsyncCommandRequest & request,DeferredGetAsyncCommandResponse reply,int fd)48397 void ProducerPortProxy::GetAsyncCommand(const GetAsyncCommandRequest& request, DeferredGetAsyncCommandResponse reply, int fd) {
48398   BeginInvoke("GetAsyncCommand", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48399               fd);
48400 }
48401 
RegisterTraceWriter(const RegisterTraceWriterRequest & request,DeferredRegisterTraceWriterResponse reply,int fd)48402 void ProducerPortProxy::RegisterTraceWriter(const RegisterTraceWriterRequest& request, DeferredRegisterTraceWriterResponse reply, int fd) {
48403   BeginInvoke("RegisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48404               fd);
48405 }
48406 
UnregisterTraceWriter(const UnregisterTraceWriterRequest & request,DeferredUnregisterTraceWriterResponse reply,int fd)48407 void ProducerPortProxy::UnregisterTraceWriter(const UnregisterTraceWriterRequest& request, DeferredUnregisterTraceWriterResponse reply, int fd) {
48408   BeginInvoke("UnregisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48409               fd);
48410 }
48411 
NotifyDataSourceStarted(const NotifyDataSourceStartedRequest & request,DeferredNotifyDataSourceStartedResponse reply,int fd)48412 void ProducerPortProxy::NotifyDataSourceStarted(const NotifyDataSourceStartedRequest& request, DeferredNotifyDataSourceStartedResponse reply, int fd) {
48413   BeginInvoke("NotifyDataSourceStarted", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48414               fd);
48415 }
48416 
NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest & request,DeferredNotifyDataSourceStoppedResponse reply,int fd)48417 void ProducerPortProxy::NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest& request, DeferredNotifyDataSourceStoppedResponse reply, int fd) {
48418   BeginInvoke("NotifyDataSourceStopped", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48419               fd);
48420 }
48421 
ActivateTriggers(const ActivateTriggersRequest & request,DeferredActivateTriggersResponse reply,int fd)48422 void ProducerPortProxy::ActivateTriggers(const ActivateTriggersRequest& request, DeferredActivateTriggersResponse reply, int fd) {
48423   BeginInvoke("ActivateTriggers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48424               fd);
48425 }
48426 
Sync(const SyncRequest & request,DeferredSyncResponse reply,int fd)48427 void ProducerPortProxy::Sync(const SyncRequest& request, DeferredSyncResponse reply, int fd) {
48428   BeginInvoke("Sync", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
48429               fd);
48430 }
48431 }  // namespace perfetto
48432 }  // namespace protos
48433 }  // namespace gen
48434 // gen_amalgamated begin source: src/base/unix_socket.cc
48435 // gen_amalgamated begin header: include/perfetto/ext/base/unix_socket.h
48436 /*
48437  * Copyright (C) 2017 The Android Open Source Project
48438  *
48439  * Licensed under the Apache License, Version 2.0 (the "License");
48440  * you may not use this file except in compliance with the License.
48441  * You may obtain a copy of the License at
48442  *
48443  *      http://www.apache.org/licenses/LICENSE-2.0
48444  *
48445  * Unless required by applicable law or agreed to in writing, software
48446  * distributed under the License is distributed on an "AS IS" BASIS,
48447  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48448  * See the License for the specific language governing permissions and
48449  * limitations under the License.
48450  */
48451 
48452 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
48453 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
48454 
48455 #include <stdint.h>
48456 #include <sys/types.h>
48457 
48458 #include <memory>
48459 #include <string>
48460 
48461 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
48462 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
48463 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
48464 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
48465 
48466 struct msghdr;
48467 
48468 namespace perfetto {
48469 namespace base {
48470 
48471 class TaskRunner;
48472 
48473 // Use arbitrarily high values to avoid that some code accidentally ends up
48474 // assuming that these enum values match the sysroot's SOCK_xxx defines rather
48475 // than using GetSockType() / GetSockFamily().
48476 enum class SockType { kStream = 100, kDgram, kSeqPacket };
48477 enum class SockFamily { kUnix = 200, kInet, kInet6 };
48478 
48479 // UnixSocketRaw is a basic wrapper around UNIX sockets. It exposes wrapper
48480 // methods that take care of most common pitfalls (e.g., marking fd as
48481 // O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as
48482 // a building block for the more sophisticated UnixSocket class.
48483 class UnixSocketRaw {
48484  public:
48485   // Creates a new unconnected unix socket.
48486   static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);
48487 
48488   // Crates a pair of connected sockets.
48489   static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePair(SockFamily,
48490                                                             SockType);
48491 
48492   // Creates an uninitialized unix socket.
48493   UnixSocketRaw();
48494 
48495   // Creates a unix socket adopting an existing file descriptor. This is
48496   // typically used to inherit fds from init via environment variables.
48497   UnixSocketRaw(ScopedFile, SockFamily, SockType);
48498 
48499   ~UnixSocketRaw() = default;
48500   UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
48501   UnixSocketRaw& operator=(UnixSocketRaw&&) = default;
48502 
48503   bool Bind(const std::string& socket_name);
48504   bool Listen();
48505   bool Connect(const std::string& socket_name);
48506   bool SetTxTimeout(uint32_t timeout_ms);
48507   bool SetRxTimeout(uint32_t timeout_ms);
48508   void Shutdown();
48509   void SetBlocking(bool);
48510   bool IsBlocking() const;
48511   void RetainOnExec();
type() const48512   SockType type() const { return type_; }
family() const48513   SockFamily family() const { return family_; }
fd() const48514   int fd() const { return *fd_; }
operator bool() const48515   explicit operator bool() const { return !!fd_; }
48516 
ReleaseFd()48517   ScopedFile ReleaseFd() { return std::move(fd_); }
48518 
48519   ssize_t Send(const void* msg,
48520                size_t len,
48521                const int* send_fds = nullptr,
48522                size_t num_fds = 0);
48523 
48524   // Re-enter sendmsg until all the data has been sent or an error occurs.
48525   // TODO(fmayer): Figure out how to do timeouts here for heapprofd.
48526   ssize_t SendMsgAll(struct msghdr* msg);
48527 
48528   ssize_t Receive(void* msg,
48529                   size_t len,
48530                   ScopedFile* fd_vec = nullptr,
48531                   size_t max_files = 0);
48532 
48533   // Exposed for testing only.
48534   // Update msghdr so subsequent sendmsg will send data that remains after n
48535   // bytes have already been sent.
48536   static void ShiftMsgHdr(size_t n, struct msghdr* msg);
48537 
48538  private:
48539   UnixSocketRaw(SockFamily, SockType);
48540 
48541   UnixSocketRaw(const UnixSocketRaw&) = delete;
48542   UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;
48543 
48544   ScopedFile fd_;
48545   SockFamily family_ = SockFamily::kUnix;
48546   SockType type_ = SockType::kStream;
48547 };
48548 
48549 // A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
48550 // None of the methods in this class are blocking.
48551 // The main design goal is making strong guarantees on the EventListener
48552 // callbacks, in order to avoid ending in some undefined state.
48553 // In case of any error it will aggressively just shut down the socket and
48554 // notify the failure with OnConnect(false) or OnDisconnect() depending on the
48555 // state of the socket (see below).
48556 // EventListener callbacks stop happening as soon as the instance is destroyed.
48557 //
48558 // Lifecycle of a client socket:
48559 //
48560 //                           Connect()
48561 //                               |
48562 //            +------------------+------------------+
48563 //            | (success)                           | (failure or Shutdown())
48564 //            V                                     V
48565 //     OnConnect(true)                         OnConnect(false)
48566 //            |
48567 //            V
48568 //    OnDataAvailable()
48569 //            |
48570 //            V
48571 //     OnDisconnect()  (failure or shutdown)
48572 //
48573 //
48574 // Lifecycle of a server socket:
48575 //
48576 //                          Listen()  --> returns false in case of errors.
48577 //                             |
48578 //                             V
48579 //              OnNewIncomingConnection(new_socket)
48580 //
48581 //          (|new_socket| inherits the same EventListener)
48582 //                             |
48583 //                             V
48584 //                     OnDataAvailable()
48585 //                             | (failure or Shutdown())
48586 //                             V
48587 //                       OnDisconnect()
48588 class UnixSocket {
48589  public:
48590   class EventListener {
48591    public:
48592     virtual ~EventListener();
48593 
48594     // After Listen().
48595     virtual void OnNewIncomingConnection(
48596         UnixSocket* self,
48597         std::unique_ptr<UnixSocket> new_connection);
48598 
48599     // After Connect(), whether successful or not.
48600     virtual void OnConnect(UnixSocket* self, bool connected);
48601 
48602     // After a successful Connect() or OnNewIncomingConnection(). Either the
48603     // other endpoint did disconnect or some other error happened.
48604     virtual void OnDisconnect(UnixSocket* self);
48605 
48606     // Whenever there is data available to Receive(). Note that spurious FD
48607     // watch events are possible, so it is possible that Receive() soon after
48608     // OnDataAvailable() returns 0 (just ignore those).
48609     virtual void OnDataAvailable(UnixSocket* self);
48610   };
48611 
48612   enum class State {
48613     kDisconnected = 0,  // Failed connection, peer disconnection or Shutdown().
48614     kConnecting,  // Soon after Connect(), before it either succeeds or fails.
48615     kConnected,   // After a successful Connect().
48616     kListening    // After Listen(), until Shutdown().
48617   };
48618 
48619   // Creates a socket and starts listening. If SockFamily::kUnix and
48620   // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
48621   // created instead of a filesystem-linked UNIX socket (Linux/Android only).
48622   // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
48623   // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000").
48624   // Returns nullptr if the socket creation or bind fails. If listening fails,
48625   // (e.g. if another socket with the same name is already listening) the
48626   // returned socket will have is_listening() == false and last_error() will
48627   // contain the failure reason.
48628   static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
48629                                             EventListener*,
48630                                             TaskRunner*,
48631                                             SockFamily,
48632                                             SockType);
48633 
48634   // Attaches to a pre-existing socket. The socket must have been created in
48635   // SOCK_STREAM mode and the caller must have called bind() on it.
48636   static std::unique_ptr<UnixSocket> Listen(ScopedFile,
48637                                             EventListener*,
48638                                             TaskRunner*,
48639                                             SockFamily,
48640                                             SockType);
48641 
48642   // Creates a Unix domain socket and connects to the listening endpoint.
48643   // Returns always an instance. EventListener::OnConnect(bool success) will
48644   // be called always, whether the connection succeeded or not.
48645   static std::unique_ptr<UnixSocket> Connect(const std::string& socket_name,
48646                                              EventListener*,
48647                                              TaskRunner*,
48648                                              SockFamily,
48649                                              SockType);
48650 
48651   // Constructs a UnixSocket using the given connected socket.
48652   static std::unique_ptr<UnixSocket> AdoptConnected(ScopedFile,
48653                                                     EventListener*,
48654                                                     TaskRunner*,
48655                                                     SockFamily,
48656                                                     SockType);
48657 
48658   UnixSocket(const UnixSocket&) = delete;
48659   UnixSocket& operator=(const UnixSocket&) = delete;
48660   // Cannot be easily moved because of tasks from the FileDescriptorWatch.
48661   UnixSocket(UnixSocket&&) = delete;
48662   UnixSocket& operator=(UnixSocket&&) = delete;
48663 
48664   // This class gives the hard guarantee that no callback is called on the
48665   // passed EventListener immediately after the object has been destroyed.
48666   // Any queued callback will be silently dropped.
48667   ~UnixSocket();
48668 
48669   // Shuts down the current connection, if any. If the socket was Listen()-ing,
48670   // stops listening. The socket goes back to kNotInitialized state, so it can
48671   // be reused with Listen() or Connect().
48672   void Shutdown(bool notify);
48673 
48674   // Returns true is the message was queued, false if there was no space in the
48675   // output buffer, in which case the client should retry or give up.
48676   // If any other error happens the socket will be shutdown and
48677   // EventListener::OnDisconnect() will be called.
48678   // If the socket is not connected, Send() will just return false.
48679   // Does not append a null string terminator to msg in any case.
48680   bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds);
48681 
Send(const void * msg,size_t len,int send_fd=-1)48682   inline bool Send(const void* msg, size_t len, int send_fd = -1) {
48683     if (send_fd != -1)
48684       return Send(msg, len, &send_fd, 1);
48685     return Send(msg, len, nullptr, 0);
48686   }
48687 
Send(const std::string & msg)48688   inline bool Send(const std::string& msg) {
48689     return Send(msg.c_str(), msg.size() + 1, -1);
48690   }
48691 
48692   // Returns the number of bytes (<= |len|) written in |msg| or 0 if there
48693   // is no data in the buffer to read or an error occurs (in which case a
48694   // EventListener::OnDisconnect() will follow).
48695   // If the ScopedFile pointer is not null and a FD is received, it moves the
48696   // received FD into that. If a FD is received but the ScopedFile pointer is
48697   // null, the FD will be automatically closed.
48698   size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1);
48699 
Receive(void * msg,size_t len)48700   inline size_t Receive(void* msg, size_t len) {
48701     return Receive(msg, len, nullptr, 0);
48702   }
48703 
48704   // Only for tests. This is slower than Receive() as it requires a heap
48705   // allocation and a copy for the std::string. Guarantees that the returned
48706   // string is null terminated even if the underlying message sent by the peer
48707   // is not.
48708   std::string ReceiveString(size_t max_length = 1024);
48709 
is_connected() const48710   bool is_connected() const { return state_ == State::kConnected; }
is_listening() const48711   bool is_listening() const { return state_ == State::kListening; }
fd() const48712   int fd() const { return sock_raw_.fd(); }
last_error() const48713   int last_error() const { return last_error_; }
48714 
48715   // User ID of the peer, as returned by the kernel. If the client disconnects
48716   // and the socket goes into the kDisconnected state, it retains the uid of
48717   // the last peer.
peer_uid() const48718   uid_t peer_uid() const {
48719     PERFETTO_DCHECK(!is_listening() && peer_uid_ != kInvalidUid);
48720     ignore_result(kInvalidPid);  // Silence warnings in amalgamated builds.
48721     return peer_uid_;
48722   }
48723 
48724 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
48725     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
48726   // Process ID of the peer, as returned by the kernel. If the client
48727   // disconnects and the socket goes into the kDisconnected state, it
48728   // retains the pid of the last peer.
48729   //
48730   // This is only available on Linux / Android.
peer_pid() const48731   pid_t peer_pid() const {
48732     PERFETTO_DCHECK(!is_listening() && peer_pid_ != kInvalidPid);
48733     return peer_pid_;
48734   }
48735 #endif
48736 
48737   // This makes the UnixSocket unusable.
48738   UnixSocketRaw ReleaseSocket();
48739 
48740  private:
48741   UnixSocket(EventListener*, TaskRunner*, SockFamily, SockType);
48742   UnixSocket(EventListener*,
48743              TaskRunner*,
48744              ScopedFile,
48745              State,
48746              SockFamily,
48747              SockType);
48748 
48749   // Called once by the corresponding public static factory methods.
48750   void DoConnect(const std::string& socket_name);
48751   void ReadPeerCredentials();
48752 
48753   void OnEvent();
48754   void NotifyConnectionState(bool success);
48755 
48756   UnixSocketRaw sock_raw_;
48757   State state_ = State::kDisconnected;
48758   int last_error_ = 0;
48759   uid_t peer_uid_ = kInvalidUid;
48760 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
48761     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
48762   pid_t peer_pid_ = kInvalidPid;
48763 #endif
48764   EventListener* const event_listener_;
48765   TaskRunner* const task_runner_;
48766   WeakPtrFactory<UnixSocket> weak_ptr_factory_;  // Keep last.
48767 };
48768 
48769 }  // namespace base
48770 }  // namespace perfetto
48771 
48772 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
48773 /*
48774  * Copyright (C) 2017 The Android Open Source Project
48775  *
48776  * Licensed under the Apache License, Version 2.0 (the "License");
48777  * you may not use this file except in compliance with the License.
48778  * You may obtain a copy of the License at
48779  *
48780  *      http://www.apache.org/licenses/LICENSE-2.0
48781  *
48782  * Unless required by applicable law or agreed to in writing, software
48783  * distributed under the License is distributed on an "AS IS" BASIS,
48784  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48785  * See the License for the specific language governing permissions and
48786  * limitations under the License.
48787  */
48788 
48789 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
48790 
48791 #include <errno.h>
48792 #include <fcntl.h>
48793 #include <netdb.h>
48794 #include <netinet/in.h>
48795 #include <stdlib.h>
48796 #include <string.h>
48797 #include <sys/socket.h>
48798 #include <sys/stat.h>
48799 #include <sys/types.h>
48800 #include <sys/un.h>
48801 #include <unistd.h>
48802 
48803 #include <algorithm>
48804 #include <memory>
48805 
48806 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
48807 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
48808 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
48809 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
48810 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
48811 
48812 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
48813 #include <sys/ucred.h>
48814 #endif
48815 
48816 namespace perfetto {
48817 namespace base {
48818 
48819 // The CMSG_* macros use NULL instead of nullptr.
48820 #pragma GCC diagnostic push
48821 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
48822 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
48823 #endif
48824 
48825 namespace {
48826 
48827 // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
48828 // created with SO_NOSIGPIPE (See InitializeSocket()).
48829 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
48830 constexpr int kNoSigPipe = 0;
48831 #else
48832 constexpr int kNoSigPipe = MSG_NOSIGNAL;
48833 #endif
48834 
48835 // Android takes an int instead of socklen_t for the control buffer size.
48836 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
48837 using CBufLenType = size_t;
48838 #else
48839 using CBufLenType = socklen_t;
48840 #endif
48841 
48842 // A wrapper around variable-size sockaddr structs.
48843 // This is solving the following problem: when calling connect() or bind(), the
48844 // caller needs to take care to allocate the right struct (sockaddr_un for
48845 // AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
48846 // more importantly, are bigger than the base struct sockaddr.
48847 struct SockaddrAny {
SockaddrAnyperfetto::base::__anon7bab3a4f9011::SockaddrAny48848   SockaddrAny() : size() {}
SockaddrAnyperfetto::base::__anon7bab3a4f9011::SockaddrAny48849   SockaddrAny(const void* addr, socklen_t sz) : data(new char[sz]), size(sz) {
48850     memcpy(data.get(), addr, static_cast<size_t>(size));
48851   }
48852 
addrperfetto::base::__anon7bab3a4f9011::SockaddrAny48853   const struct sockaddr* addr() const {
48854     return reinterpret_cast<const struct sockaddr*>(data.get());
48855   }
48856 
48857   std::unique_ptr<char[]> data;
48858   socklen_t size;
48859 };
48860 
GetSockFamily(SockFamily family)48861 inline int GetSockFamily(SockFamily family) {
48862   switch (family) {
48863     case SockFamily::kUnix:
48864       return AF_UNIX;
48865     case SockFamily::kInet:
48866       return AF_INET;
48867     case SockFamily::kInet6:
48868       return AF_INET6;
48869   }
48870   PERFETTO_CHECK(false);  // For GCC.
48871 }
48872 
GetSockType(SockType type)48873 inline int GetSockType(SockType type) {
48874 #ifdef SOCK_CLOEXEC
48875   constexpr int kSockCloExec = SOCK_CLOEXEC;
48876 #else
48877   constexpr int kSockCloExec = 0;
48878 #endif
48879   switch (type) {
48880     case SockType::kStream:
48881       return SOCK_STREAM | kSockCloExec;
48882     case SockType::kDgram:
48883       return SOCK_DGRAM | kSockCloExec;
48884     case SockType::kSeqPacket:
48885       return SOCK_SEQPACKET | kSockCloExec;
48886   }
48887   PERFETTO_CHECK(false);  // For GCC.
48888 }
48889 
MakeSockAddr(SockFamily family,const std::string & socket_name)48890 SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
48891   switch (family) {
48892     case SockFamily::kUnix: {
48893       struct sockaddr_un saddr {};
48894       const size_t name_len = socket_name.size();
48895       if (name_len >= sizeof(saddr.sun_path)) {
48896         errno = ENAMETOOLONG;
48897         return SockaddrAny();
48898       }
48899       memcpy(saddr.sun_path, socket_name.data(), name_len);
48900       if (saddr.sun_path[0] == '@')
48901         saddr.sun_path[0] = '\0';
48902       saddr.sun_family = AF_UNIX;
48903       auto size = static_cast<socklen_t>(
48904           __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
48905       PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
48906       return SockaddrAny(&saddr, size);
48907     }
48908     case SockFamily::kInet: {
48909       auto parts = SplitString(socket_name, ":");
48910       PERFETTO_CHECK(parts.size() == 2);
48911       struct addrinfo* addr_info = nullptr;
48912       struct addrinfo hints {};
48913       hints.ai_family = AF_INET;
48914       PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
48915                                  &addr_info) == 0);
48916       PERFETTO_CHECK(addr_info->ai_family == AF_INET);
48917       SockaddrAny res(addr_info->ai_addr, addr_info->ai_addrlen);
48918       freeaddrinfo(addr_info);
48919       return res;
48920     }
48921     case SockFamily::kInet6: {
48922       auto parts = SplitString(socket_name, "]");
48923       PERFETTO_CHECK(parts.size() == 2);
48924       auto address = SplitString(parts[0], "[");
48925       PERFETTO_CHECK(address.size() == 1);
48926       auto port = SplitString(parts[1], ":");
48927       PERFETTO_CHECK(port.size() == 1);
48928       struct addrinfo* addr_info = nullptr;
48929       struct addrinfo hints {};
48930       hints.ai_family = AF_INET6;
48931       PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
48932                                  &addr_info) == 0);
48933       PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
48934       SockaddrAny res(addr_info->ai_addr, addr_info->ai_addrlen);
48935       freeaddrinfo(addr_info);
48936       return res;
48937     }
48938   }
48939   PERFETTO_CHECK(false);  // For GCC.
48940 }
48941 
48942 }  // namespace
48943 
48944 // +-----------------------+
48945 // | UnixSocketRaw methods |
48946 // +-----------------------+
48947 
48948 // static
ShiftMsgHdr(size_t n,struct msghdr * msg)48949 void UnixSocketRaw::ShiftMsgHdr(size_t n, struct msghdr* msg) {
48950   using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
48951   for (LenType i = 0; i < msg->msg_iovlen; ++i) {
48952     struct iovec* vec = &msg->msg_iov[i];
48953     if (n < vec->iov_len) {
48954       // We sent a part of this iovec.
48955       vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
48956       vec->iov_len -= n;
48957       msg->msg_iov = vec;
48958       msg->msg_iovlen -= i;
48959       return;
48960     }
48961     // We sent the whole iovec.
48962     n -= vec->iov_len;
48963   }
48964   // We sent all the iovecs.
48965   PERFETTO_CHECK(n == 0);
48966   msg->msg_iovlen = 0;
48967   msg->msg_iov = nullptr;
48968 }
48969 
48970 // static
CreateMayFail(SockFamily family,SockType type)48971 UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
48972   auto fd = ScopedFile(socket(GetSockFamily(family), GetSockType(type), 0));
48973   if (!fd) {
48974     return UnixSocketRaw();
48975   }
48976   return UnixSocketRaw(std::move(fd), family, type);
48977 }
48978 
48979 // static
CreatePair(SockFamily family,SockType type)48980 std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePair(
48981     SockFamily family,
48982     SockType type) {
48983   int fds[2];
48984   if (socketpair(GetSockFamily(family), GetSockType(type), 0, fds) != 0)
48985     return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
48986 
48987   return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
48988                         UnixSocketRaw(ScopedFile(fds[1]), family, type));
48989 }
48990 
48991 UnixSocketRaw::UnixSocketRaw() = default;
48992 
UnixSocketRaw(SockFamily family,SockType type)48993 UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
48994     : UnixSocketRaw(
48995           ScopedFile(socket(GetSockFamily(family), GetSockType(type), 0)),
48996           family,
48997           type) {}
48998 
UnixSocketRaw(ScopedFile fd,SockFamily family,SockType type)48999 UnixSocketRaw::UnixSocketRaw(ScopedFile fd, SockFamily family, SockType type)
49000     : fd_(std::move(fd)), family_(family), type_(type) {
49001   PERFETTO_CHECK(fd_);
49002 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
49003   const int no_sigpipe = 1;
49004   setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
49005 #endif
49006 
49007   if (family == SockFamily::kInet || family == SockFamily::kInet6) {
49008     int flag = 1;
49009     PERFETTO_CHECK(
49010         !setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)));
49011   }
49012 
49013   // There is no reason why a socket should outlive the process in case of
49014   // exec() by default, this is just working around a broken unix design.
49015   int fcntl_res = fcntl(*fd_, F_SETFD, FD_CLOEXEC);
49016   PERFETTO_CHECK(fcntl_res == 0);
49017 }
49018 
SetBlocking(bool is_blocking)49019 void UnixSocketRaw::SetBlocking(bool is_blocking) {
49020   PERFETTO_DCHECK(fd_);
49021   int flags = fcntl(*fd_, F_GETFL, 0);
49022   if (!is_blocking) {
49023     flags |= O_NONBLOCK;
49024   } else {
49025     flags &= ~static_cast<int>(O_NONBLOCK);
49026   }
49027   bool fcntl_res = fcntl(*fd_, F_SETFL, flags);
49028   PERFETTO_CHECK(fcntl_res == 0);
49029 }
49030 
RetainOnExec()49031 void UnixSocketRaw::RetainOnExec() {
49032   PERFETTO_DCHECK(fd_);
49033   int flags = fcntl(*fd_, F_GETFD, 0);
49034   flags &= ~static_cast<int>(FD_CLOEXEC);
49035   bool fcntl_res = fcntl(*fd_, F_SETFD, flags);
49036   PERFETTO_CHECK(fcntl_res == 0);
49037 }
49038 
IsBlocking() const49039 bool UnixSocketRaw::IsBlocking() const {
49040   PERFETTO_DCHECK(fd_);
49041   return (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
49042 }
49043 
Bind(const std::string & socket_name)49044 bool UnixSocketRaw::Bind(const std::string& socket_name) {
49045   PERFETTO_DCHECK(fd_);
49046   SockaddrAny addr = MakeSockAddr(family_, socket_name);
49047   if (addr.size == 0)
49048     return false;
49049 
49050   if (bind(*fd_, addr.addr(), addr.size)) {
49051     PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
49052     return false;
49053   }
49054 
49055   return true;
49056 }
49057 
Listen()49058 bool UnixSocketRaw::Listen() {
49059   PERFETTO_DCHECK(fd_);
49060   PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
49061   return listen(*fd_, SOMAXCONN) == 0;
49062 }
49063 
Connect(const std::string & socket_name)49064 bool UnixSocketRaw::Connect(const std::string& socket_name) {
49065   PERFETTO_DCHECK(fd_);
49066   SockaddrAny addr = MakeSockAddr(family_, socket_name);
49067   if (addr.size == 0)
49068     return false;
49069 
49070   int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
49071   if (res && errno != EINPROGRESS)
49072     return false;
49073 
49074   return true;
49075 }
49076 
Shutdown()49077 void UnixSocketRaw::Shutdown() {
49078   shutdown(*fd_, SHUT_RDWR);
49079   fd_.reset();
49080 }
49081 
49082 // For the interested reader, Linux kernel dive to verify this is not only a
49083 // theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
49084 // NULL [1] (which it does when it gets interrupted [2]), returns early with the
49085 // amount of bytes already sent.
49086 //
49087 // [1]:
49088 // https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
49089 // [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
SendMsgAll(struct msghdr * msg)49090 ssize_t UnixSocketRaw::SendMsgAll(struct msghdr* msg) {
49091   // This does not make sense on non-blocking sockets.
49092   PERFETTO_DCHECK(fd_);
49093 
49094   ssize_t total_sent = 0;
49095   while (msg->msg_iov) {
49096     ssize_t sent = PERFETTO_EINTR(sendmsg(*fd_, msg, kNoSigPipe));
49097     if (sent <= 0) {
49098       if (sent == -1 && IsAgain(errno))
49099         return total_sent;
49100       return sent;
49101     }
49102     total_sent += sent;
49103     ShiftMsgHdr(static_cast<size_t>(sent), msg);
49104     // Only send the ancillary data with the first sendmsg call.
49105     msg->msg_control = nullptr;
49106     msg->msg_controllen = 0;
49107   }
49108   return total_sent;
49109 }
49110 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)49111 ssize_t UnixSocketRaw::Send(const void* msg,
49112                             size_t len,
49113                             const int* send_fds,
49114                             size_t num_fds) {
49115   PERFETTO_DCHECK(fd_);
49116   msghdr msg_hdr = {};
49117   iovec iov = {const_cast<void*>(msg), len};
49118   msg_hdr.msg_iov = &iov;
49119   msg_hdr.msg_iovlen = 1;
49120   alignas(cmsghdr) char control_buf[256];
49121 
49122   if (num_fds > 0) {
49123     const auto raw_ctl_data_sz = num_fds * sizeof(int);
49124     const CBufLenType control_buf_len =
49125         static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
49126     PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
49127     memset(control_buf, 0, sizeof(control_buf));
49128     msg_hdr.msg_control = control_buf;
49129     msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
49130     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
49131     cmsg->cmsg_level = SOL_SOCKET;
49132     cmsg->cmsg_type = SCM_RIGHTS;
49133     cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
49134     memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
49135     // note: if we were to send multiple cmsghdr structures, then
49136     // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
49137   }
49138 
49139   return SendMsgAll(&msg_hdr);
49140 }
49141 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)49142 ssize_t UnixSocketRaw::Receive(void* msg,
49143                                size_t len,
49144                                ScopedFile* fd_vec,
49145                                size_t max_files) {
49146   PERFETTO_DCHECK(fd_);
49147   msghdr msg_hdr = {};
49148   iovec iov = {msg, len};
49149   msg_hdr.msg_iov = &iov;
49150   msg_hdr.msg_iovlen = 1;
49151   alignas(cmsghdr) char control_buf[256];
49152 
49153   if (max_files > 0) {
49154     msg_hdr.msg_control = control_buf;
49155     msg_hdr.msg_controllen =
49156         static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
49157     PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
49158   }
49159   const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
49160   if (sz <= 0) {
49161     return sz;
49162   }
49163   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
49164 
49165   int* fds = nullptr;
49166   uint32_t fds_len = 0;
49167 
49168   if (max_files > 0) {
49169     for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
49170          cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
49171       const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
49172       if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
49173         PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
49174         PERFETTO_CHECK(fds == nullptr);
49175         fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
49176         fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
49177       }
49178     }
49179   }
49180 
49181   if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
49182     for (size_t i = 0; fds && i < fds_len; ++i)
49183       close(fds[i]);
49184     errno = EMSGSIZE;
49185     return -1;
49186   }
49187 
49188   for (size_t i = 0; fds && i < fds_len; ++i) {
49189     if (i < max_files)
49190       fd_vec[i].reset(fds[i]);
49191     else
49192       close(fds[i]);
49193   }
49194 
49195   return sz;
49196 }
49197 
SetTxTimeout(uint32_t timeout_ms)49198 bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
49199   PERFETTO_DCHECK(fd_);
49200   struct timeval timeout {};
49201   uint32_t timeout_sec = timeout_ms / 1000;
49202   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
49203   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
49204       (timeout_ms - (timeout_sec * 1000)) * 1000);
49205 
49206   return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
49207                     reinterpret_cast<const char*>(&timeout),
49208                     sizeof(timeout)) == 0;
49209 }
49210 
SetRxTimeout(uint32_t timeout_ms)49211 bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
49212   PERFETTO_DCHECK(fd_);
49213   struct timeval timeout {};
49214   uint32_t timeout_sec = timeout_ms / 1000;
49215   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
49216   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
49217       (timeout_ms - (timeout_sec * 1000)) * 1000);
49218 
49219   return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
49220                     reinterpret_cast<const char*>(&timeout),
49221                     sizeof(timeout)) == 0;
49222 }
49223 
49224 #pragma GCC diagnostic pop
49225 
49226 // +--------------------+
49227 // | UnixSocket methods |
49228 // +--------------------+
49229 
49230 // TODO(primiano): Add ThreadChecker to methods of this class.
49231 
49232 // static
Listen(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)49233 std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
49234                                                EventListener* event_listener,
49235                                                TaskRunner* task_runner,
49236                                                SockFamily sock_family,
49237                                                SockType sock_type) {
49238   auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
49239   if (!sock_raw || !sock_raw.Bind(socket_name))
49240     return nullptr;
49241 
49242   // Forward the call to the Listen() overload below.
49243   return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
49244                 sock_type);
49245 }
49246 
49247 // static
Listen(ScopedFile fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)49248 std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedFile fd,
49249                                                EventListener* event_listener,
49250                                                TaskRunner* task_runner,
49251                                                SockFamily sock_family,
49252                                                SockType sock_type) {
49253   return std::unique_ptr<UnixSocket>(
49254       new UnixSocket(event_listener, task_runner, std::move(fd),
49255                      State::kListening, sock_family, sock_type));
49256 }
49257 
49258 // static
Connect(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)49259 std::unique_ptr<UnixSocket> UnixSocket::Connect(const std::string& socket_name,
49260                                                 EventListener* event_listener,
49261                                                 TaskRunner* task_runner,
49262                                                 SockFamily sock_family,
49263                                                 SockType sock_type) {
49264   std::unique_ptr<UnixSocket> sock(
49265       new UnixSocket(event_listener, task_runner, sock_family, sock_type));
49266   sock->DoConnect(socket_name);
49267   return sock;
49268 }
49269 
49270 // static
AdoptConnected(ScopedFile fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)49271 std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
49272     ScopedFile fd,
49273     EventListener* event_listener,
49274     TaskRunner* task_runner,
49275     SockFamily sock_family,
49276     SockType sock_type) {
49277   return std::unique_ptr<UnixSocket>(
49278       new UnixSocket(event_listener, task_runner, std::move(fd),
49279                      State::kConnected, sock_family, sock_type));
49280 }
49281 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)49282 UnixSocket::UnixSocket(EventListener* event_listener,
49283                        TaskRunner* task_runner,
49284                        SockFamily sock_family,
49285                        SockType sock_type)
49286     : UnixSocket(event_listener,
49287                  task_runner,
49288                  ScopedFile(),
49289                  State::kDisconnected,
49290                  sock_family,
49291                  sock_type) {}
49292 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,ScopedFile adopt_fd,State adopt_state,SockFamily sock_family,SockType sock_type)49293 UnixSocket::UnixSocket(EventListener* event_listener,
49294                        TaskRunner* task_runner,
49295                        ScopedFile adopt_fd,
49296                        State adopt_state,
49297                        SockFamily sock_family,
49298                        SockType sock_type)
49299     : event_listener_(event_listener),
49300       task_runner_(task_runner),
49301       weak_ptr_factory_(this) {
49302   state_ = State::kDisconnected;
49303   if (adopt_state == State::kDisconnected) {
49304     PERFETTO_DCHECK(!adopt_fd);
49305     sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
49306     if (!sock_raw_) {
49307       last_error_ = errno;
49308       return;
49309     }
49310   } else if (adopt_state == State::kConnected) {
49311     PERFETTO_DCHECK(adopt_fd);
49312     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
49313     state_ = State::kConnected;
49314     ReadPeerCredentials();
49315   } else if (adopt_state == State::kListening) {
49316     // We get here from Listen().
49317 
49318     // |adopt_fd| might genuinely be invalid if the bind() failed.
49319     if (!adopt_fd) {
49320       last_error_ = errno;
49321       return;
49322     }
49323 
49324     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
49325     if (!sock_raw_.Listen()) {
49326       last_error_ = errno;
49327       PERFETTO_DPLOG("listen()");
49328       return;
49329     }
49330     state_ = State::kListening;
49331   } else {
49332     PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
49333   }
49334 
49335   PERFETTO_CHECK(sock_raw_);
49336   last_error_ = 0;
49337 
49338   sock_raw_.SetBlocking(false);
49339 
49340   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
49341 
49342   task_runner_->AddFileDescriptorWatch(sock_raw_.fd(), [weak_ptr] {
49343     if (weak_ptr)
49344       weak_ptr->OnEvent();
49345   });
49346 }
49347 
~UnixSocket()49348 UnixSocket::~UnixSocket() {
49349   // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
49350   Shutdown(true);
49351 }
49352 
ReleaseSocket()49353 UnixSocketRaw UnixSocket::ReleaseSocket() {
49354   // This will invalidate any pending calls to OnEvent.
49355   state_ = State::kDisconnected;
49356   if (sock_raw_)
49357     task_runner_->RemoveFileDescriptorWatch(sock_raw_.fd());
49358 
49359   return std::move(sock_raw_);
49360 }
49361 
49362 // Called only by the Connect() static constructor.
DoConnect(const std::string & socket_name)49363 void UnixSocket::DoConnect(const std::string& socket_name) {
49364   PERFETTO_DCHECK(state_ == State::kDisconnected);
49365 
49366   // This is the only thing that can gracefully fail in the ctor.
49367   if (!sock_raw_)
49368     return NotifyConnectionState(false);
49369 
49370   if (!sock_raw_.Connect(socket_name)) {
49371     last_error_ = errno;
49372     return NotifyConnectionState(false);
49373   }
49374 
49375   // At this point either connect() succeeded or started asynchronously
49376   // (errno = EINPROGRESS).
49377   last_error_ = 0;
49378   state_ = State::kConnecting;
49379 
49380   // Even if the socket is non-blocking, connecting to a UNIX socket can be
49381   // acknowledged straight away rather than returning EINPROGRESS.
49382   // The decision here is to deal with the two cases uniformly, at the cost of
49383   // delaying the straight-away-connect() case by one task, to avoid depending
49384   // on implementation details of UNIX socket on the various OSes.
49385   // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
49386   // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
49387   // evolve, if necessary, the state into either kConnected or kDisconnected.
49388   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
49389   task_runner_->PostTask([weak_ptr] {
49390     if (weak_ptr)
49391       weak_ptr->OnEvent();
49392   });
49393 }
49394 
ReadPeerCredentials()49395 void UnixSocket::ReadPeerCredentials() {
49396   // Peer credentials are supported only on AF_UNIX sockets.
49397   if (sock_raw_.family() != SockFamily::kUnix)
49398     return;
49399 
49400 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
49401     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
49402   struct ucred user_cred;
49403   socklen_t len = sizeof(user_cred);
49404   int fd = sock_raw_.fd();
49405   int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
49406   PERFETTO_CHECK(res == 0);
49407   peer_uid_ = user_cred.uid;
49408   peer_pid_ = user_cred.pid;
49409 #else
49410   struct xucred user_cred;
49411   socklen_t len = sizeof(user_cred);
49412   int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
49413   PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
49414   peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
49415 // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
49416 #endif
49417 }
49418 
OnEvent()49419 void UnixSocket::OnEvent() {
49420   if (state_ == State::kDisconnected)
49421     return;  // Some spurious event, typically queued just before Shutdown().
49422 
49423   if (state_ == State::kConnected)
49424     return event_listener_->OnDataAvailable(this);
49425 
49426   if (state_ == State::kConnecting) {
49427     PERFETTO_DCHECK(sock_raw_);
49428     int sock_err = EINVAL;
49429     socklen_t err_len = sizeof(sock_err);
49430     int res =
49431         getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
49432 
49433     if (res == 0 && sock_err == EINPROGRESS)
49434       return;  // Not connected yet, just a spurious FD watch wakeup.
49435     if (res == 0 && sock_err == 0) {
49436       ReadPeerCredentials();
49437       state_ = State::kConnected;
49438       return event_listener_->OnConnect(this, true /* connected */);
49439     }
49440     PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
49441     last_error_ = sock_err;
49442     Shutdown(false);
49443     return event_listener_->OnConnect(this, false /* connected */);
49444   }
49445 
49446   // New incoming connection.
49447   if (state_ == State::kListening) {
49448     // There could be more than one incoming connection behind each FD watch
49449     // notification. Drain'em all.
49450     for (;;) {
49451       struct sockaddr_in cli_addr {};
49452       socklen_t size = sizeof(cli_addr);
49453       ScopedFile new_fd(PERFETTO_EINTR(accept(
49454           sock_raw_.fd(), reinterpret_cast<sockaddr*>(&cli_addr), &size)));
49455       if (!new_fd)
49456         return;
49457       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
49458           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
49459           sock_raw_.family(), sock_raw_.type()));
49460       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
49461     }
49462   }
49463 }
49464 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)49465 bool UnixSocket::Send(const void* msg,
49466                       size_t len,
49467                       const int* send_fds,
49468                       size_t num_fds) {
49469   if (state_ != State::kConnected) {
49470     errno = last_error_ = ENOTCONN;
49471     return false;
49472   }
49473 
49474   sock_raw_.SetBlocking(true);
49475   const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
49476   int saved_errno = errno;
49477   sock_raw_.SetBlocking(false);
49478 
49479   if (sz == static_cast<ssize_t>(len)) {
49480     last_error_ = 0;
49481     return true;
49482   }
49483 
49484   // If sendmsg() succeeds but the returned size is < |len| it means that the
49485   // endpoint disconnected in the middle of the read, and we managed to send
49486   // only a portion of the buffer. In this case we should just give up.
49487 
49488   if (sz < 0 && (saved_errno == EAGAIN || saved_errno == EWOULDBLOCK)) {
49489     // A genuine out-of-buffer. The client should retry or give up.
49490     // Man pages specify that EAGAIN and EWOULDBLOCK have the same semantic here
49491     // and clients should check for both.
49492     last_error_ = EAGAIN;
49493     return false;
49494   }
49495 
49496   // Either the other endpoint disconnected (ECONNRESET) or some other error
49497   // happened.
49498   last_error_ = saved_errno;
49499   PERFETTO_DPLOG("sendmsg() failed");
49500   Shutdown(true);
49501   return false;
49502 }
49503 
Shutdown(bool notify)49504 void UnixSocket::Shutdown(bool notify) {
49505   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
49506   if (notify) {
49507     if (state_ == State::kConnected) {
49508       task_runner_->PostTask([weak_ptr] {
49509         if (weak_ptr)
49510           weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
49511       });
49512     } else if (state_ == State::kConnecting) {
49513       task_runner_->PostTask([weak_ptr] {
49514         if (weak_ptr)
49515           weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
49516       });
49517     }
49518   }
49519 
49520   if (sock_raw_) {
49521     task_runner_->RemoveFileDescriptorWatch(sock_raw_.fd());
49522     sock_raw_.Shutdown();
49523   }
49524   state_ = State::kDisconnected;
49525 }
49526 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)49527 size_t UnixSocket::Receive(void* msg,
49528                            size_t len,
49529                            ScopedFile* fd_vec,
49530                            size_t max_files) {
49531   if (state_ != State::kConnected) {
49532     last_error_ = ENOTCONN;
49533     return 0;
49534   }
49535 
49536   const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
49537   if (sz < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
49538     last_error_ = EAGAIN;
49539     return 0;
49540   }
49541   if (sz <= 0) {
49542     last_error_ = errno;
49543     Shutdown(true);
49544     return 0;
49545   }
49546   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
49547   return static_cast<size_t>(sz);
49548 }
49549 
ReceiveString(size_t max_length)49550 std::string UnixSocket::ReceiveString(size_t max_length) {
49551   std::unique_ptr<char[]> buf(new char[max_length + 1]);
49552   size_t rsize = Receive(buf.get(), max_length);
49553   PERFETTO_CHECK(static_cast<size_t>(rsize) <= max_length);
49554   buf[static_cast<size_t>(rsize)] = '\0';
49555   return std::string(buf.get());
49556 }
49557 
NotifyConnectionState(bool success)49558 void UnixSocket::NotifyConnectionState(bool success) {
49559   if (!success)
49560     Shutdown(false);
49561 
49562   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
49563   task_runner_->PostTask([weak_ptr, success] {
49564     if (weak_ptr)
49565       weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
49566   });
49567 }
49568 
~EventListener()49569 UnixSocket::EventListener::~EventListener() {}
OnNewIncomingConnection(UnixSocket *,std::unique_ptr<UnixSocket>)49570 void UnixSocket::EventListener::OnNewIncomingConnection(
49571     UnixSocket*,
49572     std::unique_ptr<UnixSocket>) {}
OnConnect(UnixSocket *,bool)49573 void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
OnDisconnect(UnixSocket *)49574 void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
OnDataAvailable(UnixSocket *)49575 void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
49576 
49577 }  // namespace base
49578 }  // namespace perfetto
49579 // gen_amalgamated begin source: src/ipc/client_impl.cc
49580 // gen_amalgamated begin header: src/ipc/client_impl.h
49581 /*
49582  * Copyright (C) 2017 The Android Open Source Project
49583  *
49584  * Licensed under the Apache License, Version 2.0 (the "License");
49585  * you may not use this file except in compliance with the License.
49586  * You may obtain a copy of the License at
49587  *
49588  *      http://www.apache.org/licenses/LICENSE-2.0
49589  *
49590  * Unless required by applicable law or agreed to in writing, software
49591  * distributed under the License is distributed on an "AS IS" BASIS,
49592  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49593  * See the License for the specific language governing permissions and
49594  * limitations under the License.
49595  */
49596 
49597 #ifndef SRC_IPC_CLIENT_IMPL_H_
49598 #define SRC_IPC_CLIENT_IMPL_H_
49599 
49600 #include <list>
49601 #include <map>
49602 #include <memory>
49603 
49604 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
49605 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
49606 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
49607 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
49608 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
49609 
49610 namespace perfetto {
49611 
49612 namespace protos {
49613 namespace gen {
49614 class IPCFrame_BindServiceReply;
49615 class IPCFrame_InvokeMethodReply;
49616 }  // namespace gen
49617 }  // namespace protos
49618 
49619 namespace base {
49620 class TaskRunner;
49621 }  // namespace base
49622 
49623 namespace ipc {
49624 
49625 class ServiceDescriptor;
49626 
49627 class ClientImpl : public Client, public base::UnixSocket::EventListener {
49628  public:
49629   ClientImpl(const char* socket_name, bool socket_retry, base::TaskRunner*);
49630   ~ClientImpl() override;
49631 
49632   // Client implementation.
49633   void BindService(base::WeakPtr<ServiceProxy>) override;
49634   void UnbindService(ServiceID) override;
49635   base::ScopedFile TakeReceivedFD() override;
49636 
49637   // base::UnixSocket::EventListener implementation.
49638   void OnConnect(base::UnixSocket*, bool connected) override;
49639   void OnDisconnect(base::UnixSocket*) override;
49640   void OnDataAvailable(base::UnixSocket*) override;
49641 
49642   RequestID BeginInvoke(ServiceID,
49643                         const std::string& method_name,
49644                         MethodID remote_method_id,
49645                         const ProtoMessage& method_args,
49646                         bool drop_reply,
49647                         base::WeakPtr<ServiceProxy>,
49648                         int fd = -1);
49649 
49650  private:
49651   struct QueuedRequest {
49652     QueuedRequest();
49653     int type = 0;  // From Frame::msg_case(), see wire_protocol.proto.
49654     RequestID request_id = 0;
49655     base::WeakPtr<ServiceProxy> service_proxy;
49656 
49657     // Only for type == kMsgInvokeMethod.
49658     std::string method_name;
49659   };
49660 
49661   ClientImpl(const ClientImpl&) = delete;
49662   ClientImpl& operator=(const ClientImpl&) = delete;
49663 
49664   void TryConnect();
49665   bool SendFrame(const Frame&, int fd = -1);
49666   void OnFrameReceived(const Frame&);
49667   void OnBindServiceReply(QueuedRequest,
49668                           const protos::gen::IPCFrame_BindServiceReply&);
49669   void OnInvokeMethodReply(QueuedRequest,
49670                            const protos::gen::IPCFrame_InvokeMethodReply&);
49671 
49672   bool invoking_method_reply_ = false;
49673   const char* socket_name_ = nullptr;
49674   bool socket_retry_ = false;
49675   uint32_t socket_backoff_ms_ = 0;
49676   std::unique_ptr<base::UnixSocket> sock_;
49677   base::TaskRunner* const task_runner_;
49678   RequestID last_request_id_ = 0;
49679   BufferedFrameDeserializer frame_deserializer_;
49680   base::ScopedFile received_fd_;
49681   std::map<RequestID, QueuedRequest> queued_requests_;
49682   std::map<ServiceID, base::WeakPtr<ServiceProxy>> service_bindings_;
49683 
49684   // Queue of calls to BindService() that happened before the socket connected.
49685   std::list<base::WeakPtr<ServiceProxy>> queued_bindings_;
49686 
49687   base::WeakPtrFactory<Client> weak_ptr_factory_;  // Keep last.
49688 };
49689 
49690 }  // namespace ipc
49691 }  // namespace perfetto
49692 
49693 #endif  // SRC_IPC_CLIENT_IMPL_H_
49694 /*
49695  * Copyright (C) 2017 The Android Open Source Project
49696  *
49697  * Licensed under the Apache License, Version 2.0 (the "License");
49698  * you may not use this file except in compliance with the License.
49699  * You may obtain a copy of the License at
49700  *
49701  *      http://www.apache.org/licenses/LICENSE-2.0
49702  *
49703  * Unless required by applicable law or agreed to in writing, software
49704  * distributed under the License is distributed on an "AS IS" BASIS,
49705  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49706  * See the License for the specific language governing permissions and
49707  * limitations under the License.
49708  */
49709 
49710 // gen_amalgamated expanded: #include "src/ipc/client_impl.h"
49711 
49712 #include <fcntl.h>
49713 #include <inttypes.h>
49714 #include <unistd.h>
49715 
49716 #include <utility>
49717 
49718 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
49719 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
49720 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
49721 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
49722 
49723 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
49724 
49725 // TODO(primiano): Add ThreadChecker everywhere.
49726 
49727 // TODO(primiano): Add timeouts.
49728 
49729 namespace perfetto {
49730 namespace ipc {
49731 
49732 // static
CreateInstance(const char * socket_name,bool socket_retry,base::TaskRunner * task_runner)49733 std::unique_ptr<Client> Client::CreateInstance(const char* socket_name,
49734                                                bool socket_retry,
49735                                                base::TaskRunner* task_runner) {
49736   std::unique_ptr<Client> client(
49737       new ClientImpl(socket_name, socket_retry, task_runner));
49738   return client;
49739 }
49740 
ClientImpl(const char * socket_name,bool socket_retry,base::TaskRunner * task_runner)49741 ClientImpl::ClientImpl(const char* socket_name,
49742                        bool socket_retry,
49743                        base::TaskRunner* task_runner)
49744     : socket_name_(socket_name),
49745       socket_retry_(socket_retry),
49746       task_runner_(task_runner),
49747       weak_ptr_factory_(this) {
49748   TryConnect();
49749 }
49750 
~ClientImpl()49751 ClientImpl::~ClientImpl() {
49752   // Ensure we are not destroyed in the middle of invoking a reply.
49753   PERFETTO_DCHECK(!invoking_method_reply_);
49754   OnDisconnect(
49755       nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
49756 }
49757 
TryConnect()49758 void ClientImpl::TryConnect() {
49759   sock_ = base::UnixSocket::Connect(socket_name_, this, task_runner_,
49760                                     base::SockFamily::kUnix,
49761                                     base::SockType::kStream);
49762 }
49763 
BindService(base::WeakPtr<ServiceProxy> service_proxy)49764 void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
49765   if (!service_proxy)
49766     return;
49767   if (!sock_->is_connected()) {
49768     queued_bindings_.emplace_back(service_proxy);
49769     return;
49770   }
49771   RequestID request_id = ++last_request_id_;
49772   Frame frame;
49773   frame.set_request_id(request_id);
49774   Frame::BindService* req = frame.mutable_msg_bind_service();
49775   const char* const service_name = service_proxy->GetDescriptor().service_name;
49776   req->set_service_name(service_name);
49777   if (!SendFrame(frame)) {
49778     PERFETTO_DLOG("BindService(%s) failed", service_name);
49779     return service_proxy->OnConnect(false /* success */);
49780   }
49781   QueuedRequest qr;
49782   qr.type = Frame::kMsgBindServiceFieldNumber;
49783   qr.request_id = request_id;
49784   qr.service_proxy = service_proxy;
49785   queued_requests_.emplace(request_id, std::move(qr));
49786 }
49787 
UnbindService(ServiceID service_id)49788 void ClientImpl::UnbindService(ServiceID service_id) {
49789   service_bindings_.erase(service_id);
49790 }
49791 
BeginInvoke(ServiceID service_id,const std::string & method_name,MethodID remote_method_id,const ProtoMessage & method_args,bool drop_reply,base::WeakPtr<ServiceProxy> service_proxy,int fd)49792 RequestID ClientImpl::BeginInvoke(ServiceID service_id,
49793                                   const std::string& method_name,
49794                                   MethodID remote_method_id,
49795                                   const ProtoMessage& method_args,
49796                                   bool drop_reply,
49797                                   base::WeakPtr<ServiceProxy> service_proxy,
49798                                   int fd) {
49799   RequestID request_id = ++last_request_id_;
49800   Frame frame;
49801   frame.set_request_id(request_id);
49802   Frame::InvokeMethod* req = frame.mutable_msg_invoke_method();
49803   req->set_service_id(service_id);
49804   req->set_method_id(remote_method_id);
49805   req->set_drop_reply(drop_reply);
49806   req->set_args_proto(method_args.SerializeAsString());
49807   if (!SendFrame(frame, fd)) {
49808     PERFETTO_DLOG("BeginInvoke() failed while sending the frame");
49809     return 0;
49810   }
49811   if (drop_reply)
49812     return 0;
49813   QueuedRequest qr;
49814   qr.type = Frame::kMsgInvokeMethodFieldNumber;
49815   qr.request_id = request_id;
49816   qr.method_name = method_name;
49817   qr.service_proxy = std::move(service_proxy);
49818   queued_requests_.emplace(request_id, std::move(qr));
49819   return request_id;
49820 }
49821 
SendFrame(const Frame & frame,int fd)49822 bool ClientImpl::SendFrame(const Frame& frame, int fd) {
49823   // Serialize the frame into protobuf, add the size header, and send it.
49824   std::string buf = BufferedFrameDeserializer::Serialize(frame);
49825 
49826   // TODO(primiano): this should do non-blocking I/O. But then what if the
49827   // socket buffer is full? We might want to either drop the request or throttle
49828   // the send and PostTask the reply later? Right now we are making Send()
49829   // blocking as a workaround. Propagate bakpressure to the caller instead.
49830   bool res = sock_->Send(buf.data(), buf.size(), fd);
49831   PERFETTO_CHECK(res || !sock_->is_connected());
49832   return res;
49833 }
49834 
OnConnect(base::UnixSocket *,bool connected)49835 void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
49836   if (!connected && socket_retry_) {
49837     socket_backoff_ms_ =
49838         (socket_backoff_ms_ < 10000) ? socket_backoff_ms_ + 1000 : 30000;
49839     PERFETTO_DLOG(
49840         "Connection to traced's UNIX socket failed, retrying in %u seconds",
49841         socket_backoff_ms_ / 1000);
49842     auto weak_this = weak_ptr_factory_.GetWeakPtr();
49843     task_runner_->PostDelayedTask(
49844         [weak_this] {
49845           if (weak_this)
49846             static_cast<ClientImpl&>(*weak_this).TryConnect();
49847         },
49848         socket_backoff_ms_);
49849     return;
49850   }
49851 
49852   // Drain the BindService() calls that were queued before establishig the
49853   // connection with the host.
49854   for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings_) {
49855     if (connected) {
49856       BindService(service_proxy);
49857     } else if (service_proxy) {
49858       service_proxy->OnConnect(false /* success */);
49859     }
49860   }
49861   queued_bindings_.clear();
49862 }
49863 
OnDisconnect(base::UnixSocket *)49864 void ClientImpl::OnDisconnect(base::UnixSocket*) {
49865   for (auto it : service_bindings_) {
49866     base::WeakPtr<ServiceProxy>& service_proxy = it.second;
49867     task_runner_->PostTask([service_proxy] {
49868       if (service_proxy)
49869         service_proxy->OnDisconnect();
49870     });
49871   }
49872   service_bindings_.clear();
49873   queued_bindings_.clear();
49874 }
49875 
OnDataAvailable(base::UnixSocket *)49876 void ClientImpl::OnDataAvailable(base::UnixSocket*) {
49877   size_t rsize;
49878   do {
49879     auto buf = frame_deserializer_.BeginReceive();
49880     base::ScopedFile fd;
49881     rsize = sock_->Receive(buf.data, buf.size, &fd);
49882     if (fd) {
49883       PERFETTO_DCHECK(!received_fd_);
49884       int res = fcntl(*fd, F_SETFD, FD_CLOEXEC);
49885       PERFETTO_DCHECK(res == 0);
49886       received_fd_ = std::move(fd);
49887     }
49888     if (!frame_deserializer_.EndReceive(rsize)) {
49889       // The endpoint tried to send a frame that is way too large.
49890       return sock_->Shutdown(true);  // In turn will trigger an OnDisconnect().
49891       // TODO(fmayer): check this.
49892     }
49893   } while (rsize > 0);
49894 
49895   while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame())
49896     OnFrameReceived(*frame);
49897 }
49898 
OnFrameReceived(const Frame & frame)49899 void ClientImpl::OnFrameReceived(const Frame& frame) {
49900   auto queued_requests_it = queued_requests_.find(frame.request_id());
49901   if (queued_requests_it == queued_requests_.end()) {
49902     PERFETTO_DLOG("OnFrameReceived(): got invalid request_id=%" PRIu64,
49903                   static_cast<uint64_t>(frame.request_id()));
49904     return;
49905   }
49906   QueuedRequest req = std::move(queued_requests_it->second);
49907   queued_requests_.erase(queued_requests_it);
49908 
49909   if (req.type == Frame::kMsgBindServiceFieldNumber &&
49910       frame.has_msg_bind_service_reply()) {
49911     return OnBindServiceReply(std::move(req), frame.msg_bind_service_reply());
49912   }
49913   if (req.type == Frame::kMsgInvokeMethodFieldNumber &&
49914       frame.has_msg_invoke_method_reply()) {
49915     return OnInvokeMethodReply(std::move(req), frame.msg_invoke_method_reply());
49916   }
49917   if (frame.has_msg_request_error()) {
49918     PERFETTO_DLOG("Host error: %s", frame.msg_request_error().error().c_str());
49919     return;
49920   }
49921 
49922   PERFETTO_DLOG(
49923       "OnFrameReceived() request type=%d, received unknown frame in reply to "
49924       "request_id=%" PRIu64,
49925       req.type, static_cast<uint64_t>(frame.request_id()));
49926 }
49927 
OnBindServiceReply(QueuedRequest req,const Frame::BindServiceReply & reply)49928 void ClientImpl::OnBindServiceReply(QueuedRequest req,
49929                                     const Frame::BindServiceReply& reply) {
49930   base::WeakPtr<ServiceProxy>& service_proxy = req.service_proxy;
49931   if (!service_proxy)
49932     return;
49933   const char* svc_name = service_proxy->GetDescriptor().service_name;
49934   if (!reply.success()) {
49935     PERFETTO_DLOG("BindService(): unknown service_name=\"%s\"", svc_name);
49936     return service_proxy->OnConnect(false /* success */);
49937   }
49938 
49939   auto prev_service = service_bindings_.find(reply.service_id());
49940   if (prev_service != service_bindings_.end() && prev_service->second.get()) {
49941     PERFETTO_DLOG(
49942         "BindService(): Trying to bind service \"%s\" but another service "
49943         "named \"%s\" is already bound with the same ID.",
49944         svc_name, prev_service->second->GetDescriptor().service_name);
49945     return service_proxy->OnConnect(false /* success */);
49946   }
49947 
49948   // Build the method [name] -> [remote_id] map.
49949   std::map<std::string, MethodID> methods;
49950   for (const auto& method : reply.methods()) {
49951     if (method.name().empty() || method.id() <= 0) {
49952       PERFETTO_DLOG("OnBindServiceReply(): invalid method \"%s\" -> %" PRIu64,
49953                     method.name().c_str(), static_cast<uint64_t>(method.id()));
49954       continue;
49955     }
49956     methods[method.name()] = method.id();
49957   }
49958   service_proxy->InitializeBinding(weak_ptr_factory_.GetWeakPtr(),
49959                                    reply.service_id(), std::move(methods));
49960   service_bindings_[reply.service_id()] = service_proxy;
49961   service_proxy->OnConnect(true /* success */);
49962 }
49963 
OnInvokeMethodReply(QueuedRequest req,const Frame::InvokeMethodReply & reply)49964 void ClientImpl::OnInvokeMethodReply(QueuedRequest req,
49965                                      const Frame::InvokeMethodReply& reply) {
49966   base::WeakPtr<ServiceProxy> service_proxy = req.service_proxy;
49967   if (!service_proxy)
49968     return;
49969   std::unique_ptr<ProtoMessage> decoded_reply;
49970   if (reply.success()) {
49971     // If this becomes a hotspot, optimize by maintaining a dedicated hashtable.
49972     for (const auto& method : service_proxy->GetDescriptor().methods) {
49973       if (req.method_name == method.name) {
49974         decoded_reply = method.reply_proto_decoder(reply.reply_proto());
49975         break;
49976       }
49977     }
49978   }
49979   const RequestID request_id = req.request_id;
49980   invoking_method_reply_ = true;
49981   service_proxy->EndInvoke(request_id, std::move(decoded_reply),
49982                            reply.has_more());
49983   invoking_method_reply_ = false;
49984 
49985   // If this is a streaming method and future replies will be resolved, put back
49986   // the |req| with the callback into the set of active requests.
49987   if (reply.has_more())
49988     queued_requests_.emplace(request_id, std::move(req));
49989 }
49990 
49991 ClientImpl::QueuedRequest::QueuedRequest() = default;
49992 
TakeReceivedFD()49993 base::ScopedFile ClientImpl::TakeReceivedFD() {
49994   return std::move(received_fd_);
49995 }
49996 
49997 }  // namespace ipc
49998 }  // namespace perfetto
49999 // gen_amalgamated begin source: src/ipc/service_proxy.cc
50000 /*
50001  * Copyright (C) 2017 The Android Open Source Project
50002  *
50003  * Licensed under the Apache License, Version 2.0 (the "License");
50004  * you may not use this file except in compliance with the License.
50005  * You may obtain a copy of the License at
50006  *
50007  *      http://www.apache.org/licenses/LICENSE-2.0
50008  *
50009  * Unless required by applicable law or agreed to in writing, software
50010  * distributed under the License is distributed on an "AS IS" BASIS,
50011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50012  * See the License for the specific language governing permissions and
50013  * limitations under the License.
50014  */
50015 
50016 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
50017 
50018 #include <utility>
50019 
50020 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
50021 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
50022 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
50023 // gen_amalgamated expanded: #include "src/ipc/client_impl.h"
50024 
50025 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
50026 
50027 namespace perfetto {
50028 namespace ipc {
50029 
ServiceProxy(EventListener * event_listener)50030 ServiceProxy::ServiceProxy(EventListener* event_listener)
50031     : event_listener_(event_listener), weak_ptr_factory_(this) {}
50032 
~ServiceProxy()50033 ServiceProxy::~ServiceProxy() {
50034   if (client_ && connected())
50035     client_->UnbindService(service_id_);
50036 }
50037 
InitializeBinding(base::WeakPtr<Client> client,ServiceID service_id,std::map<std::string,MethodID> remote_method_ids)50038 void ServiceProxy::InitializeBinding(
50039     base::WeakPtr<Client> client,
50040     ServiceID service_id,
50041     std::map<std::string, MethodID> remote_method_ids) {
50042   client_ = std::move(client);
50043   service_id_ = service_id;
50044   remote_method_ids_ = std::move(remote_method_ids);
50045 }
50046 
BeginInvoke(const std::string & method_name,const ProtoMessage & request,DeferredBase reply,int fd)50047 void ServiceProxy::BeginInvoke(const std::string& method_name,
50048                                const ProtoMessage& request,
50049                                DeferredBase reply,
50050                                int fd) {
50051   // |reply| will auto-resolve if it gets out of scope early.
50052   if (!connected()) {
50053     PERFETTO_DFATAL("Not connected.");
50054     return;
50055   }
50056   if (!client_)
50057     return;  // The Client object has been destroyed in the meantime.
50058 
50059   auto remote_method_it = remote_method_ids_.find(method_name);
50060   RequestID request_id = 0;
50061   const bool drop_reply = !reply.IsBound();
50062   if (remote_method_it != remote_method_ids_.end()) {
50063     request_id =
50064         static_cast<ClientImpl*>(client_.get())
50065             ->BeginInvoke(service_id_, method_name, remote_method_it->second,
50066                           request, drop_reply, weak_ptr_factory_.GetWeakPtr(),
50067                           fd);
50068   } else {
50069     PERFETTO_DLOG("Cannot find method \"%s\" on the host", method_name.c_str());
50070   }
50071 
50072   // When passing |drop_reply| == true, the returned |request_id| should be 0.
50073   PERFETTO_DCHECK(!drop_reply || !request_id);
50074 
50075   if (!request_id)
50076     return;
50077   PERFETTO_DCHECK(pending_callbacks_.count(request_id) == 0);
50078   pending_callbacks_.emplace(request_id, std::move(reply));
50079 }
50080 
EndInvoke(RequestID request_id,std::unique_ptr<ProtoMessage> result,bool has_more)50081 void ServiceProxy::EndInvoke(RequestID request_id,
50082                              std::unique_ptr<ProtoMessage> result,
50083                              bool has_more) {
50084   auto callback_it = pending_callbacks_.find(request_id);
50085   if (callback_it == pending_callbacks_.end()) {
50086     // Either we are getting a reply for a method we never invoked, or we are
50087     // getting a reply to a method marked drop_reply (that has been invoked
50088     // without binding any callback in the Defererd response object).
50089     PERFETTO_DFATAL("Unexpected reply received.");
50090     return;
50091   }
50092   DeferredBase& reply_callback = callback_it->second;
50093   AsyncResult<ProtoMessage> reply(std::move(result), has_more);
50094   reply_callback.Resolve(std::move(reply));
50095   if (!has_more)
50096     pending_callbacks_.erase(callback_it);
50097 }
50098 
OnConnect(bool success)50099 void ServiceProxy::OnConnect(bool success) {
50100   if (success) {
50101     PERFETTO_DCHECK(service_id_);
50102     return event_listener_->OnConnect();
50103   }
50104   return event_listener_->OnDisconnect();
50105 }
50106 
OnDisconnect()50107 void ServiceProxy::OnDisconnect() {
50108   pending_callbacks_.clear();  // Will Reject() all the pending callbacks.
50109   event_listener_->OnDisconnect();
50110 }
50111 
GetWeakPtr() const50112 base::WeakPtr<ServiceProxy> ServiceProxy::GetWeakPtr() const {
50113   return weak_ptr_factory_.GetWeakPtr();
50114 }
50115 
50116 }  // namespace ipc
50117 }  // namespace perfetto
50118 // gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
50119 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/default_socket.h
50120 /*
50121  * Copyright (C) 2018 The Android Open Source Project
50122  *
50123  * Licensed under the Apache License, Version 2.0 (the "License");
50124  * you may not use this file except in compliance with the License.
50125  * You may obtain a copy of the License at
50126  *
50127  *      http://www.apache.org/licenses/LICENSE-2.0
50128  *
50129  * Unless required by applicable law or agreed to in writing, software
50130  * distributed under the License is distributed on an "AS IS" BASIS,
50131  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50132  * See the License for the specific language governing permissions and
50133  * limitations under the License.
50134  */
50135 
50136 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
50137 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
50138 
50139 // gen_amalgamated expanded: #include "perfetto/base/export.h"
50140 
50141 namespace perfetto {
50142 
50143 PERFETTO_EXPORT const char* GetConsumerSocket();
50144 PERFETTO_EXPORT const char* GetProducerSocket();
50145 
50146 }  // namespace perfetto
50147 
50148 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
50149 /*
50150  * Copyright (C) 2018 The Android Open Source Project
50151  *
50152  * Licensed under the Apache License, Version 2.0 (the "License");
50153  * you may not use this file except in compliance with the License.
50154  * You may obtain a copy of the License at
50155  *
50156  *      http://www.apache.org/licenses/LICENSE-2.0
50157  *
50158  * Unless required by applicable law or agreed to in writing, software
50159  * distributed under the License is distributed on an "AS IS" BASIS,
50160  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50161  * See the License for the specific language governing permissions and
50162  * limitations under the License.
50163  */
50164 
50165 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
50166 
50167 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
50168 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
50169 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
50170 
50171 #include <stdlib.h>
50172 
50173 namespace perfetto {
50174 
50175 static_assert(kInvalidUid == ipc::kInvalidUid, "kInvalidUid mismatching");
50176 
GetProducerSocket()50177 const char* GetProducerSocket() {
50178   static const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
50179   if (name == nullptr) {
50180 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
50181     name = "/dev/socket/traced_producer";
50182 #else
50183     name = "/tmp/perfetto-producer";
50184 #endif
50185   }
50186   return name;
50187 }
50188 
GetConsumerSocket()50189 const char* GetConsumerSocket() {
50190   static const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
50191   if (name == nullptr) {
50192 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
50193     name = "/dev/socket/traced_consumer";
50194 #else
50195     name = "/tmp/perfetto-consumer";
50196 #endif
50197   }
50198   return name;
50199 }
50200 
50201 }  // namespace perfetto
50202 // gen_amalgamated begin source: src/tracing/ipc/memfd.cc
50203 // gen_amalgamated begin header: src/tracing/ipc/memfd.h
50204 /*
50205  * Copyright (C) 2020 The Android Open Source Project
50206  *
50207  * Licensed under the Apache License, Version 2.0 (the "License");
50208  * you may not use this file except in compliance with the License.
50209  * You may obtain a copy of the License at
50210  *
50211  *      http://www.apache.org/licenses/LICENSE-2.0
50212  *
50213  * Unless required by applicable law or agreed to in writing, software
50214  * distributed under the License is distributed on an "AS IS" BASIS,
50215  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50216  * See the License for the specific language governing permissions and
50217  * limitations under the License.
50218  */
50219 
50220 #ifndef SRC_TRACING_IPC_MEMFD_H_
50221 #define SRC_TRACING_IPC_MEMFD_H_
50222 
50223 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
50224 
50225 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
50226 
50227 // Some android build bots use a sysroot that doesn't support memfd when
50228 // compiling for the host, so we define the flags we need ourselves.
50229 
50230 // from memfd.h
50231 #ifndef MFD_CLOEXEC
50232 #define MFD_CLOEXEC 0x0001U
50233 #define MFD_ALLOW_SEALING 0x0002U
50234 #endif
50235 
50236 // from fcntl.h
50237 #ifndef F_ADD_SEALS
50238 #define F_ADD_SEALS 1033
50239 #define F_GET_SEALS 1034
50240 #define F_SEAL_SEAL 0x0001
50241 #define F_SEAL_SHRINK 0x0002
50242 #define F_SEAL_GROW 0x0004
50243 #define F_SEAL_WRITE 0x0008
50244 #endif
50245 
50246 namespace perfetto {
50247 
50248 // Whether the operating system supports memfd.
50249 bool HasMemfdSupport();
50250 
50251 // Call memfd(2) if available on platform and return the fd as result. This call
50252 // also makes a kernel version check for safety on older kernels (b/116769556).
50253 // Returns an invalid ScopedFile on failure.
50254 base::ScopedFile CreateMemfd(const char* name, unsigned int flags);
50255 
50256 }  // namespace perfetto
50257 
50258 #endif  // SRC_TRACING_IPC_MEMFD_H_
50259 /*
50260  * Copyright (C) 2020 The Android Open Source Project
50261  *
50262  * Licensed under the Apache License, Version 2.0 (the "License");
50263  * you may not use this file except in compliance with the License.
50264  * You may obtain a copy of the License at
50265  *
50266  *      http://www.apache.org/licenses/LICENSE-2.0
50267  *
50268  * Unless required by applicable law or agreed to in writing, software
50269  * distributed under the License is distributed on an "AS IS" BASIS,
50270  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50271  * See the License for the specific language governing permissions and
50272  * limitations under the License.
50273  */
50274 
50275 // gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
50276 
50277 #include <errno.h>
50278 
50279 #define PERFETTO_MEMFD_ENABLED()             \
50280   PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
50281       PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
50282 
50283 #if PERFETTO_MEMFD_ENABLED()
50284 
50285 #include <stdio.h>
50286 #include <string.h>
50287 #include <sys/syscall.h>
50288 #include <sys/utsname.h>
50289 #include <unistd.h>
50290 
50291 // Some android build bots use a sysroot that doesn't support memfd when
50292 // compiling for the host, so we redefine it if necessary.
50293 #if !defined(__NR_memfd_create)
50294 #if defined(__x86_64__)
50295 #define __NR_memfd_create 319
50296 #elif defined(__i386__)
50297 #define __NR_memfd_create 356
50298 #elif defined(__aarch64__)
50299 #define __NR_memfd_create 279
50300 #elif defined(__arm__)
50301 #define __NR_memfd_create 385
50302 #else
50303 #error "unsupported sysroot without memfd support"
50304 #endif
50305 #endif  // !defined(__NR_memfd_create)
50306 
50307 namespace perfetto {
HasMemfdSupport()50308 bool HasMemfdSupport() {
50309   static bool kSupportsMemfd = [] {
50310     // Check kernel version supports memfd_create(). Some older kernels segfault
50311     // executing memfd_create() rather than returning ENOSYS (b/116769556).
50312     static constexpr int kRequiredMajor = 3;
50313     static constexpr int kRequiredMinor = 17;
50314     struct utsname uts;
50315     int major, minor;
50316     if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0 &&
50317         sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
50318         ((major < kRequiredMajor ||
50319           (major == kRequiredMajor && minor < kRequiredMinor)))) {
50320       return false;
50321     }
50322 
50323     base::ScopedFile fd;
50324     fd.reset(static_cast<int>(syscall(__NR_memfd_create, "perfetto_shmem",
50325                                       MFD_CLOEXEC | MFD_ALLOW_SEALING)));
50326     return !!fd;
50327   }();
50328   return kSupportsMemfd;
50329 }
50330 
CreateMemfd(const char * name,unsigned int flags)50331 base::ScopedFile CreateMemfd(const char* name, unsigned int flags) {
50332   if (!HasMemfdSupport()) {
50333     errno = ENOSYS;
50334     return base::ScopedFile();
50335   }
50336   return base::ScopedFile(
50337       static_cast<int>(syscall(__NR_memfd_create, name, flags)));
50338 }
50339 }  // namespace perfetto
50340 
50341 #else  // PERFETTO_MEMFD_ENABLED()
50342 
50343 namespace perfetto {
HasMemfdSupport()50344 bool HasMemfdSupport() {
50345   return false;
50346 }
CreateMemfd(const char *,unsigned int)50347 base::ScopedFile CreateMemfd(const char*, unsigned int) {
50348   errno = ENOSYS;
50349   return base::ScopedFile();
50350 }
50351 }  // namespace perfetto
50352 
50353 #endif  // PERFETTO_MEMFD_ENABLED()
50354 // gen_amalgamated begin source: src/tracing/ipc/posix_shared_memory.cc
50355 // gen_amalgamated begin header: src/tracing/ipc/posix_shared_memory.h
50356 /*
50357  * Copyright (C) 2017 The Android Open Source Project
50358  *
50359  * Licensed under the Apache License, Version 2.0 (the "License");
50360  * you may not use this file except in compliance with the License.
50361  * You may obtain a copy of the License at
50362  *
50363  *      http://www.apache.org/licenses/LICENSE-2.0
50364  *
50365  * Unless required by applicable law or agreed to in writing, software
50366  * distributed under the License is distributed on an "AS IS" BASIS,
50367  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50368  * See the License for the specific language governing permissions and
50369  * limitations under the License.
50370  */
50371 
50372 #ifndef SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
50373 #define SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
50374 
50375 #include <stddef.h>
50376 
50377 #include <memory>
50378 
50379 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
50380 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
50381 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
50382 
50383 namespace perfetto {
50384 
50385 // Implements the SharedMemory and its factory for the posix-based transport.
50386 class PosixSharedMemory : public SharedMemory {
50387  public:
50388   class Factory : public SharedMemory::Factory {
50389    public:
50390     ~Factory() override;
50391     std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
50392   };
50393 
50394   // Create a brand new SHM region.
50395   static std::unique_ptr<PosixSharedMemory> Create(size_t size);
50396 
50397   // Mmaps a file descriptor to an existing SHM region. If
50398   // |require_seals_if_supported| is true and the system supports
50399   // memfd_create(), the FD is required to be a sealed memfd with F_SEAL_SEAL,
50400   // F_SEAL_GROW, and F_SEAL_SHRINK seals set (otherwise, nullptr is returned).
50401   // May also return nullptr if mapping fails for another reason (e.g. OOM).
50402   static std::unique_ptr<PosixSharedMemory> AttachToFd(
50403       base::ScopedFile,
50404       bool require_seals_if_supported = true);
50405 
50406   ~PosixSharedMemory() override;
50407 
fd() const50408   int fd() const override { return fd_.get(); }
50409 
50410   // SharedMemory implementation.
start() const50411   void* start() const override { return start_; }
size() const50412   size_t size() const override { return size_; }
50413 
50414  private:
50415   static std::unique_ptr<PosixSharedMemory> MapFD(base::ScopedFile, size_t);
50416 
50417   PosixSharedMemory(void* start, size_t size, base::ScopedFile);
50418   PosixSharedMemory(const PosixSharedMemory&) = delete;
50419   PosixSharedMemory& operator=(const PosixSharedMemory&) = delete;
50420 
50421   void* const start_;
50422   const size_t size_;
50423   base::ScopedFile fd_;
50424 };
50425 
50426 }  // namespace perfetto
50427 
50428 #endif  // SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
50429 /*
50430  * Copyright (C) 2017 The Android Open Source Project
50431  *
50432  * Licensed under the Apache License, Version 2.0 (the "License");
50433  * you may not use this file except in compliance with the License.
50434  * You may obtain a copy of the License at
50435  *
50436  *      http://www.apache.org/licenses/LICENSE-2.0
50437  *
50438  * Unless required by applicable law or agreed to in writing, software
50439  * distributed under the License is distributed on an "AS IS" BASIS,
50440  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50441  * See the License for the specific language governing permissions and
50442  * limitations under the License.
50443  */
50444 
50445 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
50446 
50447 #include <fcntl.h>
50448 #include <stdint.h>
50449 #include <stdio.h>
50450 #include <stdlib.h>
50451 #include <sys/mman.h>
50452 #include <sys/stat.h>
50453 #include <unistd.h>
50454 
50455 #include <memory>
50456 #include <utility>
50457 
50458 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
50459 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
50460 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
50461 // gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
50462 
50463 namespace perfetto {
50464 
50465 namespace {
50466 int kFileSeals = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL;
50467 }  // namespace
50468 
50469 // static
Create(size_t size)50470 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::Create(size_t size) {
50471   base::ScopedFile fd =
50472       CreateMemfd("perfetto_shmem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
50473   bool is_memfd = !!fd;
50474 
50475   // In-tree builds only allow mem_fd, so we can inspect the seals to verify the
50476   // fd is appropriately sealed. We'll crash in the PERFETTO_CHECK(fd) below if
50477   // memfd_create failed.
50478 #if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
50479   if (!fd) {
50480     // TODO: if this fails on Android we should fall back on ashmem.
50481     PERFETTO_DPLOG("memfd_create() failed");
50482     fd = base::TempFile::CreateUnlinked().ReleaseFD();
50483   }
50484 #endif
50485 
50486   PERFETTO_CHECK(fd);
50487   int res = ftruncate(fd.get(), static_cast<off_t>(size));
50488   PERFETTO_CHECK(res == 0);
50489 
50490   if (is_memfd) {
50491     // When memfd is supported, file seals should be, too.
50492     res = fcntl(*fd, F_ADD_SEALS, kFileSeals);
50493     PERFETTO_DCHECK(res == 0);
50494   }
50495 
50496   return MapFD(std::move(fd), size);
50497 }
50498 
50499 // static
AttachToFd(base::ScopedFile fd,bool require_seals_if_supported)50500 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::AttachToFd(
50501     base::ScopedFile fd,
50502     bool require_seals_if_supported) {
50503   bool requires_seals = require_seals_if_supported;
50504 
50505 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
50506   // In-tree kernels all support memfd.
50507   PERFETTO_CHECK(HasMemfdSupport());
50508 #else
50509   // In out-of-tree builds, we only require seals if the kernel supports memfd.
50510   if (requires_seals)
50511     requires_seals = HasMemfdSupport();
50512 #endif
50513 
50514   if (requires_seals) {
50515     // If the system supports memfd, we require a sealed memfd.
50516     int res = fcntl(*fd, F_GET_SEALS);
50517     if (res == -1 || (res & kFileSeals) != kFileSeals) {
50518       PERFETTO_PLOG("Couldn't verify file seals on shmem FD");
50519       return nullptr;
50520     }
50521   }
50522 
50523   struct stat stat_buf = {};
50524   int res = fstat(fd.get(), &stat_buf);
50525   PERFETTO_CHECK(res == 0 && stat_buf.st_size > 0);
50526   return MapFD(std::move(fd), static_cast<size_t>(stat_buf.st_size));
50527 }
50528 
50529 // static
MapFD(base::ScopedFile fd,size_t size)50530 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::MapFD(base::ScopedFile fd,
50531                                                             size_t size) {
50532   PERFETTO_DCHECK(fd);
50533   PERFETTO_DCHECK(size > 0);
50534   void* start =
50535       mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
50536   PERFETTO_CHECK(start != MAP_FAILED);
50537   return std::unique_ptr<PosixSharedMemory>(
50538       new PosixSharedMemory(start, size, std::move(fd)));
50539 }
50540 
PosixSharedMemory(void * start,size_t size,base::ScopedFile fd)50541 PosixSharedMemory::PosixSharedMemory(void* start,
50542                                      size_t size,
50543                                      base::ScopedFile fd)
50544     : start_(start), size_(size), fd_(std::move(fd)) {}
50545 
~PosixSharedMemory()50546 PosixSharedMemory::~PosixSharedMemory() {
50547   munmap(start(), size());
50548 }
50549 
~Factory()50550 PosixSharedMemory::Factory::~Factory() {}
50551 
CreateSharedMemory(size_t size)50552 std::unique_ptr<SharedMemory> PosixSharedMemory::Factory::CreateSharedMemory(
50553     size_t size) {
50554   return PosixSharedMemory::Create(size);
50555 }
50556 
50557 }  // namespace perfetto
50558 // gen_amalgamated begin source: src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
50559 // gen_amalgamated begin header: src/tracing/ipc/consumer/consumer_ipc_client_impl.h
50560 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/consumer_ipc_client.h
50561 /*
50562  * Copyright (C) 2017 The Android Open Source Project
50563  *
50564  * Licensed under the Apache License, Version 2.0 (the "License");
50565  * you may not use this file except in compliance with the License.
50566  * You may obtain a copy of the License at
50567  *
50568  *      http://www.apache.org/licenses/LICENSE-2.0
50569  *
50570  * Unless required by applicable law or agreed to in writing, software
50571  * distributed under the License is distributed on an "AS IS" BASIS,
50572  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50573  * See the License for the specific language governing permissions and
50574  * limitations under the License.
50575  */
50576 
50577 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
50578 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
50579 
50580 #include <memory>
50581 #include <string>
50582 
50583 // gen_amalgamated expanded: #include "perfetto/base/export.h"
50584 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
50585 
50586 namespace perfetto {
50587 
50588 class Consumer;
50589 
50590 // Allows to connect to a remote Service through a UNIX domain socket.
50591 // Exposed to:
50592 //   Consumer(s) of the tracing library.
50593 // Implemented in:
50594 //   src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
50595 class PERFETTO_EXPORT ConsumerIPCClient {
50596  public:
50597   // Connects to the producer port of the Service listening on the given
50598   // |service_sock_name|. If the connection is successful, the OnConnect()
50599   // method will be invoked asynchronously on the passed Consumer interface.
50600   // If the connection fails, OnDisconnect() will be invoked instead.
50601   // The returned ConsumerEndpoint serves also to delimit the scope of the
50602   // callbacks invoked on the Consumer interface: no more Consumer callbacks are
50603   // invoked immediately after its destruction and any pending callback will be
50604   // dropped.
50605   static std::unique_ptr<TracingService::ConsumerEndpoint>
50606   Connect(const char* service_sock_name, Consumer*, base::TaskRunner*);
50607 
50608  protected:
50609   ConsumerIPCClient() = delete;
50610 };
50611 
50612 }  // namespace perfetto
50613 
50614 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
50615 /*
50616  * Copyright (C) 2017 The Android Open Source Project
50617  *
50618  * Licensed under the Apache License, Version 2.0 (the "License");
50619  * you may not use this file except in compliance with the License.
50620  * You may obtain a copy of the License at
50621  *
50622  *      http://www.apache.org/licenses/LICENSE-2.0
50623  *
50624  * Unless required by applicable law or agreed to in writing, software
50625  * distributed under the License is distributed on an "AS IS" BASIS,
50626  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50627  * See the License for the specific language governing permissions and
50628  * limitations under the License.
50629  */
50630 
50631 #ifndef SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
50632 #define SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
50633 
50634 #include <stdint.h>
50635 
50636 #include <list>
50637 #include <vector>
50638 
50639 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
50640 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
50641 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
50642 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
50643 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
50644 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
50645 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
50646 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
50647 
50648 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
50649 
50650 namespace perfetto {
50651 
50652 namespace base {
50653 class TaskRunner;
50654 }  // namespace base
50655 
50656 namespace ipc {
50657 class Client;
50658 }  // namespace ipc
50659 
50660 class Consumer;
50661 
50662 // Exposes a Service endpoint to Consumer(s), proxying all requests through a
50663 // IPC channel to the remote Service. This class is the glue layer between the
50664 // generic Service interface exposed to the clients of the library and the
50665 // actual IPC transport.
50666 class ConsumerIPCClientImpl : public TracingService::ConsumerEndpoint,
50667                               public ipc::ServiceProxy::EventListener {
50668  public:
50669   ConsumerIPCClientImpl(const char* service_sock_name,
50670                         Consumer*,
50671                         base::TaskRunner*);
50672   ~ConsumerIPCClientImpl() override;
50673 
50674   // TracingService::ConsumerEndpoint implementation.
50675   // These methods are invoked by the actual Consumer(s) code by clients of the
50676   // tracing library, which know nothing about the IPC transport.
50677   void EnableTracing(const TraceConfig&, base::ScopedFile) override;
50678   void StartTracing() override;
50679   void ChangeTraceConfig(const TraceConfig&) override;
50680   void DisableTracing() override;
50681   void ReadBuffers() override;
50682   void FreeBuffers() override;
50683   void Flush(uint32_t timeout_ms, FlushCallback) override;
50684   void Detach(const std::string& key) override;
50685   void Attach(const std::string& key) override;
50686   void GetTraceStats() override;
50687   void ObserveEvents(uint32_t enabled_event_types) override;
50688   void QueryServiceState(QueryServiceStateCallback) override;
50689   void QueryCapabilities(QueryCapabilitiesCallback) override;
50690 
50691   // ipc::ServiceProxy::EventListener implementation.
50692   // These methods are invoked by the IPC layer, which knows nothing about
50693   // tracing, consumers and consumers.
50694   void OnConnect() override;
50695   void OnDisconnect() override;
50696 
50697  private:
50698   struct PendingQueryServiceRequest {
50699     QueryServiceStateCallback callback;
50700 
50701     // All the replies will be appended here until |has_more| == false.
50702     std::vector<uint8_t> merged_resp;
50703   };
50704 
50705   // List because we need stable iterators.
50706   using PendingQueryServiceRequests = std::list<PendingQueryServiceRequest>;
50707 
50708   void OnReadBuffersResponse(
50709       ipc::AsyncResult<protos::gen::ReadBuffersResponse>);
50710   void OnEnableTracingResponse(
50711       ipc::AsyncResult<protos::gen::EnableTracingResponse>);
50712   void OnQueryServiceStateResponse(
50713       ipc::AsyncResult<protos::gen::QueryServiceStateResponse>,
50714       PendingQueryServiceRequests::iterator);
50715 
50716   // TODO(primiano): think to dtor order, do we rely on any specific sequence?
50717   Consumer* const consumer_;
50718 
50719   // The object that owns the client socket and takes care of IPC traffic.
50720   std::unique_ptr<ipc::Client> ipc_channel_;
50721 
50722   // The proxy interface for the consumer port of the service. It is bound
50723   // to |ipc_channel_| and (de)serializes method invocations over the wire.
50724   protos::gen::ConsumerPortProxy consumer_port_;
50725 
50726   bool connected_ = false;
50727 
50728   PendingQueryServiceRequests pending_query_svc_reqs_;
50729 
50730   // When a packet is too big to fit into a ReadBuffersResponse IPC, the service
50731   // will chunk it into several IPCs, each containing few slices of the packet
50732   // (a packet's slice is always guaranteed to be << kIPCBufferSize). When
50733   // chunking happens this field accumulates the slices received until the
50734   // one with |last_slice_for_packet| == true is received.
50735   TracePacket partial_packet_;
50736 
50737   // Keep last.
50738   base::WeakPtrFactory<ConsumerIPCClientImpl> weak_ptr_factory_;
50739 };
50740 
50741 }  // namespace perfetto
50742 
50743 #endif  // SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
50744 /*
50745  * Copyright (C) 2017 The Android Open Source Project
50746  *
50747  * Licensed under the Apache License, Version 2.0 (the "License");
50748  * you may not use this file except in compliance with the License.
50749  * You may obtain a copy of the License at
50750  *
50751  *      http://www.apache.org/licenses/LICENSE-2.0
50752  *
50753  * Unless required by applicable law or agreed to in writing, software
50754  * distributed under the License is distributed on an "AS IS" BASIS,
50755  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
50756  * See the License for the specific language governing permissions and
50757  * limitations under the License.
50758  */
50759 
50760 // gen_amalgamated expanded: #include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"
50761 
50762 #include <inttypes.h>
50763 #include <string.h>
50764 
50765 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
50766 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
50767 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
50768 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
50769 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
50770 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
50771 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
50772 
50773 // TODO(fmayer): Add a test to check to what happens when ConsumerIPCClientImpl
50774 // gets destroyed w.r.t. the Consumer pointer. Also think to lifetime of the
50775 // Consumer* during the callbacks.
50776 
50777 namespace perfetto {
50778 
50779 // static. (Declared in include/tracing/ipc/consumer_ipc_client.h).
Connect(const char * service_sock_name,Consumer * consumer,base::TaskRunner * task_runner)50780 std::unique_ptr<TracingService::ConsumerEndpoint> ConsumerIPCClient::Connect(
50781     const char* service_sock_name,
50782     Consumer* consumer,
50783     base::TaskRunner* task_runner) {
50784   return std::unique_ptr<TracingService::ConsumerEndpoint>(
50785       new ConsumerIPCClientImpl(service_sock_name, consumer, task_runner));
50786 }
50787 
ConsumerIPCClientImpl(const char * service_sock_name,Consumer * consumer,base::TaskRunner * task_runner)50788 ConsumerIPCClientImpl::ConsumerIPCClientImpl(const char* service_sock_name,
50789                                              Consumer* consumer,
50790                                              base::TaskRunner* task_runner)
50791     : consumer_(consumer),
50792       ipc_channel_(ipc::Client::CreateInstance(service_sock_name,
50793                                                /*retry=*/false,
50794                                                task_runner)),
50795       consumer_port_(this /* event_listener */),
50796       weak_ptr_factory_(this) {
50797   ipc_channel_->BindService(consumer_port_.GetWeakPtr());
50798 }
50799 
50800 ConsumerIPCClientImpl::~ConsumerIPCClientImpl() = default;
50801 
50802 // Called by the IPC layer if the BindService() succeeds.
OnConnect()50803 void ConsumerIPCClientImpl::OnConnect() {
50804   connected_ = true;
50805   consumer_->OnConnect();
50806 }
50807 
OnDisconnect()50808 void ConsumerIPCClientImpl::OnDisconnect() {
50809   PERFETTO_DLOG("Tracing service connection failure");
50810   connected_ = false;
50811   consumer_->OnDisconnect();
50812 }
50813 
EnableTracing(const TraceConfig & trace_config,base::ScopedFile fd)50814 void ConsumerIPCClientImpl::EnableTracing(const TraceConfig& trace_config,
50815                                           base::ScopedFile fd) {
50816   if (!connected_) {
50817     PERFETTO_DLOG("Cannot EnableTracing(), not connected to tracing service");
50818     return;
50819   }
50820 
50821   protos::gen::EnableTracingRequest req;
50822   *req.mutable_trace_config() = trace_config;
50823   ipc::Deferred<protos::gen::EnableTracingResponse> async_response;
50824   auto weak_this = weak_ptr_factory_.GetWeakPtr();
50825   async_response.Bind(
50826       [weak_this](
50827           ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
50828         if (weak_this)
50829           weak_this->OnEnableTracingResponse(std::move(response));
50830       });
50831 
50832   // |fd| will be closed when this function returns, but it's fine because the
50833   // IPC layer dup()'s it when sending the IPC.
50834   consumer_port_.EnableTracing(req, std::move(async_response), *fd);
50835 }
50836 
ChangeTraceConfig(const TraceConfig &)50837 void ConsumerIPCClientImpl::ChangeTraceConfig(const TraceConfig&) {
50838   if (!connected_) {
50839     PERFETTO_DLOG(
50840         "Cannot ChangeTraceConfig(), not connected to tracing service");
50841     return;
50842   }
50843 
50844   ipc::Deferred<protos::gen::ChangeTraceConfigResponse> async_response;
50845   async_response.Bind(
50846       [](ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse> response) {
50847         if (!response)
50848           PERFETTO_DLOG("ChangeTraceConfig() failed");
50849       });
50850   protos::gen::ChangeTraceConfigRequest req;
50851   consumer_port_.ChangeTraceConfig(req, std::move(async_response));
50852 }
50853 
StartTracing()50854 void ConsumerIPCClientImpl::StartTracing() {
50855   if (!connected_) {
50856     PERFETTO_DLOG("Cannot StartTracing(), not connected to tracing service");
50857     return;
50858   }
50859 
50860   ipc::Deferred<protos::gen::StartTracingResponse> async_response;
50861   async_response.Bind(
50862       [](ipc::AsyncResult<protos::gen::StartTracingResponse> response) {
50863         if (!response)
50864           PERFETTO_DLOG("StartTracing() failed");
50865       });
50866   protos::gen::StartTracingRequest req;
50867   consumer_port_.StartTracing(req, std::move(async_response));
50868 }
50869 
DisableTracing()50870 void ConsumerIPCClientImpl::DisableTracing() {
50871   if (!connected_) {
50872     PERFETTO_DLOG("Cannot DisableTracing(), not connected to tracing service");
50873     return;
50874   }
50875 
50876   ipc::Deferred<protos::gen::DisableTracingResponse> async_response;
50877   async_response.Bind(
50878       [](ipc::AsyncResult<protos::gen::DisableTracingResponse> response) {
50879         if (!response)
50880           PERFETTO_DLOG("DisableTracing() failed");
50881       });
50882   consumer_port_.DisableTracing(protos::gen::DisableTracingRequest(),
50883                                 std::move(async_response));
50884 }
50885 
ReadBuffers()50886 void ConsumerIPCClientImpl::ReadBuffers() {
50887   if (!connected_) {
50888     PERFETTO_DLOG("Cannot ReadBuffers(), not connected to tracing service");
50889     return;
50890   }
50891 
50892   ipc::Deferred<protos::gen::ReadBuffersResponse> async_response;
50893 
50894   // The IPC layer guarantees that callbacks are destroyed after this object
50895   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
50896   // contract of this class expects the caller to not destroy the Consumer class
50897   // before having destroyed this class. Hence binding |this| here is safe.
50898   async_response.Bind(
50899       [this](ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
50900         OnReadBuffersResponse(std::move(response));
50901       });
50902   consumer_port_.ReadBuffers(protos::gen::ReadBuffersRequest(),
50903                              std::move(async_response));
50904 }
50905 
OnReadBuffersResponse(ipc::AsyncResult<protos::gen::ReadBuffersResponse> response)50906 void ConsumerIPCClientImpl::OnReadBuffersResponse(
50907     ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
50908   if (!response) {
50909     PERFETTO_DLOG("ReadBuffers() failed");
50910     return;
50911   }
50912   std::vector<TracePacket> trace_packets;
50913   for (auto& resp_slice : response->slices()) {
50914     const std::string& slice_data = resp_slice.data();
50915     Slice slice = Slice::Allocate(slice_data.size());
50916     memcpy(slice.own_data(), slice_data.data(), slice.size);
50917     partial_packet_.AddSlice(std::move(slice));
50918     if (resp_slice.last_slice_for_packet())
50919       trace_packets.emplace_back(std::move(partial_packet_));
50920   }
50921   if (!trace_packets.empty() || !response.has_more())
50922     consumer_->OnTraceData(std::move(trace_packets), response.has_more());
50923 }
50924 
OnEnableTracingResponse(ipc::AsyncResult<protos::gen::EnableTracingResponse> response)50925 void ConsumerIPCClientImpl::OnEnableTracingResponse(
50926     ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
50927   if (!response || response->disabled())
50928     consumer_->OnTracingDisabled();
50929 }
50930 
FreeBuffers()50931 void ConsumerIPCClientImpl::FreeBuffers() {
50932   if (!connected_) {
50933     PERFETTO_DLOG("Cannot FreeBuffers(), not connected to tracing service");
50934     return;
50935   }
50936 
50937   protos::gen::FreeBuffersRequest req;
50938   ipc::Deferred<protos::gen::FreeBuffersResponse> async_response;
50939   async_response.Bind(
50940       [](ipc::AsyncResult<protos::gen::FreeBuffersResponse> response) {
50941         if (!response)
50942           PERFETTO_DLOG("FreeBuffers() failed");
50943       });
50944   consumer_port_.FreeBuffers(req, std::move(async_response));
50945 }
50946 
Flush(uint32_t timeout_ms,FlushCallback callback)50947 void ConsumerIPCClientImpl::Flush(uint32_t timeout_ms, FlushCallback callback) {
50948   if (!connected_) {
50949     PERFETTO_DLOG("Cannot Flush(), not connected to tracing service");
50950     return callback(/*success=*/false);
50951   }
50952 
50953   protos::gen::FlushRequest req;
50954   req.set_timeout_ms(static_cast<uint32_t>(timeout_ms));
50955   ipc::Deferred<protos::gen::FlushResponse> async_response;
50956   async_response.Bind(
50957       [callback](ipc::AsyncResult<protos::gen::FlushResponse> response) {
50958         callback(!!response);
50959       });
50960   consumer_port_.Flush(req, std::move(async_response));
50961 }
50962 
Detach(const std::string & key)50963 void ConsumerIPCClientImpl::Detach(const std::string& key) {
50964   if (!connected_) {
50965     PERFETTO_DLOG("Cannot Detach(), not connected to tracing service");
50966     return;
50967   }
50968 
50969   protos::gen::DetachRequest req;
50970   req.set_key(key);
50971   ipc::Deferred<protos::gen::DetachResponse> async_response;
50972   auto weak_this = weak_ptr_factory_.GetWeakPtr();
50973 
50974   async_response.Bind(
50975       [weak_this](ipc::AsyncResult<protos::gen::DetachResponse> response) {
50976         if (weak_this)
50977           weak_this->consumer_->OnDetach(!!response);
50978       });
50979   consumer_port_.Detach(req, std::move(async_response));
50980 }
50981 
Attach(const std::string & key)50982 void ConsumerIPCClientImpl::Attach(const std::string& key) {
50983   if (!connected_) {
50984     PERFETTO_DLOG("Cannot Attach(), not connected to tracing service");
50985     return;
50986   }
50987 
50988   {
50989     protos::gen::AttachRequest req;
50990     req.set_key(key);
50991     ipc::Deferred<protos::gen::AttachResponse> async_response;
50992     auto weak_this = weak_ptr_factory_.GetWeakPtr();
50993 
50994     async_response.Bind(
50995         [weak_this](ipc::AsyncResult<protos::gen::AttachResponse> response) {
50996           if (!weak_this)
50997             return;
50998           if (!response) {
50999             weak_this->consumer_->OnAttach(/*success=*/false, TraceConfig());
51000             return;
51001           }
51002           const TraceConfig& trace_config = response->trace_config();
51003 
51004           // If attached succesfully, also attach to the end-of-trace
51005           // notificaton callback, via EnableTracing(attach_notification_only).
51006           protos::gen::EnableTracingRequest enable_req;
51007           enable_req.set_attach_notification_only(true);
51008           ipc::Deferred<protos::gen::EnableTracingResponse> enable_resp;
51009           enable_resp.Bind(
51010               [weak_this](
51011                   ipc::AsyncResult<protos::gen::EnableTracingResponse> resp) {
51012                 if (weak_this)
51013                   weak_this->OnEnableTracingResponse(std::move(resp));
51014               });
51015           weak_this->consumer_port_.EnableTracing(enable_req,
51016                                                   std::move(enable_resp));
51017 
51018           weak_this->consumer_->OnAttach(/*success=*/true, trace_config);
51019         });
51020     consumer_port_.Attach(req, std::move(async_response));
51021   }
51022 }
51023 
GetTraceStats()51024 void ConsumerIPCClientImpl::GetTraceStats() {
51025   if (!connected_) {
51026     PERFETTO_DLOG("Cannot GetTraceStats(), not connected to tracing service");
51027     return;
51028   }
51029 
51030   protos::gen::GetTraceStatsRequest req;
51031   ipc::Deferred<protos::gen::GetTraceStatsResponse> async_response;
51032 
51033   // The IPC layer guarantees that callbacks are destroyed after this object
51034   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
51035   // contract of this class expects the caller to not destroy the Consumer class
51036   // before having destroyed this class. Hence binding |this| here is safe.
51037   async_response.Bind(
51038       [this](ipc::AsyncResult<protos::gen::GetTraceStatsResponse> response) {
51039         if (!response) {
51040           consumer_->OnTraceStats(/*success=*/false, TraceStats());
51041           return;
51042         }
51043         consumer_->OnTraceStats(/*success=*/true, response->trace_stats());
51044       });
51045   consumer_port_.GetTraceStats(req, std::move(async_response));
51046 }
51047 
ObserveEvents(uint32_t enabled_event_types)51048 void ConsumerIPCClientImpl::ObserveEvents(uint32_t enabled_event_types) {
51049   if (!connected_) {
51050     PERFETTO_DLOG("Cannot ObserveEvents(), not connected to tracing service");
51051     return;
51052   }
51053 
51054   protos::gen::ObserveEventsRequest req;
51055   for (uint32_t i = 0; i < 32; i++) {
51056     const uint32_t event_id = 1u << i;
51057     if (enabled_event_types & event_id)
51058       req.add_events_to_observe(static_cast<ObservableEvents::Type>(event_id));
51059   }
51060 
51061   ipc::Deferred<protos::gen::ObserveEventsResponse> async_response;
51062   // The IPC layer guarantees that callbacks are destroyed after this object
51063   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
51064   // contract of this class expects the caller to not destroy the Consumer class
51065   // before having destroyed this class. Hence binding |this| here is safe.
51066   async_response.Bind(
51067       [this](ipc::AsyncResult<protos::gen::ObserveEventsResponse> response) {
51068         // Skip empty response, which the service sends to close the stream.
51069         if (!response.has_more()) {
51070           PERFETTO_DCHECK(!response->events().instance_state_changes().size());
51071           return;
51072         }
51073         consumer_->OnObservableEvents(response->events());
51074       });
51075   consumer_port_.ObserveEvents(req, std::move(async_response));
51076 }
51077 
QueryServiceState(QueryServiceStateCallback callback)51078 void ConsumerIPCClientImpl::QueryServiceState(
51079     QueryServiceStateCallback callback) {
51080   if (!connected_) {
51081     PERFETTO_DLOG(
51082         "Cannot QueryServiceState(), not connected to tracing service");
51083     return;
51084   }
51085 
51086   auto it = pending_query_svc_reqs_.insert(pending_query_svc_reqs_.end(),
51087                                            {std::move(callback), {}});
51088   protos::gen::QueryServiceStateRequest req;
51089   ipc::Deferred<protos::gen::QueryServiceStateResponse> async_response;
51090   auto weak_this = weak_ptr_factory_.GetWeakPtr();
51091   async_response.Bind(
51092       [weak_this,
51093        it](ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response) {
51094         if (weak_this)
51095           weak_this->OnQueryServiceStateResponse(std::move(response), it);
51096       });
51097   consumer_port_.QueryServiceState(req, std::move(async_response));
51098 }
51099 
OnQueryServiceStateResponse(ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,PendingQueryServiceRequests::iterator req_it)51100 void ConsumerIPCClientImpl::OnQueryServiceStateResponse(
51101     ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,
51102     PendingQueryServiceRequests::iterator req_it) {
51103   PERFETTO_DCHECK(req_it->callback);
51104 
51105   if (!response) {
51106     auto callback = std::move(req_it->callback);
51107     pending_query_svc_reqs_.erase(req_it);
51108     callback(false, TracingServiceState());
51109     return;
51110   }
51111 
51112   // The QueryServiceState response can be split in several chunks if the
51113   // service has several data sources. The client is supposed to merge all the
51114   // replies. The easiest way to achieve this is to re-serialize the partial
51115   // response and then re-decode the merged result in one shot.
51116   std::vector<uint8_t>& merged_resp = req_it->merged_resp;
51117   std::vector<uint8_t> part = response->service_state().SerializeAsArray();
51118   merged_resp.insert(merged_resp.end(), part.begin(), part.end());
51119 
51120   if (response.has_more())
51121     return;
51122 
51123   // All replies have been received. Decode the merged result and reply to the
51124   // callback.
51125   protos::gen::TracingServiceState svc_state;
51126   bool ok = svc_state.ParseFromArray(merged_resp.data(), merged_resp.size());
51127   if (!ok)
51128     PERFETTO_ELOG("Failed to decode merged QueryServiceStateResponse");
51129   auto callback = std::move(req_it->callback);
51130   pending_query_svc_reqs_.erase(req_it);
51131   callback(ok, std::move(svc_state));
51132 }
51133 
QueryCapabilities(QueryCapabilitiesCallback callback)51134 void ConsumerIPCClientImpl::QueryCapabilities(
51135     QueryCapabilitiesCallback callback) {
51136   if (!connected_) {
51137     PERFETTO_DLOG(
51138         "Cannot QueryCapabilities(), not connected to tracing service");
51139     return;
51140   }
51141 
51142   protos::gen::QueryCapabilitiesRequest req;
51143   ipc::Deferred<protos::gen::QueryCapabilitiesResponse> async_response;
51144   async_response.Bind(
51145       [callback](
51146           ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse> response) {
51147         if (!response) {
51148           // If the IPC fails, we are talking to an older version of the service
51149           // that didn't support QueryCapabilities at all. In this case return
51150           // an empty capabilities message.
51151           callback(TracingServiceCapabilities());
51152         } else {
51153           callback(response->capabilities());
51154         }
51155       });
51156   consumer_port_.QueryCapabilities(req, std::move(async_response));
51157 }
51158 
51159 }  // namespace perfetto
51160 // gen_amalgamated begin source: src/tracing/ipc/producer/producer_ipc_client_impl.cc
51161 // gen_amalgamated begin header: src/tracing/ipc/producer/producer_ipc_client_impl.h
51162 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/producer_ipc_client.h
51163 /*
51164  * Copyright (C) 2017 The Android Open Source Project
51165  *
51166  * Licensed under the Apache License, Version 2.0 (the "License");
51167  * you may not use this file except in compliance with the License.
51168  * You may obtain a copy of the License at
51169  *
51170  *      http://www.apache.org/licenses/LICENSE-2.0
51171  *
51172  * Unless required by applicable law or agreed to in writing, software
51173  * distributed under the License is distributed on an "AS IS" BASIS,
51174  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51175  * See the License for the specific language governing permissions and
51176  * limitations under the License.
51177  */
51178 
51179 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
51180 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
51181 
51182 #include <memory>
51183 #include <string>
51184 
51185 // gen_amalgamated expanded: #include "perfetto/base/export.h"
51186 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
51187 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
51188 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
51189 
51190 namespace perfetto {
51191 
51192 class Producer;
51193 
51194 // Allows to connect to a remote Service through a UNIX domain socket.
51195 // Exposed to:
51196 //   Producer(s) of the tracing library.
51197 // Implemented in:
51198 //   src/tracing/ipc/producer/producer_ipc_client_impl.cc
51199 class PERFETTO_EXPORT ProducerIPCClient {
51200  public:
51201   enum class ConnectionFlags {
51202     // Fails immediately with OnConnect(false) if the service connection cannot
51203     // be established.
51204     kDefault = 0,
51205 
51206     // Keeps retrying with exponential backoff indefinitely. The caller will
51207     // never see an OnConnect(false).
51208     kRetryIfUnreachable = 1,
51209   };
51210 
51211   // Connects to the producer port of the Service listening on the given
51212   // |service_sock_name|. If the connection is successful, the OnConnect()
51213   // method will be invoked asynchronously on the passed Producer interface. If
51214   // the connection fails, OnDisconnect() will be invoked instead. The returned
51215   // ProducerEndpoint serves also to delimit the scope of the callbacks invoked
51216   // on the Producer interface: no more Producer callbacks are invoked
51217   // immediately after its destruction and any pending callback will be dropped.
51218   // To provide a producer-allocated shared memory buffer, both |shm| and
51219   // |shm_arbiter| should be set. |shm_arbiter| should be an unbound
51220   // SharedMemoryArbiter instance. When |shm| and |shm_arbiter| are provided,
51221   // the service will attempt to adopt the provided SMB. If this fails, the
51222   // ProducerEndpoint will disconnect, but the SMB and arbiter will remain valid
51223   // until the client is destroyed.
51224   //
51225   // TODO(eseckler): Support adoption failure more gracefully.
51226   static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
51227       const char* service_sock_name,
51228       Producer*,
51229       const std::string& producer_name,
51230       base::TaskRunner*,
51231       TracingService::ProducerSMBScrapingMode smb_scraping_mode =
51232           TracingService::ProducerSMBScrapingMode::kDefault,
51233       size_t shared_memory_size_hint_bytes = 0,
51234       size_t shared_memory_page_size_hint_bytes = 0,
51235       std::unique_ptr<SharedMemory> shm = nullptr,
51236       std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
51237       ConnectionFlags = ConnectionFlags::kDefault);
51238 
51239  protected:
51240   ProducerIPCClient() = delete;
51241 };
51242 
51243 }  // namespace perfetto
51244 
51245 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
51246 /*
51247  * Copyright (C) 2017 The Android Open Source Project
51248  *
51249  * Licensed under the Apache License, Version 2.0 (the "License");
51250  * you may not use this file except in compliance with the License.
51251  * You may obtain a copy of the License at
51252  *
51253  *      http://www.apache.org/licenses/LICENSE-2.0
51254  *
51255  * Unless required by applicable law or agreed to in writing, software
51256  * distributed under the License is distributed on an "AS IS" BASIS,
51257  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51258  * See the License for the specific language governing permissions and
51259  * limitations under the License.
51260  */
51261 
51262 #ifndef SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
51263 #define SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
51264 
51265 #include <stdint.h>
51266 
51267 #include <set>
51268 #include <vector>
51269 
51270 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
51271 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
51272 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
51273 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
51274 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
51275 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
51276 
51277 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
51278 
51279 namespace perfetto {
51280 
51281 namespace base {
51282 class TaskRunner;
51283 }  // namespace base
51284 
51285 namespace ipc {
51286 class Client;
51287 }  // namespace ipc
51288 
51289 class Producer;
51290 class SharedMemoryArbiter;
51291 
51292 // Exposes a Service endpoint to Producer(s), proxying all requests through a
51293 // IPC channel to the remote Service. This class is the glue layer between the
51294 // generic Service interface exposed to the clients of the library and the
51295 // actual IPC transport.
51296 class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
51297                               public ipc::ServiceProxy::EventListener {
51298  public:
51299   ProducerIPCClientImpl(const char* service_sock_name,
51300                         Producer*,
51301                         const std::string& producer_name,
51302                         base::TaskRunner*,
51303                         TracingService::ProducerSMBScrapingMode,
51304                         size_t shared_memory_size_hint_bytes,
51305                         size_t shared_memory_page_size_hint_bytes,
51306                         std::unique_ptr<SharedMemory> shm,
51307                         std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
51308                         ProducerIPCClient::ConnectionFlags);
51309   ~ProducerIPCClientImpl() override;
51310 
51311   // TracingService::ProducerEndpoint implementation.
51312   // These methods are invoked by the actual Producer(s) code by clients of the
51313   // tracing library, which know nothing about the IPC transport.
51314   void RegisterDataSource(const DataSourceDescriptor&) override;
51315   void UnregisterDataSource(const std::string& name) override;
51316   void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
51317   void UnregisterTraceWriter(uint32_t writer_id) override;
51318   void CommitData(const CommitDataRequest&, CommitDataCallback) override;
51319   void NotifyDataSourceStarted(DataSourceInstanceID) override;
51320   void NotifyDataSourceStopped(DataSourceInstanceID) override;
51321   void ActivateTriggers(const std::vector<std::string>&) override;
51322   void Sync(std::function<void()> callback) override;
51323 
51324   std::unique_ptr<TraceWriter> CreateTraceWriter(
51325       BufferID target_buffer,
51326       BufferExhaustedPolicy) override;
51327   SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
51328   bool IsShmemProvidedByProducer() const override;
51329   void NotifyFlushComplete(FlushRequestID) override;
51330   SharedMemory* shared_memory() const override;
51331   size_t shared_buffer_page_size_kb() const override;
51332 
51333   // ipc::ServiceProxy::EventListener implementation.
51334   // These methods are invoked by the IPC layer, which knows nothing about
51335   // tracing, producers and consumers.
51336   void OnConnect() override;
51337   void OnDisconnect() override;
51338 
51339  private:
51340   // Invoked soon after having established the connection with the service.
51341   void OnConnectionInitialized(bool connection_succeeded,
51342                                bool using_shmem_provided_by_producer);
51343 
51344   // Invoked when the remote Service sends an IPC to tell us to do something
51345   // (e.g. start/stop a data source).
51346   void OnServiceRequest(const protos::gen::GetAsyncCommandResponse&);
51347 
51348   // TODO think to destruction order, do we rely on any specific dtor sequence?
51349   Producer* const producer_;
51350   base::TaskRunner* const task_runner_;
51351 
51352   // The object that owns the client socket and takes care of IPC traffic.
51353   std::unique_ptr<ipc::Client> ipc_channel_;
51354 
51355   // The proxy interface for the producer port of the service. It is bound
51356   // to |ipc_channel_| and (de)serializes method invocations over the wire.
51357   protos::gen::ProducerPortProxy producer_port_;
51358 
51359   std::unique_ptr<SharedMemory> shared_memory_;
51360   std::unique_ptr<SharedMemoryArbiter> shared_memory_arbiter_;
51361   size_t shared_buffer_page_size_kb_ = 0;
51362   std::set<DataSourceInstanceID> data_sources_setup_;
51363   bool connected_ = false;
51364   std::string const name_;
51365   size_t shared_memory_page_size_hint_bytes_ = 0;
51366   size_t shared_memory_size_hint_bytes_ = 0;
51367   TracingService::ProducerSMBScrapingMode const smb_scraping_mode_;
51368   bool is_shmem_provided_by_producer_ = false;
51369   std::vector<std::function<void()>> pending_sync_reqs_;
51370   PERFETTO_THREAD_CHECKER(thread_checker_)
51371 };
51372 
51373 }  // namespace perfetto
51374 
51375 #endif  // SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
51376 /*
51377  * Copyright (C) 2017 The Android Open Source Project
51378  *
51379  * Licensed under the Apache License, Version 2.0 (the "License");
51380  * you may not use this file except in compliance with the License.
51381  * You may obtain a copy of the License at
51382  *
51383  *      http://www.apache.org/licenses/LICENSE-2.0
51384  *
51385  * Unless required by applicable law or agreed to in writing, software
51386  * distributed under the License is distributed on an "AS IS" BASIS,
51387  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51388  * See the License for the specific language governing permissions and
51389  * limitations under the License.
51390  */
51391 
51392 // gen_amalgamated expanded: #include "src/tracing/ipc/producer/producer_ipc_client_impl.h"
51393 
51394 #include <inttypes.h>
51395 #include <string.h>
51396 
51397 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
51398 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
51399 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
51400 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
51401 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
51402 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
51403 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
51404 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
51405 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
51406 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
51407 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
51408 
51409 // TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
51410 // w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
51411 // the callbacks.
51412 
51413 namespace perfetto {
51414 
51415 // static. (Declared in include/tracing/ipc/producer_ipc_client.h).
Connect(const char * service_sock_name,Producer * producer,const std::string & producer_name,base::TaskRunner * task_runner,TracingService::ProducerSMBScrapingMode smb_scraping_mode,size_t shared_memory_size_hint_bytes,size_t shared_memory_page_size_hint_bytes,std::unique_ptr<SharedMemory> shm,std::unique_ptr<SharedMemoryArbiter> shm_arbiter,ConnectionFlags conn_flags)51416 std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
51417     const char* service_sock_name,
51418     Producer* producer,
51419     const std::string& producer_name,
51420     base::TaskRunner* task_runner,
51421     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
51422     size_t shared_memory_size_hint_bytes,
51423     size_t shared_memory_page_size_hint_bytes,
51424     std::unique_ptr<SharedMemory> shm,
51425     std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
51426     ConnectionFlags conn_flags) {
51427   return std::unique_ptr<TracingService::ProducerEndpoint>(
51428       new ProducerIPCClientImpl(
51429           service_sock_name, producer, producer_name, task_runner,
51430           smb_scraping_mode, shared_memory_size_hint_bytes,
51431           shared_memory_page_size_hint_bytes, std::move(shm),
51432           std::move(shm_arbiter), conn_flags));
51433 }
51434 
ProducerIPCClientImpl(const char * service_sock_name,Producer * producer,const std::string & producer_name,base::TaskRunner * task_runner,TracingService::ProducerSMBScrapingMode smb_scraping_mode,size_t shared_memory_size_hint_bytes,size_t shared_memory_page_size_hint_bytes,std::unique_ptr<SharedMemory> shm,std::unique_ptr<SharedMemoryArbiter> shm_arbiter,ProducerIPCClient::ConnectionFlags conn_flags)51435 ProducerIPCClientImpl::ProducerIPCClientImpl(
51436     const char* service_sock_name,
51437     Producer* producer,
51438     const std::string& producer_name,
51439     base::TaskRunner* task_runner,
51440     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
51441     size_t shared_memory_size_hint_bytes,
51442     size_t shared_memory_page_size_hint_bytes,
51443     std::unique_ptr<SharedMemory> shm,
51444     std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
51445     ProducerIPCClient::ConnectionFlags conn_flags)
51446     : producer_(producer),
51447       task_runner_(task_runner),
51448       ipc_channel_(ipc::Client::CreateInstance(
51449           service_sock_name,
51450           conn_flags == ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable,
51451           task_runner)),
51452       producer_port_(this /* event_listener */),
51453       shared_memory_(std::move(shm)),
51454       shared_memory_arbiter_(std::move(shm_arbiter)),
51455       name_(producer_name),
51456       shared_memory_page_size_hint_bytes_(shared_memory_page_size_hint_bytes),
51457       shared_memory_size_hint_bytes_(shared_memory_size_hint_bytes),
51458       smb_scraping_mode_(smb_scraping_mode) {
51459   // Check for producer-provided SMB (used by Chrome for startup tracing).
51460   if (shared_memory_) {
51461     // We also expect a valid (unbound) arbiter. Bind it to this endpoint now.
51462     PERFETTO_CHECK(shared_memory_arbiter_);
51463     shared_memory_arbiter_->BindToProducerEndpoint(this, task_runner_);
51464 
51465     // If the service accepts our SMB, then it must match our requested page
51466     // layout. The protocol doesn't allow the service to change the size and
51467     // layout when the SMB is provided by the producer.
51468     shared_buffer_page_size_kb_ = shared_memory_page_size_hint_bytes_ / 1024;
51469   }
51470 
51471   ipc_channel_->BindService(producer_port_.GetWeakPtr());
51472   PERFETTO_DCHECK_THREAD(thread_checker_);
51473 }
51474 
51475 ProducerIPCClientImpl::~ProducerIPCClientImpl() = default;
51476 
51477 // Called by the IPC layer if the BindService() succeeds.
OnConnect()51478 void ProducerIPCClientImpl::OnConnect() {
51479   PERFETTO_DCHECK_THREAD(thread_checker_);
51480   connected_ = true;
51481 
51482   // The IPC layer guarantees that any outstanding callback will be dropped on
51483   // the floor if producer_port_ is destroyed between the request and the reply.
51484   // Binding |this| is hence safe.
51485   ipc::Deferred<protos::gen::InitializeConnectionResponse> on_init;
51486   on_init.Bind(
51487       [this](ipc::AsyncResult<protos::gen::InitializeConnectionResponse> resp) {
51488         OnConnectionInitialized(
51489             resp.success(),
51490             resp.success() ? resp->using_shmem_provided_by_producer() : false);
51491       });
51492   protos::gen::InitializeConnectionRequest req;
51493   req.set_producer_name(name_);
51494   req.set_shared_memory_size_hint_bytes(
51495       static_cast<uint32_t>(shared_memory_size_hint_bytes_));
51496   req.set_shared_memory_page_size_hint_bytes(
51497       static_cast<uint32_t>(shared_memory_page_size_hint_bytes_));
51498   switch (smb_scraping_mode_) {
51499     case TracingService::ProducerSMBScrapingMode::kDefault:
51500       // No need to set the mode, it defaults to use the service default if
51501       // unspecified.
51502       break;
51503     case TracingService::ProducerSMBScrapingMode::kEnabled:
51504       req.set_smb_scraping_mode(
51505           protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED);
51506       break;
51507     case TracingService::ProducerSMBScrapingMode::kDisabled:
51508       req.set_smb_scraping_mode(
51509           protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
51510       break;
51511   }
51512 
51513   int shm_fd = -1;
51514   if (shared_memory_) {
51515     shm_fd = shared_memory_->fd();
51516     req.set_producer_provided_shmem(true);
51517   }
51518 
51519 #if PERFETTO_DCHECK_IS_ON()
51520   req.set_build_flags(
51521       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON);
51522 #else
51523   req.set_build_flags(
51524       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF);
51525 #endif
51526   producer_port_.InitializeConnection(req, std::move(on_init), shm_fd);
51527 
51528   // Create the back channel to receive commands from the Service.
51529   ipc::Deferred<protos::gen::GetAsyncCommandResponse> on_cmd;
51530   on_cmd.Bind(
51531       [this](ipc::AsyncResult<protos::gen::GetAsyncCommandResponse> resp) {
51532         if (!resp)
51533           return;  // The IPC channel was closed and |resp| was auto-rejected.
51534         OnServiceRequest(*resp);
51535       });
51536   producer_port_.GetAsyncCommand(protos::gen::GetAsyncCommandRequest(),
51537                                  std::move(on_cmd));
51538 
51539   // If there are pending Sync() requests, send them now.
51540   for (const auto& pending_sync : pending_sync_reqs_)
51541     Sync(std::move(pending_sync));
51542   pending_sync_reqs_.clear();
51543 }
51544 
OnDisconnect()51545 void ProducerIPCClientImpl::OnDisconnect() {
51546   PERFETTO_DCHECK_THREAD(thread_checker_);
51547   PERFETTO_DLOG("Tracing service connection failure");
51548   connected_ = false;
51549   producer_->OnDisconnect();
51550   data_sources_setup_.clear();
51551 }
51552 
OnConnectionInitialized(bool connection_succeeded,bool using_shmem_provided_by_producer)51553 void ProducerIPCClientImpl::OnConnectionInitialized(
51554     bool connection_succeeded,
51555     bool using_shmem_provided_by_producer) {
51556   PERFETTO_DCHECK_THREAD(thread_checker_);
51557   // If connection_succeeded == false, the OnDisconnect() call will follow next
51558   // and there we'll notify the |producer_|. TODO: add a test for this.
51559   if (!connection_succeeded)
51560     return;
51561   is_shmem_provided_by_producer_ = using_shmem_provided_by_producer;
51562   producer_->OnConnect();
51563 
51564   // Bail out if the service failed to adopt our producer-allocated SMB.
51565   // TODO(eseckler): Handle adoption failure more gracefully.
51566   if (shared_memory_ && !is_shmem_provided_by_producer_) {
51567     PERFETTO_DLOG("Service failed adopt producer-provided SMB, disconnecting.");
51568     ipc_channel_.reset();
51569     return;
51570   }
51571 }
51572 
OnServiceRequest(const protos::gen::GetAsyncCommandResponse & cmd)51573 void ProducerIPCClientImpl::OnServiceRequest(
51574     const protos::gen::GetAsyncCommandResponse& cmd) {
51575   PERFETTO_DCHECK_THREAD(thread_checker_);
51576 
51577   // This message is sent only when connecting to a service running Android Q+.
51578   // See comment below in kStartDataSource.
51579   if (cmd.has_setup_data_source()) {
51580     const auto& req = cmd.setup_data_source();
51581     const DataSourceInstanceID dsid = req.new_instance_id();
51582     data_sources_setup_.insert(dsid);
51583     producer_->SetupDataSource(dsid, req.config());
51584     return;
51585   }
51586 
51587   if (cmd.has_start_data_source()) {
51588     const auto& req = cmd.start_data_source();
51589     const DataSourceInstanceID dsid = req.new_instance_id();
51590     const DataSourceConfig& cfg = req.config();
51591     if (!data_sources_setup_.count(dsid)) {
51592       // When connecting with an older (Android P) service, the service will not
51593       // send a SetupDataSource message. We synthesize it here in that case.
51594       producer_->SetupDataSource(dsid, cfg);
51595     }
51596     producer_->StartDataSource(dsid, cfg);
51597     return;
51598   }
51599 
51600   if (cmd.has_stop_data_source()) {
51601     const DataSourceInstanceID dsid = cmd.stop_data_source().instance_id();
51602     producer_->StopDataSource(dsid);
51603     data_sources_setup_.erase(dsid);
51604     return;
51605   }
51606 
51607   if (cmd.has_setup_tracing()) {
51608     base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
51609     if (shmem_fd) {
51610       // This is the nominal case used in most configurations, where the service
51611       // provides the SMB.
51612       PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
51613       // TODO(primiano): handle mmap failure in case of OOM.
51614       shared_memory_ =
51615           PosixSharedMemory::AttachToFd(std::move(shmem_fd),
51616                                         /*require_seals_if_supported=*/false);
51617       shared_buffer_page_size_kb_ =
51618           cmd.setup_tracing().shared_buffer_page_size_kb();
51619       shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
51620           shared_memory_.get(), shared_buffer_page_size_kb_ * 1024, this,
51621           task_runner_);
51622     } else {
51623       // Producer-provided SMB (used by Chrome for startup tracing).
51624       PERFETTO_CHECK(is_shmem_provided_by_producer_ && shared_memory_ &&
51625                      shared_memory_arbiter_);
51626     }
51627     producer_->OnTracingSetup();
51628     return;
51629   }
51630 
51631   if (cmd.has_flush()) {
51632     // This cast boilerplate is required only because protobuf uses its own
51633     // uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
51634     // type (long vs long long) even though they have the same size.
51635     const auto* data_source_ids = cmd.flush().data_source_ids().data();
51636     static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
51637                   "data_source_ids should be 64-bit");
51638     producer_->Flush(
51639         cmd.flush().request_id(),
51640         reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
51641         static_cast<size_t>(cmd.flush().data_source_ids().size()));
51642     return;
51643   }
51644 
51645   if (cmd.has_clear_incremental_state()) {
51646     const auto* data_source_ids =
51647         cmd.clear_incremental_state().data_source_ids().data();
51648     static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
51649                   "data_source_ids should be 64-bit");
51650     producer_->ClearIncrementalState(
51651         reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
51652         static_cast<size_t>(
51653             cmd.clear_incremental_state().data_source_ids().size()));
51654     return;
51655   }
51656 
51657   PERFETTO_DFATAL("Unknown async request received from tracing service");
51658 }
51659 
RegisterDataSource(const DataSourceDescriptor & descriptor)51660 void ProducerIPCClientImpl::RegisterDataSource(
51661     const DataSourceDescriptor& descriptor) {
51662   PERFETTO_DCHECK_THREAD(thread_checker_);
51663   if (!connected_) {
51664     PERFETTO_DLOG(
51665         "Cannot RegisterDataSource(), not connected to tracing service");
51666   }
51667   protos::gen::RegisterDataSourceRequest req;
51668   *req.mutable_data_source_descriptor() = descriptor;
51669   ipc::Deferred<protos::gen::RegisterDataSourceResponse> async_response;
51670   async_response.Bind(
51671       [](ipc::AsyncResult<protos::gen::RegisterDataSourceResponse> response) {
51672         if (!response)
51673           PERFETTO_DLOG("RegisterDataSource() failed: connection reset");
51674       });
51675   producer_port_.RegisterDataSource(req, std::move(async_response));
51676 }
51677 
UnregisterDataSource(const std::string & name)51678 void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
51679   PERFETTO_DCHECK_THREAD(thread_checker_);
51680   if (!connected_) {
51681     PERFETTO_DLOG(
51682         "Cannot UnregisterDataSource(), not connected to tracing service");
51683     return;
51684   }
51685   protos::gen::UnregisterDataSourceRequest req;
51686   req.set_data_source_name(name);
51687   producer_port_.UnregisterDataSource(
51688       req, ipc::Deferred<protos::gen::UnregisterDataSourceResponse>());
51689 }
51690 
RegisterTraceWriter(uint32_t writer_id,uint32_t target_buffer)51691 void ProducerIPCClientImpl::RegisterTraceWriter(uint32_t writer_id,
51692                                                 uint32_t target_buffer) {
51693   PERFETTO_DCHECK_THREAD(thread_checker_);
51694   if (!connected_) {
51695     PERFETTO_DLOG(
51696         "Cannot RegisterTraceWriter(), not connected to tracing service");
51697     return;
51698   }
51699   protos::gen::RegisterTraceWriterRequest req;
51700   req.set_trace_writer_id(writer_id);
51701   req.set_target_buffer(target_buffer);
51702   producer_port_.RegisterTraceWriter(
51703       req, ipc::Deferred<protos::gen::RegisterTraceWriterResponse>());
51704 }
51705 
UnregisterTraceWriter(uint32_t writer_id)51706 void ProducerIPCClientImpl::UnregisterTraceWriter(uint32_t writer_id) {
51707   PERFETTO_DCHECK_THREAD(thread_checker_);
51708   if (!connected_) {
51709     PERFETTO_DLOG(
51710         "Cannot UnregisterTraceWriter(), not connected to tracing service");
51711     return;
51712   }
51713   protos::gen::UnregisterTraceWriterRequest req;
51714   req.set_trace_writer_id(writer_id);
51715   producer_port_.UnregisterTraceWriter(
51716       req, ipc::Deferred<protos::gen::UnregisterTraceWriterResponse>());
51717 }
51718 
CommitData(const CommitDataRequest & req,CommitDataCallback callback)51719 void ProducerIPCClientImpl::CommitData(const CommitDataRequest& req,
51720                                        CommitDataCallback callback) {
51721   PERFETTO_DCHECK_THREAD(thread_checker_);
51722   if (!connected_) {
51723     PERFETTO_DLOG("Cannot CommitData(), not connected to tracing service");
51724     return;
51725   }
51726   ipc::Deferred<protos::gen::CommitDataResponse> async_response;
51727   // TODO(primiano): add a test that destroys ProducerIPCClientImpl soon after
51728   // this call and checks that the callback is dropped.
51729   if (callback) {
51730     async_response.Bind(
51731         [callback](ipc::AsyncResult<protos::gen::CommitDataResponse> response) {
51732           if (!response) {
51733             PERFETTO_DLOG("CommitData() failed: connection reset");
51734             return;
51735           }
51736           callback();
51737         });
51738   }
51739   producer_port_.CommitData(req, std::move(async_response));
51740 }
51741 
NotifyDataSourceStarted(DataSourceInstanceID id)51742 void ProducerIPCClientImpl::NotifyDataSourceStarted(DataSourceInstanceID id) {
51743   PERFETTO_DCHECK_THREAD(thread_checker_);
51744   if (!connected_) {
51745     PERFETTO_DLOG(
51746         "Cannot NotifyDataSourceStarted(), not connected to tracing service");
51747     return;
51748   }
51749   protos::gen::NotifyDataSourceStartedRequest req;
51750   req.set_data_source_id(id);
51751   producer_port_.NotifyDataSourceStarted(
51752       req, ipc::Deferred<protos::gen::NotifyDataSourceStartedResponse>());
51753 }
51754 
NotifyDataSourceStopped(DataSourceInstanceID id)51755 void ProducerIPCClientImpl::NotifyDataSourceStopped(DataSourceInstanceID id) {
51756   PERFETTO_DCHECK_THREAD(thread_checker_);
51757   if (!connected_) {
51758     PERFETTO_DLOG(
51759         "Cannot NotifyDataSourceStopped(), not connected to tracing service");
51760     return;
51761   }
51762   protos::gen::NotifyDataSourceStoppedRequest req;
51763   req.set_data_source_id(id);
51764   producer_port_.NotifyDataSourceStopped(
51765       req, ipc::Deferred<protos::gen::NotifyDataSourceStoppedResponse>());
51766 }
51767 
ActivateTriggers(const std::vector<std::string> & triggers)51768 void ProducerIPCClientImpl::ActivateTriggers(
51769     const std::vector<std::string>& triggers) {
51770   PERFETTO_DCHECK_THREAD(thread_checker_);
51771   if (!connected_) {
51772     PERFETTO_DLOG(
51773         "Cannot ActivateTriggers(), not connected to tracing service");
51774     return;
51775   }
51776   protos::gen::ActivateTriggersRequest proto_req;
51777   for (const auto& name : triggers) {
51778     *proto_req.add_trigger_names() = name;
51779   }
51780   producer_port_.ActivateTriggers(
51781       proto_req, ipc::Deferred<protos::gen::ActivateTriggersResponse>());
51782 }
51783 
Sync(std::function<void ()> callback)51784 void ProducerIPCClientImpl::Sync(std::function<void()> callback) {
51785   PERFETTO_DCHECK_THREAD(thread_checker_);
51786   if (!connected_) {
51787     pending_sync_reqs_.emplace_back(std::move(callback));
51788     return;
51789   }
51790   ipc::Deferred<protos::gen::SyncResponse> resp;
51791   resp.Bind([callback](ipc::AsyncResult<protos::gen::SyncResponse>) {
51792     // Here we ACK the callback even if the service replies with a failure
51793     // (i.e. the service is too old and doesn't understand Sync()). In that
51794     // case the service has still seen the request, the IPC roundtrip is
51795     // still a (weaker) linearization fence.
51796     callback();
51797   });
51798   producer_port_.Sync(protos::gen::SyncRequest(), std::move(resp));
51799 }
51800 
CreateTraceWriter(BufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)51801 std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
51802     BufferID target_buffer,
51803     BufferExhaustedPolicy buffer_exhausted_policy) {
51804   // This method can be called by different threads. |shared_memory_arbiter_| is
51805   // thread-safe but be aware of accessing any other state in this function.
51806   return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
51807                                                    buffer_exhausted_policy);
51808 }
51809 
MaybeSharedMemoryArbiter()51810 SharedMemoryArbiter* ProducerIPCClientImpl::MaybeSharedMemoryArbiter() {
51811   return shared_memory_arbiter_.get();
51812 }
51813 
IsShmemProvidedByProducer() const51814 bool ProducerIPCClientImpl::IsShmemProvidedByProducer() const {
51815   return is_shmem_provided_by_producer_;
51816 }
51817 
NotifyFlushComplete(FlushRequestID req_id)51818 void ProducerIPCClientImpl::NotifyFlushComplete(FlushRequestID req_id) {
51819   return shared_memory_arbiter_->NotifyFlushComplete(req_id);
51820 }
51821 
shared_memory() const51822 SharedMemory* ProducerIPCClientImpl::shared_memory() const {
51823   return shared_memory_.get();
51824 }
51825 
shared_buffer_page_size_kb() const51826 size_t ProducerIPCClientImpl::shared_buffer_page_size_kb() const {
51827   return shared_buffer_page_size_kb_;
51828 }
51829 
51830 }  // namespace perfetto
51831 // gen_amalgamated begin source: src/ipc/host_impl.cc
51832 // gen_amalgamated begin header: src/ipc/host_impl.h
51833 /*
51834  * Copyright (C) 2017 The Android Open Source Project
51835  *
51836  * Licensed under the Apache License, Version 2.0 (the "License");
51837  * you may not use this file except in compliance with the License.
51838  * You may obtain a copy of the License at
51839  *
51840  *      http://www.apache.org/licenses/LICENSE-2.0
51841  *
51842  * Unless required by applicable law or agreed to in writing, software
51843  * distributed under the License is distributed on an "AS IS" BASIS,
51844  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51845  * See the License for the specific language governing permissions and
51846  * limitations under the License.
51847  */
51848 
51849 #ifndef SRC_IPC_HOST_IMPL_H_
51850 #define SRC_IPC_HOST_IMPL_H_
51851 
51852 #include <map>
51853 #include <set>
51854 #include <string>
51855 #include <vector>
51856 
51857 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
51858 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
51859 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
51860 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
51861 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
51862 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
51863 
51864 namespace perfetto {
51865 namespace ipc {
51866 
51867 class HostImpl : public Host, public base::UnixSocket::EventListener {
51868  public:
51869   HostImpl(const char* socket_name, base::TaskRunner*);
51870   HostImpl(base::ScopedFile socket_fd, base::TaskRunner*);
51871   ~HostImpl() override;
51872 
51873   // Host implementation.
51874   bool ExposeService(std::unique_ptr<Service>) override;
51875 
51876   // base::UnixSocket::EventListener implementation.
51877   void OnNewIncomingConnection(base::UnixSocket*,
51878                                std::unique_ptr<base::UnixSocket>) override;
51879   void OnDisconnect(base::UnixSocket*) override;
51880   void OnDataAvailable(base::UnixSocket*) override;
51881 
sock() const51882   const base::UnixSocket* sock() const { return sock_.get(); }
51883 
51884  private:
51885   // Owns the per-client receive buffer (BufferedFrameDeserializer).
51886   struct ClientConnection {
51887     ~ClientConnection();
51888     ClientID id;
51889     std::unique_ptr<base::UnixSocket> sock;
51890     BufferedFrameDeserializer frame_deserializer;
51891     base::ScopedFile received_fd;
51892   };
51893   struct ExposedService {
51894     ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
51895     ~ExposedService();
51896     ExposedService(ExposedService&&) noexcept;
51897     ExposedService& operator=(ExposedService&&);
51898 
51899     ServiceID id;
51900     std::string name;
51901     std::unique_ptr<Service> instance;
51902   };
51903 
51904   HostImpl(const HostImpl&) = delete;
51905   HostImpl& operator=(const HostImpl&) = delete;
51906 
51907   bool Initialize(const char* socket_name);
51908   void OnReceivedFrame(ClientConnection*, const Frame&);
51909   void OnBindService(ClientConnection*, const Frame&);
51910   void OnInvokeMethod(ClientConnection*, const Frame&);
51911   void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
51912   const ExposedService* GetServiceByName(const std::string&);
51913 
51914   static void SendFrame(ClientConnection*, const Frame&, int fd = -1);
51915 
51916   base::TaskRunner* const task_runner_;
51917   std::map<ServiceID, ExposedService> services_;
51918   std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
51919   std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
51920   std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
51921   ServiceID last_service_id_ = 0;
51922   ClientID last_client_id_ = 0;
51923   PERFETTO_THREAD_CHECKER(thread_checker_)
51924   base::WeakPtrFactory<HostImpl> weak_ptr_factory_;  // Keep last.
51925 };
51926 
51927 }  // namespace ipc
51928 }  // namespace perfetto
51929 
51930 #endif  // SRC_IPC_HOST_IMPL_H_
51931 /*
51932  * Copyright (C) 2017 The Android Open Source Project
51933  *
51934  * Licensed under the Apache License, Version 2.0 (the "License");
51935  * you may not use this file except in compliance with the License.
51936  * You may obtain a copy of the License at
51937  *
51938  *      http://www.apache.org/licenses/LICENSE-2.0
51939  *
51940  * Unless required by applicable law or agreed to in writing, software
51941  * distributed under the License is distributed on an "AS IS" BASIS,
51942  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
51943  * See the License for the specific language governing permissions and
51944  * limitations under the License.
51945  */
51946 
51947 // gen_amalgamated expanded: #include "src/ipc/host_impl.h"
51948 
51949 #include <inttypes.h>
51950 
51951 #include <algorithm>
51952 #include <utility>
51953 
51954 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
51955 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
51956 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
51957 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
51958 
51959 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
51960 
51961 // TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).
51962 
51963 namespace perfetto {
51964 namespace ipc {
51965 
51966 // static
CreateInstance(const char * socket_name,base::TaskRunner * task_runner)51967 std::unique_ptr<Host> Host::CreateInstance(const char* socket_name,
51968                                            base::TaskRunner* task_runner) {
51969   std::unique_ptr<HostImpl> host(new HostImpl(socket_name, task_runner));
51970   if (!host->sock() || !host->sock()->is_listening())
51971     return nullptr;
51972   return std::unique_ptr<Host>(std::move(host));
51973 }
51974 
51975 // static
CreateInstance(base::ScopedFile socket_fd,base::TaskRunner * task_runner)51976 std::unique_ptr<Host> Host::CreateInstance(base::ScopedFile socket_fd,
51977                                            base::TaskRunner* task_runner) {
51978   std::unique_ptr<HostImpl> host(
51979       new HostImpl(std::move(socket_fd), task_runner));
51980   if (!host->sock() || !host->sock()->is_listening())
51981     return nullptr;
51982   return std::unique_ptr<Host>(std::move(host));
51983 }
51984 
HostImpl(base::ScopedFile socket_fd,base::TaskRunner * task_runner)51985 HostImpl::HostImpl(base::ScopedFile socket_fd, base::TaskRunner* task_runner)
51986     : task_runner_(task_runner), weak_ptr_factory_(this) {
51987   PERFETTO_DCHECK_THREAD(thread_checker_);
51988   sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
51989                                    base::SockFamily::kUnix,
51990                                    base::SockType::kStream);
51991 }
51992 
HostImpl(const char * socket_name,base::TaskRunner * task_runner)51993 HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
51994     : task_runner_(task_runner), weak_ptr_factory_(this) {
51995   PERFETTO_DCHECK_THREAD(thread_checker_);
51996   sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
51997                                    base::SockFamily::kUnix,
51998                                    base::SockType::kStream);
51999 }
52000 
52001 HostImpl::~HostImpl() = default;
52002 
ExposeService(std::unique_ptr<Service> service)52003 bool HostImpl::ExposeService(std::unique_ptr<Service> service) {
52004   PERFETTO_DCHECK_THREAD(thread_checker_);
52005   const std::string& service_name = service->GetDescriptor().service_name;
52006   if (GetServiceByName(service_name)) {
52007     PERFETTO_DLOG("Duplicate ExposeService(): %s", service_name.c_str());
52008     return false;
52009   }
52010   ServiceID sid = ++last_service_id_;
52011   ExposedService exposed_service(sid, service_name, std::move(service));
52012   services_.emplace(sid, std::move(exposed_service));
52013   return true;
52014 }
52015 
OnNewIncomingConnection(base::UnixSocket *,std::unique_ptr<base::UnixSocket> new_conn)52016 void HostImpl::OnNewIncomingConnection(
52017     base::UnixSocket*,
52018     std::unique_ptr<base::UnixSocket> new_conn) {
52019   PERFETTO_DCHECK_THREAD(thread_checker_);
52020   std::unique_ptr<ClientConnection> client(new ClientConnection());
52021   ClientID client_id = ++last_client_id_;
52022   clients_by_socket_[new_conn.get()] = client.get();
52023   client->id = client_id;
52024   client->sock = std::move(new_conn);
52025   clients_[client_id] = std::move(client);
52026 }
52027 
OnDataAvailable(base::UnixSocket * sock)52028 void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
52029   PERFETTO_DCHECK_THREAD(thread_checker_);
52030   auto it = clients_by_socket_.find(sock);
52031   if (it == clients_by_socket_.end())
52032     return;
52033   ClientConnection* client = it->second;
52034   BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;
52035 
52036   size_t rsize;
52037   do {
52038     auto buf = frame_deserializer.BeginReceive();
52039     base::ScopedFile fd;
52040     rsize = client->sock->Receive(buf.data, buf.size, &fd);
52041     if (fd) {
52042       PERFETTO_DCHECK(!client->received_fd);
52043       client->received_fd = std::move(fd);
52044     }
52045     if (!frame_deserializer.EndReceive(rsize))
52046       return OnDisconnect(client->sock.get());
52047   } while (rsize > 0);
52048 
52049   for (;;) {
52050     std::unique_ptr<Frame> frame = frame_deserializer.PopNextFrame();
52051     if (!frame)
52052       break;
52053     OnReceivedFrame(client, *frame);
52054   }
52055 }
52056 
OnReceivedFrame(ClientConnection * client,const Frame & req_frame)52057 void HostImpl::OnReceivedFrame(ClientConnection* client,
52058                                const Frame& req_frame) {
52059   if (req_frame.has_msg_bind_service())
52060     return OnBindService(client, req_frame);
52061   if (req_frame.has_msg_invoke_method())
52062     return OnInvokeMethod(client, req_frame);
52063 
52064   PERFETTO_DLOG("Received invalid RPC frame from client %" PRIu64, client->id);
52065   Frame reply_frame;
52066   reply_frame.set_request_id(req_frame.request_id());
52067   reply_frame.mutable_msg_request_error()->set_error("unknown request");
52068   SendFrame(client, reply_frame);
52069 }
52070 
OnBindService(ClientConnection * client,const Frame & req_frame)52071 void HostImpl::OnBindService(ClientConnection* client, const Frame& req_frame) {
52072   // Binding a service doesn't do anything major. It just returns back the
52073   // service id and its method map.
52074   const Frame::BindService& req = req_frame.msg_bind_service();
52075   Frame reply_frame;
52076   reply_frame.set_request_id(req_frame.request_id());
52077   auto* reply = reply_frame.mutable_msg_bind_service_reply();
52078   const ExposedService* service = GetServiceByName(req.service_name());
52079   if (service) {
52080     reply->set_success(true);
52081     reply->set_service_id(service->id);
52082     uint32_t method_id = 1;  // method ids start at index 1.
52083     for (const auto& desc_method : service->instance->GetDescriptor().methods) {
52084       Frame::BindServiceReply::MethodInfo* method_info = reply->add_methods();
52085       method_info->set_name(desc_method.name);
52086       method_info->set_id(method_id++);
52087     }
52088   }
52089   SendFrame(client, reply_frame);
52090 }
52091 
OnInvokeMethod(ClientConnection * client,const Frame & req_frame)52092 void HostImpl::OnInvokeMethod(ClientConnection* client,
52093                               const Frame& req_frame) {
52094   const Frame::InvokeMethod& req = req_frame.msg_invoke_method();
52095   Frame reply_frame;
52096   RequestID request_id = req_frame.request_id();
52097   reply_frame.set_request_id(request_id);
52098   reply_frame.mutable_msg_invoke_method_reply()->set_success(false);
52099   auto svc_it = services_.find(req.service_id());
52100   if (svc_it == services_.end())
52101     return SendFrame(client, reply_frame);  // |success| == false by default.
52102 
52103   Service* service = svc_it->second.instance.get();
52104   const ServiceDescriptor& svc = service->GetDescriptor();
52105   const auto& methods = svc.methods;
52106   const uint32_t method_id = req.method_id();
52107   if (method_id == 0 || method_id > methods.size())
52108     return SendFrame(client, reply_frame);
52109 
52110   const ServiceDescriptor::Method& method = methods[method_id - 1];
52111   std::unique_ptr<ProtoMessage> decoded_req_args(
52112       method.request_proto_decoder(req.args_proto()));
52113   if (!decoded_req_args)
52114     return SendFrame(client, reply_frame);
52115 
52116   Deferred<ProtoMessage> deferred_reply;
52117   base::WeakPtr<HostImpl> host_weak_ptr = weak_ptr_factory_.GetWeakPtr();
52118   ClientID client_id = client->id;
52119 
52120   if (!req.drop_reply()) {
52121     deferred_reply.Bind([host_weak_ptr, client_id,
52122                          request_id](AsyncResult<ProtoMessage> reply) {
52123       if (!host_weak_ptr)
52124         return;  // The reply came too late, the HostImpl has gone.
52125       host_weak_ptr->ReplyToMethodInvocation(client_id, request_id,
52126                                              std::move(reply));
52127     });
52128   }
52129 
52130   service->client_info_ = ClientInfo(client->id, client->sock->peer_uid());
52131   service->received_fd_ = &client->received_fd;
52132   method.invoker(service, *decoded_req_args, std::move(deferred_reply));
52133   service->received_fd_ = nullptr;
52134   service->client_info_ = ClientInfo();
52135 }
52136 
ReplyToMethodInvocation(ClientID client_id,RequestID request_id,AsyncResult<ProtoMessage> reply)52137 void HostImpl::ReplyToMethodInvocation(ClientID client_id,
52138                                        RequestID request_id,
52139                                        AsyncResult<ProtoMessage> reply) {
52140   auto client_iter = clients_.find(client_id);
52141   if (client_iter == clients_.end())
52142     return;  // client has disconnected by the time we got the async reply.
52143 
52144   ClientConnection* client = client_iter->second.get();
52145   Frame reply_frame;
52146   reply_frame.set_request_id(request_id);
52147 
52148   // TODO(fmayer): add a test to guarantee that the reply is consumed within the
52149   // same call stack and not kept around. ConsumerIPCService::OnTraceData()
52150   // relies on this behavior.
52151   auto* reply_frame_data = reply_frame.mutable_msg_invoke_method_reply();
52152   reply_frame_data->set_has_more(reply.has_more());
52153   if (reply.success()) {
52154     std::string reply_proto = reply->SerializeAsString();
52155     reply_frame_data->set_reply_proto(reply_proto);
52156     reply_frame_data->set_success(true);
52157   }
52158   SendFrame(client, reply_frame, reply.fd());
52159 }
52160 
52161 // static
SendFrame(ClientConnection * client,const Frame & frame,int fd)52162 void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
52163   std::string buf = BufferedFrameDeserializer::Serialize(frame);
52164 
52165   // TODO(primiano): this should do non-blocking I/O. But then what if the
52166   // socket buffer is full? We might want to either drop the request or throttle
52167   // the send and PostTask the reply later? Right now we are making Send()
52168   // blocking as a workaround. Propagate bakpressure to the caller instead.
52169   bool res = client->sock->Send(buf.data(), buf.size(), fd);
52170   PERFETTO_CHECK(res || !client->sock->is_connected());
52171 }
52172 
OnDisconnect(base::UnixSocket * sock)52173 void HostImpl::OnDisconnect(base::UnixSocket* sock) {
52174   PERFETTO_DCHECK_THREAD(thread_checker_);
52175   auto it = clients_by_socket_.find(sock);
52176   if (it == clients_by_socket_.end())
52177     return;
52178   ClientID client_id = it->second->id;
52179   ClientInfo client_info(client_id, sock->peer_uid());
52180   clients_by_socket_.erase(it);
52181   PERFETTO_DCHECK(clients_.count(client_id));
52182   clients_.erase(client_id);
52183 
52184   for (const auto& service_it : services_) {
52185     Service& service = *service_it.second.instance;
52186     service.client_info_ = client_info;
52187     service.OnClientDisconnected();
52188     service.client_info_ = ClientInfo();
52189   }
52190 }
52191 
GetServiceByName(const std::string & name)52192 const HostImpl::ExposedService* HostImpl::GetServiceByName(
52193     const std::string& name) {
52194   // This could be optimized by using another map<name,ServiceID>. However this
52195   // is used only by Bind/ExposeService that are quite rare (once per client
52196   // connection and once per service instance), not worth it.
52197   for (const auto& it : services_) {
52198     if (it.second.name == name)
52199       return &it.second;
52200   }
52201   return nullptr;
52202 }
52203 
ExposedService(ServiceID id_,const std::string & name_,std::unique_ptr<Service> instance_)52204 HostImpl::ExposedService::ExposedService(ServiceID id_,
52205                                          const std::string& name_,
52206                                          std::unique_ptr<Service> instance_)
52207     : id(id_), name(name_), instance(std::move(instance_)) {}
52208 
52209 HostImpl::ExposedService::ExposedService(ExposedService&&) noexcept = default;
52210 HostImpl::ExposedService& HostImpl::ExposedService::operator=(
52211     HostImpl::ExposedService&&) = default;
52212 HostImpl::ExposedService::~ExposedService() = default;
52213 
52214 HostImpl::ClientConnection::~ClientConnection() = default;
52215 
52216 }  // namespace ipc
52217 }  // namespace perfetto
52218 // gen_amalgamated begin source: src/tracing/ipc/service/consumer_ipc_service.cc
52219 // gen_amalgamated begin header: src/tracing/ipc/service/consumer_ipc_service.h
52220 /*
52221  * Copyright (C) 2017 The Android Open Source Project
52222  *
52223  * Licensed under the Apache License, Version 2.0 (the "License");
52224  * you may not use this file except in compliance with the License.
52225  * You may obtain a copy of the License at
52226  *
52227  *      http://www.apache.org/licenses/LICENSE-2.0
52228  *
52229  * Unless required by applicable law or agreed to in writing, software
52230  * distributed under the License is distributed on an "AS IS" BASIS,
52231  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52232  * See the License for the specific language governing permissions and
52233  * limitations under the License.
52234  */
52235 
52236 #ifndef SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
52237 #define SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
52238 
52239 #include <list>
52240 #include <map>
52241 #include <memory>
52242 #include <string>
52243 
52244 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
52245 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
52246 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
52247 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
52248 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
52249 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
52250 
52251 namespace perfetto {
52252 
52253 namespace ipc {
52254 class Host;
52255 }  // namespace ipc
52256 
52257 // Implements the Consumer port of the IPC service. This class proxies requests
52258 // and responses between the core service logic (|svc_|) and remote Consumer(s)
52259 // on the IPC socket, through the methods overriddden from ConsumerPort.
52260 class ConsumerIPCService : public protos::gen::ConsumerPort {
52261  public:
52262   explicit ConsumerIPCService(TracingService* core_service);
52263   ~ConsumerIPCService() override;
52264 
52265   // ConsumerPort implementation (from .proto IPC definition).
52266   void EnableTracing(const protos::gen::EnableTracingRequest&,
52267                      DeferredEnableTracingResponse) override;
52268   void StartTracing(const protos::gen::StartTracingRequest&,
52269                     DeferredStartTracingResponse) override;
52270   void ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest&,
52271                          DeferredChangeTraceConfigResponse) override;
52272   void DisableTracing(const protos::gen::DisableTracingRequest&,
52273                       DeferredDisableTracingResponse) override;
52274   void ReadBuffers(const protos::gen::ReadBuffersRequest&,
52275                    DeferredReadBuffersResponse) override;
52276   void FreeBuffers(const protos::gen::FreeBuffersRequest&,
52277                    DeferredFreeBuffersResponse) override;
52278   void Flush(const protos::gen::FlushRequest&, DeferredFlushResponse) override;
52279   void Detach(const protos::gen::DetachRequest&,
52280               DeferredDetachResponse) override;
52281   void Attach(const protos::gen::AttachRequest&,
52282               DeferredAttachResponse) override;
52283   void GetTraceStats(const protos::gen::GetTraceStatsRequest&,
52284                      DeferredGetTraceStatsResponse) override;
52285   void ObserveEvents(const protos::gen::ObserveEventsRequest&,
52286                      DeferredObserveEventsResponse) override;
52287   void QueryServiceState(const protos::gen::QueryServiceStateRequest&,
52288                          DeferredQueryServiceStateResponse) override;
52289   void QueryCapabilities(const protos::gen::QueryCapabilitiesRequest&,
52290                          DeferredQueryCapabilitiesResponse) override;
52291   void OnClientDisconnected() override;
52292 
52293  private:
52294   // Acts like a Consumer with the core Service business logic (which doesn't
52295   // know anything about the remote transport), but all it does is proxying
52296   // methods to the remote Consumer on the other side of the IPC channel.
52297   class RemoteConsumer : public Consumer {
52298    public:
52299     RemoteConsumer();
52300     ~RemoteConsumer() override;
52301 
52302     // These methods are called by the |core_service_| business logic. There is
52303     // no connection here, these methods are posted straight away.
52304     void OnConnect() override;
52305     void OnDisconnect() override;
52306     void OnTracingDisabled() override;
52307     void OnTraceData(std::vector<TracePacket>, bool has_more) override;
52308     void OnDetach(bool) override;
52309     void OnAttach(bool, const TraceConfig&) override;
52310     void OnTraceStats(bool, const TraceStats&) override;
52311     void OnObservableEvents(const ObservableEvents&) override;
52312 
52313     void CloseObserveEventsResponseStream();
52314 
52315     // The interface obtained from the core service business logic through
52316     // TracingService::ConnectConsumer(this). This allows to invoke methods for
52317     // a specific Consumer on the Service business logic.
52318     std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint;
52319 
52320     // After ReadBuffers() is invoked, this binds the async callback that
52321     // allows to stream trace packets back to the client.
52322     DeferredReadBuffersResponse read_buffers_response;
52323 
52324     // After EnableTracing() is invoked, this binds the async callback that
52325     // allows to send the OnTracingDisabled notification.
52326     DeferredEnableTracingResponse enable_tracing_response;
52327 
52328     // After Detach() is invoked, this binds the async callback that allows to
52329     // send the session id to the consumer.
52330     DeferredDetachResponse detach_response;
52331 
52332     // As above, but for the Attach() case.
52333     DeferredAttachResponse attach_response;
52334 
52335     // As above, but for GetTraceStats().
52336     DeferredGetTraceStatsResponse get_trace_stats_response;
52337 
52338     // After ObserveEvents() is invoked, this binds the async callback that
52339     // allows to stream ObservableEvents back to the client.
52340     DeferredObserveEventsResponse observe_events_response;
52341   };
52342 
52343   // This has to be a container that doesn't invalidate iterators.
52344   using PendingFlushResponses = std::list<DeferredFlushResponse>;
52345   using PendingQuerySvcResponses = std::list<DeferredQueryServiceStateResponse>;
52346   using PendingQueryCapabilitiesResponses =
52347       std::list<DeferredQueryCapabilitiesResponse>;
52348 
52349   ConsumerIPCService(const ConsumerIPCService&) = delete;
52350   ConsumerIPCService& operator=(const ConsumerIPCService&) = delete;
52351 
52352   // Returns the ConsumerEndpoint in the core business logic that corresponds to
52353   // the current IPC request.
52354   RemoteConsumer* GetConsumerForCurrentRequest();
52355 
52356   void OnFlushCallback(bool success, PendingFlushResponses::iterator);
52357   void OnQueryServiceCallback(bool success,
52358                               const TracingServiceState&,
52359                               PendingQuerySvcResponses::iterator);
52360   void OnQueryCapabilitiesCallback(const TracingServiceCapabilities&,
52361                                    PendingQueryCapabilitiesResponses::iterator);
52362 
52363   TracingService* const core_service_;
52364 
52365   // Maps IPC clients to ConsumerEndpoint instances registered on the
52366   // |core_service_| business logic.
52367   std::map<ipc::ClientID, std::unique_ptr<RemoteConsumer>> consumers_;
52368 
52369   PendingFlushResponses pending_flush_responses_;
52370   PendingQuerySvcResponses pending_query_service_responses_;
52371   PendingQueryCapabilitiesResponses pending_query_capabilities_responses_;
52372 
52373   base::WeakPtrFactory<ConsumerIPCService> weak_ptr_factory_;  // Keep last.
52374 };
52375 
52376 }  // namespace perfetto
52377 
52378 #endif  // SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
52379 /*
52380  * Copyright (C) 2017 The Android Open Source Project
52381  *
52382  * Licensed under the Apache License, Version 2.0 (the "License");
52383  * you may not use this file except in compliance with the License.
52384  * You may obtain a copy of the License at
52385  *
52386  *      http://www.apache.org/licenses/LICENSE-2.0
52387  *
52388  * Unless required by applicable law or agreed to in writing, software
52389  * distributed under the License is distributed on an "AS IS" BASIS,
52390  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52391  * See the License for the specific language governing permissions and
52392  * limitations under the License.
52393  */
52394 
52395 // gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
52396 
52397 #include <inttypes.h>
52398 
52399 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
52400 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
52401 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
52402 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
52403 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
52404 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
52405 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
52406 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
52407 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
52408 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
52409 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
52410 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
52411 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
52412 
52413 namespace perfetto {
52414 
ConsumerIPCService(TracingService * core_service)52415 ConsumerIPCService::ConsumerIPCService(TracingService* core_service)
52416     : core_service_(core_service), weak_ptr_factory_(this) {}
52417 
52418 ConsumerIPCService::~ConsumerIPCService() = default;
52419 
52420 ConsumerIPCService::RemoteConsumer*
GetConsumerForCurrentRequest()52421 ConsumerIPCService::GetConsumerForCurrentRequest() {
52422   const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
52423   const uid_t uid = ipc::Service::client_info().uid();
52424   PERFETTO_CHECK(ipc_client_id);
52425   auto it = consumers_.find(ipc_client_id);
52426   if (it == consumers_.end()) {
52427     auto* remote_consumer = new RemoteConsumer();
52428     consumers_[ipc_client_id].reset(remote_consumer);
52429     remote_consumer->service_endpoint =
52430         core_service_->ConnectConsumer(remote_consumer, uid);
52431     return remote_consumer;
52432   }
52433   return it->second.get();
52434 }
52435 
52436 // Called by the IPC layer.
OnClientDisconnected()52437 void ConsumerIPCService::OnClientDisconnected() {
52438   ipc::ClientID client_id = ipc::Service::client_info().client_id();
52439   consumers_.erase(client_id);
52440 }
52441 
52442 // Called by the IPC layer.
EnableTracing(const protos::gen::EnableTracingRequest & req,DeferredEnableTracingResponse resp)52443 void ConsumerIPCService::EnableTracing(
52444     const protos::gen::EnableTracingRequest& req,
52445     DeferredEnableTracingResponse resp) {
52446   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52447   if (req.attach_notification_only()) {
52448     remote_consumer->enable_tracing_response = std::move(resp);
52449     return;
52450   }
52451   const TraceConfig& trace_config = req.trace_config();
52452   base::ScopedFile fd;
52453   if (trace_config.write_into_file() && trace_config.output_path().empty())
52454     fd = ipc::Service::TakeReceivedFD();
52455   remote_consumer->service_endpoint->EnableTracing(trace_config, std::move(fd));
52456   remote_consumer->enable_tracing_response = std::move(resp);
52457 }
52458 
52459 // Called by the IPC layer.
StartTracing(const protos::gen::StartTracingRequest &,DeferredStartTracingResponse resp)52460 void ConsumerIPCService::StartTracing(const protos::gen::StartTracingRequest&,
52461                                       DeferredStartTracingResponse resp) {
52462   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52463   remote_consumer->service_endpoint->StartTracing();
52464   resp.Resolve(ipc::AsyncResult<protos::gen::StartTracingResponse>::Create());
52465 }
52466 
52467 // Called by the IPC layer.
ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest & req,DeferredChangeTraceConfigResponse resp)52468 void ConsumerIPCService::ChangeTraceConfig(
52469     const protos::gen::ChangeTraceConfigRequest& req,
52470     DeferredChangeTraceConfigResponse resp) {
52471   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52472   remote_consumer->service_endpoint->ChangeTraceConfig(req.trace_config());
52473   resp.Resolve(
52474       ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse>::Create());
52475 }
52476 
52477 // Called by the IPC layer.
DisableTracing(const protos::gen::DisableTracingRequest &,DeferredDisableTracingResponse resp)52478 void ConsumerIPCService::DisableTracing(
52479     const protos::gen::DisableTracingRequest&,
52480     DeferredDisableTracingResponse resp) {
52481   GetConsumerForCurrentRequest()->service_endpoint->DisableTracing();
52482   resp.Resolve(ipc::AsyncResult<protos::gen::DisableTracingResponse>::Create());
52483 }
52484 
52485 // Called by the IPC layer.
ReadBuffers(const protos::gen::ReadBuffersRequest &,DeferredReadBuffersResponse resp)52486 void ConsumerIPCService::ReadBuffers(const protos::gen::ReadBuffersRequest&,
52487                                      DeferredReadBuffersResponse resp) {
52488   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52489   remote_consumer->read_buffers_response = std::move(resp);
52490   remote_consumer->service_endpoint->ReadBuffers();
52491 }
52492 
52493 // Called by the IPC layer.
FreeBuffers(const protos::gen::FreeBuffersRequest &,DeferredFreeBuffersResponse resp)52494 void ConsumerIPCService::FreeBuffers(const protos::gen::FreeBuffersRequest&,
52495                                      DeferredFreeBuffersResponse resp) {
52496   GetConsumerForCurrentRequest()->service_endpoint->FreeBuffers();
52497   resp.Resolve(ipc::AsyncResult<protos::gen::FreeBuffersResponse>::Create());
52498 }
52499 
52500 // Called by the IPC layer.
Flush(const protos::gen::FlushRequest & req,DeferredFlushResponse resp)52501 void ConsumerIPCService::Flush(const protos::gen::FlushRequest& req,
52502                                DeferredFlushResponse resp) {
52503   auto it = pending_flush_responses_.insert(pending_flush_responses_.end(),
52504                                             std::move(resp));
52505   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52506   auto callback = [weak_this, it](bool success) {
52507     if (weak_this)
52508       weak_this->OnFlushCallback(success, std::move(it));
52509   };
52510   GetConsumerForCurrentRequest()->service_endpoint->Flush(req.timeout_ms(),
52511                                                           std::move(callback));
52512 }
52513 
52514 // Called by the IPC layer.
Detach(const protos::gen::DetachRequest & req,DeferredDetachResponse resp)52515 void ConsumerIPCService::Detach(const protos::gen::DetachRequest& req,
52516                                 DeferredDetachResponse resp) {
52517   // OnDetach() will resolve the |detach_response|.
52518   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52519   remote_consumer->detach_response = std::move(resp);
52520   remote_consumer->service_endpoint->Detach(req.key());
52521 }
52522 
52523 // Called by the IPC layer.
Attach(const protos::gen::AttachRequest & req,DeferredAttachResponse resp)52524 void ConsumerIPCService::Attach(const protos::gen::AttachRequest& req,
52525                                 DeferredAttachResponse resp) {
52526   // OnAttach() will resolve the |attach_response|.
52527   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52528   remote_consumer->attach_response = std::move(resp);
52529   remote_consumer->service_endpoint->Attach(req.key());
52530 }
52531 
52532 // Called by the IPC layer.
GetTraceStats(const protos::gen::GetTraceStatsRequest &,DeferredGetTraceStatsResponse resp)52533 void ConsumerIPCService::GetTraceStats(const protos::gen::GetTraceStatsRequest&,
52534                                        DeferredGetTraceStatsResponse resp) {
52535   // OnTraceStats() will resolve the |get_trace_stats_response|.
52536   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52537   remote_consumer->get_trace_stats_response = std::move(resp);
52538   remote_consumer->service_endpoint->GetTraceStats();
52539 }
52540 
52541 // Called by the IPC layer.
ObserveEvents(const protos::gen::ObserveEventsRequest & req,DeferredObserveEventsResponse resp)52542 void ConsumerIPCService::ObserveEvents(
52543     const protos::gen::ObserveEventsRequest& req,
52544     DeferredObserveEventsResponse resp) {
52545   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52546 
52547   // If there's a prior stream, close it so that client can clean it up.
52548   remote_consumer->CloseObserveEventsResponseStream();
52549 
52550   remote_consumer->observe_events_response = std::move(resp);
52551 
52552   uint32_t events_mask = 0;
52553   for (const auto& type : req.events_to_observe()) {
52554     events_mask |= static_cast<uint32_t>(type);
52555   }
52556   remote_consumer->service_endpoint->ObserveEvents(events_mask);
52557 
52558   // If no events are to be observed, close the stream immediately so that the
52559   // client can clean up.
52560   if (events_mask == 0)
52561     remote_consumer->CloseObserveEventsResponseStream();
52562 }
52563 
52564 // Called by the IPC layer.
QueryServiceState(const protos::gen::QueryServiceStateRequest &,DeferredQueryServiceStateResponse resp)52565 void ConsumerIPCService::QueryServiceState(
52566     const protos::gen::QueryServiceStateRequest&,
52567     DeferredQueryServiceStateResponse resp) {
52568   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52569   auto it = pending_query_service_responses_.insert(
52570       pending_query_service_responses_.end(), std::move(resp));
52571   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52572   auto callback = [weak_this, it](bool success,
52573                                   const TracingServiceState& svc_state) {
52574     if (weak_this)
52575       weak_this->OnQueryServiceCallback(success, svc_state, std::move(it));
52576   };
52577   remote_consumer->service_endpoint->QueryServiceState(callback);
52578 }
52579 
52580 // Called by the service in response to service_endpoint->QueryServiceState().
OnQueryServiceCallback(bool success,const TracingServiceState & svc_state,PendingQuerySvcResponses::iterator pending_response_it)52581 void ConsumerIPCService::OnQueryServiceCallback(
52582     bool success,
52583     const TracingServiceState& svc_state,
52584     PendingQuerySvcResponses::iterator pending_response_it) {
52585   DeferredQueryServiceStateResponse response(std::move(*pending_response_it));
52586   pending_query_service_responses_.erase(pending_response_it);
52587   if (!success) {
52588     response.Reject();
52589     return;
52590   }
52591 
52592   // The TracingServiceState object might be too big to fit into a single IPC
52593   // message because it contains the DataSourceDescriptor of each data source.
52594   // Here we split it in chunks to fit in the IPC limit, observing the
52595   // following rule: each chunk must be invididually a valid TracingServiceState
52596   // message; all the chunks concatenated together must form the original
52597   // message. This is to deal with the legacy API that was just sending one
52598   // whole message (failing in presence of too many data sources, b/153142114).
52599   // The message is split as follows: we take the whole TracingServiceState,
52600   // take out the data sources section (which is a top-level repeated field)
52601   // and re-add them one-by-one. If, in the process of appending, the IPC msg
52602   // size is reached, a new chunk is created. This assumes that the rest of
52603   // TracingServiceState fits in one IPC message and each DataSourceDescriptor
52604   // fits in the worst case in a dedicated message (which is true, because
52605   // otherwise the RegisterDataSource() which passes the descriptor in the first
52606   // place would fail).
52607 
52608   std::vector<uint8_t> chunked_reply;
52609 
52610   // Transmits the current chunk and starts a new one.
52611   bool sent_eof = false;
52612   auto send_chunked_reply = [&chunked_reply, &response,
52613                              &sent_eof](bool has_more) {
52614     PERFETTO_CHECK(!sent_eof);
52615     sent_eof = !has_more;
52616     auto resp =
52617         ipc::AsyncResult<protos::gen::QueryServiceStateResponse>::Create();
52618     resp.set_has_more(has_more);
52619     PERFETTO_CHECK(resp->mutable_service_state()->ParseFromArray(
52620         chunked_reply.data(), chunked_reply.size()));
52621     chunked_reply.clear();
52622     response.Resolve(std::move(resp));
52623   };
52624 
52625   // Create a copy of the whole response and cut away the data_sources section.
52626   protos::gen::TracingServiceState svc_state_copy = svc_state;
52627   auto data_sources = std::move(*svc_state_copy.mutable_data_sources());
52628   chunked_reply = svc_state_copy.SerializeAsArray();
52629 
52630   // Now re-add them fitting within the IPC message limits (- some margin for
52631   // the outer IPC frame).
52632   constexpr size_t kMaxMsgSize = ipc::kIPCBufferSize - 128;
52633   for (const auto& data_source : data_sources) {
52634     protos::gen::TracingServiceState tmp;
52635     tmp.mutable_data_sources()->emplace_back(std::move(data_source));
52636     std::vector<uint8_t> chunk = tmp.SerializeAsArray();
52637     if (chunked_reply.size() + chunk.size() < kMaxMsgSize) {
52638       chunked_reply.insert(chunked_reply.end(), chunk.begin(), chunk.end());
52639     } else {
52640       send_chunked_reply(/*has_more=*/true);
52641       chunked_reply = std::move(chunk);
52642     }
52643   }
52644 
52645   PERFETTO_DCHECK(!chunked_reply.empty());
52646   send_chunked_reply(/*has_more=*/false);
52647   PERFETTO_CHECK(sent_eof);
52648 }
52649 
52650 // Called by the service in response to a service_endpoint->Flush() request.
OnFlushCallback(bool success,PendingFlushResponses::iterator pending_response_it)52651 void ConsumerIPCService::OnFlushCallback(
52652     bool success,
52653     PendingFlushResponses::iterator pending_response_it) {
52654   DeferredFlushResponse response(std::move(*pending_response_it));
52655   pending_flush_responses_.erase(pending_response_it);
52656   if (success) {
52657     response.Resolve(ipc::AsyncResult<protos::gen::FlushResponse>::Create());
52658   } else {
52659     response.Reject();
52660   }
52661 }
52662 
QueryCapabilities(const protos::gen::QueryCapabilitiesRequest &,DeferredQueryCapabilitiesResponse resp)52663 void ConsumerIPCService::QueryCapabilities(
52664     const protos::gen::QueryCapabilitiesRequest&,
52665     DeferredQueryCapabilitiesResponse resp) {
52666   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
52667   auto it = pending_query_capabilities_responses_.insert(
52668       pending_query_capabilities_responses_.end(), std::move(resp));
52669   auto weak_this = weak_ptr_factory_.GetWeakPtr();
52670   auto callback = [weak_this, it](const TracingServiceCapabilities& caps) {
52671     if (weak_this)
52672       weak_this->OnQueryCapabilitiesCallback(caps, std::move(it));
52673   };
52674   remote_consumer->service_endpoint->QueryCapabilities(callback);
52675 }
52676 
52677 // Called by the service in response to service_endpoint->QueryCapabilities().
OnQueryCapabilitiesCallback(const TracingServiceCapabilities & caps,PendingQueryCapabilitiesResponses::iterator pending_response_it)52678 void ConsumerIPCService::OnQueryCapabilitiesCallback(
52679     const TracingServiceCapabilities& caps,
52680     PendingQueryCapabilitiesResponses::iterator pending_response_it) {
52681   DeferredQueryCapabilitiesResponse response(std::move(*pending_response_it));
52682   pending_query_capabilities_responses_.erase(pending_response_it);
52683   auto resp =
52684       ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse>::Create();
52685   *resp->mutable_capabilities() = caps;
52686   response.Resolve(std::move(resp));
52687 }
52688 
52689 ////////////////////////////////////////////////////////////////////////////////
52690 // RemoteConsumer methods
52691 ////////////////////////////////////////////////////////////////////////////////
52692 
52693 ConsumerIPCService::RemoteConsumer::RemoteConsumer() = default;
52694 ConsumerIPCService::RemoteConsumer::~RemoteConsumer() = default;
52695 
52696 // Invoked by the |core_service_| business logic after the ConnectConsumer()
52697 // call. There is nothing to do here, we really expected the ConnectConsumer()
52698 // to just work in the local case.
OnConnect()52699 void ConsumerIPCService::RemoteConsumer::OnConnect() {}
52700 
52701 // Invoked by the |core_service_| business logic after we destroy the
52702 // |service_endpoint| (in the RemoteConsumer dtor).
OnDisconnect()52703 void ConsumerIPCService::RemoteConsumer::OnDisconnect() {}
52704 
OnTracingDisabled()52705 void ConsumerIPCService::RemoteConsumer::OnTracingDisabled() {
52706   if (enable_tracing_response.IsBound()) {
52707     auto result =
52708         ipc::AsyncResult<protos::gen::EnableTracingResponse>::Create();
52709     result->set_disabled(true);
52710     enable_tracing_response.Resolve(std::move(result));
52711   }
52712 }
52713 
OnTraceData(std::vector<TracePacket> trace_packets,bool has_more)52714 void ConsumerIPCService::RemoteConsumer::OnTraceData(
52715     std::vector<TracePacket> trace_packets,
52716     bool has_more) {
52717   if (!read_buffers_response.IsBound())
52718     return;
52719 
52720   auto result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
52721 
52722   // A TracePacket might be too big to fit into a single IPC message (max
52723   // kIPCBufferSize). However a TracePacket is made of slices and each slice
52724   // is way smaller than kIPCBufferSize (a slice size is effectively bounded by
52725   // the max chunk size of the SharedMemoryABI). When sending a TracePacket,
52726   // if its slices don't fit within one IPC, chunk them over several contiguous
52727   // IPCs using the |last_slice_for_packet| for glueing on the other side.
52728   static_assert(ipc::kIPCBufferSize >= SharedMemoryABI::kMaxPageSize * 2,
52729                 "kIPCBufferSize too small given the max possible slice size");
52730 
52731   auto send_ipc_reply = [this, &result](bool more) {
52732     result.set_has_more(more);
52733     read_buffers_response.Resolve(std::move(result));
52734     result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
52735   };
52736 
52737   size_t approx_reply_size = 0;
52738   for (const TracePacket& trace_packet : trace_packets) {
52739     size_t num_slices_left_for_packet = trace_packet.slices().size();
52740     for (const Slice& slice : trace_packet.slices()) {
52741       // Check if this slice would cause the IPC to overflow its max size and,
52742       // if that is the case, split the IPCs. The "16" and "64" below are
52743       // over-estimations of, respectively:
52744       // 16: the preamble that prefixes each slice (there are 2 x size fields
52745       //     in the proto + the |last_slice_for_packet| bool).
52746       // 64: the overhead of the IPC InvokeMethodReply + wire_protocol's frame.
52747       // If these estimations are wrong, BufferedFrameDeserializer::Serialize()
52748       // will hit a DCHECK anyways.
52749       const size_t approx_slice_size = slice.size + 16;
52750       if (approx_reply_size + approx_slice_size > ipc::kIPCBufferSize - 64) {
52751         // If we hit this CHECK we got a single slice that is > kIPCBufferSize.
52752         PERFETTO_CHECK(result->slices_size() > 0);
52753         send_ipc_reply(/*has_more=*/true);
52754         approx_reply_size = 0;
52755       }
52756       approx_reply_size += approx_slice_size;
52757 
52758       auto* res_slice = result->add_slices();
52759       res_slice->set_last_slice_for_packet(--num_slices_left_for_packet == 0);
52760       res_slice->set_data(slice.start, slice.size);
52761     }
52762   }
52763   send_ipc_reply(has_more);
52764 }
52765 
OnDetach(bool success)52766 void ConsumerIPCService::RemoteConsumer::OnDetach(bool success) {
52767   if (!success) {
52768     std::move(detach_response).Reject();
52769     return;
52770   }
52771   auto resp = ipc::AsyncResult<protos::gen::DetachResponse>::Create();
52772   std::move(detach_response).Resolve(std::move(resp));
52773 }
52774 
OnAttach(bool success,const TraceConfig & trace_config)52775 void ConsumerIPCService::RemoteConsumer::OnAttach(
52776     bool success,
52777     const TraceConfig& trace_config) {
52778   if (!success) {
52779     std::move(attach_response).Reject();
52780     return;
52781   }
52782   auto response = ipc::AsyncResult<protos::gen::AttachResponse>::Create();
52783   *response->mutable_trace_config() = trace_config;
52784   std::move(attach_response).Resolve(std::move(response));
52785 }
52786 
OnTraceStats(bool success,const TraceStats & stats)52787 void ConsumerIPCService::RemoteConsumer::OnTraceStats(bool success,
52788                                                       const TraceStats& stats) {
52789   if (!success) {
52790     std::move(get_trace_stats_response).Reject();
52791     return;
52792   }
52793   auto response =
52794       ipc::AsyncResult<protos::gen::GetTraceStatsResponse>::Create();
52795   *response->mutable_trace_stats() = stats;
52796   std::move(get_trace_stats_response).Resolve(std::move(response));
52797 }
52798 
OnObservableEvents(const ObservableEvents & events)52799 void ConsumerIPCService::RemoteConsumer::OnObservableEvents(
52800     const ObservableEvents& events) {
52801   if (!observe_events_response.IsBound())
52802     return;
52803 
52804   auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
52805   result.set_has_more(true);
52806   *result->mutable_events() = events;
52807   observe_events_response.Resolve(std::move(result));
52808 }
52809 
CloseObserveEventsResponseStream()52810 void ConsumerIPCService::RemoteConsumer::CloseObserveEventsResponseStream() {
52811   if (!observe_events_response.IsBound())
52812     return;
52813 
52814   auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
52815   result.set_has_more(false);
52816   observe_events_response.Resolve(std::move(result));
52817 }
52818 
52819 }  // namespace perfetto
52820 // gen_amalgamated begin source: src/tracing/ipc/service/producer_ipc_service.cc
52821 // gen_amalgamated begin header: src/tracing/ipc/service/producer_ipc_service.h
52822 /*
52823  * Copyright (C) 2017 The Android Open Source Project
52824  *
52825  * Licensed under the Apache License, Version 2.0 (the "License");
52826  * you may not use this file except in compliance with the License.
52827  * You may obtain a copy of the License at
52828  *
52829  *      http://www.apache.org/licenses/LICENSE-2.0
52830  *
52831  * Unless required by applicable law or agreed to in writing, software
52832  * distributed under the License is distributed on an "AS IS" BASIS,
52833  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52834  * See the License for the specific language governing permissions and
52835  * limitations under the License.
52836  */
52837 
52838 #ifndef SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
52839 #define SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
52840 
52841 #include <list>
52842 #include <map>
52843 #include <memory>
52844 #include <string>
52845 
52846 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
52847 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
52848 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
52849 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
52850 
52851 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
52852 
52853 namespace perfetto {
52854 
52855 namespace ipc {
52856 class Host;
52857 }  // namespace ipc
52858 
52859 // Implements the Producer port of the IPC service. This class proxies requests
52860 // and responses between the core service logic (|svc_|) and remote Producer(s)
52861 // on the IPC socket, through the methods overriddden from ProducerPort.
52862 class ProducerIPCService : public protos::gen::ProducerPort {
52863  public:
52864   explicit ProducerIPCService(TracingService* core_service);
52865   ~ProducerIPCService() override;
52866 
52867   // ProducerPort implementation (from .proto IPC definition).
52868   void InitializeConnection(const protos::gen::InitializeConnectionRequest&,
52869                             DeferredInitializeConnectionResponse) override;
52870   void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
52871                           DeferredRegisterDataSourceResponse) override;
52872   void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
52873                             DeferredUnregisterDataSourceResponse) override;
52874   void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
52875                            DeferredRegisterTraceWriterResponse) override;
52876   void UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest&,
52877                              DeferredUnregisterTraceWriterResponse) override;
52878   void CommitData(const protos::gen::CommitDataRequest&,
52879                   DeferredCommitDataResponse) override;
52880   void NotifyDataSourceStarted(
52881       const protos::gen::NotifyDataSourceStartedRequest&,
52882       DeferredNotifyDataSourceStartedResponse) override;
52883   void NotifyDataSourceStopped(
52884       const protos::gen::NotifyDataSourceStoppedRequest&,
52885       DeferredNotifyDataSourceStoppedResponse) override;
52886   void ActivateTriggers(const protos::gen::ActivateTriggersRequest&,
52887                         DeferredActivateTriggersResponse) override;
52888 
52889   void GetAsyncCommand(const protos::gen::GetAsyncCommandRequest&,
52890                        DeferredGetAsyncCommandResponse) override;
52891   void Sync(const protos::gen::SyncRequest&, DeferredSyncResponse) override;
52892   void OnClientDisconnected() override;
52893 
52894  private:
52895   // Acts like a Producer with the core Service business logic (which doesn't
52896   // know anything about the remote transport), but all it does is proxying
52897   // methods to the remote Producer on the other side of the IPC channel.
52898   class RemoteProducer : public Producer {
52899    public:
52900     RemoteProducer();
52901     ~RemoteProducer() override;
52902 
52903     // These methods are called by the |core_service_| business logic. There is
52904     // no connection here, these methods are posted straight away.
52905     void OnConnect() override;
52906     void OnDisconnect() override;
52907     void SetupDataSource(DataSourceInstanceID,
52908                          const DataSourceConfig&) override;
52909     void StartDataSource(DataSourceInstanceID,
52910                          const DataSourceConfig&) override;
52911     void StopDataSource(DataSourceInstanceID) override;
52912     void OnTracingSetup() override;
52913     void Flush(FlushRequestID,
52914                const DataSourceInstanceID* data_source_ids,
52915                size_t num_data_sources) override;
52916 
52917     void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
52918                                size_t num_data_sources) override;
52919 
52920     void SendSetupTracing();
52921 
52922     // The interface obtained from the core service business logic through
52923     // Service::ConnectProducer(this). This allows to invoke methods for a
52924     // specific Producer on the Service business logic.
52925     std::unique_ptr<TracingService::ProducerEndpoint> service_endpoint;
52926 
52927     // The back-channel (based on a never ending stream request) that allows us
52928     // to send asynchronous commands to the remote Producer (e.g. start/stop a
52929     // data source).
52930     DeferredGetAsyncCommandResponse async_producer_commands;
52931 
52932     // Set if the service calls OnTracingSetup() before the
52933     // |async_producer_commands| was bound by the service. In this case, we
52934     // forward the SetupTracing command when it is bound later.
52935     bool send_setup_tracing_on_async_commands_bound = false;
52936   };
52937 
52938   ProducerIPCService(const ProducerIPCService&) = delete;
52939   ProducerIPCService& operator=(const ProducerIPCService&) = delete;
52940 
52941   // Returns the ProducerEndpoint in the core business logic that corresponds to
52942   // the current IPC request.
52943   RemoteProducer* GetProducerForCurrentRequest();
52944 
52945   TracingService* const core_service_;
52946 
52947   // Maps IPC clients to ProducerEndpoint instances registered on the
52948   // |core_service_| business logic.
52949   std::map<ipc::ClientID, std::unique_ptr<RemoteProducer>> producers_;
52950 
52951   // List because pointers need to be stable.
52952   std::list<DeferredSyncResponse> pending_syncs_;
52953 
52954   base::WeakPtrFactory<ProducerIPCService> weak_ptr_factory_;  // Keep last.
52955 };
52956 
52957 }  // namespace perfetto
52958 
52959 #endif  // SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
52960 /*
52961  * Copyright (C) 2017 The Android Open Source Project
52962  *
52963  * Licensed under the Apache License, Version 2.0 (the "License");
52964  * you may not use this file except in compliance with the License.
52965  * You may obtain a copy of the License at
52966  *
52967  *      http://www.apache.org/licenses/LICENSE-2.0
52968  *
52969  * Unless required by applicable law or agreed to in writing, software
52970  * distributed under the License is distributed on an "AS IS" BASIS,
52971  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52972  * See the License for the specific language governing permissions and
52973  * limitations under the License.
52974  */
52975 
52976 // gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
52977 
52978 #include <inttypes.h>
52979 
52980 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
52981 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
52982 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
52983 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
52984 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
52985 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
52986 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
52987 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
52988 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
52989 
52990 // The remote Producer(s) are not trusted. All the methods from the ProducerPort
52991 // IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
52992 // compromised.
52993 
52994 namespace perfetto {
52995 
ProducerIPCService(TracingService * core_service)52996 ProducerIPCService::ProducerIPCService(TracingService* core_service)
52997     : core_service_(core_service), weak_ptr_factory_(this) {}
52998 
52999 ProducerIPCService::~ProducerIPCService() = default;
53000 
53001 ProducerIPCService::RemoteProducer*
GetProducerForCurrentRequest()53002 ProducerIPCService::GetProducerForCurrentRequest() {
53003   const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
53004   PERFETTO_CHECK(ipc_client_id);
53005   auto it = producers_.find(ipc_client_id);
53006   if (it == producers_.end())
53007     return nullptr;
53008   return it->second.get();
53009 }
53010 
53011 // Called by the remote Producer through the IPC channel soon after connecting.
InitializeConnection(const protos::gen::InitializeConnectionRequest & req,DeferredInitializeConnectionResponse response)53012 void ProducerIPCService::InitializeConnection(
53013     const protos::gen::InitializeConnectionRequest& req,
53014     DeferredInitializeConnectionResponse response) {
53015   const auto& client_info = ipc::Service::client_info();
53016   const ipc::ClientID ipc_client_id = client_info.client_id();
53017   PERFETTO_CHECK(ipc_client_id);
53018 
53019   if (producers_.count(ipc_client_id) > 0) {
53020     PERFETTO_DLOG(
53021         "The remote Producer is trying to re-initialize the connection");
53022     return response.Reject();
53023   }
53024 
53025   // Create a new entry.
53026   std::unique_ptr<RemoteProducer> producer(new RemoteProducer());
53027 
53028   TracingService::ProducerSMBScrapingMode smb_scraping_mode =
53029       TracingService::ProducerSMBScrapingMode::kDefault;
53030   switch (req.smb_scraping_mode()) {
53031     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_UNSPECIFIED:
53032       break;
53033     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED:
53034       smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kDisabled;
53035       break;
53036     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED:
53037       smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kEnabled;
53038       break;
53039   }
53040 
53041   bool dcheck_mismatch = false;
53042 #if PERFETTO_DCHECK_IS_ON()
53043   dcheck_mismatch =
53044       req.build_flags() ==
53045       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_OFF;
53046 #else
53047   dcheck_mismatch =
53048       req.build_flags() ==
53049       protos::gen::InitializeConnectionRequest::BUILD_FLAGS_DCHECKS_ON;
53050 #endif
53051   if (dcheck_mismatch) {
53052     PERFETTO_LOG(
53053         "The producer and the service binaries are built using different "
53054         "DEBUG/NDEBUG flags. This will likely cause crashes.");
53055   }
53056 
53057   // If the producer provided an SMB, tell the service to attempt to adopt it.
53058   std::unique_ptr<SharedMemory> shmem;
53059   if (req.producer_provided_shmem()) {
53060     base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();
53061     if (shmem_fd) {
53062       shmem = PosixSharedMemory::AttachToFd(
53063           std::move(shmem_fd), /*require_seals_if_supported=*/true);
53064       if (!shmem) {
53065         PERFETTO_ELOG(
53066             "Couldn't map producer-provided SMB, falling back to "
53067             "service-provided SMB");
53068       }
53069     } else {
53070       PERFETTO_DLOG(
53071           "InitializeConnectionRequest's producer_provided_shmem flag is set "
53072           "but the producer didn't provide an FD");
53073     }
53074   }
53075 
53076   // ConnectProducer will call OnConnect() on the next task.
53077   producer->service_endpoint = core_service_->ConnectProducer(
53078       producer.get(), client_info.uid(), req.producer_name(),
53079       req.shared_memory_size_hint_bytes(),
53080       /*in_process=*/false, smb_scraping_mode,
53081       req.shared_memory_page_size_hint_bytes(), std::move(shmem));
53082 
53083   // Could happen if the service has too many producers connected.
53084   if (!producer->service_endpoint) {
53085     response.Reject();
53086     return;
53087   }
53088 
53089   bool using_producer_shmem =
53090       producer->service_endpoint->IsShmemProvidedByProducer();
53091 
53092   producers_.emplace(ipc_client_id, std::move(producer));
53093   // Because of the std::move() |producer| is invalid after this point.
53094 
53095   auto async_res =
53096       ipc::AsyncResult<protos::gen::InitializeConnectionResponse>::Create();
53097   async_res->set_using_shmem_provided_by_producer(using_producer_shmem);
53098   response.Resolve(std::move(async_res));
53099 }
53100 
53101 // Called by the remote Producer through the IPC channel.
RegisterDataSource(const protos::gen::RegisterDataSourceRequest & req,DeferredRegisterDataSourceResponse response)53102 void ProducerIPCService::RegisterDataSource(
53103     const protos::gen::RegisterDataSourceRequest& req,
53104     DeferredRegisterDataSourceResponse response) {
53105   RemoteProducer* producer = GetProducerForCurrentRequest();
53106   if (!producer) {
53107     PERFETTO_DLOG(
53108         "Producer invoked RegisterDataSource() before InitializeConnection()");
53109     if (response.IsBound())
53110       response.Reject();
53111     return;
53112   }
53113 
53114   const DataSourceDescriptor& dsd = req.data_source_descriptor();
53115   GetProducerForCurrentRequest()->service_endpoint->RegisterDataSource(dsd);
53116 
53117   // RegisterDataSource doesn't expect any meaningful response.
53118   if (response.IsBound()) {
53119     response.Resolve(
53120         ipc::AsyncResult<protos::gen::RegisterDataSourceResponse>::Create());
53121   }
53122 }
53123 
53124 // Called by the IPC layer.
OnClientDisconnected()53125 void ProducerIPCService::OnClientDisconnected() {
53126   ipc::ClientID client_id = ipc::Service::client_info().client_id();
53127   PERFETTO_DLOG("Client %" PRIu64 " disconnected", client_id);
53128   producers_.erase(client_id);
53129 }
53130 
53131 // TODO(fmayer): test what happens if we receive the following tasks, in order:
53132 // RegisterDataSource, UnregisterDataSource, OnDataSourceRegistered.
53133 // which essentially means that the client posted back to back a
53134 // ReqisterDataSource and UnregisterDataSource speculating on the next id.
53135 // Called by the remote Service through the IPC channel.
UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest & req,DeferredUnregisterDataSourceResponse response)53136 void ProducerIPCService::UnregisterDataSource(
53137     const protos::gen::UnregisterDataSourceRequest& req,
53138     DeferredUnregisterDataSourceResponse response) {
53139   RemoteProducer* producer = GetProducerForCurrentRequest();
53140   if (!producer) {
53141     PERFETTO_DLOG(
53142         "Producer invoked UnregisterDataSource() before "
53143         "InitializeConnection()");
53144     if (response.IsBound())
53145       response.Reject();
53146     return;
53147   }
53148   producer->service_endpoint->UnregisterDataSource(req.data_source_name());
53149 
53150   // UnregisterDataSource doesn't expect any meaningful response.
53151   if (response.IsBound()) {
53152     response.Resolve(
53153         ipc::AsyncResult<protos::gen::UnregisterDataSourceResponse>::Create());
53154   }
53155 }
53156 
RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest & req,DeferredRegisterTraceWriterResponse response)53157 void ProducerIPCService::RegisterTraceWriter(
53158     const protos::gen::RegisterTraceWriterRequest& req,
53159     DeferredRegisterTraceWriterResponse response) {
53160   RemoteProducer* producer = GetProducerForCurrentRequest();
53161   if (!producer) {
53162     PERFETTO_DLOG(
53163         "Producer invoked RegisterTraceWriter() before "
53164         "InitializeConnection()");
53165     if (response.IsBound())
53166       response.Reject();
53167     return;
53168   }
53169   producer->service_endpoint->RegisterTraceWriter(req.trace_writer_id(),
53170                                                   req.target_buffer());
53171 
53172   // RegisterTraceWriter doesn't expect any meaningful response.
53173   if (response.IsBound()) {
53174     response.Resolve(
53175         ipc::AsyncResult<protos::gen::RegisterTraceWriterResponse>::Create());
53176   }
53177 }
53178 
UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest & req,DeferredUnregisterTraceWriterResponse response)53179 void ProducerIPCService::UnregisterTraceWriter(
53180     const protos::gen::UnregisterTraceWriterRequest& req,
53181     DeferredUnregisterTraceWriterResponse response) {
53182   RemoteProducer* producer = GetProducerForCurrentRequest();
53183   if (!producer) {
53184     PERFETTO_DLOG(
53185         "Producer invoked UnregisterTraceWriter() before "
53186         "InitializeConnection()");
53187     if (response.IsBound())
53188       response.Reject();
53189     return;
53190   }
53191   producer->service_endpoint->UnregisterTraceWriter(req.trace_writer_id());
53192 
53193   // UnregisterTraceWriter doesn't expect any meaningful response.
53194   if (response.IsBound()) {
53195     response.Resolve(
53196         ipc::AsyncResult<protos::gen::UnregisterTraceWriterResponse>::Create());
53197   }
53198 }
53199 
CommitData(const protos::gen::CommitDataRequest & req,DeferredCommitDataResponse resp)53200 void ProducerIPCService::CommitData(const protos::gen::CommitDataRequest& req,
53201                                     DeferredCommitDataResponse resp) {
53202   RemoteProducer* producer = GetProducerForCurrentRequest();
53203   if (!producer) {
53204     PERFETTO_DLOG(
53205         "Producer invoked CommitData() before InitializeConnection()");
53206     if (resp.IsBound())
53207       resp.Reject();
53208     return;
53209   }
53210 
53211   // We don't want to send a response if the client didn't attach a callback to
53212   // the original request. Doing so would generate unnecessary wakeups and
53213   // context switches.
53214   std::function<void()> callback;
53215   if (resp.IsBound()) {
53216     // Capturing |resp| by reference here speculates on the fact that
53217     // CommitData() in tracing_service_impl.cc invokes the passed callback
53218     // inline, without posting it. If that assumption changes this code needs to
53219     // wrap the response in a shared_ptr (C+11 lambdas don't support move) and
53220     // use a weak ptr in the caller.
53221     callback = [&resp] {
53222       resp.Resolve(ipc::AsyncResult<protos::gen::CommitDataResponse>::Create());
53223     };
53224   }
53225   producer->service_endpoint->CommitData(req, callback);
53226 }
53227 
NotifyDataSourceStarted(const protos::gen::NotifyDataSourceStartedRequest & request,DeferredNotifyDataSourceStartedResponse response)53228 void ProducerIPCService::NotifyDataSourceStarted(
53229     const protos::gen::NotifyDataSourceStartedRequest& request,
53230     DeferredNotifyDataSourceStartedResponse response) {
53231   RemoteProducer* producer = GetProducerForCurrentRequest();
53232   if (!producer) {
53233     PERFETTO_DLOG(
53234         "Producer invoked NotifyDataSourceStarted() before "
53235         "InitializeConnection()");
53236     if (response.IsBound())
53237       response.Reject();
53238     return;
53239   }
53240   producer->service_endpoint->NotifyDataSourceStarted(request.data_source_id());
53241 
53242   // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
53243   // a useless IPC in that case.
53244   if (response.IsBound()) {
53245     response.Resolve(ipc::AsyncResult<
53246                      protos::gen::NotifyDataSourceStartedResponse>::Create());
53247   }
53248 }
53249 
NotifyDataSourceStopped(const protos::gen::NotifyDataSourceStoppedRequest & request,DeferredNotifyDataSourceStoppedResponse response)53250 void ProducerIPCService::NotifyDataSourceStopped(
53251     const protos::gen::NotifyDataSourceStoppedRequest& request,
53252     DeferredNotifyDataSourceStoppedResponse response) {
53253   RemoteProducer* producer = GetProducerForCurrentRequest();
53254   if (!producer) {
53255     PERFETTO_DLOG(
53256         "Producer invoked NotifyDataSourceStopped() before "
53257         "InitializeConnection()");
53258     if (response.IsBound())
53259       response.Reject();
53260     return;
53261   }
53262   producer->service_endpoint->NotifyDataSourceStopped(request.data_source_id());
53263 
53264   // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
53265   // a useless IPC in that case.
53266   if (response.IsBound()) {
53267     response.Resolve(ipc::AsyncResult<
53268                      protos::gen::NotifyDataSourceStoppedResponse>::Create());
53269   }
53270 }
53271 
ActivateTriggers(const protos::gen::ActivateTriggersRequest & proto_req,DeferredActivateTriggersResponse resp)53272 void ProducerIPCService::ActivateTriggers(
53273     const protos::gen::ActivateTriggersRequest& proto_req,
53274     DeferredActivateTriggersResponse resp) {
53275   RemoteProducer* producer = GetProducerForCurrentRequest();
53276   if (!producer) {
53277     PERFETTO_DLOG(
53278         "Producer invoked ActivateTriggers() before InitializeConnection()");
53279     if (resp.IsBound())
53280       resp.Reject();
53281     return;
53282   }
53283   std::vector<std::string> triggers;
53284   for (const auto& name : proto_req.trigger_names()) {
53285     triggers.push_back(name);
53286   }
53287   producer->service_endpoint->ActivateTriggers(triggers);
53288   // ActivateTriggers shouldn't expect any meaningful response, avoid
53289   // a useless IPC in that case.
53290   if (resp.IsBound()) {
53291     resp.Resolve(
53292         ipc::AsyncResult<protos::gen::ActivateTriggersResponse>::Create());
53293   }
53294 }
53295 
GetAsyncCommand(const protos::gen::GetAsyncCommandRequest &,DeferredGetAsyncCommandResponse response)53296 void ProducerIPCService::GetAsyncCommand(
53297     const protos::gen::GetAsyncCommandRequest&,
53298     DeferredGetAsyncCommandResponse response) {
53299   RemoteProducer* producer = GetProducerForCurrentRequest();
53300   if (!producer) {
53301     PERFETTO_DLOG(
53302         "Producer invoked GetAsyncCommand() before "
53303         "InitializeConnection()");
53304     return response.Reject();
53305   }
53306   // Keep the back channel open, without ever resolving the ipc::Deferred fully,
53307   // to send async commands to the RemoteProducer (e.g., starting/stopping a
53308   // data source).
53309   producer->async_producer_commands = std::move(response);
53310 
53311   // Service may already have issued the OnTracingSetup() event, in which case
53312   // we should forward it to the producer now.
53313   if (producer->send_setup_tracing_on_async_commands_bound)
53314     producer->SendSetupTracing();
53315 }
53316 
Sync(const protos::gen::SyncRequest &,DeferredSyncResponse resp)53317 void ProducerIPCService::Sync(const protos::gen::SyncRequest&,
53318                               DeferredSyncResponse resp) {
53319   RemoteProducer* producer = GetProducerForCurrentRequest();
53320   if (!producer) {
53321     PERFETTO_DLOG("Producer invoked Sync() before InitializeConnection()");
53322     return resp.Reject();
53323   }
53324   auto weak_this = weak_ptr_factory_.GetWeakPtr();
53325   auto resp_it = pending_syncs_.insert(pending_syncs_.end(), std::move(resp));
53326   auto callback = [weak_this, resp_it]() {
53327     if (!weak_this)
53328       return;
53329     auto pending_resp = std::move(*resp_it);
53330     weak_this->pending_syncs_.erase(resp_it);
53331     pending_resp.Resolve(ipc::AsyncResult<protos::gen::SyncResponse>::Create());
53332   };
53333   producer->service_endpoint->Sync(callback);
53334 }
53335 
53336 ////////////////////////////////////////////////////////////////////////////////
53337 // RemoteProducer methods
53338 ////////////////////////////////////////////////////////////////////////////////
53339 
53340 ProducerIPCService::RemoteProducer::RemoteProducer() = default;
53341 ProducerIPCService::RemoteProducer::~RemoteProducer() = default;
53342 
53343 // Invoked by the |core_service_| business logic after the ConnectProducer()
53344 // call. There is nothing to do here, we really expected the ConnectProducer()
53345 // to just work in the local case.
OnConnect()53346 void ProducerIPCService::RemoteProducer::OnConnect() {}
53347 
53348 // Invoked by the |core_service_| business logic after we destroy the
53349 // |service_endpoint| (in the RemoteProducer dtor).
OnDisconnect()53350 void ProducerIPCService::RemoteProducer::OnDisconnect() {}
53351 
53352 // Invoked by the |core_service_| business logic when it wants to create a new
53353 // data source.
SetupDataSource(DataSourceInstanceID dsid,const DataSourceConfig & cfg)53354 void ProducerIPCService::RemoteProducer::SetupDataSource(
53355     DataSourceInstanceID dsid,
53356     const DataSourceConfig& cfg) {
53357   if (!async_producer_commands.IsBound()) {
53358     PERFETTO_DLOG(
53359         "The Service tried to create a new data source but the remote Producer "
53360         "has not yet initialized the connection");
53361     return;
53362   }
53363   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
53364   cmd.set_has_more(true);
53365   cmd->mutable_setup_data_source()->set_new_instance_id(dsid);
53366   *cmd->mutable_setup_data_source()->mutable_config() = cfg;
53367   async_producer_commands.Resolve(std::move(cmd));
53368 }
53369 
53370 // Invoked by the |core_service_| business logic when it wants to start a new
53371 // data source.
StartDataSource(DataSourceInstanceID dsid,const DataSourceConfig & cfg)53372 void ProducerIPCService::RemoteProducer::StartDataSource(
53373     DataSourceInstanceID dsid,
53374     const DataSourceConfig& cfg) {
53375   if (!async_producer_commands.IsBound()) {
53376     PERFETTO_DLOG(
53377         "The Service tried to start a new data source but the remote Producer "
53378         "has not yet initialized the connection");
53379     return;
53380   }
53381   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
53382   cmd.set_has_more(true);
53383   cmd->mutable_start_data_source()->set_new_instance_id(dsid);
53384   *cmd->mutable_start_data_source()->mutable_config() = cfg;
53385   async_producer_commands.Resolve(std::move(cmd));
53386 }
53387 
StopDataSource(DataSourceInstanceID dsid)53388 void ProducerIPCService::RemoteProducer::StopDataSource(
53389     DataSourceInstanceID dsid) {
53390   if (!async_producer_commands.IsBound()) {
53391     PERFETTO_DLOG(
53392         "The Service tried to stop a data source but the remote Producer "
53393         "has not yet initialized the connection");
53394     return;
53395   }
53396   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
53397   cmd.set_has_more(true);
53398   cmd->mutable_stop_data_source()->set_instance_id(dsid);
53399   async_producer_commands.Resolve(std::move(cmd));
53400 }
53401 
OnTracingSetup()53402 void ProducerIPCService::RemoteProducer::OnTracingSetup() {
53403   if (!async_producer_commands.IsBound()) {
53404     // Service may call this before the producer issued GetAsyncCommand.
53405     send_setup_tracing_on_async_commands_bound = true;
53406     return;
53407   }
53408   SendSetupTracing();
53409 }
53410 
SendSetupTracing()53411 void ProducerIPCService::RemoteProducer::SendSetupTracing() {
53412   PERFETTO_CHECK(async_producer_commands.IsBound());
53413   PERFETTO_CHECK(service_endpoint->shared_memory());
53414   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
53415   cmd.set_has_more(true);
53416   auto setup_tracing = cmd->mutable_setup_tracing();
53417   if (!service_endpoint->IsShmemProvidedByProducer()) {
53418     // Nominal case (% Chrome): service provides SMB.
53419     setup_tracing->set_shared_buffer_page_size_kb(
53420         static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
53421     const int shm_fd =
53422         static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
53423             ->fd();
53424     cmd.set_fd(shm_fd);
53425   }
53426   async_producer_commands.Resolve(std::move(cmd));
53427 }
53428 
Flush(FlushRequestID flush_request_id,const DataSourceInstanceID * data_source_ids,size_t num_data_sources)53429 void ProducerIPCService::RemoteProducer::Flush(
53430     FlushRequestID flush_request_id,
53431     const DataSourceInstanceID* data_source_ids,
53432     size_t num_data_sources) {
53433   if (!async_producer_commands.IsBound()) {
53434     PERFETTO_DLOG(
53435         "The Service tried to request a flush but the remote Producer has not "
53436         "yet initialized the connection");
53437     return;
53438   }
53439   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
53440   cmd.set_has_more(true);
53441   for (size_t i = 0; i < num_data_sources; i++)
53442     cmd->mutable_flush()->add_data_source_ids(data_source_ids[i]);
53443   cmd->mutable_flush()->set_request_id(flush_request_id);
53444   async_producer_commands.Resolve(std::move(cmd));
53445 }
53446 
ClearIncrementalState(const DataSourceInstanceID * data_source_ids,size_t num_data_sources)53447 void ProducerIPCService::RemoteProducer::ClearIncrementalState(
53448     const DataSourceInstanceID* data_source_ids,
53449     size_t num_data_sources) {
53450   if (!async_producer_commands.IsBound()) {
53451     PERFETTO_DLOG(
53452         "The Service tried to request an incremental state invalidation, but "
53453         "the remote Producer has not yet initialized the connection");
53454     return;
53455   }
53456   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
53457   cmd.set_has_more(true);
53458   for (size_t i = 0; i < num_data_sources; i++)
53459     cmd->mutable_clear_incremental_state()->add_data_source_ids(
53460         data_source_ids[i]);
53461   async_producer_commands.Resolve(std::move(cmd));
53462 }
53463 
53464 }  // namespace perfetto
53465 // gen_amalgamated begin source: src/tracing/ipc/service/service_ipc_host_impl.cc
53466 // gen_amalgamated begin header: src/tracing/ipc/service/service_ipc_host_impl.h
53467 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/service_ipc_host.h
53468 /*
53469  * Copyright (C) 2017 The Android Open Source Project
53470  *
53471  * Licensed under the Apache License, Version 2.0 (the "License");
53472  * you may not use this file except in compliance with the License.
53473  * You may obtain a copy of the License at
53474  *
53475  *      http://www.apache.org/licenses/LICENSE-2.0
53476  *
53477  * Unless required by applicable law or agreed to in writing, software
53478  * distributed under the License is distributed on an "AS IS" BASIS,
53479  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53480  * See the License for the specific language governing permissions and
53481  * limitations under the License.
53482  */
53483 
53484 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
53485 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
53486 
53487 #include <memory>
53488 
53489 // gen_amalgamated expanded: #include "perfetto/base/export.h"
53490 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
53491 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
53492 
53493 namespace perfetto {
53494 namespace base {
53495 class TaskRunner;
53496 }  // namespace base.
53497 
53498 class TracingService;
53499 
53500 // Creates an instance of the service (business logic + UNIX socket transport).
53501 // Exposed to:
53502 //   The code in the tracing client that will host the service e.g., traced.
53503 // Implemented in:
53504 //   src/tracing/ipc/service/service_ipc_host_impl.cc
53505 class PERFETTO_EXPORT ServiceIPCHost {
53506  public:
53507   static std::unique_ptr<ServiceIPCHost> CreateInstance(base::TaskRunner*);
53508   virtual ~ServiceIPCHost();
53509 
53510   // Start listening on the Producer & Consumer ports. Returns false in case of
53511   // failure (e.g., something else is listening on |socket_name|).
53512   virtual bool Start(const char* producer_socket_name,
53513                      const char* consumer_socket_name) = 0;
53514 
53515   // Like the above, but takes two file descriptors to already bound sockets.
53516   // This is used when building as part of the Android tree, where init opens
53517   // and binds the socket beore exec()-ing us.
53518   virtual bool Start(base::ScopedFile producer_socket_fd,
53519                      base::ScopedFile consumer_socket_fd) = 0;
53520 
53521   virtual TracingService* service() const = 0;
53522 
53523  protected:
53524   ServiceIPCHost();
53525 
53526  private:
53527   ServiceIPCHost(const ServiceIPCHost&) = delete;
53528   ServiceIPCHost& operator=(const ServiceIPCHost&) = delete;
53529 };
53530 
53531 }  // namespace perfetto
53532 
53533 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
53534 /*
53535  * Copyright (C) 2017 The Android Open Source Project
53536  *
53537  * Licensed under the Apache License, Version 2.0 (the "License");
53538  * you may not use this file except in compliance with the License.
53539  * You may obtain a copy of the License at
53540  *
53541  *      http://www.apache.org/licenses/LICENSE-2.0
53542  *
53543  * Unless required by applicable law or agreed to in writing, software
53544  * distributed under the License is distributed on an "AS IS" BASIS,
53545  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53546  * See the License for the specific language governing permissions and
53547  * limitations under the License.
53548  */
53549 
53550 #ifndef SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
53551 #define SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
53552 
53553 #include <memory>
53554 
53555 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
53556 
53557 namespace perfetto {
53558 
53559 namespace ipc {
53560 class Host;
53561 }
53562 
53563 // The implementation of the IPC host for the tracing service. This class does
53564 // very few things: it mostly initializes the IPC transport. The actual
53565 // implementation of the IPC <> Service business logic glue lives in
53566 // producer_ipc_service.cc and consumer_ipc_service.cc.
53567 class ServiceIPCHostImpl : public ServiceIPCHost {
53568  public:
53569   ServiceIPCHostImpl(base::TaskRunner*);
53570   ~ServiceIPCHostImpl() override;
53571 
53572   // ServiceIPCHost implementation.
53573   bool Start(const char* producer_socket_name,
53574              const char* consumer_socket_name) override;
53575   bool Start(base::ScopedFile producer_socket_fd,
53576              base::ScopedFile consumer_socket_fd) override;
53577 
53578   TracingService* service() const override;
53579 
53580  private:
53581   bool DoStart();
53582   void Shutdown();
53583 
53584   base::TaskRunner* const task_runner_;
53585   std::unique_ptr<TracingService> svc_;  // The service business logic.
53586 
53587   // The IPC host that listens on the Producer socket. It owns the
53588   // PosixServiceProducerPort instance which deals with all producers' IPC(s).
53589   std::unique_ptr<ipc::Host> producer_ipc_port_;
53590 
53591   // As above, but for the Consumer port.
53592   std::unique_ptr<ipc::Host> consumer_ipc_port_;
53593 };
53594 
53595 }  // namespace perfetto
53596 
53597 #endif  // SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
53598 /*
53599  * Copyright (C) 2017 The Android Open Source Project
53600  *
53601  * Licensed under the Apache License, Version 2.0 (the "License");
53602  * you may not use this file except in compliance with the License.
53603  * You may obtain a copy of the License at
53604  *
53605  *      http://www.apache.org/licenses/LICENSE-2.0
53606  *
53607  * Unless required by applicable law or agreed to in writing, software
53608  * distributed under the License is distributed on an "AS IS" BASIS,
53609  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53610  * See the License for the specific language governing permissions and
53611  * limitations under the License.
53612  */
53613 
53614 // gen_amalgamated expanded: #include "src/tracing/ipc/service/service_ipc_host_impl.h"
53615 
53616 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
53617 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
53618 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
53619 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
53620 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
53621 // gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
53622 // gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
53623 
53624 namespace perfetto {
53625 
53626 // TODO(fmayer): implement per-uid connection limit (b/69093705).
53627 
53628 // Implements the publicly exposed factory method declared in
53629 // include/tracing/posix_ipc/posix_service_host.h.
CreateInstance(base::TaskRunner * task_runner)53630 std::unique_ptr<ServiceIPCHost> ServiceIPCHost::CreateInstance(
53631     base::TaskRunner* task_runner) {
53632   return std::unique_ptr<ServiceIPCHost>(new ServiceIPCHostImpl(task_runner));
53633 }
53634 
ServiceIPCHostImpl(base::TaskRunner * task_runner)53635 ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner)
53636     : task_runner_(task_runner) {}
53637 
~ServiceIPCHostImpl()53638 ServiceIPCHostImpl::~ServiceIPCHostImpl() {}
53639 
Start(const char * producer_socket_name,const char * consumer_socket_name)53640 bool ServiceIPCHostImpl::Start(const char* producer_socket_name,
53641                                const char* consumer_socket_name) {
53642   PERFETTO_CHECK(!svc_);  // Check if already started.
53643 
53644   // Initialize the IPC transport.
53645   producer_ipc_port_ =
53646       ipc::Host::CreateInstance(producer_socket_name, task_runner_);
53647   consumer_ipc_port_ =
53648       ipc::Host::CreateInstance(consumer_socket_name, task_runner_);
53649   return DoStart();
53650 }
53651 
Start(base::ScopedFile producer_socket_fd,base::ScopedFile consumer_socket_fd)53652 bool ServiceIPCHostImpl::Start(base::ScopedFile producer_socket_fd,
53653                                base::ScopedFile consumer_socket_fd) {
53654   PERFETTO_CHECK(!svc_);  // Check if already started.
53655 
53656   // Initialize the IPC transport.
53657   producer_ipc_port_ =
53658       ipc::Host::CreateInstance(std::move(producer_socket_fd), task_runner_);
53659   consumer_ipc_port_ =
53660       ipc::Host::CreateInstance(std::move(consumer_socket_fd), task_runner_);
53661   return DoStart();
53662 }
53663 
DoStart()53664 bool ServiceIPCHostImpl::DoStart() {
53665   // Create and initialize the platform-independent tracing business logic.
53666   std::unique_ptr<SharedMemory::Factory> shm_factory(
53667       new PosixSharedMemory::Factory());
53668   svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_);
53669 
53670   if (!producer_ipc_port_ || !consumer_ipc_port_) {
53671     Shutdown();
53672     return false;
53673   }
53674 
53675   // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
53676   // Start() and checks that no spurious callbacks are issued.
53677   bool producer_service_exposed = producer_ipc_port_->ExposeService(
53678       std::unique_ptr<ipc::Service>(new ProducerIPCService(svc_.get())));
53679   PERFETTO_CHECK(producer_service_exposed);
53680 
53681   bool consumer_service_exposed = consumer_ipc_port_->ExposeService(
53682       std::unique_ptr<ipc::Service>(new ConsumerIPCService(svc_.get())));
53683   PERFETTO_CHECK(consumer_service_exposed);
53684 
53685   return true;
53686 }
53687 
service() const53688 TracingService* ServiceIPCHostImpl::service() const {
53689   return svc_.get();
53690 }
53691 
Shutdown()53692 void ServiceIPCHostImpl::Shutdown() {
53693   // TODO(primiano): add a test that causes the Shutdown() and checks that no
53694   // spurious callbacks are issued.
53695   producer_ipc_port_.reset();
53696   consumer_ipc_port_.reset();
53697   svc_.reset();
53698 }
53699 
53700 // Definitions for the base class ctor/dtor.
53701 ServiceIPCHost::ServiceIPCHost() = default;
53702 ServiceIPCHost::~ServiceIPCHost() = default;
53703 
53704 }  // namespace perfetto
53705 // gen_amalgamated begin source: src/tracing/internal/system_tracing_backend.cc
53706 /*
53707  * Copyright (C) 2019 The Android Open Source Project
53708  *
53709  * Licensed under the Apache License, Version 2.0 (the "License");
53710  * you may not use this file except in compliance with the License.
53711  * You may obtain a copy of the License at
53712  *
53713  *      http://www.apache.org/licenses/LICENSE-2.0
53714  *
53715  * Unless required by applicable law or agreed to in writing, software
53716  * distributed under the License is distributed on an "AS IS" BASIS,
53717  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53718  * See the License for the specific language governing permissions and
53719  * limitations under the License.
53720  */
53721 
53722 // gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
53723 
53724 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
53725 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
53726 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
53727 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
53728 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
53729 
53730 namespace perfetto {
53731 namespace internal {
53732 
53733 // static
GetInstance()53734 TracingBackend* SystemTracingBackend::GetInstance() {
53735   static auto* instance = new SystemTracingBackend();
53736   return instance;
53737 }
53738 
SystemTracingBackend()53739 SystemTracingBackend::SystemTracingBackend() {}
53740 
ConnectProducer(const ConnectProducerArgs & args)53741 std::unique_ptr<ProducerEndpoint> SystemTracingBackend::ConnectProducer(
53742     const ConnectProducerArgs& args) {
53743   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
53744 
53745   auto endpoint = ProducerIPCClient::Connect(
53746       GetProducerSocket(), args.producer, args.producer_name, args.task_runner,
53747       TracingService::ProducerSMBScrapingMode::kEnabled,
53748       args.shmem_size_hint_bytes, args.shmem_page_size_hint_bytes, nullptr,
53749       nullptr, ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable);
53750   PERFETTO_CHECK(endpoint);
53751   return endpoint;
53752 }
53753 
ConnectConsumer(const ConnectConsumerArgs &)53754 std::unique_ptr<ConsumerEndpoint> SystemTracingBackend::ConnectConsumer(
53755     const ConnectConsumerArgs&) {
53756   PERFETTO_FATAL(
53757       "Trace session creation is not supported yet when using the system "
53758       "tracing backend. Use the perfetto cmdline client instead to start "
53759       "system-wide tracing sessions");
53760 }
53761 
53762 }  // namespace internal
53763 }  // namespace perfetto
53764 // gen_amalgamated begin source: src/tracing/platform_posix.cc
53765 /*
53766  * Copyright (C) 2019 The Android Open Source Project
53767  *
53768  * Licensed under the Apache License, Version 2.0 (the "License");
53769  * you may not use this file except in compliance with the License.
53770  * You may obtain a copy of the License at
53771  *
53772  *      http://www.apache.org/licenses/LICENSE-2.0
53773  *
53774  * Unless required by applicable law or agreed to in writing, software
53775  * distributed under the License is distributed on an "AS IS" BASIS,
53776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53777  * See the License for the specific language governing permissions and
53778  * limitations under the License.
53779  */
53780 
53781 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
53782 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
53783 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
53784 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
53785 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
53786 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
53787 
53788 #include <pthread.h>
53789 #include <stdlib.h>
53790 
53791 namespace perfetto {
53792 
53793 namespace {
53794 
53795 class PlatformPosix : public Platform {
53796  public:
53797   PlatformPosix();
53798   ~PlatformPosix() override;
53799 
53800   ThreadLocalObject* GetOrCreateThreadLocalObject() override;
53801   std::unique_ptr<base::TaskRunner> CreateTaskRunner(
53802       const CreateTaskRunnerArgs&) override;
53803   std::string GetCurrentProcessName() override;
53804 
53805  private:
53806   pthread_key_t tls_key_{};
53807 };
53808 
53809 // TODO(primiano): make base::ThreadTaskRunner directly inherit TaskRunner, so
53810 // we can avoid this boilerplate.
53811 class TaskRunnerInstance : public base::TaskRunner {
53812  public:
53813   TaskRunnerInstance();
53814   ~TaskRunnerInstance() override;
53815 
53816   void PostTask(std::function<void()>) override;
53817   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
53818   void AddFileDescriptorWatch(int fd, std::function<void()>) override;
53819   void RemoveFileDescriptorWatch(int fd) override;
53820   bool RunsTasksOnCurrentThread() const override;
53821 
53822  private:
53823   base::ThreadTaskRunner thread_task_runner_;
53824 };
53825 
53826 using ThreadLocalObject = Platform::ThreadLocalObject;
53827 
PlatformPosix()53828 PlatformPosix::PlatformPosix() {
53829   auto tls_dtor = [](void* obj) {
53830     delete static_cast<ThreadLocalObject*>(obj);
53831   };
53832   PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
53833 }
53834 
~PlatformPosix()53835 PlatformPosix::~PlatformPosix() {
53836   pthread_key_delete(tls_key_);
53837 }
53838 
GetOrCreateThreadLocalObject()53839 ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
53840   // In chromium this should be implemented using base::ThreadLocalStorage.
53841   auto tls = static_cast<ThreadLocalObject*>(pthread_getspecific(tls_key_));
53842   if (!tls) {
53843     tls = ThreadLocalObject::CreateInstance().release();
53844     pthread_setspecific(tls_key_, tls);
53845   }
53846   return tls;
53847 }
53848 
CreateTaskRunner(const CreateTaskRunnerArgs &)53849 std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
53850     const CreateTaskRunnerArgs&) {
53851   return std::unique_ptr<base::TaskRunner>(new TaskRunnerInstance());
53852 }
53853 
GetCurrentProcessName()53854 std::string PlatformPosix::GetCurrentProcessName() {
53855 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
53856     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
53857   std::string cmdline;
53858   base::ReadFile("/proc/self/cmdline", &cmdline);
53859   return cmdline.substr(0, cmdline.find('\0'));
53860 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
53861   return std::string(getprogname());
53862 #else
53863   return "unknown_producer";
53864 #endif
53865 }
53866 
TaskRunnerInstance()53867 TaskRunnerInstance::TaskRunnerInstance()
53868     : thread_task_runner_(base::ThreadTaskRunner::CreateAndStart()) {}
53869 TaskRunnerInstance::~TaskRunnerInstance() = default;
PostTask(std::function<void ()> func)53870 void TaskRunnerInstance::PostTask(std::function<void()> func) {
53871   thread_task_runner_.get()->PostTask(func);
53872 }
53873 
PostDelayedTask(std::function<void ()> func,uint32_t delay_ms)53874 void TaskRunnerInstance::PostDelayedTask(std::function<void()> func,
53875                                          uint32_t delay_ms) {
53876   thread_task_runner_.get()->PostDelayedTask(func, delay_ms);
53877 }
53878 
AddFileDescriptorWatch(int fd,std::function<void ()> func)53879 void TaskRunnerInstance::AddFileDescriptorWatch(int fd,
53880                                                 std::function<void()> func) {
53881   thread_task_runner_.get()->AddFileDescriptorWatch(fd, func);
53882 }
53883 
RemoveFileDescriptorWatch(int fd)53884 void TaskRunnerInstance::RemoveFileDescriptorWatch(int fd) {
53885   thread_task_runner_.get()->RemoveFileDescriptorWatch(fd);
53886 }
53887 
RunsTasksOnCurrentThread() const53888 bool TaskRunnerInstance::RunsTasksOnCurrentThread() const {
53889   return thread_task_runner_.get()->RunsTasksOnCurrentThread();
53890 }
53891 
53892 }  // namespace
53893 
53894 // static
GetDefaultPlatform()53895 Platform* Platform::GetDefaultPlatform() {
53896   static PlatformPosix* instance = new PlatformPosix();
53897   return instance;
53898 }
53899 
53900 }  // namespace perfetto
53901 
53902